32 #define DEBUG_TYPE "cgscc-passmgr"
37 STATISTIC(MaxSCCIterations,
"Maximum CGSCCPassMgr iterations on one SCC");
49 explicit CGPassManager()
54 bool runOnModule(
Module &M)
override;
69 const char *getPassName()
const override {
70 return "CallGraph Pass Manager";
74 Pass *getAsPass()
override {
return this; }
77 void dumpPassStructure(
unsigned Offset)
override {
78 errs().
indent(Offset*2) <<
"Call Graph SCC Pass Manager\n";
79 for (
unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
80 Pass *
P = getContainedPass(Index);
82 dumpLastUses(P, Offset+1);
86 Pass *getContainedPass(
unsigned N) {
87 assert(N < PassVector.size() &&
"Pass number out of range!");
88 return static_cast<Pass *
>(PassVector[
N]);
97 bool &DevirtualizedCall);
101 bool &DevirtualizedCall);
103 bool IsCheckingMode);
113 bool &DevirtualizedCall) {
114 bool Changed =
false;
119 if (!CallGraphUpToDate) {
120 DevirtualizedCall |= RefreshCallGraph(CurSCC, CG,
false);
121 CallGraphUpToDate =
true;
133 RefreshCallGraph(CurSCC, CG,
true);
141 "Invalid CGPassManager member");
150 Changed |= FPP->runOnFunction(*
F);
152 F->getContext().yield();
158 if (Changed && CallGraphUpToDate) {
159 DEBUG(
dbgs() <<
"CGSCCPASSMGR: Pass Dirtied SCC: "
161 CallGraphUpToDate =
false;
177 bool CGPassManager::RefreshCallGraph(
CallGraphSCC &CurSCC,
181 DEBUG(
dbgs() <<
"CGSCCPASSMGR: Refreshing SCC with " << CurSCC.
size()
187 bool MadeChange =
false;
188 bool DevirtualizedCall =
false;
191 unsigned FunctionNo = 0;
193 SCCIdx != E; ++SCCIdx, ++FunctionNo) {
203 unsigned NumDirectRemoved = 0, NumIndirectRemoved = 0;
213 CallSites.
count(
I->first) ||
224 assert(!CheckingMode &&
225 "CallGraphSCCPass did not update the CallGraph correctly!");
228 if (!
I->second->getFunction())
229 ++NumIndirectRemoved;
235 bool WasLast =
I + 1 == E;
247 assert(!CallSites.
count(
I->first) &&
248 "Call site occurs in node multiple times");
255 CallSites.
insert(std::make_pair(
I->first,
I->second));
262 unsigned NumDirectAdded = 0, NumIndirectAdded = 0;
274 CallSites.
find(
CS.getInstruction());
275 if (ExistingIt != CallSites.
end()) {
279 CallSites.
erase(ExistingIt);
290 if (CheckingMode &&
CS.getCalledFunction() &&
294 assert(!CheckingMode &&
295 "CallGraphSCCPass did not update the CallGraph correctly!");
300 if (
Function *Callee =
CS.getCalledFunction()) {
305 DevirtualizedCall =
true;
306 DEBUG(
dbgs() <<
" CGSCCPASSMGR: Devirtualized call to '"
307 << Callee->
getName() <<
"'\n");
319 assert(!CheckingMode &&
320 "CallGraphSCCPass did not update the CallGraph correctly!");
324 if (
Function *Callee =
CS.getCalledFunction()) {
346 if (NumIndirectRemoved > NumIndirectAdded &&
347 NumDirectRemoved < NumDirectAdded)
348 DevirtualizedCall =
true;
353 assert(CallSites.
empty() &&
"Dangling pointers found in call sites map");
357 if ((FunctionNo & 15) == 15)
361 DEBUG(
if (MadeChange) {
362 dbgs() <<
"CGSCCPASSMGR: Refreshed SCC is now:\n";
365 if (DevirtualizedCall)
366 dbgs() <<
"CGSCCPASSMGR: Refresh devirtualized a call!\n";
369 dbgs() <<
"CGSCCPASSMGR: SCC Refresh didn't change call graph.\n";
374 return DevirtualizedCall;
381 bool &DevirtualizedCall) {
382 bool Changed =
false;
391 bool CallGraphUpToDate =
true;
394 for (
unsigned PassNo = 0, e = getNumContainedPasses();
395 PassNo != e; ++PassNo) {
396 Pass *P = getContainedPass(PassNo);
400 if (isPassDebuggingExecutionsOrMore()) {
401 std::string Functions;
406 if (
I != CurSCC.
begin()) OS <<
", ";
415 initializeAnalysisImpl(P);
418 Changed |= RunPassOnSCC(P, CurSCC, CG,
419 CallGraphUpToDate, DevirtualizedCall);
425 verifyPreservedAnalysis(P);
426 removeNotPreservedAnalysis(P);
427 recordAvailableAnalysis(P);
433 if (!CallGraphUpToDate)
434 DevirtualizedCall |= RefreshCallGraph(CurSCC, CG,
false);
440 bool CGPassManager::runOnModule(
Module &M) {
441 CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
442 bool Changed = doInitialization(CG);
451 const std::vector<CallGraphNode *> &NodeVec = *CGI;
452 CurSCC.
initialize(NodeVec.data(), NodeVec.data() + NodeVec.size());
467 unsigned Iteration = 0;
468 bool DevirtualizedCall =
false;
471 dbgs() <<
" SCCPASSMGR: Re-visiting SCC, iteration #"
472 << Iteration <<
'\n');
473 DevirtualizedCall =
false;
474 Changed |= RunAllPassesOnSCC(CurSCC, CG, DevirtualizedCall);
477 if (DevirtualizedCall)
478 DEBUG(
dbgs() <<
" CGSCCPASSMGR: Stopped iteration after " << Iteration
479 <<
" times, due to -max-cg-scc-iterations\n");
481 if (Iteration > MaxSCCIterations)
482 MaxSCCIterations = Iteration;
485 Changed |= doFinalization(CG);
491 bool CGPassManager::doInitialization(
CallGraph &CG) {
492 bool Changed =
false;
493 for (
unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
494 if (
PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
496 "Invalid CGPassManager member");
506 bool CGPassManager::doFinalization(
CallGraph &CG) {
507 bool Changed =
false;
508 for (
unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
509 if (
PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
511 "Invalid CGPassManager member");
527 assert(Old != New &&
"Should not replace node with self");
528 for (
unsigned i = 0; ; ++i) {
529 assert(i != Nodes.size() &&
"Node not in SCC");
530 if (Nodes[i] != Old)
continue;
550 while (!PMS.
empty() &&
554 assert(!PMS.
empty() &&
"Unable to handle Call Graph Pass");
558 CGP = (CGPassManager*)PMS.
top();
561 assert(!PMS.
empty() &&
"Unable to create Call Graph Pass Manager");
565 CGP =
new CGPassManager();
605 PrintCallGraphPass(
const std::string &B,
raw_ostream &o)
618 Out <<
"\nPrinting <null> Function\n";
629 const std::string &Banner)
const {
630 return new PrintCallGraphPass(Banner, O);
Pass interface - Implemented by all 'passes'.
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
PassManagerType
Different types of internal pass managers.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
STATISTIC(NumFunctions,"Total number of functions")
virtual PMDataManager * getAsPMDataManager()
virtual void dumpPassStructure(unsigned Offset=0)
A Module instance is used to store all the information related to an LLVM module. ...
std::vector< CallGraphNode * >::const_iterator iterator
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
virtual const char * getPassName() const
getPassName - Return a nice clean name for a pass.
bool isAtEnd() const
Direct loop termination test which is more efficient than comparison with end().
A node in the call graph for a module.
void getAnalysisUsage(AnalysisUsage &Info) const override
getAnalysisUsage - For this class, we declare that we require and preserve the call graph...
void dump() const
Print out this call graph node.
virtual PassManagerType getPassManagerType() const
Module & getModule() const
Returns the module the call graph corresponds to.
PMTopLevelManager manages LastUser info and collects common APIs used by top level pass managers...
Timer * getPassTimer(Pass *)
If TimingInfo is enabled then start pass timer.
StringRef getName() const
Return a constant reference to the value's name.
Function * getFunction() const
Returns the function that this call graph node represents.
The TimeRegion class is used as a helper class to call the startTimer() and stopTimer() methods of th...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void addCalledFunction(CallSite CS, CallGraphNode *M)
Adds a function to the list of functions called by this one.
std::vector< CallRecord >::iterator iterator
void schedulePass(Pass *P)
Schedule pass P for execution.
AnalysisUsage & addRequired()
void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode)
Replaces the edge in the node for the specified call site with a new one.
virtual bool doFinalization(Module &)
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
FPPassManager manages BBPassManagers and FunctionPasses.
PMStack - This class implements a stack data structure of PMDataManager pointers. ...
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
virtual bool doInitialization(Module &)
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
static cl::opt< unsigned > MaxIterations("max-cg-scc-iterations", cl::ReallyHidden, cl::init(4))
initializer< Ty > init(const Ty &Val)
bool erase(const KeyT &Val)
The ModulePass which wraps up a CallGraph and the logic to build it.
bool isLeaf(ID id)
Returns true if the intrinsic is a leaf, i.e.
FunTy * getCalledFunction() const
getCalledFunction - Return the function being called if this is a direct call, otherwise return null ...
void addIndirectPassManager(PMDataManager *Manager)
Pass * createPrinterPass(raw_ostream &O, const std::string &Banner) const override
createPrinterPass - Get a pass that prints the Module corresponding to a CallGraph.
Represent the analysis usage information of a pass.
void ReplaceNode(NodeType *Old, NodeType *New)
This informs the scc_iterator that the specified Old node has been deleted, and New is to be used in ...
void assignPassManager(PMStack &PMS, PassManagerType PMT) override
Assign pass manager to manager this pass.
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
PMDataManager * top() const
void setPreservesAll()
Set by analyses that do not transform their input at all.
void removeCallEdge(iterator I)
void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW=nullptr) const
Print the function to an output stream with an optional AssemblyAnnotationWriter. ...
The basic data container for the call graph of a Module of IR.
void ReplaceNode(CallGraphNode *Old, CallGraphNode *New)
ReplaceNode - This informs the SCC and the pass manager that the specified Old node has been deleted...
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
iterator find(const KeyT &Val)
void push(PMDataManager *PM)
PMDataManager provides the common place to manage the analysis data used by pass managers.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
virtual bool runOnSCC(CallGraphSCC &SCC)=0
runOnSCC - This method should be implemented by the subclass to perform whatever action is necessary ...
A raw_ostream that writes to an std::string.
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
CallGraphNode * getOrInsertFunction(const Function *F)
Similar to operator[], but this will insert a new CallGraphNode for F if one does not already exist...
This class implements an extremely fast bulk output stream that can only output to a stream...
void initialize(CallGraphNode *const *I, CallGraphNode *const *E)
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
CallGraphNode * getCallsExternalNode() const