<div dir="ltr">Greetings, I've had the time to take a better look at the code in the NewPMDriver.cpp source and I believe I have a good overview of the task now. Here are some things which I'm not too sure about so I'd like your input on this:<br><br>- What are the PreservedAnalyses and how do we use them? Is it crucial for the LLVM-C API?<br>- How do we want to handle the various callbacks for the PassInstrumentationCallbacks? They're taking the templated IRUnit which could be different types upon each invocation.<br>- Where do we want the binding code itself? Some places have files like ExecutionEngineBindings.cpp, while others have it at the end of files relevant to the code being hooked into.<br>- I see the C++ API accepts PGO Options, should that be hooked into as well?<br><br>With that being said, I think I have a decent plan for the interface itself. We'll provide a PassBuilder which we can construct with the PassInstrumentationCallbacks, PipelineTuningOptions, etc. The various *AnalysisManagers may also be added to the PassBuilder. The StandardInstrumentation can be added by passing a PassInstrumentationCallbacks and optionally a FunctionAnalysisManager like the C++ llvm::StandardInstrumentation::registerCallbacks method does.<br><br>The PassBuilder will then be able to accept a Module and an opt-style string with the passes to be used. A ModulePassManager will be constructed as you described and it will run the passes over the module.<br><br>Let me know what you think of an approach like this...<br><br>Best regards<br>Mats Larsen<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 28, 2021 at 11:13 PM Mats Larsen <<a href="mailto:me@supergrecko.com">me@supergrecko.com</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 dir="ltr">Thank you Arthur, that sounds great. Using opt's pass name parser sounds like a good plan and a great way to save ourselves from complications with the different PM types. We can then construct the ModulePassManager and run that over an LLVM module the user passes to us.<br><br>I'll have a closer look at this over the next few days and I'll possibly gather a tiny list of questions I may have before we get started.<br><br>Mats</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 27, 2021 at 6:26 PM Arthur Eubanks <<a href="mailto:aeubanks@google.com" target="_blank">aeubanks@google.com</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 dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Apr 26, 2021 at 1:48 PM Mats Larsen <<a href="mailto:me@supergrecko.com" target="_blank">me@supergrecko.com</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 dir="ltr">Hello everyone<br><br>I wouldn't mind looking into hooking the new PM infrastructure into the LLVM C API. However, I would like to know a little more about the task. I've had a look at the new PM infrastructure, and from taking a quick glance at the available APIs and how it's used in the tests I assume we'd look to do something similar to the existing legacy PM hooks.<br><br>Things are a bit different as far as I've understood because we have Module, CGSCC, Function, and Loop passes, each of which may be adapted into "higher" kinds, eg FunctionPM -> ModulePM, all of which differs a bit from the legacy PM. From what I've gathered, we'll need to set up the PMs themselves as you mentioned and we'll have to hook a set (all?) of the new PM passes into this. Would it be possible to get a more comprehensive list of what needs to be done?<br><br>I'm pretty new around here so I'll probably require some guidance further down the line.<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank"></a><br>
</blockquote></div></blockquote><div>Awesome, I'm happy to do reviews and answer any further questions.</div><div><br></div><div>I'm imagining a new PassBuilder.h in llvm/include/llvm-c where PassManagerBuilder.h was.</div><div>Initially I was thinking we'd need wrappers around the various types of pass managers as you've mentioned, as well as the adaptors (e.g. createModuleToFunctionPassAdaptor()). And each of the LLVMAdd*Pass() would need a corresponding new PM alternative that adds the pass to the proper pass manager type.</div><div><br></div><div>But now that I think about it some more, we might be able to bypass all of that and instead use the new PM's pass pipeline text parsing (the same thing that `opt -passes=foo` uses). This seems exactly the sort of thing it would be useful for. We'll bypass the need to create wrappers for the different types of pass managers since we just get back a ModulePassManager from the PassBuilder.</div><div>The code in NewPMDriver.cpp should be a good starting place to figure out what's necessary to create a PassBuilder, then how to get a ModulePassManager from it and run it on some IR.</div><div>I imagine first you'll need some way to setup the options to pass to the PassBuilder, so the C wrapper would probably own various things like the various *AnalysisManagers, PassInstrumentationCallbacks, StandardInstrumentations, and PipelineTuningOptions. Then the user can ask for some pipeline via a string, whether that's an individual pass like "instcombine" or a full pipeline like "default<O2>", and you create a PassBuilder from the options, then tell it to create the ModulePassManager via PassBuilder::parsePassPipeline().</div></div></div>
</blockquote></div>
</blockquote></div>