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" 21 class AnalysisManager;
31 struct AllAnalysesType {};
35 void preserveAll() { preservedIDs.insert(TypeID::get<AllAnalysesType>()); }
39 return preservedIDs.count(TypeID::get<AllAnalysesType>());
43 bool isNone()
const {
return preservedIDs.empty(); }
46 template <
typename AnalysisT>
50 template <
typename AnalysisT,
typename AnalysisT2,
typename... OtherAnalysesT>
52 preserve<AnalysisT>();
53 preserve<AnalysisT2, OtherAnalysesT...>();
60 template <
typename AnalysisT>
68 template <
typename AnalysisT>
70 preservedIDs.erase(TypeID::get<AnalysisT>());
81 namespace analysis_impl {
83 template <
typename T,
typename... Args>
85 std::declval<const PreservedAnalyses &>()));
88 template <
typename AnalysisT>
91 return analysis.isInvalidated(pa);
94 template <
typename AnalysisT>
115 template <
typename AnalysisT>
117 template <
typename... Args>
119 : analysis(std::forward<Args>(args)...) {}
126 pa.unpreserve<AnalysisT>();
138 using ConceptMap = llvm::MapVector<TypeID, std::unique_ptr<AnalysisConcept>>;
141 template <
typename AnalysisT>
142 static StringRef getAnalysisName() {
143 StringRef name = llvm::getTypeName<AnalysisT>();
144 if (!name.consume_front(
"mlir::"))
145 name.consume_front(
"(anonymous namespace)::");
153 template <
typename AnalysisT>
155 return getAnalysisImpl<AnalysisT, Operation *>(pi, ir, am);
160 template <
typename AnalysisT,
typename OpT>
166 return getAnalysisImpl<AnalysisT, OpT>(pi, cast<OpT>(ir), am);
170 template <
typename AnalysisT>
172 auto res = analyses.find(TypeID::get<AnalysisT>());
173 if (res == analyses.end())
192 [&](
auto &val) {
return val.second->invalidate(paCopy); });
196 template <
typename AnalysisT,
typename OpT>
199 TypeID id = TypeID::get<AnalysisT>();
201 auto it = analyses.find(
id);
204 if (analyses.end() == it) {
209 std::tie(it, wasInserted) =
210 analyses.insert({id, constructAnalysis<AnalysisT>(am, op)});
220 template <
typename AnalysisT,
typename OpT,
221 std::enable_if_t<std::is_constructible<
224 return std::make_unique<AnalysisModel<AnalysisT>>(op, am);
228 template <
typename AnalysisT,
typename OpT,
229 std::enable_if_t<!std::is_constructible<
232 return std::make_unique<AnalysisModel<AnalysisT>>(op);
243 : analyses(op), parentOrInstrumentor(instrumentor) {}
245 : analyses(op), parentOrInstrumentor(parent) {}
262 if (
auto *parent = getParent())
263 return parent->getPassInstrumentor();
303 template <
typename AnalysisT>
307 while (
auto *parentAM = curParent->
getParent()) {
308 if (parentAM->getOperation() == parentOp)
309 return parentAM->analyses.getCachedAnalysis<AnalysisT>();
310 curParent = parentAM;
316 template <
typename AnalysisT>
318 return impl->analyses.getAnalysis<AnalysisT>(getPassInstrumentor(), *
this);
323 template <
typename AnalysisT,
typename OpT>
325 return impl->analyses.getAnalysis<AnalysisT, OpT>(getPassInstrumentor(),
330 template <
typename AnalysisT>
332 return impl->analyses.getCachedAnalysis<AnalysisT>();
336 template <
typename AnalysisT>
338 return nest(op).template getAnalysis<AnalysisT>();
343 template <
typename AnalysisT,
typename OpT>
345 return nest(child).template getAnalysis<AnalysisT, OpT>();
349 template <
typename AnalysisT>
353 auto it =
impl->childAnalyses.find(op);
354 if (it ==
impl->childAnalyses.end())
356 return it->second->analyses.getCachedAnalysis<AnalysisT>();
368 impl->analyses.clear();
369 impl->childAnalyses.clear();
375 return impl->getPassInstrumentor();
398 : analyses(op, passInstrumentor) {}
412 #endif // MLIR_PASS_ANALYSISMANAGER_H Include the generated interface declarations.
AnalysisT & getAnalysis()
Query for the given analysis for the current operation.
Operation is a basic unit of execution within MLIR.
bool isAll() const
Returns true if all analyses were marked preserved.
void runAfterAnalysis(StringRef name, TypeID id, Operation *op)
See PassInstrumentation::runAfterAnalysis for details.
AnalysisModel(Args &&...args)
PassInstrumentor * getPassInstrumentor() const
Returns a pass instrumentation object for the current operation.
This class represents an analysis manager for a particular operation instance.
PointerUnion< NestedAnalysisMap *, PassInstrumentor * > parentOrInstrumentor
This value has three possible states: NestedAnalysisMap*: A pointer to the parent analysis map...
void preserveAll()
Mark all analyses as preserved.
AnalysisMap(Operation *ir)
static constexpr const bool value
This class provides an efficient unique identifier for a specific C++ type.
void invalidate(const PreservedAnalyses &pa)
Invalidate any cached analyses based upon the given set of preserved analyses.
bool invalidate(PreservedAnalyses &pa) final
A hook used to query analyses for invalidation.
PassInstrumentor * getPassInstrumentor() const
Returns a pass instrumentation object for the current operation.
An analysis manager class specifically for the top-level operation.
AnalysisT analysis
The actual analysis object.
The abstract polymorphic base class representing an analysis.
const NestedAnalysisMap * getParent() const
Returns the parent analysis map for this analysis map, or null if this is the top-level map...
decltype(std::declval< T & >().isInvalidated(std::declval< const PreservedAnalyses & >())) has_is_invalidated
Trait to check if T provides a static 'isInvalidated' method.
ModuleAnalysisManager(Operation *op, PassInstrumentor *passInstrumentor)
Operation * getOperation() const
Get the operation for this analysis map.
This class represents a cache of analyses for a single operation.
detail::AnalysisMap analyses
The analyses for the owning operation.
NestedAnalysisMap(Operation *op, PassInstrumentor *instrumentor)
Operation * getParentOp()
Returns the closest surrounding operation that contains this operation or nullptr if this is a top-le...
Operation * getOperation() const
Returns the operation that this analysis map represents.
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...
std::enable_if_t<!llvm::is_detected< has_is_invalidated, AnalysisT >::value, bool > isInvalidated(AnalysisT &analysis, const PreservedAnalyses &pa)
Default implementation of 'isInvalidated'.
A utility class to represent the analyses that are known to be preserved.
void runBeforeAnalysis(StringRef name, TypeID id, Operation *op)
See PassInstrumentation::runBeforeAnalysis for details.
bool isPreserved() const
Returns true if the given analysis has been marked as preserved.
Optional< std::reference_wrapper< AnalysisT > > getCachedChildAnalysis(Operation *op) const
Query for a cached analysis of a child operation, or return null.
void invalidate(const PreservedAnalyses &pa)
Invalidate any non preserved analyses,.
NestedAnalysisMap(Operation *op, NestedAnalysisMap *parent)
This class holds a collection of PassInstrumentation objects, and invokes their respective call backs...
std::enable_if_t< llvm::is_detected< has_is_invalidated, AnalysisT >::value, bool > isInvalidated(AnalysisT &analysis, const PreservedAnalyses &pa)
Implementation of 'isInvalidated' if the analysis provides a definition.
AnalysisT & getAnalysis(PassInstrumentor *pi, AnalysisManager &am)
Get an analysis for the current IR unit, computing it if necessary.
AnalysisT & getChildAnalysis(OpT child)
Query for an analysis of a child operation of a specific derived operation type, constructing it if n...
DenseMap< Operation *, std::unique_ptr< NestedAnalysisMap > > childAnalyses
The cached analyses for nested operations.
An analysis map that contains a map for the current operation, and a set of maps for any child operat...
void clear()
Clear any held analyses.
AnalysisT & getChildAnalysis(Operation *op)
Query for an analysis of a child operation, constructing it if necessary.
AnalysisT & getAnalysis()
Query for the given analysis for the current operation of a specific derived operation type...
bool isPreserved(TypeID id) const
Optional< std::reference_wrapper< AnalysisT > > getCachedAnalysis() const
Query for a cached entry of the given analysis on the current operation.
Optional< std::reference_wrapper< AnalysisT > > getCachedAnalysis() const
Get a cached analysis instance if one exists, otherwise return null.
Optional< std::reference_wrapper< AnalysisT > > getCachedParentAnalysis(Operation *parentOp) const
Query for a cached analysis on the given parent operation.
void clear()
Clear any held analyses.
A derived analysis model used to hold a specific analysis object.
bool isNone() const
Returns true if no analyses were marked preserved.
void preserve()
Preserve the given analyses.