Skip to content

[AA] Move Target Specific AA before BasicAA #125965

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

Merged
merged 8 commits into from
May 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions llvm/include/llvm/Analysis/AliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,18 @@ 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 {
AU.setPreservesAll();
}
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/Target/TargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,11 @@ class TargetMachine {
// TODO: Populate all pass names by using <Target>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 &) {}
Expand Down
37 changes: 29 additions & 8 deletions llvm/lib/Analysis/AliasAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -736,28 +736,49 @@ bool AAResultsWrapperPass::runOnFunction(Function &F) {
AAR.reset(
new AAResults(getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F)));

// Add any target-specific alias analyses that should be run early.
auto *ExtWrapperPass = getAnalysisIfAvailable<ExternalAAWrapperPass>();
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");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this new debug output just for the test case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I do not find a good way to test the change in Legacy pass manager, so I have these debug outputs. These outputs are also helpful when I'm making the change for NVPTX AA. Do you have any suggestions for doing the test?

AAR->addAAResult(getAnalysis<BasicAAWrapperPass>().getResult());
}

// Populate the results with the currently available AAs.
if (auto *WrapperPass = getAnalysisIfAvailable<ScopedNoAliasAAWrapperPass>())
if (auto *WrapperPass =
getAnalysisIfAvailable<ScopedNoAliasAAWrapperPass>()) {
LLVM_DEBUG(dbgs() << "AAResults register ScopedNoAliasAA\n");
AAR->addAAResult(WrapperPass->getResult());
if (auto *WrapperPass = getAnalysisIfAvailable<TypeBasedAAWrapperPass>())
}
if (auto *WrapperPass = getAnalysisIfAvailable<TypeBasedAAWrapperPass>()) {
LLVM_DEBUG(dbgs() << "AAResults register TypeBasedAA\n");
AAR->addAAResult(WrapperPass->getResult());
if (auto *WrapperPass = getAnalysisIfAvailable<GlobalsAAWrapperPass>())
}
if (auto *WrapperPass = getAnalysisIfAvailable<GlobalsAAWrapperPass>()) {
LLVM_DEBUG(dbgs() << "AAResults register GlobalsAA\n");
AAR->addAAResult(WrapperPass->getResult());
if (auto *WrapperPass = getAnalysisIfAvailable<SCEVAAWrapperPass>())
}
if (auto *WrapperPass = getAnalysisIfAvailable<SCEVAAWrapperPass>()) {
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 (auto *WrapperPass = getAnalysisIfAvailable<ExternalAAWrapperPass>())
if (WrapperPass->CB)
WrapperPass->CB(*this, F, *AAR);
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;
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Passes/PassBuilderPipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2320,6 +2320,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.
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,23 @@ class NVPTXAAWrapperPass : public ImmutablePass {

// Wrapper around ExternalAAWrapperPass so that the default
// constructor gets the callback.
// Note that NVPTXAA will run before BasicAA 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 =
P.getAnalysisIfAvailable<NVPTXAAWrapperPass>())
AAR.addAAResult(WrapperPass->getResult());
}) {}

StringRef getPassName() const override {
return "NVPTX Address space based Alias Analysis Wrapper";
}
};

ImmutablePass *createNVPTXAAWrapperPass();
Expand Down
7 changes: 2 additions & 5 deletions llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ MachineFunctionInfo *NVPTXTargetMachine::createMachineFunctionInfo(
F, STI);
}

void NVPTXTargetMachine::registerDefaultAliasAnalyses(AAManager &AAM) {
void NVPTXTargetMachine::registerEarlyDefaultAliasAnalyses(AAManager &AAM) {
AAM.registerFunctionAnalysis<NVPTXAA>();
}

Expand Down Expand Up @@ -347,10 +347,7 @@ void NVPTXPassConfig::addIRPasses() {
disablePass(&RemoveLoadsIntoFakeUsesID);

addPass(createNVPTXAAWrapperPass());
addPass(createExternalAAWrapperPass([](Pass &P, Function &, AAResults &AAR) {
if (auto *WrapperPass = P.getAnalysisIfAvailable<NVPTXAAWrapperPass>())
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
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/NVPTX/NVPTXTargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class NVPTXTargetMachine : public CodeGenTargetMachineImpl {
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;

Expand Down
17 changes: 17 additions & 0 deletions llvm/test/Analysis/NVPTXAA/NVPTXAA_before_BasicAA.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; REQUIRES: asserts
; RUN: opt -aa-pipeline=default -passes='require<aa>' -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
}