38 #ifndef LLVM_IR_PASSMANAGER_H
39 #define LLVM_IR_PASSMANAGER_H
75 : PreservedPassIDs(Arg.PreservedPassIDs) {}
77 : PreservedPassIDs(std::move(Arg.PreservedPassIDs)) {}
80 swap(LHS.PreservedPassIDs, RHS.PreservedPassIDs);
93 PA.PreservedPassIDs.
insert((
void *)AllPassesID);
103 PreservedPassIDs.
insert(PassID);
114 PreservedPassIDs = Arg.PreservedPassIDs;
117 for (
void *
P : PreservedPassIDs)
118 if (!Arg.PreservedPassIDs.
count(
P))
119 PreservedPassIDs.
erase(
P);
127 if (Arg.areAllPreserved())
130 PreservedPassIDs = std::move(Arg.PreservedPassIDs);
133 for (
void *
P : PreservedPassIDs)
134 if (!Arg.PreservedPassIDs.count(
P))
135 PreservedPassIDs.erase(
P);
146 return PreservedPassIDs.
count((
void *)AllPassesID) ||
147 PreservedPassIDs.
count(PassID);
155 return PreservedPassIDs.
count((
void *)AllPassesID);
161 static const uintptr_t AllPassesID = (
intptr_t)(-3);
167 template <
typename IRUnitT>
class AnalysisManager;
185 PassManager(
bool DebugLogging =
false) : DebugLogging(DebugLogging) {}
189 : Passes(std::move(Arg.Passes)),
190 DebugLogging(std::move(Arg.DebugLogging)) {}
192 Passes = std::move(RHS.Passes);
193 DebugLogging = std::move(RHS.DebugLogging);
202 dbgs() <<
"Starting pass manager run.\n";
204 for (
unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
206 dbgs() <<
"Running pass: " << Passes[Idx]->name() <<
"\n";
216 PassPA = AM->invalidate(IR, std::move(PassPA));
230 dbgs() <<
"Finished pass manager run.\n";
237 Passes.emplace_back(
new PassModelT(std::move(Pass)));
248 std::vector<std::unique_ptr<PassConceptT>> Passes;
280 DerivedT *derived_this() {
return static_cast<DerivedT *
>(
this); }
281 const DerivedT *derived_this()
const {
282 return static_cast<const DerivedT *
>(
this);
300 : AnalysisPasses(std::move(Arg.AnalysisPasses)) {}
302 AnalysisPasses = std::move(RHS.AnalysisPasses);
311 template <
typename PassT>
typename PassT::Result &
getResult(IRUnitT &
IR) {
313 "This analysis pass was not registered prior to being queried");
316 derived_this()->getResultImpl(
PassT::ID(), IR);
319 return static_cast<ResultModelT &
>(ResultConcept).Result;
327 template <
typename PassT>
330 "This analysis pass was not registered prior to being queried");
333 derived_this()->getCachedResultImpl(
PassT::ID(), IR);
339 return &
static_cast<ResultModelT *
>(ResultConcept)->Result;
349 "Registered the same analysis pass twice!");
351 AnalysisPasses[
PassT::ID()].reset(
new PassModelT(std::move(Pass)));
359 "This analysis pass was not registered prior to being invalidated");
360 derived_this()->invalidateImpl(
PassT::ID(), IR);
371 return derived_this()->invalidateImpl(IR, std::move(PA));
378 assert(PI != AnalysisPasses.
end() &&
379 "Analysis passes must be registered prior to being queried!");
386 assert(PI != AnalysisPasses.
end() &&
387 "Analysis passes must be registered prior to being queried!");
396 AnalysisPassMapT AnalysisPasses;
407 template <
typename IRUnitT>
408 class AnalysisManager
409 :
public detail::AnalysisManagerBase<AnalysisManager<IRUnitT>, IRUnitT> {
427 :
BaseT(std::move(static_cast<
BaseT &>(Arg))),
428 AnalysisResults(std::move(Arg.AnalysisResults)),
429 DebugLogging(std::move(Arg.DebugLogging)) {}
431 BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
432 AnalysisResults = std::move(RHS.AnalysisResults);
433 DebugLogging = std::move(RHS.DebugLogging);
439 assert(AnalysisResults.
empty() == AnalysisResultLists.
empty() &&
440 "The storage and index of analysis results disagree on how many "
442 return AnalysisResults.
empty();
452 AnalysisResults.
clear();
453 AnalysisResultLists.
clear();
461 ResultConceptT &getResultImpl(
void *PassID, IRUnitT &
IR) {
464 std::tie(RI, Inserted) = AnalysisResults.
insert(std::make_pair(
465 std::make_pair(PassID, &IR),
typename AnalysisResultListT::iterator()));
472 dbgs() <<
"Running analysis: " <<
P.name() <<
"\n";
473 AnalysisResultListT &ResultList = AnalysisResultLists[&
IR];
474 ResultList.emplace_back(PassID,
P.run(IR,
this));
478 RI = AnalysisResults.
find(std::make_pair(PassID, &IR));
479 assert(RI != AnalysisResults.
end() &&
"we just inserted it!");
481 RI->second = std::prev(ResultList.end());
484 return *RI->second->second;
488 ResultConceptT *getCachedResultImpl(
void *PassID, IRUnitT &IR)
const {
490 AnalysisResults.
find(std::make_pair(PassID, &IR));
491 return RI == AnalysisResults.
end() ?
nullptr : &*RI->second->second;
495 void invalidateImpl(
void *PassID, IRUnitT &IR) {
497 AnalysisResults.
find(std::make_pair(PassID, &IR));
498 if (RI == AnalysisResults.
end())
504 AnalysisResultLists[&
IR].
erase(RI->second);
505 AnalysisResults.
erase(RI);
509 PreservedAnalyses invalidateImpl(IRUnitT &IR, PreservedAnalyses PA) {
511 if (PA.areAllPreserved())
515 dbgs() <<
"Invalidating all non-preserved analyses for: "
516 << IR.getName() <<
"\n";
520 SmallVector<void *, 8> InvalidatedPassIDs;
521 AnalysisResultListT &ResultsList = AnalysisResultLists[&
IR];
522 for (
typename AnalysisResultListT::iterator
I = ResultsList.begin(),
523 E = ResultsList.end();
525 void *PassID =
I->first;
530 if (
I->second->invalidate(IR, PA)) {
535 InvalidatedPassIDs.push_back(
I->first);
536 I = ResultsList.erase(
I);
546 while (!InvalidatedPassIDs.empty())
547 AnalysisResults.
erase(
548 std::make_pair(InvalidatedPassIDs.pop_back_val(), &
IR));
549 if (ResultsList.empty())
550 AnalysisResultLists.
erase(&IR);
560 typedef std::list<std::pair<
561 void *, std::unique_ptr<detail::AnalysisResultConcept<IRUnitT>>>>
565 typedef DenseMap<IRUnitT *, AnalysisResultListT> AnalysisResultListMapT;
571 AnalysisResultListMapT AnalysisResultLists;
575 typedef DenseMap<std::pair<void *, IRUnitT *>,
576 typename AnalysisResultListT::iterator> AnalysisResultMapT;
580 AnalysisResultMapT AnalysisResults;
604 static void *
ID() {
return (
void *)&PassID; }
616 : FAM(std::move(Arg.FAM)) {}
712 static void *
ID() {
return (
void *)&PassID; }
724 : MAM(std::move(Arg.MAM)) {}
767 : Pass(std::move(Pass)) {}
777 swap(LHS.Pass, RHS.Pass);
793 if (
F.isDeclaration())
827 template <
typename FunctionPassT>
828 ModuleToFunctionPassAdaptor<FunctionPassT>
844 template <
typename IRUnitT>
847 (void)AM->template getResult<AnalysisT>(Arg);
867 template <
typename IRUnitT>
872 (void)AM->template invalidate<AnalysisT>(Arg);
Pass interface - Implemented by all 'passes'.
Wrapper to model the analysis pass concept.
Result(const ModuleAnalysisManager &MAM)
FunctionAnalysisManagerModuleProxy & operator=(FunctionAnalysisManagerModuleProxy RHS)
PreservedAnalyses run(Module &M, ModuleAnalysisManager *AM)
Runs the function pass across every function in the module.
ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManagerFunctionProxy &Arg)
AnalysisManager(bool DebugLogging=false)
Construct an empty analysis manager.
A module analysis which acts as a proxy for a function analysis manager.
void intersect(const PreservedAnalyses &Arg)
Intersect this set with another in place.
Trivial adaptor that maps from a module to its functions.
PreservedAnalyses invalidate(IRUnitT &IR, PreservedAnalyses PA)
Invalidate analyses cached for an IR unit.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for this module.
A Module instance is used to store all the information related to an LLVM module. ...
AnalysisManager & operator=(AnalysisManager &&RHS)
ModuleAnalysisManagerFunctionProxy(const ModuleAnalysisManager &MAM)
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
Result & operator=(Result RHS)
AnalysisManager(AnalysisManager &&Arg)
Template for the abstract base class used to dispatch polymorphically over pass objects.
ModuleAnalysisManagerFunctionProxy(ModuleAnalysisManagerFunctionProxy &&Arg)
detail::AnalysisPassConcept< IRUnitT > PassConceptT
A template utility pass to force an analysis result to be available.
Result(FunctionAnalysisManager &FAM)
A function analysis which acts as a proxy for a module analysis manager.
Abstract concept of an analysis pass.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
ModuleAnalysisManagerFunctionProxy & operator=(ModuleAnalysisManagerFunctionProxy RHS)
The result proxy object for the FunctionAnalysisManagerModuleProxy.
const PassConceptT & lookupPass(void *PassID) const
Lookup a registered analysis pass.
Result & operator=(Result RHS)
detail::AnalysisResultConcept< IRUnitT > ResultConceptT
Result proxy object for ModuleAnalysisManagerFunctionProxy.
const ModuleAnalysisManager & getManager() const
PreservedAnalyses run(IRUnitT &IR, AnalysisManager< IRUnitT > *AM=nullptr)
Run all of the passes in this manager over the IR.
AnalysisManagerBase & operator=(AnalysisManagerBase &&RHS)
ModuleToFunctionPassAdaptor & operator=(ModuleToFunctionPassAdaptor RHS)
Result(const Result &Arg)
PreservedAnalyses run(IRUnitT &Arg)
Run this pass over some unit of IR.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
friend void swap(PreservedAnalyses &LHS, PreservedAnalyses &RHS)
bool empty() const
Returns true if the analysis manager has an empty results cache.
bool erase(const KeyT &Val)
An abstract set of preserved analyses following a transformation pass run.
ModuleToFunctionPassAdaptor< FunctionPassT > createModuleToFunctionPassAdaptor(FunctionPassT Pass)
A function to deduce a function pass type and wrap it in the templated adaptor.
friend void swap(ModuleToFunctionPassAdaptor &LHS, ModuleToFunctionPassAdaptor &RHS)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Wrapper to model the analysis result concept.
ModuleToFunctionPassAdaptor(const ModuleToFunctionPassAdaptor &Arg)
PreservedAnalyses(PreservedAnalyses &&Arg)
Result(const Result &Arg)
PreservedAnalyses run(IRUnitT &Arg, AnalysisManager< IRUnitT > *AM)
Run this pass over some unit of IR.
A CRTP base used to implement analysis managers.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void intersect(PreservedAnalyses &&Arg)
Intersect this set with a temporary other set in place.
bool areAllPreserved() const
Test whether all passes are preserved.
ModuleToFunctionPassAdaptor(ModuleToFunctionPassAdaptor &&Arg)
llvm::DenseMapBase< DenseMap< std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator, DenseMapInfo< std::pair< void *, IRUnitT * > >, detail::DenseMapPair< std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator > >, std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator, DenseMapInfo< std::pair< void *, IRUnitT * > >, detail::DenseMapPair< std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator > >::const_iterator DenseMapIterator< std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator, DenseMapInfo< std::pair< void *, IRUnitT * > >, detail::DenseMapPair< std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator >, true > const_iterator
FunctionAnalysisManagerModuleProxy(const FunctionAnalysisManagerModuleProxy &Arg)
ModuleToFunctionPassAdaptor(FunctionPassT Pass)
void registerPass(PassT Pass)
Register an analysis pass with the manager.
PassManager(bool DebugLogging=false)
Construct a pass manager.
void invalidate(IRUnitT &IR)
Invalidate a specific analysis pass for an IR module.
PreservedAnalyses(const PreservedAnalyses &Arg)
Result run(Module &M)
Run the analysis pass and create our proxy result object.
virtual StringRef name()=0
Polymorphic method to access the name of a pass.
void preserve(void *PassID)
Mark an abstract PassID as preserved, adding it to the set.
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
A template wrapper used to implement the polymorphic API.
Module.h This file contains the declarations for the Module class.
PassT::Result & getResult(IRUnitT &IR)
Get the result of an analysis pass for this module.
Abstract concept of an analysis result.
llvm::DenseMapBase< DenseMap< std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator, DenseMapInfo< std::pair< void *, IRUnitT * > >, detail::DenseMapPair< std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator > >, std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator, DenseMapInfo< std::pair< void *, IRUnitT * > >, detail::DenseMapPair< std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator > >::iterator DenseMapIterator< std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator, DenseMapInfo< std::pair< void *, IRUnitT * > >, detail::DenseMapPair< std::pair< void *, IRUnitT * >, typename AnalysisResultListT::iterator > > iterator
PassManager & operator=(PassManager &&RHS)
AnalysisManagerBase(AnalysisManagerBase &&Arg)
FunctionAnalysisManagerModuleProxy(FunctionAnalysisManager &FAM)
A utility pass that does nothing but preserves no analyses.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This header provides internal APIs and implementation details used by the pass management interfaces ...
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
bool invalidate(Function &)
Handle invalidation by ignoring it, this pass is immutable.
bool invalidate(Module &M, const PreservedAnalyses &PA)
Handler for invalidation of the module.
Manages a sequence of passes over units of IR.
void clear()
Clear the analysis result cache.
PassConceptT & lookupPass(void *PassID)
Lookup a registered analysis pass.
iterator find(const KeyT &Val)
FunctionAnalysisManagerModuleProxy(FunctionAnalysisManagerModuleProxy &&Arg)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
void preserve()
Mark a particular pass as preserved, adding it to the set.
A template utility pass to force an analysis result to be invalidated.
bool preserved(void *PassID) const
Query whether an abstract pass ID is marked as preserved by this set.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
PassManager(PassManager &&Arg)
bool preserved() const
Query whether a pass is marked as preserved by this set.
Result run(Function &)
Run the analysis pass and create our proxy result object.
PreservedAnalyses run(IRUnitT &Arg, AnalysisManager< IRUnitT > *AM)
Run this pass over some unit of IR.
StringRef - Represent a constant reference to a string, i.e.
A generic analysis pass manager with lazy running and caching of results.
FunctionAnalysisManager & getManager()
Accessor for the FunctionAnalysisManager.
PreservedAnalyses & operator=(PreservedAnalyses RHS)
Statically lint checks LLVM IR
PassManager< Module > ModulePassManager
Convenience typedef for a pass manager over modules.