summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/PassManager.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2013-11-20 11:31:50 +0000
committerChandler Carruth <chandlerc@gmail.com>2013-11-20 11:31:50 +0000
commitc0bfa8c2310fd415886835f130c01a660bca8940 (patch)
treeb2cf0525996b33d0c8bef717ed7679d4acd45c2f /llvm/lib/IR/PassManager.cpp
parent06c84f2e071203e6a2acaa3ff0c1c30d63c9c063 (diff)
downloadbcm5719-llvm-c0bfa8c2310fd415886835f130c01a660bca8940.tar.gz
bcm5719-llvm-c0bfa8c2310fd415886835f130c01a660bca8940.zip
[PM] Add the preservation system to the new pass manager.
This adds a new set-like type which represents a set of preserved analysis passes. The set is managed via the opaque PassT::ID() void*s. The expected convenience templates for interacting with specific passes are provided. It also supports a symbolic "all" state which is represented by an invalid pointer in the set. This state is nicely saturating as it comes up often. Finally, it supports intersection which is used when finding the set of preserved passes after N different transforms. The pass API is then changed to return the preserved set rather than a bool. This is much more self-documenting than the previous system. Returning "none" is a conservatively correct solution just like returning "true" from todays passes and not marking any passes as preserved. Passes can also be dynamically preserved or not throughout the run of the pass, and whatever gets returned is the binding state. Finally, preserving "all" the passes is allowed for no-op transforms that simply can't harm such things. Finally, the analysis managers are changed to instead of blindly invalidating all of the analyses, invalidate those which were not preserved. This should rig up all of the basic preservation functionality. This also correctly combines the preservation moving up from one IR-layer to the another and the preservation aggregation across N pass runs. Still to go is incrementally correct invalidation and preservation across IR layers incrementally during N pass runs. That will wait until we have a device for even exposing analyses across IR layers. While the core of this change is obvious, I'm not happy with the current testing, so will improve it to cover at least some of the invalidation that I can test easily in a subsequent commit. llvm-svn: 195241
Diffstat (limited to 'llvm/lib/IR/PassManager.cpp')
-rw-r--r--llvm/lib/IR/PassManager.cpp40
1 files changed, 22 insertions, 18 deletions
diff --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp
index 35fc534151a..0508b3cb281 100644
--- a/llvm/lib/IR/PassManager.cpp
+++ b/llvm/lib/IR/PassManager.cpp
@@ -12,20 +12,24 @@
using namespace llvm;
-void ModulePassManager::run(Module *M) {
- for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx)
- if (Passes[Idx]->run(M))
- if (AM)
- AM->invalidateAll(M);
+PreservedAnalyses ModulePassManager::run(Module *M) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
+ PreservedAnalyses PassPA = Passes[Idx]->run(M);
+ if (AM)
+ AM->invalidate(M, PassPA);
+ PA.intersect(llvm_move(PassPA));
+ }
+ return PA;
}
-void ModuleAnalysisManager::invalidateAll(Module *M) {
+void ModuleAnalysisManager::invalidate(Module *M, const PreservedAnalyses &PA) {
// FIXME: This is a total hack based on the fact that erasure doesn't
// invalidate iteration for DenseMap.
for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(),
E = ModuleAnalysisResults.end();
I != E; ++I)
- if (I->second->invalidate(M))
+ if (!PA.preserved(I->first) && I->second->invalidate(M))
ModuleAnalysisResults.erase(I);
}
@@ -53,18 +57,18 @@ void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) {
ModuleAnalysisResults.erase(PassID);
}
-bool FunctionPassManager::run(Function *F) {
- bool Changed = false;
- for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx)
- if (Passes[Idx]->run(F)) {
- Changed = true;
- if (AM)
- AM->invalidateAll(F);
- }
- return Changed;
+PreservedAnalyses FunctionPassManager::run(Function *F) {
+ PreservedAnalyses PA = PreservedAnalyses::all();
+ for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
+ PreservedAnalyses PassPA = Passes[Idx]->run(F);
+ if (AM)
+ AM->invalidate(F, PassPA);
+ PA.intersect(llvm_move(PassPA));
+ }
+ return PA;
}
-void FunctionAnalysisManager::invalidateAll(Function *F) {
+void FunctionAnalysisManager::invalidate(Function *F, const PreservedAnalyses &PA) {
// Clear all the invalidated results associated specifically with this
// function.
SmallVector<void *, 8> InvalidatedPassIDs;
@@ -72,7 +76,7 @@ void FunctionAnalysisManager::invalidateAll(Function *F) {
for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(),
E = ResultsList.end();
I != E;)
- if (I->second->invalidate(F)) {
+ if (!PA.preserved(I->first) && I->second->invalidate(F)) {
InvalidatedPassIDs.push_back(I->first);
I = ResultsList.erase(I);
} else {
OpenPOWER on IntegriCloud