blob: 30b46b01c1def2527fb2a1bb975be58017a66800 [file] [log] [blame]
Chandler Carruth74015a72013-11-13 01:12:08 +00001//===- PassManager.h - Infrastructure for managing & running IR passes ----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/IR/PassManager.h"
11#include "llvm/ADT/STLExtras.h"
12
13using namespace llvm;
14
Chandler Carruthb3e72192013-11-22 00:43:29 +000015PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) {
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000016 PreservedAnalyses PA = PreservedAnalyses::all();
17 for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
Chandler Carruthb3e72192013-11-22 00:43:29 +000018 PreservedAnalyses PassPA = Passes[Idx]->run(M, AM);
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000019 if (AM)
20 AM->invalidate(M, PassPA);
21 PA.intersect(llvm_move(PassPA));
22 }
23 return PA;
Chandler Carruthed1ffe02013-11-20 04:01:38 +000024}
25
Chandler Carruth16ea68e2013-11-26 11:24:37 +000026const ModuleAnalysisManager::ResultConceptT &
Chandler Carruthed1ffe02013-11-20 04:01:38 +000027ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) {
28 ModuleAnalysisResultMapT::iterator RI;
29 bool Inserted;
30 llvm::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair(
Chandler Carruth5bf5e312013-11-22 11:34:43 +000031 PassID, polymorphic_ptr<detail::AnalysisResultConcept<Module *> >()));
Chandler Carruthed1ffe02013-11-20 04:01:38 +000032
Chandler Carruth16ea68e2013-11-26 11:24:37 +000033 // If we don't have a cached result for this module, look up the pass and run
34 // it to produce a result, which we then add to the cache.
35 if (Inserted)
36 RI->second = lookupPass(PassID).run(M, this);
Chandler Carruthed1ffe02013-11-20 04:01:38 +000037
38 return *RI->second;
39}
40
Chandler Carruth16ea68e2013-11-26 11:24:37 +000041const ModuleAnalysisManager::ResultConceptT *
Chandler Carruthde9afd82013-11-23 00:38:42 +000042ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module *M) const {
43 ModuleAnalysisResultMapT::const_iterator RI = ModuleAnalysisResults.find(PassID);
44 return RI == ModuleAnalysisResults.end() ? 0 : &*RI->second;
45}
46
Chandler Carruthed1ffe02013-11-20 04:01:38 +000047void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) {
48 ModuleAnalysisResults.erase(PassID);
Chandler Carruth74015a72013-11-13 01:12:08 +000049}
50
Chandler Carruth16ea68e2013-11-26 11:24:37 +000051void ModuleAnalysisManager::invalidateImpl(Module *M,
52 const PreservedAnalyses &PA) {
53 // FIXME: This is a total hack based on the fact that erasure doesn't
54 // invalidate iteration for DenseMap.
55 for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(),
56 E = ModuleAnalysisResults.end();
57 I != E; ++I)
58 if (I->second->invalidate(M, PA))
59 ModuleAnalysisResults.erase(I);
60}
61
Chandler Carruthb3e72192013-11-22 00:43:29 +000062PreservedAnalyses FunctionPassManager::run(Function *F, FunctionAnalysisManager *AM) {
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000063 PreservedAnalyses PA = PreservedAnalyses::all();
64 for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
Chandler Carruthb3e72192013-11-22 00:43:29 +000065 PreservedAnalyses PassPA = Passes[Idx]->run(F, AM);
Chandler Carruthc0bfa8c2013-11-20 11:31:50 +000066 if (AM)
67 AM->invalidate(F, PassPA);
68 PA.intersect(llvm_move(PassPA));
69 }
70 return PA;
Chandler Carruth74015a72013-11-13 01:12:08 +000071}
72
Chandler Carruth16ea68e2013-11-26 11:24:37 +000073bool FunctionAnalysisManager::empty() const {
74 assert(FunctionAnalysisResults.empty() ==
75 FunctionAnalysisResultLists.empty() &&
76 "The storage and index of analysis results disagree on how many there "
77 "are!");
78 return FunctionAnalysisResults.empty();
79}
80
81void FunctionAnalysisManager::clear() {
82 FunctionAnalysisResults.clear();
83 FunctionAnalysisResultLists.clear();
84}
85
86const FunctionAnalysisManager::ResultConceptT &
87FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) {
88 FunctionAnalysisResultMapT::iterator RI;
89 bool Inserted;
90 llvm::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair(
91 std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator()));
92
93 // If we don't have a cached result for this function, look up the pass and
94 // run it to produce a result, which we then add to the cache.
95 if (Inserted) {
96 FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F];
97 ResultList.push_back(std::make_pair(PassID, lookupPass(PassID).run(F, this)));
98 RI->second = llvm::prior(ResultList.end());
99 }
100
101 return *RI->second->second;
102}
103
104const FunctionAnalysisManager::ResultConceptT *
105FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function *F) const {
106 FunctionAnalysisResultMapT::const_iterator RI =
107 FunctionAnalysisResults.find(std::make_pair(PassID, F));
108 return RI == FunctionAnalysisResults.end() ? 0 : &*RI->second->second;
109}
110
111void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) {
112 FunctionAnalysisResultMapT::iterator RI =
113 FunctionAnalysisResults.find(std::make_pair(PassID, F));
114 if (RI == FunctionAnalysisResults.end())
115 return;
116
117 FunctionAnalysisResultLists[F].erase(RI->second);
118}
119
120void FunctionAnalysisManager::invalidateImpl(Function *F,
121 const PreservedAnalyses &PA) {
Chandler Carruthed1ffe02013-11-20 04:01:38 +0000122 // Clear all the invalidated results associated specifically with this
Chandler Carruth74015a72013-11-13 01:12:08 +0000123 // function.
124 SmallVector<void *, 8> InvalidatedPassIDs;
125 FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F];
126 for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(),
127 E = ResultsList.end();
Chandler Carruth8c60bc92013-11-15 21:56:44 +0000128 I != E;)
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000129 if (I->second->invalidate(F, PA)) {
Chandler Carruth8c60bc92013-11-15 21:56:44 +0000130 InvalidatedPassIDs.push_back(I->first);
131 I = ResultsList.erase(I);
132 } else {
133 ++I;
Chandler Carruth74015a72013-11-13 01:12:08 +0000134 }
135 while (!InvalidatedPassIDs.empty())
136 FunctionAnalysisResults.erase(
137 std::make_pair(InvalidatedPassIDs.pop_back_val(), F));
138}
139
Chandler Carruthb3e72192013-11-22 00:43:29 +0000140char FunctionAnalysisManagerModuleProxy::PassID;
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000141
Chandler Carruthb3e72192013-11-22 00:43:29 +0000142FunctionAnalysisManagerModuleProxy::Result
143FunctionAnalysisManagerModuleProxy::run(Module *M) {
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000144 assert(FAM.empty() && "Function analyses ran prior to the module proxy!");
145 return Result(FAM);
146}
147
Chandler Carruthb3e72192013-11-22 00:43:29 +0000148FunctionAnalysisManagerModuleProxy::Result::~Result() {
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000149 // Clear out the analysis manager if we're being destroyed -- it means we
150 // didn't even see an invalidate call when we got invalidated.
151 FAM.clear();
152}
153
Chandler Carruthb3e72192013-11-22 00:43:29 +0000154bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
155 Module *M, const PreservedAnalyses &PA) {
Chandler Carruthbceeb222013-11-22 23:38:07 +0000156 // If this proxy isn't marked as preserved, then we can't even invalidate
157 // individual function analyses, there may be an invalid set of Function
158 // objects in the cache making it impossible to incrementally preserve them.
159 // Just clear the entire manager.
160 if (!PA.preserved(ID()))
Chandler Carruth2846e9e2013-11-21 10:53:05 +0000161 FAM.clear();
Chandler Carruth851a2aa2013-11-21 02:11:31 +0000162
163 // Return false to indicate that this result is still a valid proxy.
164 return false;
165}
Chandler Carruthc1ff9ed2013-11-23 01:25:07 +0000166
167char ModuleAnalysisManagerFunctionProxy::PassID;