9 #ifndef MLIR_PASS_ANALYSISMANAGER_H
10 #define MLIR_PASS_ANALYSISMANAGER_H
15 #include "llvm/ADT/DenseMap.h"
16 #include "llvm/ADT/MapVector.h"
17 #include "llvm/ADT/SmallPtrSet.h"
18 #include "llvm/Support/TypeName.h"
22 class AnalysisManager;
32 struct AllAnalysesType {};
36 void preserveAll() { preservedIDs.insert(TypeID::get<AllAnalysesType>()); }
40 return preservedIDs.count(TypeID::get<AllAnalysesType>());
44 bool isNone()
const {
return preservedIDs.empty(); }
47 template <
typename AnalysisT>
51 template <
typename AnalysisT,
typename AnalysisT2,
typename... OtherAnalysesT>
53 preserve<AnalysisT>();
54 preserve<AnalysisT2, OtherAnalysesT...>();
61 template <
typename AnalysisT>
69 template <
typename AnalysisT>
71 preservedIDs.erase(TypeID::get<AnalysisT>());
82 namespace analysis_impl {
84 template <
typename T,
typename... Args>
86 std::declval<const PreservedAnalyses &>()));
88 template <
typename AnalysisT>
90 if constexpr (llvm::is_detected<has_is_invalidated, AnalysisT>::value)
92 return analysis.isInvalidated(pa);
113 template <
typename AnalysisT>
115 template <
typename... Args>
117 :
analysis(std::forward<Args>(args)...) {}
124 pa.unpreserve<AnalysisT>();
136 using ConceptMap = llvm::MapVector<TypeID, std::unique_ptr<AnalysisConcept>>;
139 template <
typename AnalysisT>
140 static StringRef getAnalysisName() {
141 StringRef name = llvm::getTypeName<AnalysisT>();
142 if (!name.consume_front(
"mlir::"))
143 name.consume_front(
"(anonymous namespace)::");
151 template <
typename AnalysisT>
153 return getAnalysisImpl<AnalysisT, Operation *>(pi, ir, am);
158 template <
typename AnalysisT,
typename OpT>
160 std::is_constructible<AnalysisT, OpT>::value ||
161 std::is_constructible<AnalysisT, OpT, AnalysisManager &>::value,
164 return getAnalysisImpl<AnalysisT, OpT>(pi, cast<OpT>(ir), am);
168 template <
typename AnalysisT>
170 auto res = analyses.find(TypeID::get<AnalysisT>());
171 if (res == analyses.end())
190 [&](
auto &val) {
return val.second->invalidate(paCopy); });
194 template <
typename AnalysisT,
typename OpT>
197 TypeID id = TypeID::get<AnalysisT>();
199 auto it = analyses.find(
id);
202 if (analyses.end() == it) {
207 std::tie(it, wasInserted) =
208 analyses.insert({id, constructAnalysis<AnalysisT>(am, op)});
214 return static_cast<AnalysisModel<AnalysisT> &
>(*it->second).analysis;
218 template <
typename AnalysisT,
typename OpT,
219 std::enable_if_t<std::is_constructible<
220 AnalysisT, OpT, AnalysisManager &>::value> * =
nullptr>
221 static auto constructAnalysis(AnalysisManager &am, OpT op) {
222 return std::make_unique<AnalysisModel<AnalysisT>>(op, am);
226 template <
typename AnalysisT,
typename OpT,
227 std::enable_if_t<!std::is_constructible<
228 AnalysisT, OpT, AnalysisManager &>::value> * =
nullptr>
229 static auto constructAnalysis(AnalysisManager &, OpT op) {
230 return std::make_unique<AnalysisModel<AnalysisT>>(op);
261 return parent->getPassInstrumentor();
301 template <
typename AnalysisT>
302 std::optional<std::reference_wrapper<AnalysisT>>
305 while (
auto *parentAM = curParent->
getParent()) {
306 if (parentAM->getOperation() == parentOp)
307 return parentAM->analyses.getCachedAnalysis<AnalysisT>();
308 curParent = parentAM;
314 template <
typename AnalysisT>
321 template <
typename AnalysisT,
typename OpT>
328 template <
typename AnalysisT>
330 return impl->analyses.getCachedAnalysis<AnalysisT>();
334 template <
typename AnalysisT>
336 return nest(op).template getAnalysis<AnalysisT>();
341 template <
typename AnalysisT,
typename OpT>
343 return nest(child).template getAnalysis<AnalysisT, OpT>();
347 template <
typename AnalysisT>
348 std::optional<std::reference_wrapper<AnalysisT>>
351 auto it =
impl->childAnalyses.find(op);
352 if (it ==
impl->childAnalyses.end())
354 return it->second->analyses.getCachedAnalysis<AnalysisT>();
366 impl->analyses.clear();
367 impl->childAnalyses.clear();
373 return impl->getPassInstrumentor();
380 AnalysisManager nestImmediate(Operation *op);
383 detail::NestedAnalysisMap *
impl;
396 : analyses(op, passInstrumentor) {}
This class represents an analysis manager for a particular operation instance.
AnalysisT & getChildAnalysis(OpT child)
Query for an analysis of a child operation of a specific derived operation type, constructing it if n...
std::optional< std::reference_wrapper< AnalysisT > > getCachedChildAnalysis(Operation *op) const
Query for a cached analysis of a child operation, or return null.
void clear()
Clear any held analyses.
void invalidate(const PreservedAnalyses &pa)
Invalidate any non preserved analyses,.
AnalysisManager nest(Operation *op)
Get an analysis manager for the given operation, which must be a proper descendant of the current ope...
std::optional< std::reference_wrapper< AnalysisT > > getCachedAnalysis() const
Query for a cached entry of the given analysis on the current operation.
AnalysisT & getAnalysis()
Query for the given analysis for the current operation of a specific derived operation type.
AnalysisT & getAnalysis()
Query for the given analysis for the current operation.
std::optional< std::reference_wrapper< AnalysisT > > getCachedParentAnalysis(Operation *parentOp) const
Query for a cached analysis on the given parent operation.
AnalysisT & getChildAnalysis(Operation *op)
Query for an analysis of a child operation, constructing it if necessary.
PassInstrumentor * getPassInstrumentor() const
Returns a pass instrumentation object for the current operation.
An analysis manager class specifically for the top-level operation.
ModuleAnalysisManager & operator=(const ModuleAnalysisManager &)=delete
ModuleAnalysisManager(Operation *op, PassInstrumentor *passInstrumentor)
ModuleAnalysisManager(const ModuleAnalysisManager &)=delete
Operation is the basic unit of execution within MLIR.
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
This class holds a collection of PassInstrumentation objects, and invokes their respective call backs...
void runBeforeAnalysis(StringRef name, TypeID id, Operation *op)
See PassInstrumentation::runBeforeAnalysis for details.
void runAfterAnalysis(StringRef name, TypeID id, Operation *op)
See PassInstrumentation::runAfterAnalysis for details.
This class provides an efficient unique identifier for a specific C++ type.
This class represents a cache of analyses for a single operation.
std::optional< std::reference_wrapper< AnalysisT > > getCachedAnalysis() const
Get a cached analysis instance if one exists, otherwise return null.
AnalysisMap(Operation *ir)
AnalysisT & getAnalysis(PassInstrumentor *pi, AnalysisManager &am)
Get an analysis for the current IR unit, computing it if necessary.
void clear()
Clear any held analyses.
std::enable_if_t< std::is_constructible< AnalysisT, OpT >::value||std::is_constructible< AnalysisT, OpT, AnalysisManager & >::value, AnalysisT & > getAnalysis(PassInstrumentor *pi, AnalysisManager &am)
Get an analysis for the current IR unit assuming it's of specific derived operation type.
void invalidate(const PreservedAnalyses &pa)
Invalidate any cached analyses based upon the given set of preserved analyses.
Operation * getOperation() const
Returns the operation that this analysis map represents.
A utility class to represent the analyses that are known to be preserved.
bool isPreserved(TypeID id) const
void preserveAll()
Mark all analyses as preserved.
bool isAll() const
Returns true if all analyses were marked preserved.
bool isPreserved() const
Returns true if the given analysis has been marked as preserved.
void preserve()
Preserve the given analyses.
bool isNone() const
Returns true if no analyses were marked preserved.
decltype(std::declval< T & >().isInvalidated(std::declval< const PreservedAnalyses & >())) has_is_invalidated
Trait to check if T provides a static 'isInvalidated' method.
bool isInvalidated(AnalysisT &analysis, const PreservedAnalyses &pa)
Include the generated interface declarations.
The abstract polymorphic base class representing an analysis.
virtual ~AnalysisConcept()=default
virtual bool invalidate(PreservedAnalyses &pa)=0
A hook used to query analyses for invalidation.
A derived analysis model used to hold a specific analysis object.
AnalysisModel(Args &&...args)
AnalysisT analysis
The actual analysis object.
bool invalidate(PreservedAnalyses &pa) final
A hook used to query analyses for invalidation.
An analysis map that contains a map for the current operation, and a set of maps for any child operat...
detail::AnalysisMap analyses
The analyses for the owning operation.
DenseMap< Operation *, std::unique_ptr< NestedAnalysisMap > > childAnalyses
The cached analyses for nested operations.
NestedAnalysisMap(Operation *op, NestedAnalysisMap *parent)
PassInstrumentor * getPassInstrumentor() const
Returns a pass instrumentation object for the current operation.
NestedAnalysisMap(Operation *op, PassInstrumentor *instrumentor)
PointerUnion< NestedAnalysisMap *, PassInstrumentor * > parentOrInstrumentor
This value has three possible states: NestedAnalysisMap*: A pointer to the parent analysis map.
void invalidate(const PreservedAnalyses &pa)
Invalidate any non preserved analyses.
Operation * getOperation() const
Get the operation for this analysis map.
const NestedAnalysisMap * getParent() const
Returns the parent analysis map for this analysis map, or null if this is the top-level map.