Skip to content
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

Merged
merged 10 commits into from
Sep 24, 2024
Merged

Port refprune pass to NewPassManager #1057

merged 10 commits into from
Sep 24, 2024

Conversation

yashssh
Copy link
Contributor

@yashssh yashssh commented Jun 7, 2024

Based on the changes introduced in #1042 by @modiking

@yashssh
Copy link
Contributor Author

yashssh commented Jun 7, 2024

Please just review the last commit as it is rebased on top of #1046

Not relevant anymore

@dlee992
Copy link
Contributor

dlee992 commented Jun 17, 2024

I "checked" the last commit. LGTM. only has some minor format issues, but I feel don't need to bring it up.
Also learned the difference of how to add a pass for old and new pass managers. Nice.

@modiking
Copy link

LGTM

@yashssh
Copy link
Contributor Author

yashssh commented Jul 9, 2024

Rebased

@yashssh
Copy link
Contributor Author

yashssh commented Jul 9, 2024

Clang format does not report anything for me locally. What version of clang-format is used in the checks?

@yashssh
Copy link
Contributor Author

yashssh commented Jul 18, 2024

I missed to update test_refprune.py and there might be some complications there. Consider this "not yet ready for review" for now.
Thanks :)

Edit: Ready for review

@gmarkall
Copy link
Member

Clang format does not report anything for me locally. What version of clang-format is used in the checks?

It is clang-format-14, I think.

@yashssh
Copy link
Contributor Author

yashssh commented Jul 19, 2024

using clang-format 14 made the tests pass, should llvmlite consider moving to a more recent clang-format?

@yashssh
Copy link
Contributor Author

yashssh commented Jul 30, 2024

Gentle ping

Copy link
Contributor Author

@yashssh yashssh left a 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:

  1. We prefix the old refprune passes with legacy keyword.
  2. We create a new refprune pass following the new pass manager syntax.
  3. 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

Comment on lines +29 to +30
void initializeRefNormalizeLegacyPassPass(PassRegistry &Registry);
void initializeRefPruneLegacyPassPass(PassRegistry &Registry);
Copy link
Contributor Author

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

Comment on lines +1170 to +1187
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();
}
};
Copy link
Contributor Author

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) {
Copy link
Contributor Author

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 {
Copy link
Contributor Author

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.

Comment on lines +1273 to +1287
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));
Copy link
Contributor Author

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.

Copy link
Contributor Author

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

Copy link
Contributor Author

@yashssh yashssh Aug 14, 2024

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.

Copy link
Member

@gmarkall gmarkall left a 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.

@yashssh
Copy link
Contributor Author

yashssh commented Aug 20, 2024

Thanks for the review @gmarkall! I have addressed the comments.

gmarkall
gmarkall previously approved these changes Aug 23, 2024
Copy link
Member

@gmarkall gmarkall left a 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!

@esc
Copy link
Member

esc commented Sep 18, 2024

@yashssh @gmarkall code needs a fix, it's become conflicting with main due to recent merges. 🙏

@yashssh
Copy link
Contributor Author

yashssh commented Sep 19, 2024

Resolved now, thanks!

@esc
Copy link
Member

esc commented Sep 19, 2024

Resolved now, thanks!

@yashssh thank your for the swift update! -- @gmarkall can you check this and approve the fixes?

@yashssh
Copy link
Contributor Author

yashssh commented Sep 24, 2024

Ping

Copy link
Member

@gmarkall gmarkall left a 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.

@esc esc merged commit 23e02cb into numba:main Sep 24, 2024
24 checks passed
@esc
Copy link
Member

esc commented Sep 24, 2024

Thank you for the patch!

@stuartarchibald stuartarchibald added this to the v0.44.0 milestone Nov 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants