Jon Chesterfield via llvm-dev
2018-Nov-05 21:07 UTC
[llvm-dev] Confused by how to register a pass with opt
I have a pre instruction selection pass that is registered by calling addPass from Target::addPreISel. This works fine - it runs at the appropriate point in the pipeline and does what it is supposed to. I would like to call the pass from opt in order to write some test cases in IR. Unfortunately I'm missing something - despite a determined attempt to do what other passes do, mine doesn't show up in opt. With variables renamed, the pass amounts to: #define DEBUG_TYPE "my-pass" #define EXAMPLE_NAME "A longer description of my pass" namespace { class MyExample : public FunctionPass { public: static char ID; MyExample() : FunctionPass(ID) { initializeMyExamplePass(*PassRegistry::getPassRegistry()); } bool runOnFunction(Function &) override; StringRef getPassName() const override { return EXAMPLE_NAME; } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<DominatorTreeWrapperPass>(); AU.addRequired<LoopInfoWrapperPass>(); AU.addRequired<ScalarEvolutionWrapperPass>(); } }; } // namespace char MyExample::ID = 0; INITIALIZE_PASS_BEGIN(MyExample, DEBUG_TYPE, EXAMPLE_NAME, false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) INITIALIZE_PASS_END(MyExample, DEBUG_TYPE, EXAMPLE_NAME, false, false) FunctionPass *llvm::createMyExamplePass() { return new MyExample(); } I think the problem is that addPreISel isn't called by opt, so the constructor is never run and the pass never added to the list. This is somewhat confirmed by the following hack: static struct once_t { once_t() { createMyExamplePass(); } } unused_variable; which creates an instance of the pass then immediately throws it away, in which case opt will let me run the pass as desired. So while I have a workaround, said workaround looks absurd - what's the correct way to use this API? Thanks! Jon -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20181105/80039231/attachment.html>
Krzysztof Parzyszek via llvm-dev
2018-Nov-05 21:20 UTC
[llvm-dev] Confused by how to register a pass with opt
You need to call "initializeMyExamplePass" ahead of time. Look at include/llvm/InitializePasses.h, and for the actual calls that initialize individual passes, at lib/Analysis/Analysis.cpp, lib/Transforms/Scalar/Scalar.cpp, etc. These are all called from "main" in opt.cpp. -Krzysztof On 11/5/2018 3:07 PM, Jon Chesterfield via llvm-dev wrote:> I have a pre instruction selection pass that is registered by calling > addPass from Target::addPreISel. This works fine - it runs at the > appropriate point in the pipeline and does what it is supposed to. > > I would like to call the pass from opt in order to write some test cases > in IR. Unfortunately I'm missing something - despite a determined > attempt to do what other passes do, mine doesn't show up in opt. With > variables renamed, the pass amounts to: > > #define DEBUG_TYPE "my-pass" > #define EXAMPLE_NAME "A longer description of my pass" > > namespace { > class MyExample : public FunctionPass { > public: > static char ID; > MyExample() : FunctionPass(ID) { > initializeMyExamplePass(*PassRegistry::getPassRegistry()); > } > > bool runOnFunction(Function &) override; > StringRef getPassName() const override { return EXAMPLE_NAME; } > > void getAnalysisUsage(AnalysisUsage &AU) const override { > AU.addRequired<DominatorTreeWrapperPass>(); > AU.addRequired<LoopInfoWrapperPass>(); > AU.addRequired<ScalarEvolutionWrapperPass>(); > } > }; > } // namespace > char MyExample::ID = 0; > > INITIALIZE_PASS_BEGIN(MyExample, DEBUG_TYPE, EXAMPLE_NAME, false, false) > INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) > INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) > INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass) > INITIALIZE_PASS_END(MyExample, DEBUG_TYPE, EXAMPLE_NAME, false, false) > > FunctionPass *llvm::createMyExamplePass() { return new MyExample(); } > > I think the problem is that addPreISel isn't called by opt, so the > constructor is never run and the pass never added to the list. This is > somewhat confirmed by the following hack: > > static struct once_t { > once_t() { createMyExamplePass(); } > } unused_variable; > > which creates an instance of the pass then immediately throws it away, > in which case opt will let me run the pass as desired. > > So while I have a workaround, said workaround looks absurd - what's the > correct way to use this API? > > Thanks! > > Jon > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation