From 749e4bbb3b56569e526dec15a8ceae25d968e6da Mon Sep 17 00:00:00 2001 From: chengjunp Date: Tue, 25 Feb 2025 01:01:29 +0000 Subject: [PATCH 1/6] Add support for moving target specific AA before basic AA --- llvm/include/llvm/Analysis/AliasAnalysis.h | 2 ++ llvm/include/llvm/Target/TargetMachine.h | 5 +++++ llvm/lib/Analysis/AliasAnalysis.cpp | 10 +++++++--- llvm/lib/Passes/PassBuilderPipelines.cpp | 4 ++++ llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h | 3 +++ llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp | 2 +- llvm/lib/Target/NVPTX/NVPTXTargetMachine.h | 2 +- .../Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll | 15 +++++++++++++++ 8 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h index 9c6084d2d9dee..175e16f607e7e 100644 --- a/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -993,6 +993,8 @@ struct ExternalAAWrapperPass : ImmutablePass { explicit ExternalAAWrapperPass(CallbackT CB); + virtual bool runEarly() { return false; } + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); } diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h index c3e9d41315f61..588025525d8fe 100644 --- a/llvm/include/llvm/Target/TargetMachine.h +++ b/llvm/include/llvm/Target/TargetMachine.h @@ -371,6 +371,11 @@ class TargetMachine { // TODO: Populate all pass names by using PassRegistry.def. virtual void registerPassBuilderCallbacks(PassBuilder &) {} + /// Allow the target to register early alias analyses(AA before basicAA) with + /// the AAManager for use with the new pass manager. Only affects the + /// "default" AAManager. + virtual void registerEarlyDefaultAliasAnalyses(AAManager &) {} + /// Allow the target to register alias analyses with the AAManager for use /// with the new pass manager. Only affects the "default" AAManager. virtual void registerDefaultAliasAnalyses(AAManager &) {} diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp index 20cdbb6320322..ca7a68b3cbca4 100644 --- a/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/llvm/lib/Analysis/AliasAnalysis.cpp @@ -752,6 +752,11 @@ bool AAResultsWrapperPass::runOnFunction(Function &F) { AAR.reset( new AAResults(getAnalysis().getTLI(F))); + // Add any target-specific alias analyses that should be run early. + auto *ExtWrapperPass = getAnalysisIfAvailable(); + if (ExtWrapperPass && ExtWrapperPass->runEarly() && ExtWrapperPass->CB) + ExtWrapperPass->CB(*this, F, *AAR); + // BasicAA is always available for function analyses. Also, we add it first // so that it can trump TBAA results when it proves MustAlias. // FIXME: TBAA should have an explicit mode to support this and then we @@ -771,9 +776,8 @@ bool AAResultsWrapperPass::runOnFunction(Function &F) { // If available, run an external AA providing callback over the results as // well. - if (auto *WrapperPass = getAnalysisIfAvailable()) - if (WrapperPass->CB) - WrapperPass->CB(*this, F, *AAR); + if (ExtWrapperPass && !ExtWrapperPass->runEarly() && ExtWrapperPass->CB) + ExtWrapperPass->CB(*this, F, *AAR); // Analyses don't mutate the IR, so return false. return false; diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index 17710eb94b6de..0afcf992dcde7 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -2202,6 +2202,10 @@ AAManager PassBuilder::buildDefaultAAPipeline() { // The order in which these are registered determines their priority when // being queried. + // Add any target-specific alias analyses that should be run early. + if (TM) + TM->registerEarlyDefaultAliasAnalyses(AA); + // First we register the basic alias analysis that provides the majority of // per-function local AA logic. This is a stateless, on-demand local set of // AA techniques. diff --git a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h index 2d204979eb6ce..e509ef3abe67e 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h +++ b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h @@ -79,10 +79,13 @@ class NVPTXAAWrapperPass : public ImmutablePass { // Wrapper around ExternalAAWrapperPass so that the default // constructor gets the callback. +// Note that NVPTXAA will run before BasicAA to for compile time considerations. class NVPTXExternalAAWrapper : public ExternalAAWrapperPass { public: static char ID; + bool runEarly() override { return true; } + NVPTXExternalAAWrapper() : ExternalAAWrapperPass([](Pass &P, Function &, AAResults &AAR) { if (auto *WrapperPass = diff --git a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp index 7d04cf3dc51e6..c6823961a6e80 100644 --- a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp @@ -221,7 +221,7 @@ MachineFunctionInfo *NVPTXTargetMachine::createMachineFunctionInfo( F, STI); } -void NVPTXTargetMachine::registerDefaultAliasAnalyses(AAManager &AAM) { +void NVPTXTargetMachine::registerEarlyDefaultAliasAnalyses(AAManager &AAM) { AAM.registerFunctionAnalysis(); } diff --git a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.h b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.h index 2b88da67a50f9..bb65a14a8d792 100644 --- a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.h +++ b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.h @@ -64,7 +64,7 @@ class NVPTXTargetMachine : public LLVMTargetMachine { createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override; - void registerDefaultAliasAnalyses(AAManager &AAM) override; + void registerEarlyDefaultAliasAnalyses(AAManager &AAM) override; void registerPassBuilderCallbacks(PassBuilder &PB) override; diff --git a/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll b/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll new file mode 100644 index 0000000000000..f01dae60085ed --- /dev/null +++ b/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll @@ -0,0 +1,15 @@ +; RUN: opt -aa-pipeline=default -passes='require' -debug-pass-manager -disable-output -S < %s 2>&1 | FileCheck %s +; RUN: opt -O2 -debug-aa -disable-output -S < %s 2>&1 | FileCheck %s --check-prefix=LEGACY +; LEGACY: NVPTX AA +; LEGACY-NEXT: Basic Alias Analysis (stateless AA impl) + +; In default AA pipeline, NVPTXAA should run before BasicAA to reduce compile time for NVPTX backend +target triple = "nvptx64-nvidia-cuda" + +; CHECK: Running analysis: NVPTXAA on foo +; CHECK-NEXT: Running analysis: BasicAA on foo +define void @foo(){ +entry: + ret void +} + From 0b95b09ca02f02241c1e9f23094a44a11bb4f7cf Mon Sep 17 00:00:00 2001 From: chengjunp Date: Wed, 26 Feb 2025 03:11:21 +0000 Subject: [PATCH 2/6] Update test --- llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll | 3 --- 1 file changed, 3 deletions(-) diff --git a/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll b/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll index f01dae60085ed..7d980b0e6f807 100644 --- a/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll +++ b/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll @@ -1,7 +1,4 @@ ; RUN: opt -aa-pipeline=default -passes='require' -debug-pass-manager -disable-output -S < %s 2>&1 | FileCheck %s -; RUN: opt -O2 -debug-aa -disable-output -S < %s 2>&1 | FileCheck %s --check-prefix=LEGACY -; LEGACY: NVPTX AA -; LEGACY-NEXT: Basic Alias Analysis (stateless AA impl) ; In default AA pipeline, NVPTXAA should run before BasicAA to reduce compile time for NVPTX backend target triple = "nvptx64-nvidia-cuda" From 4c285abc655771fdb83d4a12114a7fe0729d00d6 Mon Sep 17 00:00:00 2001 From: chengjunp Date: Mon, 3 Mar 2025 23:37:03 +0000 Subject: [PATCH 3/6] Add test for Legacy PM --- llvm/lib/Analysis/AliasAnalysis.cpp | 28 ++++++++++++++----- llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h | 2 ++ llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp | 5 +--- .../NVPTXAA/NVPTXAA_before_BasicAA.ll | 5 ++++ 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp index 6ac9a3fab6e36..880ecdfdb4562 100644 --- a/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/llvm/lib/Analysis/AliasAnalysis.cpp @@ -750,30 +750,44 @@ bool AAResultsWrapperPass::runOnFunction(Function &F) { // Add any target-specific alias analyses that should be run early. auto *ExtWrapperPass = getAnalysisIfAvailable(); - if (ExtWrapperPass && ExtWrapperPass->runEarly() && ExtWrapperPass->CB) + if (ExtWrapperPass && ExtWrapperPass->runEarly() && ExtWrapperPass->CB) { + LLVM_DEBUG(dbgs() << "AAResults register Early ExternalAA: " << ExtWrapperPass->getPassName() << "\n"); ExtWrapperPass->CB(*this, F, *AAR); + } // BasicAA is always available for function analyses. Also, we add it first // so that it can trump TBAA results when it proves MustAlias. // FIXME: TBAA should have an explicit mode to support this and then we // should reconsider the ordering here. - if (!DisableBasicAA) + if (!DisableBasicAA) { + LLVM_DEBUG(dbgs() << "AAResults register BasicAA\n"); AAR->addAAResult(getAnalysis().getResult()); + } // Populate the results with the currently available AAs. - if (auto *WrapperPass = getAnalysisIfAvailable()) + if (auto *WrapperPass = getAnalysisIfAvailable()) { + LLVM_DEBUG(dbgs() << "AAResults register ScopedNoAliasAA\n"); AAR->addAAResult(WrapperPass->getResult()); - if (auto *WrapperPass = getAnalysisIfAvailable()) + } + if (auto *WrapperPass = getAnalysisIfAvailable()) { + LLVM_DEBUG(dbgs() << "AAResults register TypeBasedAA\n"); AAR->addAAResult(WrapperPass->getResult()); - if (auto *WrapperPass = getAnalysisIfAvailable()) + } + if (auto *WrapperPass = getAnalysisIfAvailable()) { + LLVM_DEBUG(dbgs() << "AAResults register GlobalsAA\n"); AAR->addAAResult(WrapperPass->getResult()); - if (auto *WrapperPass = getAnalysisIfAvailable()) + } + if (auto *WrapperPass = getAnalysisIfAvailable()) { + LLVM_DEBUG(dbgs() << "AAResults register SCEVAA\n"); AAR->addAAResult(WrapperPass->getResult()); + } // If available, run an external AA providing callback over the results as // well. - if (ExtWrapperPass && !ExtWrapperPass->runEarly() && ExtWrapperPass->CB) + if (ExtWrapperPass && !ExtWrapperPass->runEarly() && ExtWrapperPass->CB) { + LLVM_DEBUG(dbgs() << "AAResults register Late ExternalAA: " << ExtWrapperPass->getPassName() << "\n"); ExtWrapperPass->CB(*this, F, *AAR); + } // Analyses don't mutate the IR, so return false. return false; diff --git a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h index e509ef3abe67e..b2b6ef7fe733b 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h +++ b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h @@ -92,6 +92,8 @@ class NVPTXExternalAAWrapper : public ExternalAAWrapperPass { P.getAnalysisIfAvailable()) AAR.addAAResult(WrapperPass->getResult()); }) {} + + StringRef getPassName() const override { return "NVPTX Address space based Alias Analysis Wrapper"; } }; ImmutablePass *createNVPTXAAWrapperPass(); diff --git a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp index fb126851f3b5f..539b03edbfb15 100644 --- a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp +++ b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp @@ -360,10 +360,7 @@ void NVPTXPassConfig::addIRPasses() { disablePass(&RemoveLoadsIntoFakeUsesID); addPass(createNVPTXAAWrapperPass()); - addPass(createExternalAAWrapperPass([](Pass &P, Function &, AAResults &AAR) { - if (auto *WrapperPass = P.getAnalysisIfAvailable()) - AAR.addAAResult(WrapperPass->getResult()); - })); + addPass(createNVPTXExternalAAWrapperPass()); // NVVMReflectPass is added in addEarlyAsPossiblePasses, so hopefully running // it here does nothing. But since we need it for correctness when lowering diff --git a/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll b/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll index 7d980b0e6f807..0d16b344e9f66 100644 --- a/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll +++ b/llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll @@ -1,10 +1,15 @@ +; REQUIRES: asserts ; RUN: opt -aa-pipeline=default -passes='require' -debug-pass-manager -disable-output -S < %s 2>&1 | FileCheck %s +; RUN: llc --debug-only='aa' -o /dev/null %s 2>&1 | FileCheck %s -check-prefix=LEGACY ; In default AA pipeline, NVPTXAA should run before BasicAA to reduce compile time for NVPTX backend target triple = "nvptx64-nvidia-cuda" ; CHECK: Running analysis: NVPTXAA on foo ; CHECK-NEXT: Running analysis: BasicAA on foo + +; LEGACY: AAResults register Early ExternalAA: NVPTX Address space based Alias Analysis Wrapper +; LEGACY-NEXT: AAResults register BasicAA define void @foo(){ entry: ret void From 9d9a05ca2aa88f068daa11a7b62dffe39e9fdb60 Mon Sep 17 00:00:00 2001 From: chengjunp Date: Wed, 12 Mar 2025 01:02:09 +0000 Subject: [PATCH 4/6] Format --- llvm/lib/Analysis/AliasAnalysis.cpp | 9 ++++++--- llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp index 880ecdfdb4562..913a228f07bd3 100644 --- a/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/llvm/lib/Analysis/AliasAnalysis.cpp @@ -751,7 +751,8 @@ bool AAResultsWrapperPass::runOnFunction(Function &F) { // Add any target-specific alias analyses that should be run early. auto *ExtWrapperPass = getAnalysisIfAvailable(); if (ExtWrapperPass && ExtWrapperPass->runEarly() && ExtWrapperPass->CB) { - LLVM_DEBUG(dbgs() << "AAResults register Early ExternalAA: " << ExtWrapperPass->getPassName() << "\n"); + LLVM_DEBUG(dbgs() << "AAResults register Early ExternalAA: " + << ExtWrapperPass->getPassName() << "\n"); ExtWrapperPass->CB(*this, F, *AAR); } @@ -765,7 +766,8 @@ bool AAResultsWrapperPass::runOnFunction(Function &F) { } // Populate the results with the currently available AAs. - if (auto *WrapperPass = getAnalysisIfAvailable()) { + if (auto *WrapperPass = + getAnalysisIfAvailable()) { LLVM_DEBUG(dbgs() << "AAResults register ScopedNoAliasAA\n"); AAR->addAAResult(WrapperPass->getResult()); } @@ -785,7 +787,8 @@ bool AAResultsWrapperPass::runOnFunction(Function &F) { // If available, run an external AA providing callback over the results as // well. if (ExtWrapperPass && !ExtWrapperPass->runEarly() && ExtWrapperPass->CB) { - LLVM_DEBUG(dbgs() << "AAResults register Late ExternalAA: " << ExtWrapperPass->getPassName() << "\n"); + LLVM_DEBUG(dbgs() << "AAResults register Late ExternalAA: " + << ExtWrapperPass->getPassName() << "\n"); ExtWrapperPass->CB(*this, F, *AAR); } diff --git a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h index b2b6ef7fe733b..f9495517ebfb1 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h +++ b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h @@ -93,7 +93,9 @@ class NVPTXExternalAAWrapper : public ExternalAAWrapperPass { AAR.addAAResult(WrapperPass->getResult()); }) {} - StringRef getPassName() const override { return "NVPTX Address space based Alias Analysis Wrapper"; } + StringRef getPassName() const override { + return "NVPTX Address space based Alias Analysis Wrapper"; + } }; ImmutablePass *createNVPTXAAWrapperPass(); From fc8a5e702e5c805e09c002662193731f5f517c02 Mon Sep 17 00:00:00 2001 From: chengjunp Date: Tue, 29 Apr 2025 18:55:01 +0000 Subject: [PATCH 5/6] Add doc comment & fix typos --- llvm/include/llvm/Analysis/AliasAnalysis.h | 9 +++++++++ llvm/include/llvm/Target/TargetMachine.h | 2 +- llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h index bf16ab3668066..d275ad498bff2 100644 --- a/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -1007,6 +1007,15 @@ struct ExternalAAWrapperPass : ImmutablePass { explicit ExternalAAWrapperPass(CallbackT CB); + /// Returns whether this external AA should run before Basic AA. + /// + /// By default, external AA passes are run after Basic AA. If this returns true, + /// the external AA will be run before Basic AA during alias analysis. + /// + /// For some targets, we prefer to run the external AA early to improve compile + /// time as it has more target-specific information. This is particularly useful + /// when the external AA can provide more precise results than Basic AA so that + /// Basic AA does not need to spend time recomputing them. virtual bool runEarly() { return false; } void getAnalysisUsage(AnalysisUsage &AU) const override { diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h index 9cb90e8b06752..3e437817c103a 100644 --- a/llvm/include/llvm/Target/TargetMachine.h +++ b/llvm/include/llvm/Target/TargetMachine.h @@ -396,7 +396,7 @@ class TargetMachine { // TODO: Populate all pass names by using PassRegistry.def. virtual void registerPassBuilderCallbacks(PassBuilder &) {} - /// Allow the target to register early alias analyses(AA before basicAA) with + /// Allow the target to register early alias analyses (AA before BasicAA) with /// the AAManager for use with the new pass manager. Only affects the /// "default" AAManager. virtual void registerEarlyDefaultAliasAnalyses(AAManager &) {} diff --git a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h index f9495517ebfb1..eec0c537448dd 100644 --- a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h +++ b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h @@ -79,7 +79,7 @@ class NVPTXAAWrapperPass : public ImmutablePass { // Wrapper around ExternalAAWrapperPass so that the default // constructor gets the callback. -// Note that NVPTXAA will run before BasicAA to for compile time considerations. +// Note that NVPTXAA will run before BasicAA for compile time considerations. class NVPTXExternalAAWrapper : public ExternalAAWrapperPass { public: static char ID; From e5dd0928037945f47732e93ed83225b0f5bca177 Mon Sep 17 00:00:00 2001 From: chengjunp Date: Tue, 29 Apr 2025 19:03:28 +0000 Subject: [PATCH 6/6] Format --- llvm/include/llvm/Analysis/AliasAnalysis.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h index daf1175fa7928..d23b81854c9ea 100644 --- a/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -1015,13 +1015,14 @@ struct ExternalAAWrapperPass : ImmutablePass { /// Returns whether this external AA should run before Basic AA. /// - /// By default, external AA passes are run after Basic AA. If this returns true, - /// the external AA will be run before Basic AA during alias analysis. + /// By default, external AA passes are run after Basic AA. If this returns + /// true, the external AA will be run before Basic AA during alias analysis. /// - /// For some targets, we prefer to run the external AA early to improve compile - /// time as it has more target-specific information. This is particularly useful - /// when the external AA can provide more precise results than Basic AA so that - /// Basic AA does not need to spend time recomputing them. + /// For some targets, we prefer to run the external AA early to improve + /// compile time as it has more target-specific information. This is + /// particularly useful when the external AA can provide more precise results + /// than Basic AA so that Basic AA does not need to spend time recomputing + /// them. virtual bool runEarly() { return false; } void getAnalysisUsage(AnalysisUsage &AU) const override {