<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>I support the notion of the general synthetic marker.  We ended
      up developing something very similar in downstream patches related
      to our embedded high level IR abstraction notion.  While we've
      been slowly migrating away from the original heavy use of such
      abstractions, they were an *incredibly* powerful tool for
      prototyping designs and figuring out what a good long term
      designed looked like.  Having first class support for this type of
      design prototyping upstream seems like a wonderful idea to me.</p>
    <p>Quick semantic question: Do you intend the marker to prevent
      removal of an otherwise internal function without uses?  (i.e. can
      you custom passes *insert* uses?)  We've found semantics both with
      and without to be useful.  I'm just wanting to clarify what you
      intend.  A reasonable design would be to have "synthetic" allow
      global dce, but add an orthogonal attribute for the alternate
      case.  (We call ours "has-latent-use".)<br>
    </p>
    <p>Philip<br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 01/09/2018 10:20 PM, John McCall via
      llvm-dev wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:D29B55B9-0FC8-4E0C-9F71-827AD857E7B3@apple.com">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <div class=""><b class="">Summary</b></div>
      <div class=""><br class="">
      </div>
      <div class="">I would like to propose that we add the following
        function attribute to LLVM:</div>
      <div class=""><br class="">
      </div>
      <div class="">  synthetic(<string>)</div>
      <div class=""><br class="">
      </div>
      <div class="">This attribute can only be applied to functions.  It
        is not a semantic statement about the function it decorates.  It
        is, instead, an explicit directive to LLVM to not attempt to
        propagate information about the function body outside of the
        function, including by changing the attributes of the function.
         The expectation is that some special pass will eventually
        remove the attribute and enable normal optimization.</div>
      <div class=""><br class="">
      </div>
      <div class="">So, why should we add this?</div>
      <div class=""><br class="">
      </div>
      <div class=""><b class="">Problem: coroutine structure</b></div>
      <div class=""><br class="">
      </div>
      <div class="">I've recently been working on implementing
        coroutines for Swift.  This involves embracing and extending
        Gor's excellent work on LLVM coroutines with an alternate
        code-generation pattern and ABI. (*)  LLVM doesn't natively
        support coroutines, which means that a pre-split coroutine
        represented in IR looks rather artificial.</div>
      <div class=""><br class="">
      </div>
      <div class="">
        <div class="">
          <div class="">(* This work has been happening out-of-tree
            while I qualify the design with Swift frontend support.
             That doesn't mean it's closed-source; if you're curious,
            you can see the current documentation update here:</div>
          <div class="">  <a
href="https://github.com/apple/swift-llvm/blob/upstream-with-swift/docs/Coroutines.rst"
              class="" moz-do-not-send="true">https://github.com/apple/swift-llvm/blob/upstream-with-swift/docs/Coroutines.rst</a></div>
          <div class="">or just check out the implementation:</div>
          <div class="">  <a
href="https://github.com/apple/swift-llvm/tree/upstream-with-swift/lib/Transforms/Coroutines"
              class="" moz-do-not-send="true">https://github.com/apple/swift-llvm/tree/upstream-with-swift/lib/Transforms/Coroutines</a></div>
        </div>
        <div class="">I promise it will be submitted to LLVM when we've
          proven the design to our satisfaction by starting to use it in
          the frontend.  That should be within the next few months.)</div>
      </div>
      <div class=""><br class="">
      </div>
      <div class="">For example, here's a simple coroutine:</div>
      <div class="">
        <div class=""><br class="">
        </div>
        <blockquote style="margin: 0 0 0 40px; border: none; padding:
          0px;" class="">
          <div class="">
            <div class="">define i8* @f(i8* %buffer, i32 %n) {</div>
          </div>
          <div class="">
            <div class="">entry:</div>
          </div>
          <div class="">
            <div class="">  %id = call token @llvm.coro.id.retcon(i32 8,
              i32 4, i8* %buffer, i8* bitcast (i8* (i8*, i1)* @prototype
              to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8*
              bitcast (void (i8*)* @deallocate to i8*))</div>
          </div>
          <div class="">
            <div class="">  %hdl = call i8* @llvm.coro.begin(token %id,
              i8* null)</div>
          </div>
          <div class="">
            <div class="">  br label %loop</div>
          </div>
          <div class="">
            <div class=""><br class="">
            </div>
          </div>
          <div class="">
            <div class="">loop:</div>
          </div>
          <div class="">
            <div class="">  %n.val = phi i32 [ %n, %entry ], [ %inc,
              %resume ]</div>
          </div>
          <div class="">
            <div class="">  call void @print(i32 %n.val)</div>
          </div>
          <div class="">
            <div class="">  %unwind0 = call i1 (...)
              @llvm.coro.suspend.retcon.i1()</div>
          </div>
          <div class="">
            <div class="">  br i1 %unwind0, label %cleanup, label
              %resume</div>
          </div>
          <div class="">
            <div class=""><br class="">
            </div>
          </div>
          <div class="">
            <div class="">resume:</div>
          </div>
          <div class="">
            <div class="">  %inc = add i32 %n.val, 1</div>
          </div>
          <div class="">
            <div class="">  br label %loop</div>
          </div>
          <div class="">
            <div class=""><br class="">
            </div>
          </div>
          <div class="">
            <div class="">cleanup:</div>
          </div>
          <div class="">
            <div class="">  call i1 @llvm.coro.end(i8* %hdl, i1 0)</div>
          </div>
          <div class="">
            <div class="">  unreachable</div>
          </div>
          <div class="">
            <div class="">}</div>
          </div>
        </blockquote>
        <div class="">
          <div class=""><br class="">
          </div>
          <div class="">In this function body, the coroutine intrinsics
            are structurally special: they are tied to the identity of
            this function and cannot be independently understood.  This
            is true in the same general sense that "ret" and "unwind"
            are structurally special in an ordinary function.  The
            control flow and semantics of this function are *internally*
            consistent and correct, and accordingly most
            intra-procedural analyses will not pose a problem.  However,
            its interaction with other functions, and especially with
            its caller, cannot be understood by a naive function-wide
            analysis which does not know about these intrinsics.  Such
            an analysis is likely to take actions that would cause a
            miscompile.</div>
          <div class=""><br class="">
          </div>
          <div class="">For example:</div>
          <div class=""><br class="">
          </div>
          <div class="">  - It is not legal to clone these intrinsics
            into another function, e.g. during inlining.  A function is
            a coroutine if (and only if) it contains an @llvm.coro.id.*
            call.  Cloning the 'id' call into the caller would turn that
            function into a coroutine, which is not correct.  Similarly,
            cloning a 'suspend' into the caller would probably create
            malformed IR and, if not, would be semantically incorrect in
            the same way as cloning a "ret" into the caller would be.</div>
          <div class=""><br class="">
          </div>
          <div class="">  - Some of these intrinsics will be expanded to
            things that are not ordinarily legal for functions to expand
            to.  For example, the llvm.coro.suspend call will expand
            into a code sequence that contains a return.  The
            llvm.coro.end call also expands to contain a return, but
            with different semantics.  An analysis that does not know
            that might add the 'noreturn' attribute to this function,
            which will then be incorrect after expansion.  If a caller
            propagates that information to its call site, it will be
            badly miscompiled.</div>
          <div class=""><br class="">
          </div>
          <div class="">We need some way to stop these things from
            happening.</div>
          <div class=""><br class="">
          </div>
          <div class=""><b class="">Should we just update existing
              passes to know about these intrinsics?</b></div>
          <div class=""><br class="">
          </div>
          <div class="">This is a reasonable question, but I am quite
            convinced the answer is "no".</div>
          <div class=""><br class="">
          </div>
          <div class="">Even just considering coroutines, I think this
            is not really a reasonable request.  There may be many
            different places that would need to updated to know about
            most of these intrinsics.  Moreover, it is likely that the
            set of intrinsics will grow and change over time, because
            the details of LLVM coroutine lowering are very much in
            flux, for a pair of reasons:</div>
          <div class=""><br class="">
          </div>
          <div class="">  - First, there isn't a standard,
            widely-accepted ABI for coroutines.  For ordinary functions,
            there's general agreement on concepts like "return
            addresses", "return registers", "argument registers",
            "argument areas", and "the stack", even if there's a lot of
            target-specific variation in how to apply them.  But with
            coroutines, there's a lot of room for debate about how to do
            even basic things like allocating space for the execution
            record, yielding and resuming control, and passing values in
            and out of the coroutine.  I'm already adding a second ABI
            for Swift (in fact, I'm really adding two closely-related
            ABIs), and more will come after that.  These ABIs have
            trade-offs with each other, and I don't think that any one
            of them will eventually "win"; I think we'll just have to
            support them all, as they get adopted in different
            languages.</div>
          <div class=""><br class="">
          </div>
          <div class="">  - Even if there were agreement about the ABI,
            it's not clear to me that there's agreement about how best
            to compile and optimize them.  As we gain more experience
            with this, it is not unlikely that we will want to evolve
            the intrinsics.  I don't think we want to encumber all this
            experimentation with the need to go update a ton of
            analyses, especially when the right answer across all of
            them is generally just "ignore the function for now".</div>
          <div class=""><br class="">
          </div>
          <div class="">Moreover, I doubt that coroutines are the only
            feature with a similar set of problems.  My experience with
            compilers that have tried to use LLVM IR for higher-level
            analyses and optimizations is that they often want some way
            of explicitly limiting LLVM's ability to analyze their
            functions until they've gotten to a certain stage in the
            lowering.  This becomes more and more likely the more
            structurally interesting the IR gets.</div>
          <div class=""><br class="">
          </div>
          <div class=""><b class="">Aren't there already ways to make a
              function opaque?</b></div>
          <div class=""><br class="">
          </div>
          <div class="">Well, yes, but they're all independently
            meaningful, which is a problem.  You can block
            inter-procedural analysis by giving a function weak linkage,
            but at the end of the day, it's not okay to make all
            coroutine functions weak!  Coroutines ought to be able to
            have the same spectrum of linkages, visibilities, etc. as
            normal functions, so if we play linkage tricks to block
            analysis, we have to also find a way to tunnel the real
            linkage all the way to the coroutine lowering pass.  The
            same thing applies for 'noinline' — there might be good
            reasons to make the coroutine function 'noinline' even after
            lowering, so we have to tunnel the real value through.</div>
          <div class=""><br class="">
          </div>
          <div class="">It's possible to make the call indirect, e.g. by
            hiding the function pointer behind an intrinsic just in case
            it gets devirtualized, but this requires a lot of awkward
            casting (all of which needs to be removed in order to make
            the call properly direct if possible later), and it creates
            a bunch of extra IR that then needs to be removed at the
            right point in a careful phase-order with the lowering.
             Still, it works, which is why it's how I'm currently trying
            to solve the problem.  However:</div>
          <div class=""><br class="">
          </div>
          <div class="">None of those approaches stops passes from
            changing the function attributes based on the function body,
            like the (very real) example above of an analysis that
            decides that the coroutine cannot return.  As far as I know,
            there's no way to stop this; my current pass just has
            explicit code to remove 'noreturn' when doing the lowering,
            but that does not seem like a satisfactory solution.</div>
          <div class=""><br class="">
          </div>
          <div class="">That is why I think we should have a dedicated
            attribute whose sole purpose is to block analysis.</div>
        </div>
      </div>
      <div class=""><br class="">
      </div>
      <div class="">John.</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>