<div dir="ltr">You may need a TargetMachine available when constructing the pass. See SampleProfileProbePass in PassRegistry.def, or most of the passes added in AMDGPUTargetMachine::registerPassBuilderCallbacks().<div>As for how the TargetMachine is created, you could look at how opt does it in opt.cpp.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Mar 2, 2021 at 1:26 AM Anna Sophia Welker via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div>
<p>Hello experts,<br>
<br>
I am trying to build an LLVM pass that can make predictions about
the benefits of certain transformations by exploring them, i.e.,
sending the respective code sections 'ahead in time' and comparing
the outcome if this or that choice is made.<br>
<br>
To my understanding, because of how the pass pipeline is set up,
this does require to build an entirely new pipeline (or at least
parts of it), to which I pass the module I create from the code I
want to examine.<br>
I haven't really found any documentation on how the pass pipeline
is stitched together, so everything I know about how to do it
comes from reading code present in LLVM. Specifically, I've been
looking at <span style="color:rgb(0,0,0)">EmitAssemblyHelper::EmitAssemblyWithNewPassManager
in clang's BackendUtil, as I expect the run my pass would be
used in to be started from there, and I want to exactly copy
what happens to the real code.<br>
<br>
What I have achieved so far:<br>
I have imitated the creation of the AnalysisManagers and have
the PassBuilder pass information like PTO and PGOOpt to the
constructor of my pass, so when the pass is run in the
middle-end I can build a new PassBuilder from that information,
register all the AnalysisManagers and build a pipeline (using
buildPerModuleDefaultPipeline). As the old PassManager structure
allows it, I can even hand over a complete CodeGen pipeline to
said constructor. So my pass can run the module it creates
through the middle-end passes all the way to code generation in
the backend with no issues.<br>
<br>
My problem:<br>
The middle-end run that I am getting is a 'generic' one, it does
not exhibit the characteristics that I expect to see for the
concrete architecture I specify on the command line. E.g., it is
using a plain TTI instead of the target's TTI, so for my partial
code vectorization does not at all do what it would do for the
normal run. Which kind of defeats the whole point of the
exploration.<br>
I have identified the issue to be the TargetMachine, which seems
to be responsible for any target-specific adaptations in the
middle-end. From my understanding, if it is set to nullptr, you
get a generic run like I do, if it isn't, you should get a run
fine-tuned for the architecture you're looking at. The problem
is, what is the proper way to acquire a TargetMachine?<br>
The copy-constructor of the class has been deleted, so I cannot
simply hand it over to my pass like I do for the other
information. In BackendUtil, the TargetMachine is constructed as
a singleton from a long range of option information, some of it
clang options. From trying and failing I gather that I can not
include clang headers in my llvm pass, so I don't know how to
even pass all the required options to my pass if I were to build
the machine on my own from scratch, which does not feel like the
right thing to do anyway. I have tried passing the whole
original PassBuilder to my pass, which works fine, and then
taking the TargetMachine from there when creating my new
PassBuilder (I added a function getTargetMachine() to the class
for testing purposes). All I get is a nullptr.<br>
<br>
Can anyone give me a hint on what I am doing wrong, or how to do
it right? Or is this simply something that LLVM is not supposed
to allow, period?<br>
I do realise I could just manually add the passes I need for the
architecture I'm looking at, but the idea was to make the tool
usable for any architecture by just doing exactly what the
'parent run' is doing. Only, everything is so nicely
encapsulated that I'm struggeling to access the information
necessary in the place I need it.<br>
<br>
Looking forward to any feedback or suggestions!<br>
<br>
Many thanks,<br>
Anna Welker<br>
</span></p>
</div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>