<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    On 06/07/2018 07:14 PM, Philip Pfaffe wrote:<br>
    <blockquote type="cite"
cite="mid:CAHe691FQDLMijmnekfYDjG6Q3JXGbNbVR_h_Xe2dLOkrUoCHmQ@mail.gmail.com">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <div dir="ltr">Hi Fedor,<br>
        <div class="gmail_extra"><br>
          <div class="gmail_quote">2018-06-07 17:48 GMT+02:00 Fedor
            Sergeev via llvm-dev <span dir="ltr"><<a
                href="mailto:llvm-dev@lists.llvm.org" target="_blank"
                moz-do-not-send="true">llvm-dev@lists.llvm.org</a>></span>:<br>
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div text="#000000" bgcolor="#FFFFFF"><span class=""> <br>
                  <br>
                  <div class="m_-2287610747771355697moz-cite-prefix">[...]</div>
                  <blockquote type="cite">
                    <div dir="ltr">
                      <div class="gmail_quote"> </div>
                    </div>
                  </blockquote>
                </span> I consider LLVM context to be a good reference
                point for "compilation-local singleton stuff".<br>
                My task is to provide a way to handle callbacks
                per-compilation-context, and preferably have a single
                copy of those<br>
                (possibly stateful) callbacks per compilation.<br>
                <br>
                In my implementation (linked at the end of RFC) I'm
                using PassInstrumentationImpl to have a single copy of
                object.<br>
                What entity should *own* PassInstrumentationImpl object
                to make it unique per-compilation?<br>
              </div>
            </blockquote>
            <div><br>
            </div>
            <div>Both the PassBuilder and the AnalysisManager owning the
              analysis is unique per compilation for all intents and
              purposes. Just making it an analysis does not force you to
              extend the contract of IRUnitT to access the context. The
              PassBuilder is also exposed to pass plugins, so you get
              support for instrumentation plugins for free.</div>
          </div>
        </div>
      </div>
    </blockquote>
    Conceptually I have always considered PassBuilder to be responsible
    only for construction of the pipeline.<br>
    Say, In our downstream usage we apply PassBuilder to construct a
    pipeline and get rid of it before even starting<br>
    the pipeline run. It appears to be a valid use as of right now.<br>
    <br>
    If we enhance PassBuilder with bookkeeping capabilities then we will
    introduce the new requirement<br>
    for PassBuilder to stay alive till the end of compilation.<br>
    I'm not saying that it is a problem, it just breaks my view on a
    current design.<br>
    <br>
    Also, keep in mind that technically you can create a pipeline
    without PassBuilder at all.<br>
    <br>
    On other hand, using PassBuilder to own InstrumentationImpl makes
    implementation rather simple since it can "seed" all the analyses<br>
    with instance that it owns. <br>
    <br>
    AnalysisManager owning the InstrumentationImpl instance seems
    conceptually clearner to me, however to make this analysis unique<br>
    we need a way to make a single analysis manager responsible for that
    and to teach it how to feed other analyses (without transferring <br>
    the ownership). And that requires nontrivial implementation effort
    which I cant estimate right now.<br>
    <br>
    Is it reasonable to enforce a requirement that ModulePassManager and
    ModuleAnalysisManager are always created?<br>
    Then we can put all this bookkeeping activity into
    ModuleAnalysisManager.<br>
    <br>
    I'm kinda torn on this...<br>
    <br>
    regards,<br>
      Fedor.<br>
    <br>
    <blockquote type="cite"
cite="mid:CAHe691FQDLMijmnekfYDjG6Q3JXGbNbVR_h_Xe2dLOkrUoCHmQ@mail.gmail.com">
      <div dir="ltr">
        <div class="gmail_extra">
          <div class="gmail_quote">
            <div><br>
            </div>
            <div>Cheers,</div>
            <div>Philip</div>
            <div> </div>
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">
              <div text="#000000" bgcolor="#FFFFFF"> <br>
                Again, in my implementation with Analysis-managed
                PassInstrumentation I put Impl into PassBuilder<br>
                which registers Analyses with a reference to its Impl.<br>
                However that makes Impl to be per-Builder unique, which
                is not the same as per-compilation.<span class=""><br>
                  <br>
                  <blockquote type="cite">
                    <div dir="ltr">
                      <div class="gmail_quote">
                        <div><br>
                        </div>
                        <div>Because this is very pass specific, I think
                          it would be substantially cleaner for it to be
                          more specifically based in the pass
                          infrastructure.</div>
                        <div><br>
                        </div>
                        <div>I also think that this can be more cleanly
                          designed by focusing on the new PM. The legacy
                          PM has reasonable solutions for these problems
                          already, and I think the desgin can be made
                          somewhat simpler if we don't have to support
                          both in some way.</div>
                      </div>
                    </div>
                  </blockquote>
                </span> That I kind of agree with.<br>
                And I do not plan to implement both at once.<br>
                So in a good case we just switch to new PM and go
                forward.<br>
                And in a bad case of postponing the switch we can use
                experience and details of implementation of new PM to
                solve problems with legacy PM<br>
                (but that is definitely a much lower priority for me).<span
                  class=""><br>
                  <br>
                  <blockquote type="cite">
                    <div dir="ltr">
                      <div class="gmail_quote">
                        <div><br>
                        </div>
                        <div>My hope would be that there are two basic
                          "layers" to this. Along side a particular
                          PassManager, we would have an analysis that
                          instruments the running passes. This would
                          just expose the basic API to track and control
                          pass behavior and none of the "business
                          logic".</div>
                      </div>
                    </div>
                  </blockquote>
                  <br>
                </span> Yes. PassInstrumentation seems to provide that.<span
                  class=""><br>
                  <br>
                  <blockquote type="cite">
                    <div dir="ltr">
                      <div class="gmail_quote">
                        <div><br>
                        </div>
                        <div>Then I would hope that the Passes library
                          can build an instance of this analysis with
                          callbacks (or a type parameter that gets type
                          erased internally) which handles all the
                          business logic.</div>
                      </div>
                    </div>
                  </blockquote>
                </span> As an idea I do agree with this.<br>
                But practically I dont have  a clear picture on how to
                manage the instance(s).<br>
                <br>
                regards,<br>
                  Fedor.
                <div>
                  <div class="h5"><br>
                    <br>
                    <blockquote type="cite">
                      <div dir="ltr">
                        <div class="gmail_quote"><br>
                          <div>I think this will also address the
                            layering issues around IR units because I
                            think that the generic code can use
                            templates to generically lower the IR unit
                            down to something that can be cleanly
                            handled by the Passes library. I think it is
                            generally fine for this layer to rapidly
                            lose strong typing or only have limited
                            typed facilities because this is about
                            instrumenting things and shouldn't be having
                            interesting (non-debug) behavioral effects.</div>
                          <div> </div>
                          <blockquote class="gmail_quote"
                            style="margin:0 0 0 .8ex;border-left:1px
                            #ccc solid;padding-left:1ex"> <br>
                            <br>
                            Details:<br>
                               1. introduce llvm::PassInstrumentation<br>
                            <br>
                                  This is the main interface that
                            handles the customization and <br>
                            provides instrumentation calls<br>
                            <br>
                                  - resides in IR<br>
                                  - is accessible through LLVMContext::<wbr>getPassInstrumentation()<br>
                                    (with context owning this object).<br>
                            <br>
                               2. every single point of Pass execution
                            in the (new) PassManager(s) <br>
                            will query<br>
                                  this analysis and run instrumentation
                            call specific to a <br>
                            particular point.<br>
                            <br>
                                  Instrumentation points:<br>
                            <br>
                                     bool BeforePass (PassID,
                            PassExecutionCounter);<br>
                                     void AfterPass (PassID,
                            PassExecutionCounter);<br>
                            <br>
                                      Run before/after a particular pass
                            execution<br>
                                          BeforePass instrumentation
                            call returns true if this <br>
                            execution is allowed to run.<br>
                            <br>
                                         'PassID'<br>
                                              certain unique identifier
                            for a pass (pass name?).<br>
                            <br>
                                         'PassExecutionCounter'<br>
                                              a number that uniquely
                            identifies this particular pass <br>
                            execution<br>
                                              in current pipeline, as
                            tracked by Pass Manager.<br>
                            <br>
                                     void StartPipeline()<br>
                                     void EndPipeline()<br>
                            <br>
                                      Run at the start/end of a pass
                            pipeline execution.<br>
                                      (useful for
                            initialization/finalization purposes)<br>
                            <br>
                            <br>
                               3. custom callbacks are registered with <br>
                            PassInstrumentation::register* interfaces<br>
                            <br>
                                  A sequence of registered callbacks is
                            called at each <br>
                            instrumentation point as appropriate.<br>
                            <br>
                               4. introduce llvm::ExecutionCounter to
                            track execution of passes<br>
                            <br>
                                  (akin to DebugCounter, yet enabled in
                            Release mode as well?)<br>
                            <br>
                                  Note: it is somewhat nontrivial to
                            uniquely track pass executions <br>
                            with counters in new pass<br>
                                  manager as its pipeline schedule can
                            be dynamic. Ideas are welcome <br>
                            on how to efficiently<br>
                                  implement unique execution tracking
                            that does not break in <br>
                            presence of fixed-point iteration<br>
                                  passes like RepeatedPass/<wbr>DevirtSCCRepeatedPass<br>
                            <br>
                                  Also, the intent is for execution
                            counters to be able provide <br>
                            thread-safety in multi-threaded<br>
                                  pipeline execution (though no work
                            planned for it yet).<br>
                            <br>
                               5. introduce a new analysis llvm::<wbr>PassInstrumentationAnalysis<br>
                            <br>
                                  This is a convenience wrapper to
                            provide an access to <br>
                            PassInstrumentation via analysis framework.<br>
                                  If using analysis is not convenient
                            (?legacy) then <br>
                            PassInstrumentation can be queried<br>
                                  directly from LLVMContext.<br>
                            <br>
                            <br>
                            Additional goals<br>
                            ================<br>
                            <br>
                               - layering problem<br>
                                 Currently OptBisect/OptPassGate has
                            layering issue - interface <br>
                            dependencies on all the "IR units",<br>
                                 even those that are analyses - Loop,
                            CallGraphSCC.<br>
                            <br>
                                 Generic PassInstrumentation facilitiy
                            allows to inject arbitrary <br>
                            call-backs in run-time,<br>
                                 removing any compile-time interface
                            dependencies on internals of <br>
                            those callbacks,<br>
                                 effectively solving this layering
                            issue.<br>
                            <br>
                               - life-time/scope control for
                            multi-context execution<br>
                            <br>
                                 Currently there are issues with
                            multi-context execution of, say, <br>
                            -time-passes which store<br>
                                 their data in global maps.<br>
                            <br>
                                 With LLVMContext owning
                            PassInstrumentation there should be no <br>
                            problem with multi-context execution<br>
                                 (callbacks can be made owning the
                            instrumentation data).<br>
                            <br>
                            Open Questions<br>
                            ==============<br>
                            <br>
                               - whats the best way to handle ownership
                            of PassInstrumentation<br>
                            <br>
                                 Any problems with owning by
                            LLVMContext?<br>
                                 Something similar to TargetLibraryInfo
                            (owned by <br>
                            TargetLibraryAnalysis/<wbr>TargetLibraryInfoWrapperPass)?<br>
                            <br>
                               - using PassInstrumentationAnalysis or
                            directly querying LLVMContext<br>
                            <br>
                                 PassInstrumentationAnalysis appeared to
                            be a nice idea, only until <br>
                            I tried querying it<br>
                                 in new pass manager framework, and
                            amount of hooplas to jump over <br>
                            makes me shiver a bit...<br>
                            <br>
                                 Querying LLVMContext is plain and
                            straightforward, but we do not <br>
                            have a generic way to access LLVMContext<br>
                                 from a PassManager template (need to
                            introduce generic <br>
                            IRUnit::getContext?)<br>
                            <br>
                            Implementation<br>
                            ==============<br>
                            <br>
                            PassInstrumentationAnalysis proof-of-concept
                            unfinished prototype <br>
                            implementation:<br>
                            (Heavily under construction, do not enter
                            without wearing a hard hat...)<br>
                            <br>
                                <a
                              href="https://reviews.llvm.org/D47858"
                              rel="noreferrer" target="_blank"
                              moz-do-not-send="true">https://reviews.llvm.org/<wbr>D47858</a><br>
                            <br>
                          </blockquote>
                        </div>
                      </div>
                    </blockquote>
                    <br>
                  </div>
                </div>
              </div>
              <br>
              ______________________________<wbr>_________________<br>
              LLVM Developers mailing list<br>
              <a href="mailto:llvm-dev@lists.llvm.org"
                moz-do-not-send="true">llvm-dev@lists.llvm.org</a><br>
              <a
                href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev"
                rel="noreferrer" target="_blank" moz-do-not-send="true">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
              <br>
            </blockquote>
          </div>
          <br>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>