37#ifndef LLVM_IR_PASSMANAGER_H
38#define LLVM_IR_PASSMANAGER_H
77 IR.convertToNewDbgValues();
81 IR.convertFromNewDbgValues();
85template <
typename IRUnitT,
typename... ExtraArgTs>
class AnalysisManager;
94 static_assert(std::is_base_of<PassInfoMixin, DerivedT>::value,
95 "Must pass the derived type as the template argument!");
97 Name.consume_front(
"llvm::");
104 auto PassName = MapClassName2PassName(ClassName);
113template <
typename DerivedT>
131 static_assert(std::is_base_of<AnalysisInfoMixin, DerivedT>::value,
132 "Must pass the derived type as the template argument!");
133 return &DerivedT::Key;
141template <
typename PassT,
typename IRUnitT,
typename AnalysisManagerT,
142 typename... ArgTs,
size_t... Ns>
143typename PassT::Result
145 std::tuple<ArgTs...> Args,
146 std::index_sequence<Ns...>) {
148 return AM.template getResult<PassT>(
IR, std::get<Ns>(Args)...);
156template <
typename PassT,
typename IRUnitT,
typename... AnalysisArgTs,
157 typename... MainArgTs>
158typename PassT::Result
160 std::tuple<MainArgTs...> Args) {
162 PassT, IRUnitT>)(AM,
IR, Args,
163 std::index_sequence_for<AnalysisArgTs...>{});
172class PassInstrumentationAnalysis;
186template <
typename IRUnitT,
187 typename AnalysisManagerT = AnalysisManager<IRUnitT>,
188 typename... ExtraArgTs>
190 PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...>> {
210 P->printPipeline(
OS, MapClassName2PassName);
219 ExtraArgTs... ExtraArgs) {
227 detail::getAnalysisResult<PassInstrumentationAnalysis>(
228 AM,
IR, std::tuple<ExtraArgTs...>(ExtraArgs...));
233 if (ShouldConvertDbgInfo)
247 AM.invalidate(
IR, PassPA);
258 if (ShouldConvertDbgInfo)
270 template <
typename PassT>
272 std::enable_if_t<!std::is_same<PassT, PassManager>::value>
278 Passes.push_back(std::unique_ptr<PassConceptT>(
279 new PassModelT(std::forward<PassT>(
Pass))));
287 template <
typename PassT>
289 std::enable_if_t<std::is_same<PassT, PassManager>::value>
291 for (
auto &
P :
Pass.Passes)
292 Passes.push_back(std::move(
P));
304 std::vector<std::unique_ptr<PassConceptT>>
Passes;
333 : Callbacks(Callbacks) {}
337 template <
typename IRUnitT,
typename AnalysisManagerT,
typename... ExtraArgTs>
338 Result run(IRUnitT &, AnalysisManagerT &, ExtraArgTs &&...) {
364 using AnalysisResultListT =
365 std::list<std::pair<AnalysisKey *, std::unique_ptr<ResultConceptT>>>;
375 typename AnalysisResultListT::iterator>;
404 template <
typename PassT>
410 return invalidateImpl<ResultModelT>(PassT::ID(),
IR, PA);
420 return invalidateImpl<>(
ID,
IR, PA);
426 template <
typename ResultT = ResultConceptT>
431 auto IMapI = IsResultInvalidated.find(
ID);
432 if (IMapI != IsResultInvalidated.end())
433 return IMapI->second;
438 "Trying to invalidate a dependent result that isn't in the "
439 "manager's cache is always an error, likely due to a stale result "
442 auto &Result =
static_cast<ResultT &
>(*RI->second->second);
449 std::tie(IMapI, Inserted) =
450 IsResultInvalidated.insert({
ID, Result.invalidate(
IR, PA, *
this)});
452 assert(Inserted &&
"Should not have already inserted this ID, likely "
453 "indicates a dependency cycle!");
454 return IMapI->second;
457 Invalidator(SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated,
458 const AnalysisResultMapT &
Results)
461 SmallDenseMap<AnalysisKey *, bool, 8> &IsResultInvalidated;
462 const AnalysisResultMapT &
Results;
473 "The storage and index of analysis results disagree on how many "
475 return AnalysisResults.
empty();
492 AnalysisResults.
clear();
493 AnalysisResultLists.
clear();
499 template <
typename PassT>
500 typename PassT::Result &
getResult(IRUnitT &
IR, ExtraArgTs... ExtraArgs) {
502 "This analysis pass was not registered prior to being queried");
504 getResultImpl(PassT::ID(),
IR, ExtraArgs...);
510 return static_cast<ResultModelT &
>(ResultConcept).Result;
518 template <
typename PassT>
521 "This analysis pass was not registered prior to being queried");
531 return &
static_cast<ResultModelT *
>(ResultConcept)->Result;
535 template <
typename PassT>
539 Invalidator Inv(IsResultInvalidated, AnalysisResults);
540 assert(!Result->invalidate(
IR, PA, Inv) &&
541 "Cached result cannot be invalidated");
561 template <
typename PassBuilderT>
567 auto &PassPtr = AnalysisPasses[PassT::ID()];
588 "Analysis passes must be registered prior to being queried!");
593 const PassConceptT &lookUpPass(AnalysisKey *
ID)
const {
596 "Analysis passes must be registered prior to being queried!");
601 ResultConceptT &getResultImpl(AnalysisKey *
ID, IRUnitT &
IR,
602 ExtraArgTs... ExtraArgs);
605 ResultConceptT *getCachedResultImpl(AnalysisKey *
ID, IRUnitT &
IR)
const {
608 return RI == AnalysisResults.
end() ? nullptr : &*RI->second->second;
612 using AnalysisPassMapT =
613 DenseMap<AnalysisKey *, std::unique_ptr<PassConceptT>>;
616 AnalysisPassMapT AnalysisPasses;
622 AnalysisResultListMapT AnalysisResultLists;
626 AnalysisResultMapT AnalysisResults;
629extern template class AnalysisManager<Module>;
655template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
658 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT>> {
662 explicit Result(AnalysisManagerT &InnerAM) : InnerAM(&InnerAM) {}
668 Arg.InnerAM =
nullptr;
682 InnerAM =
RHS.InnerAM;
686 RHS.InnerAM =
nullptr;
708 AnalysisManagerT *InnerAM;
712 : InnerAM(&InnerAM) {}
730 AnalysisManagerT *InnerAM;
733template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
735 InnerAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
744bool FunctionAnalysisManagerModuleProxy::Result::invalidate(
780template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
783 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>> {
788 explicit Result(
const AnalysisManagerT &OuterAM) : OuterAM(&OuterAM) {}
792 template <
typename PassT,
typename IRUnitTParam>
794 typename PassT::Result *Res =
795 OuterAM->template getCachedResult<PassT>(
IR);
797 OuterAM->template verifyNotInvalidated<PassT>(
IR, Res);
802 template <
typename PassT,
typename IRUnitTParam>
804 typename PassT::Result *Res =
805 OuterAM->template getCachedResult<PassT>(
IR);
806 return Res !=
nullptr;
816 for (
auto &KeyValuePair : OuterAnalysisInvalidationMap) {
818 auto &InnerIDs = KeyValuePair.second;
822 if (InnerIDs.empty())
826 for (
auto *OuterID : DeadKeys)
827 OuterAnalysisInvalidationMap.erase(OuterID);
835 template <
typename OuterAnalysisT,
typename Inval
idatedAnalysisT>
838 AnalysisKey *InvalidatedID = InvalidatedAnalysisT::ID();
840 auto &InvalidatedIDList = OuterAnalysisInvalidationMap[OuterID];
846 InvalidatedIDList.push_back(InvalidatedID);
853 return OuterAnalysisInvalidationMap;
857 const AnalysisManagerT *OuterAM;
862 OuterAnalysisInvalidationMap;
866 : OuterAM(&OuterAM) {}
882 const AnalysisManagerT *OuterAM;
885template <
typename AnalysisManagerT,
typename IRUnitT,
typename... ExtraArgTs>
887 OuterAnalysisManagerProxy<AnalysisManagerT, IRUnitT, ExtraArgTs...>::Key;
924 bool EagerlyInvalidate)
935 std::unique_ptr<PassConceptT>
Pass;
936 bool EagerlyInvalidate;
941template <
typename FunctionPassT>
942ModuleToFunctionPassAdaptor
944 bool EagerlyInvalidate =
false) {
950 std::unique_ptr<ModuleToFunctionPassAdaptor::PassConceptT>(
951 new PassModelT(std::forward<FunctionPassT>(
Pass))),
964template <
typename AnalysisT,
typename IRUnitT,
965 typename AnalysisManagerT = AnalysisManager<IRUnitT>,
966 typename... ExtraArgTs>
968 :
PassInfoMixin<RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
977 ExtraArgTs &&... Args) {
978 (void)AM.template getResult<AnalysisT>(Arg,
979 std::forward<ExtraArgTs>(Args)...);
985 auto ClassName = AnalysisT::name();
986 auto PassName = MapClassName2PassName(ClassName);
994template <
typename AnalysisT>
1003 template <
typename IRUnitT,
typename AnalysisManagerT,
typename... ExtraArgTs>
1011 auto ClassName = AnalysisT::name();
1012 auto PassName = MapClassName2PassName(ClassName);
1023 template <
typename IRUnitT,
typename AnalysisManagerT,
typename... ExtraArgTs>
1033template <
typename PassT>
1037 : Count(Count), P(
std::forward<PassT>(P)) {}
1039 template <
typename IRUnitT,
typename AnalysisManagerT,
typename... Ts>
1047 detail::getAnalysisResult<PassInstrumentationAnalysis>(
1048 AM,
IR, std::tuple<Ts...>(Args...));
1051 for (
int i = 0; i < Count; ++i) {
1066 OS <<
"repeat<" << Count <<
">(";
1067 P.printPipeline(
OS, MapClassName2PassName);
1076template <
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 std::enable_if_t<!std::is_same< PassT, PassManager >::value > 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< PassT, PassManager >::value > 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.
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)
void doConvertDebugInfoToOld(IRUnitT &IR)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
void doConvertDbgInfoToNew(IRUnitT &IR)
bool shouldConvertDbgInfo(IRUnitT &IR)
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.
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.