<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">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><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">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">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div></div>