LLVM 17.0.0git
PassManagerImpl.h
Go to the documentation of this file.
1//===- PassManagerImpl.h - Pass management infrastructure -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// Provides implementations for PassManager and AnalysisManager template
10/// methods. These classes should be explicitly instantiated for any IR unit,
11/// and files doing the explicit instantiation should include this header.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_IR_PASSMANAGERIMPL_H
16#define LLVM_IR_PASSMANAGERIMPL_H
17
18#include "llvm/IR/PassManager.h"
19
20namespace llvm {
21
22template <typename IRUnitT, typename... ExtraArgTs>
24
25template <typename IRUnitT, typename... ExtraArgTs>
27 AnalysisManager &&) = default;
28
29template <typename IRUnitT, typename... ExtraArgTs>
30inline AnalysisManager<IRUnitT, ExtraArgTs...> &
32 default;
33
34template <typename IRUnitT, typename... ExtraArgTs>
35inline void
38 if (auto *PI = getCachedResult<PassInstrumentationAnalysis>(IR))
39 PI->runAnalysesCleared(Name);
40
41 auto ResultsListI = AnalysisResultLists.find(&IR);
42 if (ResultsListI == AnalysisResultLists.end())
43 return;
44 // Delete the map entries that point into the results list.
45 for (auto &IDAndResult : ResultsListI->second)
46 AnalysisResults.erase({IDAndResult.first, &IR});
47
48 // And actually destroy and erase the results associated with this IR.
49 AnalysisResultLists.erase(ResultsListI);
50}
51
52template <typename IRUnitT, typename... ExtraArgTs>
53inline typename AnalysisManager<IRUnitT, ExtraArgTs...>::ResultConceptT &
55 AnalysisKey *ID, IRUnitT &IR, ExtraArgTs... ExtraArgs) {
56 typename AnalysisResultMapT::iterator RI;
57 bool Inserted;
58 std::tie(RI, Inserted) = AnalysisResults.insert(std::make_pair(
59 std::make_pair(ID, &IR), typename AnalysisResultListT::iterator()));
60
61 // If we don't have a cached result for this function, look up the pass and
62 // run it to produce a result, which we then add to the cache.
63 if (Inserted) {
64 auto &P = this->lookUpPass(ID);
65
68 PI = getResult<PassInstrumentationAnalysis>(IR, ExtraArgs...);
70 }
71
72 AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
73 ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
74
76
77 // P.run may have inserted elements into AnalysisResults and invalidated
78 // RI.
79 RI = AnalysisResults.find({ID, &IR});
80 assert(RI != AnalysisResults.end() && "we just inserted it!");
81
82 RI->second = std::prev(ResultList.end());
83 }
84
85 return *RI->second->second;
86}
87
88template <typename IRUnitT, typename... ExtraArgTs>
90 IRUnitT &IR, const PreservedAnalyses &PA) {
91 // We're done if all analyses on this IR unit are preserved.
93 return;
94
95 // Track whether each analysis's result is invalidated in
96 // IsResultInvalidated.
97 SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
98 Invalidator Inv(IsResultInvalidated, AnalysisResults);
99 AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
100 for (auto &AnalysisResultPair : ResultsList) {
101 // This is basically the same thing as Invalidator::invalidate, but we
102 // can't call it here because we're operating on the type-erased result.
103 // Moreover if we instead called invalidate() directly, it would do an
104 // unnecessary look up in ResultsList.
105 AnalysisKey *ID = AnalysisResultPair.first;
106 auto &Result = *AnalysisResultPair.second;
107
108 auto IMapI = IsResultInvalidated.find(ID);
109 if (IMapI != IsResultInvalidated.end())
110 // This result was already handled via the Invalidator.
111 continue;
112
113 // Try to invalidate the result, giving it the Invalidator so it can
114 // recursively query for any dependencies it has and record the result.
115 // Note that we cannot reuse 'IMapI' here or pre-insert the ID, as
116 // Result.invalidate may insert things into the map, invalidating our
117 // iterator.
118 bool Inserted =
119 IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, Inv)}).second;
120 (void)Inserted;
121 assert(Inserted && "Should never have already inserted this ID, likely "
122 "indicates a cycle!");
123 }
124
125 // Now erase the results that were marked above as invalidated.
126 if (!IsResultInvalidated.empty()) {
127 for (auto I = ResultsList.begin(), E = ResultsList.end(); I != E;) {
128 AnalysisKey *ID = I->first;
129 if (!IsResultInvalidated.lookup(ID)) {
130 ++I;
131 continue;
132 }
133
134 if (auto *PI = getCachedResult<PassInstrumentationAnalysis>(IR))
135 PI->runAnalysisInvalidated(this->lookUpPass(ID), IR);
136
137 I = ResultsList.erase(I);
138 AnalysisResults.erase({ID, &IR});
139 }
140 }
141
142 if (ResultsList.empty())
143 AnalysisResultLists.erase(&IR);
144}
145} // end namespace llvm
146
147#endif // LLVM_IR_PASSMANAGERIMPL_H
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
std::string Name
Statically lint checks LLVM IR
Definition: Lint.cpp:746
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
This header defines various interfaces for pass management in LLVM.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This templated class represents "all analyses that operate over <a particular IR unit>" (e....
Definition: PassManager.h:90
API to communicate dependencies between analyses during invalidation.
Definition: PassManager.h:661
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:620
AnalysisManager()
Construct an empty analysis manager.
void clear()
Clear all analysis results cached by this AnalysisManager.
Definition: PassManager.h:765
AnalysisManager & operator=(AnalysisManager &&)
void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Invalidate cached analyses for an IR unit.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:197
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
bool empty() const
Definition: DenseMap.h:98
iterator end()
Definition: DenseMap.h:84
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
This class provides instrumentation entry points for the Pass Manager, doing calls to callbacks regis...
void runBeforeAnalysis(const PassT &Analysis, const IRUnitT &IR) const
BeforeAnalysis instrumentation point - takes Analysis instance to be executed and constant reference ...
void runAnalysisInvalidated(const PassT &Analysis, const IRUnitT &IR) const
AnalysisInvalidated instrumentation point - takes Analysis instance that has just been invalidated an...
void runAfterAnalysis(const PassT &Analysis, const IRUnitT &IR) const
AfterAnalysis instrumentation point - takes Analysis instance that has just been executed and constan...
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
bool allAnalysesInSetPreserved() const
Directly test whether a set of analyses is preserved.
Definition: PassManager.h:335
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
static AnalysisKey * ID()
Returns an opaque, unique ID for this analysis type.
Definition: PassManager.h:410
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: PassManager.h:69