Fedor Sergeev via llvm-dev
2018-Jun-07 15:48 UTC
[llvm-dev] RFC: Pass Execution Instrumentation interface
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 instance(s). regards, Fedor.> > 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>
Philip Pfaffe via llvm-dev
2018-Jun-07 16:14 UTC
[llvm-dev] RFC: Pass Execution Instrumentation interface
Hi Fedor, 2018-06-07 17:48 GMT+02:00 Fedor Sergeev via llvm-dev < llvm-dev at lists.llvm.org>:> > > [...] > > 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? >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. Cheers, Philip> > 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 > instance(s). > > regards, > Fedor. > > > > 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 >> >> > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180607/2a820eea/attachment.html>
Fedor Sergeev via llvm-dev
2018-Jun-07 20:07 UTC
[llvm-dev] RFC: Pass Execution Instrumentation interface
On 06/07/2018 07:14 PM, Philip Pfaffe wrote:> Hi Fedor, > > 2018-06-07 17:48 GMT+02:00 Fedor Sergeev via llvm-dev > <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>>: > > > > [...] > 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? > > > 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.Conceptually I have always considered PassBuilder to be responsible only for construction of the pipeline. Say, In our downstream usage we apply PassBuilder to construct a pipeline and get rid of it before even starting the pipeline run. It appears to be a valid use as of right now. If we enhance PassBuilder with bookkeeping capabilities then we will introduce the new requirement for PassBuilder to stay alive till the end of compilation. I'm not saying that it is a problem, it just breaks my view on a current design. Also, keep in mind that technically you can create a pipeline without PassBuilder at all. On other hand, using PassBuilder to own InstrumentationImpl makes implementation rather simple since it can "seed" all the analyses with instance that it owns. AnalysisManager owning the InstrumentationImpl instance seems conceptually clearner to me, however to make this analysis unique we need a way to make a single analysis manager responsible for that and to teach it how to feed other analyses (without transferring the ownership). And that requires nontrivial implementation effort which I cant estimate right now. Is it reasonable to enforce a requirement that ModulePassManager and ModuleAnalysisManager are always created? Then we can put all this bookkeeping activity into ModuleAnalysisManager. I'm kinda torn on this... regards, Fedor.> > Cheers, > Philip > > > 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 > instance(s). > > regards, > Fedor. > > >> >> 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 <https://reviews.llvm.org/D47858> >> > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev> > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180607/2553ed5b/attachment.html>