<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    I also haven't seen this discussion.  Can you provide a pointer to
    the thread where this was discussed?<br>
    <br>
    p.s. If this discussion *hasn't* happened, that would definitely be
    a blocker for any of the specific work discussed below.<br>
    <br>
    Philip<br>
    <br>
    <div class="moz-cite-prefix">On 07/14/2016 10:48 PM, Vadim Chugunov
      via llvm-dev wrote:<br>
    </div>
    <blockquote
cite="mid:CADecdiJcDk3misFib4vTYh7FJoSvp-Hx8EQHS864bgmKuGq7rw@mail.gmail.com"
      type="cite">
      <div dir="ltr">Hi!
        <div>Sorry for jumping in late, but I have a general question
          (that I perhaps should have asked during round 1):
          <div><br>
            <div>This proposal jumps straight into the thick of
              implementation, but I don't think I've seen a motivation
              of why coroutines need to be represented at the LLVM IR
              level.   Can't this transform be performed entirely in the
              front-end?</div>
            <div><br>
            </div>
            <div>Vadim</div>
          </div>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Thu, Jul 14, 2016 at 9:28 PM, Gor
          Nishanov via llvm-dev <span dir="ltr"><<a
              moz-do-not-send="true"
              href="mailto:llvm-dev@lists.llvm.org" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a></a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi David:<br>
            <span class=""><br>
              >> How do you deal with basic blocks which appear to
              be used by multiple parts<br>
              >> of the coroutine? We handled this in WinEHPrepare
              by cloning any BBs which<br>
              >> were shared.<br>
              <br>
            </span>I experimented with several approaches, but, cloning
            ended up being the simplest<br>
            and most reliable. Suspend points express three different
            control flows that<br>
            can happen at the suspend point: a suspension (default),
            resumption (0) and<br>
            destruction (1).<br>
            <br>
              %0 = call i8 @llvm.coro.suspend([..])<br>
              switch i8 %0, label %suspend [i8 0, label %resume,<br>
                                            i8 1, label %destroy]<br>
            <br>
            I slap a switch that jumps to all suspend points in the
            function. Then I clone<br>
            the function twice (one will become resume clone, and
            another destroy clone).<br>
            This switch becomes the entry block in the clones. Then, I
            RAUW coro.suspends<br>
            with -1, 0, or 1 (in original, resume and destroy clones
            respectively) and let<br>
            SimplifyCFG do the rest. (This is slightly simplified
            explanation, but it should<br>
             give the idea).<br>
            <span class=""><br>
              >> I would remove the attribute.  There are all
              sorts of tricks you can do to<br>
              >> avoid scanning the function for calls to the
              intrinsic.  For example, you<br>
              >> can see if a declaration of your intrinsic exists
              and, if so, if it has an<br>
              >> users in the function in question (under the
              assumption that there are few).<br>
              <br>
            </span>Aye-aye. Will remove the attribute.<br>
            <br>
            With respect to lessening the impact of coroutine passes,
            one approach I tried<br>
            was to look during doInitialize whether there are any uses
            of coroutine<br>
            intrinsics and set a flag if there are any, or maybe build a
            set of functions<br>
            with coroutines intrinsics in doInitialize, so that in
            runOnFunction, I can just<br>
            check whether the function is in the set and skip if it is
            not.<br>
            <br>
            Then, I scared myself silly that some optimization passes
            can materialize<br>
            new functions or new function bodies and I will miss them.
            So I stopped doing<br>
            that.<br>
            <br>
            I think your approach takes care of my "materialization"
            concern. (BTW, I don't<br>
            even know if that is a real concern). But may not be
            profitable if there are a<br>
            lot of small functions that are faster to scan for coroutine
            intrinsics then to<br>
            scan potentially longer list of coroutine intrinsics users.<br>
            <br>
            BTW, Do you have a preference on how to restart CGSCC
            pipeline? One of the four<br>
            options I listed (repeated in P.S), or even some better way
            I did not think<br>
            about?<br>
            <br>
            Thank you,<br>
            Gor<br>
            <br>
            P.S.<br>
            <br>
            Option 1: <a moz-do-not-send="true"
              href="https://reviews.llvm.org/D21569" rel="noreferrer"
              target="_blank">https://reviews.llvm.org/D21569</a> (no
            longer relevant, since we are<br>
                                                       removing
            AttrKind::Coroutine)<br>
            Option 2: <a moz-do-not-send="true"
              href="https://reviews.llvm.org/D21570" rel="noreferrer"
              target="_blank">https://reviews.llvm.org/D21570</a>
            (bool& Devirt in runSCC)<br>
            Option 3: <a moz-do-not-send="true"
              href="https://reviews.llvm.org/D21572" rel="noreferrer"
              target="_blank">https://reviews.llvm.org/D21572</a>
            (virtual bool restatedRequested())<br>
            Option 4: Fake devirtualized call in a function pass, so
            that RefreshSCC will<br>
                      detect devirtualization and restart the pipeline
            by itself.<br>
            <div class="HOEnZb">
              <div class="h5">_______________________________________________<br>
                LLVM Developers mailing list<br>
                <a moz-do-not-send="true"
                  href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
                <a moz-do-not-send="true"
                  href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev"
                  rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
              </div>
            </div>
          </blockquote>
        </div>
        <br>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
LLVM Developers mailing list
<a class="moz-txt-link-abbreviated" href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>