89 #ifndef LLVM_ANALYSIS_CGSCCPASSMANAGER_H
90 #define LLVM_ANALYSIS_CGSCCPASSMANAGER_H
101 struct CGSCCUpdateResult;
104 extern template class AllAnalysesOn<LazyCallGraph::SCC>;
106 extern template class AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>;
113 typedef AnalysisManager<LazyCallGraph::SCC, LazyCallGraph &>
138 template <
typename AnalysisT>
141 :
PassInfoMixin<RequireAnalysisPass<AnalysisT, LazyCallGraph::SCC,
142 CGSCCAnalysisManager, LazyCallGraph &,
143 CGSCCUpdateResult &>> {
146 (void)AM.template getResult<AnalysisT>(C, CG);
152 typedef InnerAnalysisManagerProxy<CGSCCAnalysisManager, Module>
161 : InnerAM(&InnerAM), G(&G) {}
289 template <
typename CGSCCPassT>
291 :
public PassInfoMixin<ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>> {
294 : Pass(std::move(Pass)), DebugLogging(DebugLogging) {}
299 :
Pass(Arg.
Pass), DebugLogging(Arg.DebugLogging) {}
301 :
Pass(std::move(Arg.
Pass)), DebugLogging(Arg.DebugLogging) {}
305 swap(LHS.Pass, RHS.Pass);
306 swap(LHS.DebugLogging, RHS.DebugLogging);
334 InvalidSCCSet,
nullptr,
nullptr};
340 assert(RCWorklist.empty() &&
341 "Should always start with an empty RefSCC worklist");
353 RCWorklist.insert(&*RCI++);
357 if (InvalidRefSCCSet.
count(RC)) {
359 dbgs() <<
"Skipping an invalid RefSCC...\n";
364 "Should always start with an empty SCC worklist");
367 dbgs() <<
"Running an SCC pass across the RefSCC: " << *RC <<
"\n";
380 if (InvalidSCCSet.
count(C)) {
382 dbgs() <<
"Skipping an invalid SCC...\n";
387 dbgs() <<
"Skipping an SCC that is now part of some other "
394 assert(!InvalidSCCSet.
count(C) &&
"Processing an invalid SCC!");
397 "Processing an SCC in a different RefSCC!");
427 dbgs() <<
"Re-running SCC passes after a refinement of the "
436 }
while (!CWorklist.
empty());
437 }
while (!RCWorklist.empty());
456 template <
typename CGSCCPassT>
457 ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>
495 extern template class OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>;
497 typedef OuterAnalysisManagerProxy<CGSCCAnalysisManager, Function>
518 template <
typename FunctionPassT>
523 : Pass(std::move(Pass)), DebugLogging(DebugLogging) {}
527 :
Pass(Arg.
Pass), DebugLogging(Arg.DebugLogging) {}
529 :
Pass(std::move(Arg.
Pass)), DebugLogging(Arg.DebugLogging) {}
533 swap(LHS.Pass, RHS.Pass);
534 swap(LHS.DebugLogging, RHS.DebugLogging);
558 dbgs() <<
"Running function passes across an SCC: " << C <<
"\n";
582 CG, *CurrentC, *
N, AM, UR, DebugLogging);
584 "Current SCC not updated to the SCC containing the current node!");
607 template <
typename FunctionPassT>
608 CGSCCToFunctionPassAdaptor<FunctionPassT>
628 template <
typename PassT>
633 bool DebugLogging =
false)
634 : Pass(std::move(Pass)), MaxIterations(MaxIterations),
635 DebugLogging(DebugLogging) {}
661 assert(CallHandles.
empty() &&
"Must start with a clear set of handles.");
666 CallCount &Count = CallCounts.back();
669 if (CS.getCalledFunction()) {
682 auto CallCounts = ScanSCC(*C, CallHandles);
684 for (
int Iteration = 0;; ++Iteration) {
698 "Cannot have changed the size of the SCC!");
701 auto IsDevirtualizedHandle = [&](
WeakVH &CallH) {
714 dbgs() <<
"Found devirutalized call from "
715 << CS.getParent()->getParent()->getName() <<
" to "
722 bool Devirt =
any_of(CallHandles, IsDevirtualizedHandle);
728 auto NewCallCounts = ScanSCC(*C, CallHandles);
736 for (
int i = 0, Size = C->
size();
i < Size; ++
i)
737 if (CallCounts[
i].Indirect > NewCallCounts[
i].Indirect &&
738 CallCounts[
i].Direct < NewCallCounts[
i].Direct) {
749 if (Iteration >= MaxIterations) {
751 dbgs() <<
"Found another devirtualization after hitting the max "
752 "number of repetitions ("
753 << MaxIterations <<
") on SCC: " << *C <<
"\n";
759 dbgs() <<
"Repeating an SCC pass after finding a devirtualization in: "
763 CallCounts = std::move(NewCallCounts);
785 template <
typename PassT>
786 DevirtSCCRepeatedPass<PassT>
788 bool DebugLogging =
false) {
Pass interface - Implemented by all 'passes'.
This file provides a priority worklist.
SCC * lookupSCC(Node &N) const
Lookup a function's SCC in the graph.
void push_back(const T &Elt)
Result run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &)
Computes the FunctionAnalysisManager and stores it in the result proxy.
ModuleToPostOrderCGSCCPassAdaptor(ModuleToPostOrderCGSCCPassAdaptor &&Arg)
PreservedAnalyses run(LazyCallGraph::SCC &InitialC, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
Runs the wrapped pass up to MaxIterations on the SCC, iterating whenever an indirect call is refined...
bool insert(const T &X)
Insert a new element into the PriorityWorklist.
DevirtSCCRepeatedPass< PassT > createDevirtSCCRepeatedPass(PassT Pass, int MaxIterations, bool DebugLogging=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
LLVM_NODISCARD T pop_back_val()
SmallPriorityWorklist< LazyCallGraph::RefSCC *, 1 > & RCWorklist
Worklist of the RefSCCs queued for processing.
void intersect(const PreservedAnalyses &Arg)
Intersect this set with another in place.
A Module instance is used to store all the information related to an LLVM module. ...
aarch64 AArch64 CCMP Pass
CGSCCToFunctionPassAdaptor & operator=(CGSCCToFunctionPassAdaptor RHS)
Implements a lazy call graph analysis and related passes for the new pass manager.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Result(FunctionAnalysisManager &FAM)
OuterAnalysisManagerProxy< CGSCCAnalysisManager, Function > CGSCCAnalysisManagerFunctionProxy
A proxy from a CGSCCAnalysisManager to a Function.
ModuleToPostOrderCGSCCPassAdaptor & operator=(ModuleToPostOrderCGSCCPassAdaptor RHS)
A utility pass template to force an analysis result to be available.
Result(CGSCCAnalysisManager &InnerAM, LazyCallGraph &G)
A proxy from a FunctionAnalysisManager to an SCC.
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
StringRef getName() const
Return a constant reference to the value's name.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
Runs the function pass across every function in the module.
ModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass, bool DebugLogging=false)
DevirtSCCRepeatedPass(PassT Pass, int MaxIterations, bool DebugLogging=false)
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
LazyCallGraph::SCC * UpdatedC
If non-null, the updated current SCC being processed.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
postorder_ref_scc_iterator postorder_ref_scc_begin()
ModuleToPostOrderCGSCCPassAdaptor(const ModuleToPostOrderCGSCCPassAdaptor &Arg)
LLVM_NODISCARD bool empty() const
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
CGSCCToFunctionPassAdaptor(const CGSCCToFunctionPassAdaptor &Arg)
A RefSCC of the call graph.
Value handle that is nullable, but tries to track the Value.
A CRTP mix-in to automatically provide informational APIs needed for passes.
A lazily constructed view of the call graph of a module.
Result run(IRUnitT &IR, AnalysisManager< IRUnitT, ExtraArgTs...> &AM, ExtraArgTs...)
Run the analysis pass and create our proxy result object.
static cl::opt< unsigned > MaxIterations("max-cg-scc-iterations", cl::ReallyHidden, cl::init(4))
A set of analyses that are preserved following a run of a transformation pass.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
CGSCCToFunctionPassAdaptor< FunctionPassT > createCGSCCToFunctionPassAdaptor(FunctionPassT Pass, bool DebugLogging=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
The core module pass which does a post-order walk of the SCCs and runs a CGSCC pass over each one...
SmallPtrSetImpl< LazyCallGraph::RefSCC * > & InvalidatedRefSCCs
The set of invalidated RefSCCs which should be skipped if they are found in RCWorklist.
SmallPtrSetImpl< LazyCallGraph::SCC * > & InvalidatedSCCs
The set of invalidated SCCs which should be skipped if they are found in CWorklist.
A CRTP mix-in that provides informational APIs needed for analysis passes.
friend void swap(ModuleToPostOrderCGSCCPassAdaptor &LHS, ModuleToPostOrderCGSCCPassAdaptor &RHS)
LazyCallGraph::RefSCC * UpdatedRC
If non-null, the updated current RefSCC being processed.
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
friend void swap(CGSCCToFunctionPassAdaptor &LHS, CGSCCToFunctionPassAdaptor &RHS)
FunctionAnalysisManager & getManager()
Accessor for the analysis manager.
RefSCC & getOuterRefSCC() const
A node in the call graph.
A version of PriorityWorklist that selects small size optimized data structures for the vector and ma...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
SmallPriorityWorklist< LazyCallGraph::SCC *, 1 > & CWorklist
Worklist of the SCCs queued for processing.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Runs the CGSCC pass across every SCC in the module.
CGSCCAnalysisManager & getManager()
Accessor for the analysis manager.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
PassManager< LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, CGSCCUpdateResult & > CGSCCPassManager
The CGSCC pass manager.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void invalidate(IRUnitT &IR)
Invalidate a specific analysis pass for an IR module.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A helper that repeats an SCC pass each time an indirect call is refined to a direct call by that pass...
CGSCCToFunctionPassAdaptor(CGSCCToFunctionPassAdaptor &&Arg)
Adaptor that maps from a SCC to its functions.
bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA, typename AnalysisManager< IRUnitT, ExtraArgTs...>::Invalidator &Inv)
Handler for invalidation of the outer IR unit, IRUnitT.
Manages a sequence of passes over a particular unit of IR.
void preserveSet()
Mark an analysis set as preserved.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
void preserve()
Mark an analysis as preserved.
An analysis pass which computes the call graph for a module.
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &)
API to communicate dependencies between analyses during invalidation.
bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA, CGSCCAnalysisManager::Invalidator &Inv)
ModuleToPostOrderCGSCCPassAdaptor< CGSCCPassT > createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT Pass, bool DebugLogging=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This templated class represents "all analyses that operate over \<a particular IR unit\>" (e...
An SCC of the call graph.
inst_range instructions(Function *F)
A container for analyses that lazily runs them and caches their results.
This header defines various interfaces for pass management in LLVM.
postorder_ref_scc_iterator postorder_ref_scc_end()
InnerAnalysisManagerProxy< CGSCCAnalysisManager, Module > CGSCCAnalysisManagerModuleProxy
A proxy from a CGSCCAnalysisManager to a Module.
LazyCallGraph::SCC & updateCGAndAnalysisManagerForFunctionPass(LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, bool DebugLogging=false)
Helper to update the call graph after running a function pass.
A special type used by analysis passes to provide an address that identifies that particular analysis...
bool empty() const
Determine if the PriorityWorklist is empty or not.
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
CGSCCToFunctionPassAdaptor(FunctionPassT Pass, bool DebugLogging=false)