44#define DEBUG_TYPE "cgscc-passmgr"
48 return LibraryOptions.
get<AnalysisOptions>().max_devirt_iterations;
51STATISTIC(MaxSCCIterations,
"Maximum CGSCCPassMgr iterations on one SCC");
68 bool runOnModule(
Module &M)
override;
70 using ModulePass::doInitialization;
71 using ModulePass::doFinalization;
73 bool doInitialization(CallGraph &CG);
74 bool doFinalization(CallGraph &CG);
77 void getAnalysisUsage(AnalysisUsage &Info)
const override {
79 Info.addRequired<CallGraphWrapperPass>();
80 Info.setPreservesAll();
83 StringRef getPassName()
const override {
return "CallGraph Pass Manager"; }
85 PMDataManager *getAsPMDataManager()
override {
return this; }
86 Pass *getAsPass()
override {
return this; }
89 void dumpPassStructure(
unsigned Offset)
override {
91 for (
unsigned Index = 0;
Index < getNumContainedPasses(); ++
Index) {
92 Pass *
P = getContainedPass(Index);
93 P->dumpPassStructure(
Offset + 1);
98 Pass *getContainedPass(
unsigned N) {
99 assert(
N < PassVector.size() &&
"Pass number out of range!");
100 return static_cast<Pass *
>(PassVector[
N]);
108 bool RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG,
109 bool &DevirtualizedCall);
111 bool RunPassOnSCC(
Pass *
P, CallGraphSCC &CurSCC,
112 CallGraph &CG,
bool &CallGraphUpToDate,
113 bool &DevirtualizedCall);
114 bool RefreshCallGraph(
const CallGraphSCC &CurSCC, CallGraph &CG,
115 bool IsCheckingMode);
120char CGPassManager::ID = 0;
124 bool &DevirtualizedCall) {
126 PMDataManager *PM =
P->getAsPMDataManager();
130 CallGraphSCCPass *CGSP = (CallGraphSCCPass *)
P;
131 if (!CallGraphUpToDate) {
132 DevirtualizedCall |= RefreshCallGraph(CurSCC, CG,
false);
133 CallGraphUpToDate =
true;
138 StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount;
139 bool EmitICRemark =
M.shouldEmitInstrCountChangedRemark();
142 InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount);
147 SCCCount =
M.getInstructionCount();
152 static_cast<int64_t
>(SCCCount) -
static_cast<int64_t
>(
InstrCount);
153 emitInstrCountChangedRemark(
P, M, Delta,
InstrCount,
154 FunctionToInstrCount);
164 RefreshCallGraph(CurSCC, CG,
true);
171 "Invalid CGPassManager member");
172 FPPassManager *FPP = (FPPassManager*)
P;
175 for (CallGraphNode *CGN : CurSCC) {
182 F->getContext().yield();
188 if (
Changed && CallGraphUpToDate) {
189 LLVM_DEBUG(
dbgs() <<
"CGSCCPASSMGR: Pass Dirtied SCC: " <<
P->getPassName()
191 CallGraphUpToDate =
false;
205bool CGPassManager::RefreshCallGraph(
const CallGraphSCC &CurSCC, CallGraph &CG,
207 DenseMap<Value *, CallGraphNode *> Calls;
211 for (CallGraphNode *CGN
212 : CurSCC) CGN->dump(););
214 bool MadeChange =
false;
215 bool DevirtualizedCall =
false;
218 unsigned FunctionNo = 0;
220 SCCIdx !=
E; ++SCCIdx, ++FunctionNo) {
221 CallGraphNode *CGN = *SCCIdx;
223 if (!
F ||
F->isDeclaration())
continue;
230 unsigned NumDirectRemoved = 0, NumIndirectRemoved = 0;
237 bool WasLast =
I + 1 == CGNEnd;
259 if (RemoveAndCheckForDone(
I))
273 "CallGraphSCCPass did not update the CallGraph correctly!");
276 if (!
I->second->getFunction())
277 ++NumIndirectRemoved;
281 if (RemoveAndCheckForDone(
I))
286 assert(!Calls.
count(
Call) &&
"Call site occurs in node multiple times");
291 if (!Callee || !(
Callee->isIntrinsic()))
299 unsigned NumDirectAdded = 0, NumIndirectAdded = 0;
301 for (BasicBlock &BB : *
F)
302 for (Instruction &
I : BB) {
307 if (Callee &&
Callee->isIntrinsic())
322 if (ExistingIt != Calls.
end()) {
323 CallGraphNode *ExistingNode = ExistingIt->second;
326 Calls.
erase(ExistingIt);
342 "CallGraphSCCPass did not update the CallGraph correctly!");
346 CallGraphNode *CalleeNode;
352 DevirtualizedCall =
true;
354 <<
Callee->getName() <<
"'\n");
367 "CallGraphSCCPass did not update the CallGraph correctly!");
370 CallGraphNode *CalleeNode;
393 if (NumIndirectRemoved > NumIndirectAdded &&
394 NumDirectRemoved < NumDirectAdded)
395 DevirtualizedCall =
true;
401 assert(Calls.
empty() &&
"Dangling pointers found in call sites map");
405 if ((FunctionNo & 15) == 15)
410 dbgs() <<
"CGSCCPASSMGR: Refreshed SCC is now:\n";
411 for (CallGraphNode *CGN : CurSCC)
413 if (DevirtualizedCall)
414 dbgs() <<
"CGSCCPASSMGR: Refresh devirtualized a call!\n";
416 dbgs() <<
"CGSCCPASSMGR: SCC Refresh didn't change call graph.\n";
420 return DevirtualizedCall;
426bool CGPassManager::RunAllPassesOnSCC(CallGraphSCC &CurSCC, CallGraph &CG,
427 bool &DevirtualizedCall) {
437 bool CallGraphUpToDate =
true;
440 for (
unsigned PassNo = 0, e = getNumContainedPasses();
441 PassNo !=
e; ++PassNo) {
442 Pass *
P = getContainedPass(PassNo);
446 if (isPassDebuggingExecutionsOrMore()) {
447 std::string Functions;
449 raw_string_ostream OS(Functions);
451 for (
const CallGraphNode *CGN : CurSCC) {
460 initializeAnalysisImpl(
P);
462#ifdef EXPENSIVE_CHECKS
468 RunPassOnSCC(
P, CurSCC, CG, CallGraphUpToDate, DevirtualizedCall);
472#ifdef EXPENSIVE_CHECKS
473 if (!LocalChanged && (RefHash !=
P->structuralHash(CG.
getModule()))) {
474 llvm::errs() <<
"Pass modifies its input and doesn't report it: "
475 <<
P->getPassName() <<
"\n";
483 verifyPreservedAnalysis(
P);
485 removeNotPreservedAnalysis(
P);
486 recordAvailableAnalysis(
P);
492 if (!CallGraphUpToDate)
493 DevirtualizedCall |= RefreshCallGraph(CurSCC, CG,
false);
499bool CGPassManager::runOnModule(
Module &M) {
500 const unsigned MaxDevirtIterations =
502 CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
503 bool Changed = doInitialization(CG);
506 scc_iterator<CallGraph*> CGI =
scc_begin(&CG);
508 CallGraphSCC CurSCC(CG);
512 const std::vector<CallGraphNode *> &NodeVec = *CGI;
513 CurSCC.initialize(NodeVec);
528 unsigned Iteration = 0;
529 bool DevirtualizedCall =
false;
532 <<
" SCCPASSMGR: Re-visiting SCC, iteration #" << Iteration
534 DevirtualizedCall =
false;
535 Changed |= RunAllPassesOnSCC(CurSCC, CG, DevirtualizedCall);
536 }
while (Iteration++ < MaxDevirtIterations && DevirtualizedCall);
538 if (DevirtualizedCall)
541 <<
" times, due to -max-devirt-iterations\n");
543 MaxSCCIterations.updateMax(Iteration);
550bool CGPassManager::doInitialization(CallGraph &CG) {
552 for (
unsigned i = 0, e = getNumContainedPasses(); i !=
e; ++i) {
553 if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
555 "Invalid CGPassManager member");
558 Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doInitialization(CG);
565bool CGPassManager::doFinalization(CallGraph &CG) {
567 for (
unsigned i = 0, e = getNumContainedPasses(); i !=
e; ++i) {
568 if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
570 "Invalid CGPassManager member");
573 Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doFinalization(CG);
587 while (!PMS.
empty() &&
591 assert(!PMS.
empty() &&
"Unable to handle Call Graph Pass");
595 CGP = (CGPassManager*)PMS.
top();
598 assert(!PMS.
empty() &&
"Unable to create Call Graph Pass Manager");
602 CGP =
new CGPassManager();
643 PrintCallGraphPass(
const std::string &
B,
raw_ostream &OS)
650 bool runOnSCC(CallGraphSCC &SCC)
override {
651 bool BannerPrinted =
false;
652 auto PrintBannerOnce = [&]() {
655 OS << Banner <<
"\n";
656 BannerPrinted =
true;
663 SCC.getCallGraph().getModule().print(OS,
nullptr);
666 bool FoundFunction =
false;
667 for (CallGraphNode *CGN : SCC) {
670 FoundFunction =
true;
678 OS <<
"\nPrinting <null> Function\n";
681 if (NeedModule && FoundFunction) {
684 SCC.getCallGraph().getModule().print(OS,
nullptr);
689 StringRef getPassName()
const override {
return "Print CallGraph IR"; }
694char PrintCallGraphPass::ID = 0;
697 const std::string &Banner)
const {
698 return new PrintCallGraphPass(Banner, OS);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
static unsigned InstrCount
This file defines the DenseMap class.
Module.h This file contains the declarations for the Module class.
print mir2vec MIR2Vec Vocabulary Printer Pass
Machine Check Debug Module
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This header defines classes/functions to handle pass execution timing information with interfaces for...
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI void print(raw_ostream &OS) const
void addCalledFunction(CallBase *Call, CallGraphNode *M)
Adds a function to the list of functions called by this one.
LLVM_ABI void replaceCallEdge(CallBase &Call, CallBase &NewCall, CallGraphNode *NewNode)
Replaces the edge in the node for the specified call site with a new one.
LLVM_ABI void dump() const
Print out this call graph node.
Function * getFunction() const
Returns the function that this call graph node represents.
std::vector< CallRecord >::iterator iterator
void removeCallEdge(iterator I)
Pass * createPrinterPass(raw_ostream &OS, const std::string &Banner) const override
createPrinterPass - Get a pass that prints the Module corresponding to a CallGraph.
virtual bool runOnSCC(CallGraphSCC &SCC)=0
runOnSCC - This method should be implemented by the subclass to perform whatever action is necessary ...
void getAnalysisUsage(AnalysisUsage &Info) const override
getAnalysisUsage - For this class, we declare that we require and preserve the call graph.
void assignPassManager(PMStack &PMS, PassManagerType PMT) override
Assign pass manager to manager this pass.
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
std::vector< CallGraphNode * >::const_iterator iterator
The ModulePass which wraps up a CallGraph and the logic to build it.
The basic data container for the call graph of a Module of IR.
LLVM_ABI CallGraphNode * getOrInsertFunction(const Function *F)
Similar to operator[], but this will insert a new CallGraphNode for F if one does not already exist.
CallGraphNode * getCallsExternalNode() const
Module & getModule() const
Returns the module the call graph corresponds to.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
This pass is required by interprocedural register allocation.
bool runOnFunction(Function &F)
run - Execute all of the passes scheduled for execution.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
PMDataManager provides the common place to manage the analysis data used by pass managers.
PMTopLevelManager * getTopLevelManager()
virtual PassManagerType getPassManagerType() const
PMStack - This class implements a stack data structure of PMDataManager pointers.
PMDataManager * top() const
LLVM_ABI void push(PMDataManager *PM)
PMTopLevelManager manages LastUser info and collects common APIs used by top level pass managers.
void addIndirectPassManager(PMDataManager *Manager)
void schedulePass(Pass *P)
Schedule pass P for execution.
Pass interface - Implemented by all 'passes'.
Pass(PassKind K, char &pid)
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
bool isAtEnd() const
Direct loop termination test which is more efficient than comparison with end().
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool forcePrintModuleIR()
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
PassManagerType
Different types of internal pass managers.
@ PMT_CallGraphPassManager
CGPassManager.
@ PMT_FunctionPassManager
FPPassManager.
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI Timer * getPassTimer(Pass *)
Request the timer for this legacy-pass-manager's pass instance.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI bool shouldPrintFunction(const Function &F)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void forEachCallbackFunction(const CallBase &CB, UnaryFunction Func)
Apply function Func to each CB's callback function.
LLVM_ABI unsigned getMaxDevirtIterations(const cl::LibraryOptionsContext &)
LLVM_ABI bool shouldPrintAllFunctions()