<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Yes, that's exactly it - I have a small amount of extra code that
I want to run on MachineFunctions within the X86 target machine
implementation. I've tried a couple of ways around this and the
easiest way I've come up with is very similar to the
PassManagerBuilder::addGlobalExtension used for IR passes. I'll
post some code below showing the interface, in case anyone has any
feedback before I write some tests for a patch submission.<br>
</p>
<p>My apologies for taking so long to reply, by the way.</p>
<p>The basic idea is to add an enum for different extension points
within TargetPassConfig and keep a global list of per-target
extensions. The interface changes look like the below. The
existing addPass function has to be made public so the client code
can use it from the callback function that it registers.<br>
</p>
<blockquote> class TargetPassConfig : public ImmutablePass {<br>
<p>+public:<br>
+ enum CodegenExtensionPointTy {<br>
+ CGEP_EarlyAsPossible,<br>
+ CGEP_BeforePreRegAlloc,<br>
+ CGEP_AfterPreRegAlloc,<br>
+ CGEP_BeforePostRegAlloc,<br>
+ CGEP_AfterPostRegAlloc,<br>
+ CGEP_BeforePreSched2,<br>
+ CGEP_AfterPreSched2,<br>
+ CGEP_BeforePreEmitPass,<br>
+ CGEP_AfterPreEmitPass,<br>
+ CGEP_BeforePreEmitPass2,<br>
+ CGEP_AfterPreEmitPass2,<br>
+ CGEP_LateAsPossible<br>
+ };<br>
+<br>
+ using ExtensionFn = std::function<void(TargetPassConfig
&)>;<br>
+<br>
private:<br>
PassManagerBase *PM = nullptr;<br>
AnalysisID StartBefore = nullptr;<br>
@@ -343,6 +363,19 @@ public:<br>
/// Returns the CSEConfig object to use for the current
optimization level.<br>
virtual std::unique_ptr<CSEConfigBase> getCSEConfig()
const;<br>
<br>
+ /// Add a global extension to be applied for the given Target
TODO:<br>
+ /// add ID and removal (cf commit<br>
+ /// ab2300bc154f7bed43f85f74fd3fe31be71d90e0)<br>
+ static void addGlobalExtension(const Target* Target,<br>
+ CodegenExtensionPointTy CGEP,
ExtensionFn Fn);<br>
+<br>
+ /// Add a pass to the PassManager if that pass is supposed to
be run, as<br>
+ /// determined by the StartAfter and StopAfter options. Takes
ownership of the<br>
+ /// pass.<br>
+ /// @p verifyAfter if true and adding a machine function
pass add an extra<br>
+ /// machine verification pass afterwards.<br>
+ void addPass(Pass *P, bool verifyAfter = true);<br>
+<br>
protected:</p>
</blockquote>
<br>
<p>Then the client code can do something like this:</p>
<p> const Target* target = TargetRegistry::lookupTarget(<br>
"x86_64-unknown-linux-gnu", error);<br>
<br>
TargetPassConfig::addGlobalExtension(<br>
target, TargetPassConfig::CGEP_BeforePreRegAlloc,<br>
&drti::X86DrtiTreenodePass::addSelf);<br>
</p>
<p>If anyone has any suggestions, please let me know</p>
<p>Thanks,<br>
Raoul.<br>
</p>
<div class="moz-cite-prefix"><br>
</div>
<div class="moz-cite-prefix">On 15/10/2020 18:51, Chen, Yuanfang
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CH2PR13MB3334C29F227CA5165FC532EB9D020@CH2PR13MB3334.namprd13.prod.outlook.com">
<pre class="moz-quote-pre" wrap="">Looks like you want to add an out-of-tree machine pass for X86, is that right? I'm not aware of any existing mechanism to do that, but it should be straightforward to add one.
Basically you need to
* make X86PassConfig a public API and override the interesting hooks according to your use case.
* add a new hook (say X86TargetMachine::getExtendedPassConfig) to X86TargetMachine to return an inherited X86PassConfig
* check the return value of X86TargetMachine::getExtendedPassConfig and optionally return it in X86TargetMachine::createPassConfig
Hope it helps.
-Yuanfang
-----Original Message-----
From: llvm-dev <a class="moz-txt-link-rfc2396E" href="mailto:llvm-dev-bounces@lists.llvm.org"><llvm-dev-bounces@lists.llvm.org></a> On Behalf Of Raoul Gough via llvm-dev
Sent: Thursday, October 15, 2020 12:18 AM
To: LLVM dev <a class="moz-txt-link-rfc2396E" href="mailto:llvm-dev@lists.llvm.org"><llvm-dev@lists.llvm.org></a>
Subject: [llvm-dev] Injecting customizations for TargetMachine pass
Hello llvm-dev,
I would like to be able to customise the X86TargetMachine but I couldn't
find any proper way to do this from code external to the LLVM codebase.
For the IR passes there are RegisterPass and RegisterStandardPasses.
Have I overlooked an existing mechanism for extending TargetMachine
passes or is this not really supported?
As background, I'm working on runtime inlining of calls made via
function pointers, including C++ virtual functions. This uses a normal
compiler like clang with some additional decoration of the IR before
running llc to get the ahead-of-time compiled machine code. The
decorated code can then re-compile parts of the IR at runtime by calling
into LLJIT.
I use some low-level mechanisms to pass information between decorated
functions alongside the normal platform ABI, and this is where I need to
manipulate the target machine behaviour. The end result is to store some
data in the instruction stream preceding the function return address,
and pass a context pointer in r14.
Currently I have a workaround by adding a whole new target via
RegisterTargetMachine. The implementation does the additional processing
in runOnMachineFunction and delegates as much as possible to the real
X86 target obtained via TargetRegistry::lookupTarget. This is especially
messy because many of the TargetPassConfig virtual functions that I
delegate to X86PassConfig are protected (e.g. addPreRegAlloc) so it's
clearly not a "proper" way of doing what I want. The code in question is
in
<a class="moz-txt-link-freetext" href="https://github.com/drti/drti/blob/a204564d74ac5f8ad6946b1c96e10c84a1ffb97e/passes/drti-target.cpp">https://github.com/drti/drti/blob/a204564d74ac5f8ad6946b1c96e10c84a1ffb97e/passes/drti-target.cpp</a>
and a general description of the runtime inliner is at
<a class="moz-txt-link-freetext" href="https://github.com/drti/drti">https://github.com/drti/drti</a>
Can anyone suggest a better way to do the TargetMachine customization?
If necessary I could contribute some LLVM code changes to add extension
points but would appreciate some guidance on which way to approach it first.
Thanks,
Raoul.
_______________________________________________
LLVM Developers mailing list
<a class="moz-txt-link-abbreviated" href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
</blockquote>
<p><br>
</p>
</body>
</html>