37#ifndef LLVM_IR_PASSMANAGER_H
38#define LLVM_IR_PASSMANAGER_H
68template <
typename IRUnitT,
typename... ExtraArgTs>
class AnalysisManager;
77 static_assert(std::is_base_of<PassInfoMixin, DerivedT>::value,
78 "Must pass the derived type as the template argument!");
80 Name.consume_front(
"llvm::");
87 auto PassName = MapClassName2PassName(ClassName);
96template <
typename DerivedT>
114 static_assert(std::is_base_of<AnalysisInfoMixin, DerivedT>::value,
115 "Must pass the derived type as the template argument!");
116 return &DerivedT::Key;
124template <
typename PassT,
typename IRUnitT,
typename AnalysisManagerT,
125 typename... ArgTs,
size_t... Ns>
126typename PassT::Result
128 std::tuple<ArgTs...> Args,
129 std::index_sequence<Ns...>) {
131 return AM.template getResult<PassT>(
IR, std::get<Ns>(Args)...);
139template <
typename PassT,
typename IRUnitT,
typename... AnalysisArgTs,
140 typename... MainArgTs>
141typename PassT::Result
143 std::tuple<MainArgTs...> Args) {
146 std::index_sequence_for<AnalysisArgTs...>{});
155class PassInstrumentationAnalysis;
169template <
typename IRUnitT,
170 typename AnalysisManagerT = AnalysisManager<IRUnitT>,
171 typename... ExtraArgTs>
173 PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...>> {
193 P->printPipeline(
OS, MapClassName2PassName);
202 ExtraArgTs... ExtraArgs) {
210 detail::getAnalysisResult<PassInstrumentationAnalysis>(
211 AM,
IR, std::tuple<ExtraArgTs...>(ExtraArgs...));
228 AM.invalidate(
IR, PassPA);
252 if constexpr (!std::is_same_v<PassT, PassManager>) {
255 Passes.push_back(std::unique_ptr<PassConceptT>(
256 new PassModelT(std::forward<PassT>(
Pass))));
263 for (
auto &
P :
Pass.Passes)
264 Passes.push_back(std::move(
P));
277 std::vector<std::unique_ptr<PassConceptT>>
Passes;
306 : Callbacks(Callbacks) {}
310 template <
typename IRUnitT,
typename AnalysisManagerT,
typename... ExtraArgTs>
311 Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {
337 using AnalysisResultListT =
338 std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>;
348 typename AnalysisResultListT::iterator>;
377 template <
typename PassT>
383 return invalidateImpl<ResultModelT>(PassT::ID(),
IR, PA);
393 return invalidateImpl<>(
ID,
IR, PA);
399 template <
typename ResultT = ResultConceptT>
404 auto IMapI = IsResultInvalidated.find(
ID);
405 if (IMapI != IsResultInvalidated.end())
406 return IMapI->second;
411 "Trying to invalidate a dependent result that isn't in the "
412 "manager's cache is always an error, likely due to a stale result "
415 auto &Result =
static_cast<ResultT &
>(*RI->second->second);
422 std::tie(IMapI, Inserted) =
423 IsResultInvalidated.insert({
ID, Result.invalidate(
IR, PA, *
this)});
425 assert(Inserted &&
"Should not have already inserted this ID, likely "
426 "indicates a dependency cycle!");
427 return IMapI->second;
430 Invalidator(SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated,
431 const AnalysisResultMapT &
Results)
434 SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated;
435 const AnalysisResultMapT &
Results;
446 "The storage and index of analysis results disagree on how many "
448 return AnalysisResults.
empty();
465 AnalysisResults.
clear();
466 AnalysisResultLists.
clear();
472 template <
typename PassT>
473 typename PassT::Result &
getResult(IRUnitT &
IR, ExtraArgTs... ExtraArgs) {
475 "This analysis pass was not registered prior to being queried");
477 getResultImpl(PassT::ID(),
IR, ExtraArgs...);
483 return static_cast<ResultModelT &
>(ResultConcept).Result;
491 template <
typename PassT>
494 "This analysis pass was not registered prior to being queried");
504 return &
static_cast<ResultModelT *
>(ResultConcept)->Result;
508 template <
typename PassT>
512 Invalidator Inv(IsResultInvalidated, AnalysisResults);
513 assert(!Result->invalidate(
IR, PA, Inv) &&
514 "Cached result cannot be invalidated");
534 template <
typename PassBuilderT>
540 auto &PassPtr = AnalysisPasses[PassT::ID()];
561 "Analysis passes must be registered prior to being queried!");
566 const PassConceptT &lookUpPass(AnalysisKey *
ID)
const {
569 "Analysis passes must be registered prior to being queried!");
574 ResultConceptT &getResultImpl(AnalysisKey *
ID, IRUnitT &
IR,
575 ExtraArgTs... ExtraArgs);
578 ResultConceptT *getCachedResultImpl(AnalysisKey *
ID, IRUnitT &
IR)
const {
581 return RI == AnalysisResults.
end() ? nullptr : &*RI->second->second;
585 using AnalysisPassMapT =
586 DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>>;
589 AnalysisPassMapT AnalysisPasses;
595 AnalysisResultListMapT AnalysisResultLists;
599 AnalysisResultMapT AnalysisResults;
602extern template class AnalysisManager<Module>;
607extern template class AnalysisManager<Function>;
628template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
631 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> {
635 explicit Result(AnalysisManagerT &InnerAM) : InnerAM(&InnerAM) {}
641 Arg.InnerAM =
nullptr;
655 InnerAM =
RHS.InnerAM;
659 RHS.InnerAM =
nullptr;
681 AnalysisManagerT *InnerAM;
685 : InnerAM(&InnerAM) {}
703 AnalysisManagerT *InnerAM;
706template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
708 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
717bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
753template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
756 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>> {
761 explicit Result(
const AnalysisManagerT &OuterAM) : OuterAM(&OuterAM) {}
765 template <
typename PassT,
typename IRUnitTParam>
767 typename PassT::Result *Res =
768 OuterAM->template getCachedResult<PassT>(
IR);
770 OuterAM->template verifyNotInvalidated<PassT>(
IR, Res);
775 template <
typename PassT,
typename IRUnitTParam>
777 typename PassT::Result *Res =
778 OuterAM->template getCachedResult<PassT>(
IR);
779 return Res !=
nullptr;
789 for (
auto &KeyValuePair : OuterAnalysisInvalidationMap) {
791 auto &InnerIDs = KeyValuePair.second;
795 if (InnerIDs.empty())
799 for (
auto *OuterID : DeadKeys)
800 OuterAnalysisInvalidationMap.erase(OuterID);
808 template <
typename OuterAnalysisT,
typename Inval
idatedAnalysisT>
811 AnalysisKey *InvalidatedID = InvalidatedAnalysisT::ID();
813 auto &InvalidatedIDList = OuterAnalysisInvalidationMap[OuterID];
819 InvalidatedIDList.push_back(InvalidatedID);
826 return OuterAnalysisInvalidationMap;
830 const AnalysisManagerT *OuterAM;
835 OuterAnalysisInvalidationMap;
839 : OuterAM(&OuterAM) {}
855 const AnalysisManagerT *OuterAM;
858template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
860 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
897 bool EagerlyInvalidate)
908 std::unique_ptr<PassConceptT>
Pass;
909 bool EagerlyInvalidate;
914template <
typename FunctionPassT>
915ModuleToFunctionPassAdaptor
917 bool EagerlyInvalidate =
false) {
923 std::unique_ptr<ModuleToFunctionPassAdaptor::PassConceptT>(
924 new PassModelT(std::forward<FunctionPassT>(
Pass))),
937template <
typename AnalysisT,
typename IRUnitT,
938 typename AnalysisManagerT = AnalysisManager<IRUnitT>,
939 typename... ExtraArgTs>
941 :
PassInfoMixin<RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
950 ExtraArgTs &&... Args) {
951 (void)AM.template getResult<AnalysisT>(Arg,
952 std::forward<ExtraArgTs>(Args)...);
958 auto ClassName = AnalysisT::name();
959 auto PassName = MapClassName2PassName(ClassName);
967template <
typename AnalysisT>
976 template <
typename IRUnitT,
typename AnalysisManagerT,
typename... ExtraArgTs>
984 auto ClassName = AnalysisT::name();
985 auto PassName = MapClassName2PassName(ClassName);
996 template <
typename IRUnitT,
typename AnalysisManagerT,
typename... ExtraArgTs>
1006template <
typename PassT>
1010 : Count(Count), P(
std::forward<
PassT>(P)) {}
1012 template <
typename IRUnitT,
typename AnalysisManagerT,
typename... Ts>
1020 detail::getAnalysisResult<PassInstrumentationAnalysis>(
1021 AM,
IR, std::tuple<Ts...>(Args...));
1024 for (
int i = 0; i < Count; ++i) {
1039 OS <<
"repeat<" << Count <<
">(";
1040 P.printPipeline(
OS, MapClassName2PassName);
1049template <
typename PassT>
Function Alias Analysis Results
#define LLVM_ATTRIBUTE_MINSIZE
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
Module.h This file contains the declarations for the Module class.
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
This header provides internal APIs and implementation details used by the pass management interfaces ...
llvm::cl::opt< bool > UseNewDbgInfoFormat
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
static const char PassName[]
This templated class represents "all analyses that operate over <a particular IR unit>" (e....
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.
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.
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)
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)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Runs the function pass across every function in the module.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
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.
Pseudo-analysis pass that exposes the PassInstrumentation to pass managers.
Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...)
PassInstrumentationAnalysis(PassInstrumentationCallbacks *Callbacks=nullptr)
PassInstrumentationCallbacks object is shared, owned by something else, not this analysis.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
This class provides instrumentation entry points for the Pass Manager, doing calls to callbacks regis...
void runAfterPass(const PassT &Pass, const IRUnitT &IR, const PreservedAnalyses &PA) const
AfterPass instrumentation point - takes Pass instance that has just been executed and constant refere...
bool runBeforePass(const PassT &Pass, const IRUnitT &IR) const
BeforePass instrumentation point - takes Pass instance to be executed and constant reference to IR it...
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 void addPass(PassT &&Pass)
std::vector< std::unique_ptr< PassConceptT > > Passes
PassManager()=default
Construct a pass manager.
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.
void intersect(const PreservedAnalyses &Arg)
Intersect this set with another in place.
void preserveSet()
Mark an analysis set as preserved.
void abandon()
Mark an analysis as abandoned.
A utility pass template that simply runs another pass multiple times.
PreservedAnalyses run(IRUnitT &IR, AnalysisManagerT &AM, Ts &&... Args)
RepeatedPass(int Count, PassT &&P)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
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.
RepeatedPass< PassT > createRepeatedPass(int Count, PassT &&P)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move 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.