[llvm-dev] RFC: Pass Execution Instrumentation interface

Fedor Sergeev via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 7 08:48:35 PDT 2018

On 06/07/2018 06:11 PM, Chandler Carruth wrote:
> We had already talked about this, so unsurprisingly I'm generally in 
> favor of the direction. Some comments below.
> On Thu, Jun 7, 2018 at 2:00 AM Fedor Sergeev <fedor.sergeev at azul.com 
> <mailto:fedor.sergeev at azul.com>> wrote:
>        - access through LLVM Context (allows to control life-time and
>     scope
>     in multi-context execution)
>        - wrap it into an analysis for easier access from pass managers
> Why not simply make it an analysis, and leave LLVM context out?
I consider LLVM context to be a good reference point for 
"compilation-local singleton stuff".
My task is to provide a way to handle callbacks per-compilation-context, 
and preferably have a single copy of those
(possibly stateful) callbacks per compilation.

In my implementation (linked at the end of RFC) I'm using 
PassInstrumentationImpl to have a single copy of object.
What entity should *own* PassInstrumentationImpl object to make it 
unique per-compilation?

Again, in my implementation with Analysis-managed PassInstrumentation I 
put Impl into PassBuilder
which registers Analyses with a reference to its Impl.
However that makes Impl to be per-Builder unique, which is not the same 
as per-compilation.

> Because this is very pass specific, I think it would be substantially 
> cleaner for it to be more specifically based in the pass infrastructure.
> 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.
That I kind of agree with.
And I do not plan to implement both at once.
So in a good case we just switch to new PM and go forward.
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
(but that is definitely a much lower priority for me).

> 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".

Yes. PassInstrumentation seems to provide that.

> 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.
As an idea I do agree with this.
But practically I dont have  a clear picture on how to manage the 


> 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.
>     Details:
>        1. introduce llvm::PassInstrumentation
>           This is the main interface that handles the customization and
>     provides instrumentation calls
>           - resides in IR
>           - is accessible through LLVMContext::getPassInstrumentation()
>             (with context owning this object).
>        2. every single point of Pass execution in the (new)
>     PassManager(s)
>     will query
>           this analysis and run instrumentation call specific to a
>     particular point.
>           Instrumentation points:
>              bool BeforePass (PassID, PassExecutionCounter);
>              void AfterPass (PassID, PassExecutionCounter);
>               Run before/after a particular pass execution
>                   BeforePass instrumentation call returns true if this
>     execution is allowed to run.
>                  'PassID'
>                       certain unique identifier for a pass (pass name?).
>                  'PassExecutionCounter'
>                       a number that uniquely identifies this
>     particular pass
>     execution
>                       in current pipeline, as tracked by Pass Manager.
>              void StartPipeline()
>              void EndPipeline()
>               Run at the start/end of a pass pipeline execution.
>               (useful for initialization/finalization purposes)
>        3. custom callbacks are registered with
>     PassInstrumentation::register* interfaces
>           A sequence of registered callbacks is called at each
>     instrumentation point as appropriate.
>        4. introduce llvm::ExecutionCounter to track execution of passes
>           (akin to DebugCounter, yet enabled in Release mode as well?)
>           Note: it is somewhat nontrivial to uniquely track pass
>     executions
>     with counters in new pass
>           manager as its pipeline schedule can be dynamic. Ideas are
>     welcome
>     on how to efficiently
>           implement unique execution tracking that does not break in
>     presence of fixed-point iteration
>           passes like RepeatedPass/DevirtSCCRepeatedPass
>           Also, the intent is for execution counters to be able provide
>     thread-safety in multi-threaded
>           pipeline execution (though no work planned for it yet).
>        5. introduce a new analysis llvm::PassInstrumentationAnalysis
>           This is a convenience wrapper to provide an access to
>     PassInstrumentation via analysis framework.
>           If using analysis is not convenient (?legacy) then
>     PassInstrumentation can be queried
>           directly from LLVMContext.
>     Additional goals
>     ================
>        - layering problem
>          Currently OptBisect/OptPassGate has layering issue - interface
>     dependencies on all the "IR units",
>          even those that are analyses - Loop, CallGraphSCC.
>          Generic PassInstrumentation facilitiy allows to inject arbitrary
>     call-backs in run-time,
>          removing any compile-time interface dependencies on internals of
>     those callbacks,
>          effectively solving this layering issue.
>        - life-time/scope control for multi-context execution
>          Currently there are issues with multi-context execution of, say,
>     -time-passes which store
>          their data in global maps.
>          With LLVMContext owning PassInstrumentation there should be no
>     problem with multi-context execution
>          (callbacks can be made owning the instrumentation data).
>     Open Questions
>     ==============
>        - whats the best way to handle ownership of PassInstrumentation
>          Any problems with owning by LLVMContext?
>          Something similar to TargetLibraryInfo (owned by
>     TargetLibraryAnalysis/TargetLibraryInfoWrapperPass)?
>        - using PassInstrumentationAnalysis or directly querying
>     LLVMContext
>          PassInstrumentationAnalysis appeared to be a nice idea, only
>     until
>     I tried querying it
>          in new pass manager framework, and amount of hooplas to jump
>     over
>     makes me shiver a bit...
>          Querying LLVMContext is plain and straightforward, but we do not
>     have a generic way to access LLVMContext
>          from a PassManager template (need to introduce generic
>     IRUnit::getContext?)
>     Implementation
>     ==============
>     PassInstrumentationAnalysis proof-of-concept unfinished prototype
>     implementation:
>     (Heavily under construction, do not enter without wearing a hard
>     hat...)
>     https://reviews.llvm.org/D47858

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180607/6e4ff131/attachment.html>

More information about the llvm-dev mailing list