37#ifndef LLVM_IR_PASSMANAGER_H
38#define LLVM_IR_PASSMANAGER_H
64template <
typename IRUnitT,
typename... ExtraArgTs>
class AnalysisManager;
73 static_assert(std::is_base_of<PassInfoMixin, DerivedT>::value,
74 "Must pass the derived type as the template argument!");
76 Name.consume_front(
"llvm::");
83 auto PassName = MapClassName2PassName(ClassName);
92template <
typename DerivedT>
110 static_assert(std::is_base_of<AnalysisInfoMixin, DerivedT>::value,
111 "Must pass the derived type as the template argument!");
112 return &DerivedT::Key;
120template <
typename PassT,
typename IRUnitT,
typename AnalysisManagerT,
121 typename... ArgTs,
size_t... Ns>
122typename PassT::Result
124 std::tuple<ArgTs...> Args,
125 std::index_sequence<Ns...>) {
127 return AM.template getResult<PassT>(
IR, std::get<Ns>(Args)...);
135template <
typename PassT,
typename IRUnitT,
typename... AnalysisArgTs,
136 typename... MainArgTs>
137typename PassT::Result
139 std::tuple<MainArgTs...> Args) {
141 PassT, IRUnitT>)(AM,
IR, Args,
142 std::index_sequence_for<AnalysisArgTs...>{});
159template <
typename IRUnitT,
160 typename AnalysisManagerT = AnalysisManager<IRUnitT>,
161 typename... ExtraArgTs>
163 PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...>> {
183 P->printPipeline(
OS, MapClassName2PassName);
192 ExtraArgTs... ExtraArgs);
194 template <
typename PassT>
201 Passes.push_back(std::unique_ptr<PassConceptT>(
202 new PassModelT(std::forward<PassT>(
Pass))));
210 template <
typename PassT>
213 for (
auto &
P :
Pass.Passes)
214 Passes.push_back(std::move(
P));
226 std::vector<std::unique_ptr<PassConceptT>>
Passes;
229template <
typename IRUnitT>
271 using AnalysisResultListT =
272 std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>;
282 typename AnalysisResultListT::iterator>;
311 template <
typename PassT>
317 return invalidateImpl<ResultModelT>(PassT::ID(),
IR, PA);
327 return invalidateImpl<>(
ID,
IR, PA);
333 template <
typename ResultT = ResultConceptT>
338 auto IMapI = IsResultInvalidated.find(
ID);
339 if (IMapI != IsResultInvalidated.end())
340 return IMapI->second;
345 "Trying to invalidate a dependent result that isn't in the "
346 "manager's cache is always an error, likely due to a stale result "
349 auto &Result =
static_cast<ResultT &
>(*RI->second->second);
356 std::tie(IMapI, Inserted) =
357 IsResultInvalidated.insert({
ID, Result.invalidate(
IR, PA, *
this)});
359 assert(Inserted &&
"Should not have already inserted this ID, likely "
360 "indicates a dependency cycle!");
361 return IMapI->second;
364 Invalidator(SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated,
365 const AnalysisResultMapT &
Results)
368 SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated;
369 const AnalysisResultMapT &
Results;
380 "The storage and index of analysis results disagree on how many "
382 return AnalysisResults.
empty();
399 AnalysisResults.
clear();
400 AnalysisResultLists.
clear();
405 return AnalysisPasses.
count(PassT::ID());
411 template <
typename PassT>
412 typename PassT::Result &
getResult(IRUnitT &
IR, ExtraArgTs... ExtraArgs) {
414 "This analysis pass was not registered prior to being queried");
416 getResultImpl(PassT::ID(),
IR, ExtraArgs...);
422 return static_cast<ResultModelT &
>(ResultConcept).Result;
430 template <
typename PassT>
433 "This analysis pass was not registered prior to being queried");
443 return &
static_cast<ResultModelT *
>(ResultConcept)->Result;
447 template <
typename PassT>
451 Invalidator Inv(IsResultInvalidated, AnalysisResults);
452 assert(!Result->invalidate(
IR, PA, Inv) &&
453 "Cached result cannot be invalidated");
472 template <
typename PassBuilderT>
478 auto &PassPtr = AnalysisPasses[PassT::ID()];
500 AnalysisResultListT &ResultsList = AnalysisResultLists[&
IR];
505 assert(
I != ResultsList.end() &&
"Analysis must be available");
506 ResultsList.erase(
I);
515 "Analysis passes must be registered prior to being queried!");
520 const PassConceptT &lookUpPass(AnalysisKey *
ID)
const {
523 "Analysis passes must be registered prior to being queried!");
528 ResultConceptT &getResultImpl(AnalysisKey *
ID, IRUnitT &
IR,
529 ExtraArgTs... ExtraArgs);
532 ResultConceptT *getCachedResultImpl(AnalysisKey *
ID, IRUnitT &
IR)
const {
535 return RI == AnalysisResults.
end() ? nullptr : &*RI->second->second;
539 using AnalysisPassMapT =
540 DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>>;
543 AnalysisPassMapT AnalysisPasses;
549 AnalysisResultListMapT AnalysisResultLists;
553 AnalysisResultMapT AnalysisResults;
582template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
585 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> {
589 explicit Result(AnalysisManagerT &InnerAM) : InnerAM(&InnerAM) {}
595 Arg.InnerAM =
nullptr;
609 InnerAM =
RHS.InnerAM;
613 RHS.InnerAM =
nullptr;
635 AnalysisManagerT *InnerAM;
639 : InnerAM(&InnerAM) {}
657 AnalysisManagerT *InnerAM;
666template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
668 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
677LLVM_ABI bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
713template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
716 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>> {
721 explicit Result(
const AnalysisManagerT &OuterAM) : OuterAM(&OuterAM) {}
725 template <
typename PassT,
typename IRUnitTParam>
727 typename PassT::Result *Res =
728 OuterAM->template getCachedResult<PassT>(
IR);
730 OuterAM->template verifyNotInvalidated<PassT>(
IR, Res);
735 template <
typename PassT,
typename IRUnitTParam>
737 typename PassT::Result *Res =
738 OuterAM->template getCachedResult<PassT>(
IR);
739 return Res !=
nullptr;
749 for (
auto &KeyValuePair : OuterAnalysisInvalidationMap) {
751 auto &InnerIDs = KeyValuePair.second;
755 if (InnerIDs.empty())
759 for (
auto *OuterID : DeadKeys)
760 OuterAnalysisInvalidationMap.erase(OuterID);
768 template <
typename OuterAnalysisT,
typename Inval
idatedAnalysisT>
771 AnalysisKey *InvalidatedID = InvalidatedAnalysisT::ID();
773 auto &InvalidatedIDList = OuterAnalysisInvalidationMap[OuterID];
779 InvalidatedIDList.push_back(InvalidatedID);
786 return OuterAnalysisInvalidationMap;
790 const AnalysisManagerT *OuterAM;
795 OuterAnalysisInvalidationMap;
799 : OuterAM(&OuterAM) {}
815 const AnalysisManagerT *OuterAM;
818template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
820 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
857 bool EagerlyInvalidate)
869 std::unique_ptr<PassConceptT>
Pass;
870 bool EagerlyInvalidate;
875template <
typename FunctionPassT>
876ModuleToFunctionPassAdaptor
878 bool EagerlyInvalidate =
false) {
884 std::unique_ptr<ModuleToFunctionPassAdaptor::PassConceptT>(
885 new PassModelT(std::forward<FunctionPassT>(
Pass))),
898template <
typename AnalysisT,
typename IRUnitT,
899 typename AnalysisManagerT = AnalysisManager<IRUnitT>,
900 typename... ExtraArgTs>
902 :
PassInfoMixin<RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
911 ExtraArgTs &&... Args) {
912 (void)AM.template getResult<AnalysisT>(Arg,
913 std::forward<ExtraArgTs>(Args)...);
919 auto ClassName = AnalysisT::name();
920 auto PassName = MapClassName2PassName(ClassName);
928template <
typename AnalysisT>
937 template <
typename IRUnitT,
typename AnalysisManagerT,
typename... ExtraArgTs>
945 auto ClassName = AnalysisT::name();
946 auto PassName = MapClassName2PassName(ClassName);
957 template <
typename IRUnitT,
typename AnalysisManagerT,
typename... ExtraArgTs>
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_TEMPLATE_ABI
#define LLVM_ATTRIBUTE_MINSIZE
#define LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
Legalize the Machine IR a function s Machine IR
Machine Check Debug Module
This header provides internal APIs and implementation details used by the pass management interfaces ...
static const char PassName[]
API to communicate dependencies between analyses during invalidation.
bool invalidate(AnalysisKey *ID, IRUnitT &IR, const PreservedAnalyses &PA)
A type-erased variant of the above invalidate method with the same core API other than passing an ana...
bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Trigger the invalidation of some other analysis pass if not already handled and return whether it was...
A container for analyses that lazily runs them and caches their results.
bool isPassRegistered() const
Returns true if the specified analysis pass is registered.
AnalysisManager()
Construct an empty analysis manager.
void clear()
Clear all analysis results cached by this AnalysisManager.
AnalysisManager(AnalysisManager &&)
void verifyNotInvalidated(IRUnitT &IR, typename PassT::Result *Result) const
Verify that the given Result cannot be invalidated, assert otherwise.
AnalysisManager & operator=(AnalysisManager &&)
void invalidate(IRUnitT &IR, const PreservedAnalyses &PA)
Invalidate cached analyses for an IR unit.
void clearAnalysis(IRUnitT &IR)
Directly clear a cached analysis for an IR unit.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
bool empty() const
Returns true if the analysis manager has an empty results cache.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA, typename AnalysisManager< IRUnitT, ExtraArgTs... >::Invalidator &Inv)
Handler for invalidation of the outer IR unit, IRUnitT.
Result(AnalysisManagerT &InnerAM)
Result & operator=(Result &&RHS)
AnalysisManagerT & getManager()
Accessor for the analysis manager.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Result run(IRUnitT &IR, AnalysisManager< IRUnitT, ExtraArgTs... > &AM, ExtraArgTs...)
Run the analysis pass and create our proxy result object.
InnerAnalysisManagerProxy(AnalysisManagerT &InnerAM)
Trivial adaptor that maps from a module to its functions.
ModuleToFunctionPassAdaptor(std::unique_ptr< PassConceptT > Pass, bool EagerlyInvalidate)
A Module instance is used to store all the information related to an LLVM module.
Result proxy object for OuterAnalysisManagerProxy.
Result(const AnalysisManagerT &OuterAM)
PassT::Result * getCachedResult(IRUnitTParam &IR) const
Get a cached analysis.
bool invalidate(IRUnitT &IRUnit, const PreservedAnalyses &PA, typename AnalysisManager< IRUnitT, ExtraArgTs... >::Invalidator &Inv)
When invalidation occurs, remove any registered invalidation events.
bool cachedResultExists(IRUnitTParam &IR) const
Method provided for unit testing, not intended for general use.
const SmallDenseMap< AnalysisKey *, TinyPtrVector< AnalysisKey * >, 2 > & getOuterInvalidations() const
Access the map from outer analyses to deferred invalidation requiring analyses.
void registerOuterAnalysisInvalidation()
Register a deferred invalidation event for when the outer analysis manager processes its invalidation...
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
Result run(IRUnitT &, AnalysisManager< IRUnitT, ExtraArgTs... > &, ExtraArgTs...)
Run the analysis pass and create our proxy result object.
OuterAnalysisManagerProxy(const AnalysisManagerT &OuterAM)
This class provides access to building LLVM's passes.
Manages a sequence of passes over a particular unit of IR.
PassManager(PassManager &&Arg)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PassManager & operator=(PassManager &&RHS)
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
std::vector< std::unique_ptr< PassConceptT > > Passes
PassManager()=default
Construct a pass manager.
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t< std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
When adding a pass manager pass that has the same type as this pass manager, simply move the passes o...
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, ExtraArgTs... ExtraArgs)
Run all of the passes in this manager over the given unit of IR.
bool isEmpty() const
Returns if the pass manager contains any passes.
Pass interface - Implemented by all 'passes'.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Pass manager infrastructure for declaring and invalidating analyses.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
PassT::Result getAnalysisResultUnpackTuple(AnalysisManagerT &AM, IRUnitT &IR, std::tuple< ArgTs... > Args, std::index_sequence< Ns... >)
Actual unpacker of extra arguments in getAnalysisResult, passes only those tuple arguments that are m...
PassT::Result getAnalysisResult(AnalysisManager< IRUnitT, AnalysisArgTs... > &AM, IRUnitT &IR, std::tuple< MainArgTs... > Args)
Helper for partial unpacking of extra arguments in getAnalysisResult.
This is an optimization pass for GlobalISel generic memory operations.
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
template class LLVM_TEMPLATE_ABI OuterAnalysisManagerProxy< ModuleAnalysisManager, Function >
template class LLVM_TEMPLATE_ABI AnalysisManager< Module >
LLVM_ABI void printIRUnitNameForStackTrace< Function >(raw_ostream &OS, const Function &IR)
void printIRUnitNameForStackTrace(raw_ostream &OS, const IRUnitT &IR)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void printIRUnitNameForStackTrace< Module >(raw_ostream &OS, const Module &IR)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
template class LLVM_TEMPLATE_ABI AnalysisManager< Function >
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Implement std::hash so that hash_code can be used in STL containers.
A CRTP mix-in that provides informational APIs needed for analysis passes.
static AnalysisKey * ID()
Returns an opaque, unique ID for this analysis type.
A special type used by analysis passes to provide an address that identifies that particular analysis...
A utility pass that does nothing, but preserves no analyses.
PreservedAnalyses run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...)
Run this pass over some unit of IR.
A no-op pass template which simply forces a specific analysis result to be invalidated.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, ExtraArgTs &&...)
Run this pass over some unit of IR.
A CRTP mix-in to automatically provide informational APIs needed for passes.
static StringRef name()
Gets the name of the pass we are mixed into.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
A utility pass template to force an analysis result to be available.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(IRUnitT &Arg, AnalysisManagerT &AM, ExtraArgTs &&... Args)
Run this pass over some unit of IR.
Abstract concept of an analysis pass.
Wrapper to model the analysis pass concept.
Abstract concept of an analysis result.
Wrapper to model the analysis result concept.
A template wrapper used to implement the polymorphic API.