summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/AliasAnalysis.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2015-10-21 12:15:19 +0000
committerChandler Carruth <chandlerc@gmail.com>2015-10-21 12:15:19 +0000
commit2be10754a90e3e5fb1079a99029c9507a43b81f0 (patch)
treec92668f0c56fec614b73e08287f2e7505a35eb6c /llvm/lib/Analysis/AliasAnalysis.cpp
parent3ad76a1acdfa499f3ace3c087d0453dc0ae96064 (diff)
downloadbcm5719-llvm-2be10754a90e3e5fb1079a99029c9507a43b81f0.tar.gz
bcm5719-llvm-2be10754a90e3e5fb1079a99029c9507a43b81f0.zip
[AA] Enhance the new AliasAnalysis infrastructure with an optional
"external" AA wrapper pass. This is a generic hook that can be used to thread custom code into the primary AAResultsWrapperPass for the legacy pass manager in order to allow it to merge external AA results into the AA results it is building. It does this by threading in a raw callback and so it is *very* powerful and should serve almost any use case I have come up with for extending the set of alias analyses used. The only thing not well supported here is using a *different order* of alias analyses. That form of extension *is* supportable with the new pass manager, and I can make the callback structure here more elaborate to support it in the legacy pass manager if this is a critical use case that people are already depending on, but the only use cases I have heard of thus far should be reasonably satisfied by this simpler extension mechanism. It is hard to test this using normal facilities (the built-in AAs don't use this for obvious reasons) so I've written a fairly extensive set of custom passes in the alias analysis unit test that should be an excellent test case because it models the out-of-tree users: it adds a totally custom AA to the system. This should also serve as a reasonably good example and guide for out-of-tree users to follow in order to rig up their existing alias analyses. No support in opt for commandline control is provided here however. I'm really unhappy with the kind of contortions that would be required to support that. It would fully re-introduce the analysis group self-recursion kind of patterns. =/ I've heard from out-of-tree users that this will unblock their use cases with extending AAs on top of the new infrastructure and let us retain the new analysis-group-free-world. Differential Revision: http://reviews.llvm.org/D13418 llvm-svn: 250894
Diffstat (limited to 'llvm/lib/Analysis/AliasAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/AliasAnalysis.cpp40
1 files changed, 40 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp
index 4cf8dcfbbe7..0fef5c66651 100644
--- a/llvm/lib/Analysis/AliasAnalysis.cpp
+++ b/llvm/lib/Analysis/AliasAnalysis.cpp
@@ -364,6 +364,39 @@ bool AAResults::canInstructionRangeModRef(const Instruction &I1,
// Provide a definition for the root virtual destructor.
AAResults::Concept::~Concept() {}
+namespace {
+/// A wrapper pass for external alias analyses. This just squirrels away the
+/// callback used to run any analyses and register their results.
+struct ExternalAAWrapperPass : ImmutablePass {
+ typedef std::function<void(Pass &, Function &, AAResults &)> CallbackT;
+
+ CallbackT CB;
+
+ static char ID;
+
+ ExternalAAWrapperPass() : ImmutablePass(ID) {
+ initializeExternalAAWrapperPassPass(*PassRegistry::getPassRegistry());
+ }
+ explicit ExternalAAWrapperPass(CallbackT CB)
+ : ImmutablePass(ID), CB(std::move(CB)) {
+ initializeExternalAAWrapperPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+};
+}
+
+char ExternalAAWrapperPass::ID = 0;
+INITIALIZE_PASS(ExternalAAWrapperPass, "external-aa", "External Alias Analysis",
+ false, true)
+
+ImmutablePass *
+llvm::createExternalAAWrapperPass(ExternalAAWrapperPass::CallbackT Callback) {
+ return new ExternalAAWrapperPass(std::move(Callback));
+}
+
AAResultsWrapperPass::AAResultsWrapperPass() : FunctionPass(ID) {
initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());
}
@@ -374,6 +407,7 @@ INITIALIZE_PASS_BEGIN(AAResultsWrapperPass, "aa",
"Function Alias Analysis Results", false, true)
INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(CFLAAWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(ExternalAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ObjCARCAAWrapperPass)
INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
@@ -425,6 +459,12 @@ bool AAResultsWrapperPass::runOnFunction(Function &F) {
if (auto *WrapperPass = getAnalysisIfAvailable<CFLAAWrapperPass>())
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);
+
// Analyses don't mutate the IR, so return false.
return false;
}
OpenPOWER on IntegriCloud