-
Notifications
You must be signed in to change notification settings - Fork 322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port refprune pass to NewPassManager #1057
Conversation
Not relevant anymore |
I "checked" the last commit. LGTM. only has some minor format issues, but I feel don't need to bring it up. |
LGTM |
Rebased |
Clang format does not report anything for me locally. What version of clang-format is used in the checks? |
Based on the changes introduced in numba#1042 by @modiking
This reverts commit 2d9f8e6.
Edit: Ready for review |
It is clang-format-14, I think. |
using clang-format 14 made the tests pass, should llvmlite consider moving to a more recent clang-format? |
Gentle ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added some inline comments to make the thought process behind the the changes more apparent to the reviewers.
The gist of the changes are:
- We prefix the old refprune passes with legacy keyword.
- We create a new refprune pass following the new pass manager syntax.
- Now that we have multiple instances of the same pass, to prevent duplication of code we move the computation functions to a more global scope(struct) so that both passes can share them.
Found this article online which comes very close to explaining what we did here https://www.neilhenning.dev/posts/llvm-new-pass-manager/
Examples from llvm codebase on porting a pass to NPM
void initializeRefNormalizeLegacyPassPass(PassRegistry &Registry); | ||
void initializeRefPruneLegacyPassPass(PassRegistry &Registry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefix the pass name with "Legacy" to be used with legacy pass manager
class RefPrunePass : public PassInfoMixin<RefPrunePass> { | ||
|
||
public: | ||
Subpasses flags; | ||
size_t subgraph_limit; | ||
RefPrunePass(Subpasses flags = Subpasses::All, size_t subgraph_limit = -1) | ||
: flags(flags), subgraph_limit(subgraph_limit) {} | ||
|
||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) { | ||
auto &DT = AM.getResult<DominatorTreeAnalysis>(F); | ||
auto &PDT = AM.getResult<PostDominatorTreeAnalysis>(F); | ||
if (RefPrune(DT, PDT, flags, subgraph_limit).runOnFunction(F)) { | ||
return PreservedAnalyses::none(); | ||
} | ||
|
||
return PreservedAnalyses::all(); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have renamed the pass with "Legacy" keyword, we are free to create another pass with the name RefPrunePass
, we will call this pass from NewPassManager . The passes for new pass manager follow this template mixin inheritance syntax that's visible here. There's also a difference in how we get the Analysis results needed for the pass to run, instead of explicitly specifying dependencies in getAnalysisUsage
function we can directly query the NPM analysis manager for the result.
Note that wrapped in all this new pass manager syntax we are calling runOnFunction(F)
which actually does the computation for this pass and is also used by legacy version of this pass.
|
||
bool runOnFunction(Function &F) override { | ||
bool runOnFunction(Function &F) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the core of the RefNormalize pass, we will call this function from legacy and new version of RefNormalize pass.
All = PerBasicBlock | Diamond | Fanout | FanoutRaise | ||
} Subpasses; | ||
|
||
struct RefPrune { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have moved all the computation related functions from inside struct RefPrunePass : public FunctionPass
to struct RefPrune
so that we can re-use these functions from both the Legacy pass and the new pass.
API_EXPORT(void) | ||
LLVMPY_AddRefPrunePass_module(LLVMModulePassManagerRef MPM, int subpasses, | ||
size_t subgraph_limit) { | ||
llvm::unwrap(MPM)->addPass( | ||
createModuleToFunctionPassAdaptor(RefNormalizePass())); | ||
llvm::unwrap(MPM)->addPass(createModuleToFunctionPassAdaptor( | ||
RefPrunePass((Subpasses)subpasses, subgraph_limit))); | ||
} | ||
|
||
API_EXPORT(void) | ||
LLVMPY_AddRefPrunePass_function(LLVMFunctionPassManagerRef FPM, int subpasses, | ||
size_t subgraph_limit) { | ||
llvm::unwrap(FPM)->addPass(RefNormalizePass()); | ||
llvm::unwrap(FPM)->addPass( | ||
RefPrunePass((Subpasses)subpasses, subgraph_limit)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API to register new passes in MPM and FPM respectively.
llvmlite/binding/newpassmanagers.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copied the APIs from passmanagers.py
llvmlite/tests/test_refprune.py
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Creating new tests for refprune
in new pass manager would have involved some duplication, so I migrated the old tests to NewPassManager
. Let me know if you think that's not the best way forward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR - the code changes look good, and I was able to follow them well from the info you provided / linked to. I think there are two things that need adding:
- Documentation for the
add_refprune_pass
functions of the new module and function pass managers - Keep the tests for the legacy pass manager, as well as testing with the new pass manager. Although there's a low probability of issues with the legacy pass manager, the changes do touch their code (and other future changes might potentially as well, we never know) so keeping both paths in use tested is important.
Thanks for the review @gmarkall! I have addressed the comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the additions - I think this is now good to merge!
Resolved now, thanks! |
Ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fixup looks good to me.
Thank you for the patch! |
Based on the changes introduced in #1042 by @modiking