PassManager.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
1//===- PassManager.cpp - 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/ADT/STLExtras.h"
11#include "llvm/IR/PassManager.h"
12#include "llvm/Support/CommandLine.h"
13#include "llvm/Support/Debug.h"
14
15using namespace llvm;
16
17static cl::opt<bool>
18DebugPM("debug-pass-manager", cl::Hidden,
19        cl::desc("Print pass management debugging information"));
20
21PreservedAnalyses ModulePassManager::run(Module *M, ModuleAnalysisManager *AM) {
22  PreservedAnalyses PA = PreservedAnalyses::all();
23
24  if (DebugPM)
25    dbgs() << "Starting module pass manager run.\n";
26
27  for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
28    if (DebugPM)
29      dbgs() << "Running module pass: " << Passes[Idx]->name() << "\n";
30
31    PreservedAnalyses PassPA = Passes[Idx]->run(M, AM);
32    if (AM)
33      AM->invalidate(M, PassPA);
34    PA.intersect(std::move(PassPA));
35  }
36
37  if (DebugPM)
38    dbgs() << "Finished module pass manager run.\n";
39
40  return PA;
41}
42
43ModuleAnalysisManager::ResultConceptT &
44ModuleAnalysisManager::getResultImpl(void *PassID, Module *M) {
45  ModuleAnalysisResultMapT::iterator RI;
46  bool Inserted;
47  std::tie(RI, Inserted) = ModuleAnalysisResults.insert(std::make_pair(
48      PassID, std::unique_ptr<detail::AnalysisResultConcept<Module *>>()));
49
50  // If we don't have a cached result for this module, look up the pass and run
51  // it to produce a result, which we then add to the cache.
52  if (Inserted)
53    RI->second = std::move(lookupPass(PassID).run(M, this));
54
55  return *RI->second;
56}
57
58ModuleAnalysisManager::ResultConceptT *
59ModuleAnalysisManager::getCachedResultImpl(void *PassID, Module *M) const {
60  ModuleAnalysisResultMapT::const_iterator RI =
61      ModuleAnalysisResults.find(PassID);
62  return RI == ModuleAnalysisResults.end() ? 0 : &*RI->second;
63}
64
65void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) {
66  ModuleAnalysisResults.erase(PassID);
67}
68
69void ModuleAnalysisManager::invalidateImpl(Module *M,
70                                           const PreservedAnalyses &PA) {
71  // FIXME: This is a total hack based on the fact that erasure doesn't
72  // invalidate iteration for DenseMap.
73  for (ModuleAnalysisResultMapT::iterator I = ModuleAnalysisResults.begin(),
74                                          E = ModuleAnalysisResults.end();
75       I != E; ++I)
76    if (I->second->invalidate(M, PA))
77      ModuleAnalysisResults.erase(I);
78}
79
80PreservedAnalyses FunctionPassManager::run(Function *F,
81                                           FunctionAnalysisManager *AM) {
82  PreservedAnalyses PA = PreservedAnalyses::all();
83
84  if (DebugPM)
85    dbgs() << "Starting function pass manager run.\n";
86
87  for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
88    if (DebugPM)
89      dbgs() << "Running function pass: " << Passes[Idx]->name() << "\n";
90
91    PreservedAnalyses PassPA = Passes[Idx]->run(F, AM);
92    if (AM)
93      AM->invalidate(F, PassPA);
94    PA.intersect(std::move(PassPA));
95  }
96
97  if (DebugPM)
98    dbgs() << "Finished function pass manager run.\n";
99
100  return PA;
101}
102
103bool FunctionAnalysisManager::empty() const {
104  assert(FunctionAnalysisResults.empty() ==
105             FunctionAnalysisResultLists.empty() &&
106         "The storage and index of analysis results disagree on how many there "
107         "are!");
108  return FunctionAnalysisResults.empty();
109}
110
111void FunctionAnalysisManager::clear() {
112  FunctionAnalysisResults.clear();
113  FunctionAnalysisResultLists.clear();
114}
115
116FunctionAnalysisManager::ResultConceptT &
117FunctionAnalysisManager::getResultImpl(void *PassID, Function *F) {
118  FunctionAnalysisResultMapT::iterator RI;
119  bool Inserted;
120  std::tie(RI, Inserted) = FunctionAnalysisResults.insert(std::make_pair(
121      std::make_pair(PassID, F), FunctionAnalysisResultListT::iterator()));
122
123  // If we don't have a cached result for this function, look up the pass and
124  // run it to produce a result, which we then add to the cache.
125  if (Inserted) {
126    FunctionAnalysisResultListT &ResultList = FunctionAnalysisResultLists[F];
127    ResultList.emplace_back(PassID, lookupPass(PassID).run(F, this));
128    RI->second = std::prev(ResultList.end());
129  }
130
131  return *RI->second->second;
132}
133
134FunctionAnalysisManager::ResultConceptT *
135FunctionAnalysisManager::getCachedResultImpl(void *PassID, Function *F) const {
136  FunctionAnalysisResultMapT::const_iterator RI =
137      FunctionAnalysisResults.find(std::make_pair(PassID, F));
138  return RI == FunctionAnalysisResults.end() ? 0 : &*RI->second->second;
139}
140
141void FunctionAnalysisManager::invalidateImpl(void *PassID, Function *F) {
142  FunctionAnalysisResultMapT::iterator RI =
143      FunctionAnalysisResults.find(std::make_pair(PassID, F));
144  if (RI == FunctionAnalysisResults.end())
145    return;
146
147  FunctionAnalysisResultLists[F].erase(RI->second);
148}
149
150void FunctionAnalysisManager::invalidateImpl(Function *F,
151                                             const PreservedAnalyses &PA) {
152  // Clear all the invalidated results associated specifically with this
153  // function.
154  SmallVector<void *, 8> InvalidatedPassIDs;
155  FunctionAnalysisResultListT &ResultsList = FunctionAnalysisResultLists[F];
156  for (FunctionAnalysisResultListT::iterator I = ResultsList.begin(),
157                                             E = ResultsList.end();
158       I != E;)
159    if (I->second->invalidate(F, PA)) {
160      InvalidatedPassIDs.push_back(I->first);
161      I = ResultsList.erase(I);
162    } else {
163      ++I;
164    }
165  while (!InvalidatedPassIDs.empty())
166    FunctionAnalysisResults.erase(
167        std::make_pair(InvalidatedPassIDs.pop_back_val(), F));
168}
169
170char FunctionAnalysisManagerModuleProxy::PassID;
171
172FunctionAnalysisManagerModuleProxy::Result
173FunctionAnalysisManagerModuleProxy::run(Module *M) {
174  assert(FAM->empty() && "Function analyses ran prior to the module proxy!");
175  return Result(*FAM);
176}
177
178FunctionAnalysisManagerModuleProxy::Result::~Result() {
179  // Clear out the analysis manager if we're being destroyed -- it means we
180  // didn't even see an invalidate call when we got invalidated.
181  FAM->clear();
182}
183
184bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
185    Module *M, const PreservedAnalyses &PA) {
186  // If this proxy isn't marked as preserved, then we can't even invalidate
187  // individual function analyses, there may be an invalid set of Function
188  // objects in the cache making it impossible to incrementally preserve them.
189  // Just clear the entire manager.
190  if (!PA.preserved(ID()))
191    FAM->clear();
192
193  // Return false to indicate that this result is still a valid proxy.
194  return false;
195}
196
197char ModuleAnalysisManagerFunctionProxy::PassID;
198