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