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 &>()));
89 template <
typename AnalysisT>
90 std::enable_if_t<llvm::is_detected<has_is_invalidated, AnalysisT>::value,
bool>
92 return analysis.isInvalidated(pa);
95 template <
typename AnalysisT>
96 std::enable_if_t<!llvm::is_detected<has_is_invalidated, AnalysisT>::value,
bool>
116 template <
typename AnalysisT>
118 template <
typename... Args>
120 :
analysis(std::forward<Args>(args)...) {}
127 pa.unpreserve<AnalysisT>();
139 using ConceptMap = llvm::MapVector<TypeID, std::unique_ptr<AnalysisConcept>>;
142 template <
typename AnalysisT>
143 static StringRef getAnalysisName() {
144 StringRef name = llvm::getTypeName<AnalysisT>();
145 if (!name.consume_front(
"mlir::"))
146 name.consume_front(
"(anonymous namespace)::");
154 template <
typename AnalysisT>
156 return getAnalysisImpl<AnalysisT, Operation *>(pi, ir, am);
161 template <
typename AnalysisT,
typename OpT>
163 std::is_constructible<AnalysisT, OpT>::value ||
164 std::is_constructible<AnalysisT, OpT, AnalysisManager &>::value,
167 return getAnalysisImpl<AnalysisT, OpT>(pi, cast<OpT>(ir), am);
171 template <
typename AnalysisT>
173 auto res = analyses.find(TypeID::get<AnalysisT>());
174 if (res == analyses.end())
193 [&](
auto &val) {
return val.second->invalidate(paCopy); });
197 template <
typename AnalysisT,
typename OpT>
200 TypeID id = TypeID::get<AnalysisT>();
202 auto it = analyses.find(
id);
205 if (analyses.end() == it) {
210 std::tie(it, wasInserted) =
211 analyses.insert({id, constructAnalysis<AnalysisT>(am, op)});
217 return static_cast<AnalysisModel<AnalysisT> &
>(*it->second).analysis;
221 template <
typename AnalysisT,
typename OpT,
222 std::enable_if_t<std::is_constructible<
223 AnalysisT, OpT, AnalysisManager &>::value> * =
nullptr>
224 static auto constructAnalysis(AnalysisManager &am, OpT op) {
225 return std::make_unique<AnalysisModel<AnalysisT>>(op, am);
229 template <
typename AnalysisT,
typename OpT,
230 std::enable_if_t<!std::is_constructible<
231 AnalysisT, OpT, AnalysisManager &>::value> * =
nullptr>
232 static auto constructAnalysis(AnalysisManager &, OpT op) {
233 return std::make_unique<AnalysisModel<AnalysisT>>(op);
264 return parent->getPassInstrumentor();
304 template <
typename AnalysisT>
305 std::optional<std::reference_wrapper<AnalysisT>>
308 while (
auto *parentAM = curParent->
getParent()) {
309 if (parentAM->getOperation() == parentOp)
310 return parentAM->analyses.getCachedAnalysis<AnalysisT>();
311 curParent = parentAM;
317 template <
typename AnalysisT>
324 template <
typename AnalysisT,
typename OpT>
331 template <
typename AnalysisT>
333 return impl->analyses.getCachedAnalysis<AnalysisT>();
337 template <
typename AnalysisT>
339 return nest(op).template getAnalysis<AnalysisT>();
344 template <
typename AnalysisT,
typename OpT>
346 return nest(child).template getAnalysis<AnalysisT, OpT>();
350 template <
typename AnalysisT>
351 std::optional<std::reference_wrapper<AnalysisT>>
354 auto it =
impl->childAnalyses.find(op);
355 if (it ==
impl->childAnalyses.end())
357 return it->second->analyses.getCachedAnalysis<AnalysisT>();
369 impl->analyses.clear();
370 impl->childAnalyses.clear();
376 return impl->getPassInstrumentor();
383 AnalysisManager nestImmediate(Operation *op);
386 detail::NestedAnalysisMap *
impl;
399 : 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.
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.
decltype(std::declval< T & >().isInvalidated(std::declval< const PreservedAnalyses & >())) has_is_invalidated
Trait to check if T provides a static 'isInvalidated' method.
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.