<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 12 May 2014 17:20, Andrew Trick <span dir="ltr"><<a href="mailto:atrick@apple.com" target="_blank">atrick@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div style="word-wrap:break-word"><br><div><div class=""><div>On May 12, 2014, at 3:52 PM, Philip Reames <<a href="mailto:listmail@philipreames.com" target="_blank">listmail@philipreames.com</a>> wrote:</div><br><blockquote type="cite">


  
    
  
  <div bgcolor="#FFFFFF" text="#000000">
    I don't have a strong opinion on this topic at the moment, but given
    that it is potentially GC related, I figured I'd speak up.  <br>
    <br>
    I see two unspoken assumptions in the thread so far:<br>
    - The runtime needs a means to bring all threads to a stop to
    perform some action.  In particular, no thread can be excepted.<br></div></blockquote><div><br></div></div><div>The *only* assumption that we want client to make of this API is that a compiler thread can be suspended at this point without blocking other non-compiler threads in the same process, or blocking other compiler threads associated with a *different* LLVM context.</div>

<div><br></div><div>There will be no assumption about the state of the suspended thread’s LLVM context and no assumption that other threads in the same context will continue executing (if there were such a thing).</div><div class="">

<div><br></div><blockquote type="cite"><div bgcolor="#FFFFFF" text="#000000">
    - A single LLVM library call takes longer to complete than the
    runtime is willing to wait for the thread stoppage to occur.  <br></div></blockquote><div><br></div></div><div>I’m not sure what you mean by this.</div><div class=""><div><br></div><blockquote type="cite"><div bgcolor="#FFFFFF" text="#000000">


    
    Both are entirely reasonable; I'm just spelling them out since they
    might not be obvious to everyone.  The second is particularly
    noteworthy since it's entirely new in LLVM.  <br>
    <br>
    I largely agree with Andy at the moment that the existing interface
    assumes one thread per context.  I don't see the issue with
    continuing with this assumption, particular since no one t.m.k. has
    put forward any serious plans to change this.  If this does happen,
    having it occur in an opt-in manner will be a matter of practical
    necessity.  <br></div></blockquote><div><br></div></div><div>I don’t think this API makes any assumption about LLVM’s threading model. I don’t even see how this API assumes one thread per context. However, I will concede that it does if it helps focus this discussion. Either way, the JIT should determine the threading model and be given a C API that allows configuring and scheduling those threads. As you correctly said, if we hypothetically implement a parallel pass manager mode that breaks some JITs, then clients will need to opt-in. We are not beholden to implement this callback in that mode. We just need to make that clear.</div>

<div class=""><div><br></div><blockquote type="cite"><div bgcolor="#FFFFFF" text="#000000">
    
    I find myself somewhat uncertain of the choice to leverage the pass
    manager for this purpose though.  It's the entirely logical place to
    start, but is it enough?  What if a single pass takes too long to
    complete?  Do we start scattering these call backs throughout large
    parts of LLVM?  Also, how does this interact with something like the
    hoped for parallel LTO?  <br>
    <br>
    Like Chandler, I believe there needs to be a fully thought out
    proposal and discussion on this list.  I would weakly oppose the
    change in it's current form solely on this basis.<br></div></blockquote><div><br></div></div><div>Would you (or anyone) oppose a simple maySuspendContext() callback API? It would mean nothing more than the thread(s) for a given LLVM context can be suspended independent from other contexts.</div>

</div></div></blockquote><div><br></div><div>I think this is the right approach. So a given thread hits a safe point, it optionally calls a "suspend check" or "i an safe to suspend right now" callback if set. It doesn't stop other threads, it doesn't continue until the function returns.</div>

<div><br></div><div>If you want to stop all threads then the user callback may contain a barrier and count down how many threads have stopped until it sees all of them.</div><div><br></div><div>Nick</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div style="word-wrap:break-word"><div><div class=""><blockquote type="cite"><div bgcolor="#FFFFFF" text="#000000">Andy, Juergen - Can you start by providing a bit more background
    information?  What do you need the thread yield call back for? 
    Garbage collection?  Other VM tasks?  User mode scheduling of
    threads?  Something else entirely?<br></div></blockquote><div><br></div></div>The thread yield API is primarily for user mode scheduling of threads. </div><div><br></div><div>A JIT could certainly use it for GC and other VM tasks. That isn’t necessary for us because those tasks can run concurrent with the LLVM thread until it completes. It would only be a problem if there are resource constraints.</div>

<div><br></div><div>-Andy</div><div><div class="h5"><div><br><blockquote type="cite"><div bgcolor="#FFFFFF" text="#000000">
    <br>
    Yours,<br>
    Philip<br>
    <br>
    <br>
    <br>
    <div>On 05/10/2014 11:11 AM, Juergen
      Ributzka wrote:<br>
    </div>
    <blockquote type="cite">
      
      <br>
      <div>
        <div>On May 9, 2014, at 7:36 PM, Andrew Trick <<a href="mailto:atrick@apple.com" target="_blank">atrick@apple.com</a>>
          wrote:</div>
        <br>
        <blockquote type="cite">
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">


            <div><br>
              On May 9, 2014, at 6:33 PM, Chandler Carruth <<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>>
              wrote:</div>
            <br>
            <blockquote type="cite">
              <div dir="ltr">So, I'm bringing a discussion that has thus
                far been on llvm-commits to llvmdev because I finally
                (and thanks for helping me understand this Andy)
                understand what is *really* going on, and I think lots
                of others need to be aware of this and involved to
                figure out the right path forward.
                <div><br>
                </div>
                <div>You can find the full review thread and more
                  context under the subject "[PATCH][PM] Add pass run
                  listeners to the pass manager.", but here is the
                  important bit from Juergen's initial email:</div>
                <div><br>
                </div>
                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span style="font-family:arial,sans-serif;font-size:13px">this patch provides
                    the necessary C/C++ APIs and infastructure to enable
                    fine-<br>
                  </span><span style="font-family:arial,sans-serif;font-size:13px">grain progress report and safe
                    suspension points after each </span><span style="font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,204);background-repeat:initial initial">pass</span><span style="font-family:arial,sans-serif;font-size:13px"> in the </span><span style="font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,204);background-repeat:initial initial">pass<br>


                  </span><span style="font-family:arial,sans-serif;font-size:13px">manager.</span> </blockquote>
                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> </blockquote>
                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span style="font-family:arial,sans-serif;font-size:13px">Clients can provide a
                    callback function to the </span><span style="font-family:arial,sans-serif;font-size:13px">pass</span><span style="font-family:arial,sans-serif;font-size:13px"> manager to call after
                    each<br>
                  </span><span style="font-family:arial,sans-serif;font-size:13px">pass</span><span style="font-family:arial,sans-serif;font-size:13px">. This can be used in a variety of ways
                    (progress report, dumping of IR<br>
                  </span><span style="font-family:arial,sans-serif;font-size:13px">between passes, safe suspension of
                    threads, etc).</span></blockquote>
                <div><br>
                </div>
                <div>I had wrongly (perhaps because of the
                  implementation, but still, wrongly) focused on the
                  progress report and IR dumping use cases. It sounds
                  (from talking to Andy offline, sorry for that
                  confusion) like the real use case is safe suspension
                  of threads. The idea is that we would have a callback
                  from the pass manager into the LLVMContext which would
                  be used to recognize safe points at which the entire
                  LLVMContext could be suspended, and to expose these
                  callbacks through C API to JIT users.</div>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>Good. Let’s table the discussion of how to report
              passes and just focus on the thread suspension API. It
              never occurred to me that a client using the new API for
              thread scheduling would not *already* be making an
              assumption about one thread per context. I believe
              anything else will break these clients regardless of the
              API. So I didn’t see this API as imposing a new
              restriction. The more explicit we can be about this, the
              better.</div>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>They not only have to make the assumption of one thread per
          context, but they actually have to enforce it. According to
          the comments in LLVMContext there is no locking guarantee and
          the user/client has to be careful to use one context per
          thread. This is the current C API and that is how clients are
          using it right now.</div>
        <div><br>
        </div>
        <div>Any future extension to the LLVMContext and to the pass
          manager that change this requirement - namely running in
          parallel - should be backwards compatible. Although I don’t
          see how this could or should be an issue to begin with as long
          we default to the current single-threaded execution model per
          LLVMContext. Anything that changes this behavior should and
          have to be explicitly requested by the client. That means
          there has to be a new C API call to communicate this
          information. For now all the threads are created by the client
          and I think this should also stay so in the future.</div>
        <br>
        <blockquote type="cite">
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">


            <blockquote type="cite">
              <div dir="ltr">Increasingly, I can't fathom a way to get a
                good design for safe suspension of JIT-ing threads using
                callbacks tied to when passes run today. I think it is a
                huge mistake to bake this into the C API at this point.
                If you need this functionality in the C API, with a
                design we can use going forward, I'd like to see a
                *really* careful write up of exactly what the suspension
                point requirements are and a design for achieving them.
                I think it should be completely independent from any
                infrastructure for reporting or dumping IR in pass
                managers.</div>
            </blockquote>
            <div><br>
            </div>
            <div>Yes, there absolutely needs to be a way to expose
              functionality within LLVM in its current form through the
              C API. We can say that the API works under some explicit
              set of rules. If some future LLVM can be configured in a
              way that breaks the rules, you don’t get the callback in
              that case.</div>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>It is already a conscious choice of the client if and how
          to use threads. This choice already affects how callbacks that
          we already have are implemented by the client. The same would
          apply for the proposed callback. The client knows exactly the
          conditions, because it is in full control of setting up the
          environment.</div>
        <br>
        <blockquote type="cite">
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

<br>
            <blockquote type="cite">
              <div dir="ltr">
                <div>I think something much simpler than this might work
                  outside of the C API, where we can essentially change
                  how it works when we start designing how multiple
                  threads will actually work within an LLVMContext.
                  Would that work? Is there a way to make progress more
                  rapidly there?</div>
                <div><br>
                </div>
                <div>Ultimately, this is opening a huge can of worms if
                  we put it into the C API, as I think it is going to
                  fundamentally impact what options we actually have for
                  parallelizing parts of LLVM in the future. If we want
                  to go there, we need be *incredibly* explicit about
                  what assumptions are being made here.</div>
              </div>
            </blockquote>
          </div>
        </blockquote>
        <div><br>
        </div>
        <div>Yes, this will definitely impact the design, but only in a
          positive way :D There is only one big requirement and that is
          a given: The thread cannot hold a global mutex when making
          this call. This would deadlock everything - even other
          concurrent running contexts in todays implementation.</div>
        <div><br>
        </div>
        <div>When a thread group is running concurrently in the future
          pass manager then it clear that the suspension of any thread
          in this thread group might deadlock the remaining threads in
          the thread group and that is perfectly fine. Also having this
          callback being fired concurrently is fine too. The client
          created a parallel pass manager and has to write the callback
          thread-safe.</div>
        <div><br>
        </div>
        <div>The important thing here is that LLVM is holding the thread
          hostage and we need the control back to safely suspend it. It
          is possible suspend the thread from outside, but then it might
          be inside a system call or library call that holds a mutex.
          This could deadlock the whole application. By giving the
          control back to the client via the call back we know that this
          cannot happen. We know that LLVM might hold some mutex local
          to the context, but that is fine and won’t deadlock the whole
          application.</div>
        <div><br>
        </div>
        <div>-Juergen</div>
        <br>
        <blockquote type="cite">
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

<br>
          </div>
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

Let’s be
            explicit then.</div>
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

<br>
          </div>
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

We will
            always need to be able to configure LLVM with one thread per
            context. Always. So it’s not like we’re adding something
            that could become unusable in the future. Does anyone
            disagree?</div>
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

<br>
          </div>
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

Incidentally,
            I have no idea why the callback would not work with parallel
            context. If you suspend a thread within a thread group, it
            is totally expected that the other threads will also
            eventually block.</div>
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

<br>
          </div>
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

Tangentially,
            how many other places do we assume that an LLVMContext
            corresponds to a thread?</div>
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

<br>
          </div>
          <div style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

-Andy</div>
        </blockquote>
      </div>
      <br>
      <br>
      <fieldset></fieldset>
      <br>
      <pre>_______________________________________________
LLVM Developers mailing list
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu/" target="_blank">http://llvm.cs.uiuc.edu</a>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a>
</pre>
    </blockquote>
    <br>
  </div>

</blockquote></div><br></div></div></div><br>_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
<br></blockquote></div><br></div></div>