18 #define DEBUG_TYPE "cgscc-passmgr"
35 STATISTIC(MaxSCCIterations,
"Maximum CGSCCPassMgr iterations on one SCC");
47 explicit CGPassManager()
52 bool runOnModule(
Module &M);
67 virtual const char *getPassName()
const {
68 return "CallGraph Pass Manager";
72 virtual Pass *getAsPass() {
return this; }
75 void dumpPassStructure(
unsigned Offset) {
76 errs().
indent(Offset*2) <<
"Call Graph SCC Pass Manager\n";
77 for (
unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
78 Pass *
P = getContainedPass(Index);
80 dumpLastUses(P, Offset+1);
84 Pass *getContainedPass(
unsigned N) {
85 assert(N < PassVector.size() &&
"Pass number out of range!");
86 return static_cast<Pass *
>(PassVector[
N]);
95 bool &DevirtualizedCall);
99 bool &DevirtualizedCall);
101 bool IsCheckingMode);
111 bool &DevirtualizedCall) {
112 bool Changed =
false;
117 if (!CallGraphUpToDate) {
118 DevirtualizedCall |= RefreshCallGraph(CurSCC, CG,
false);
119 CallGraphUpToDate =
true;
131 RefreshCallGraph(CurSCC, CG,
true);
139 "Invalid CGPassManager member");
148 Changed |= FPP->runOnFunction(*
F);
154 if (Changed && CallGraphUpToDate) {
155 DEBUG(
dbgs() <<
"CGSCCPASSMGR: Pass Dirtied SCC: "
157 CallGraphUpToDate =
false;
173 bool CGPassManager::RefreshCallGraph(
CallGraphSCC &CurSCC,
177 DEBUG(
dbgs() <<
"CGSCCPASSMGR: Refreshing SCC with " << CurSCC.
size()
184 bool MadeChange =
false;
185 bool DevirtualizedCall =
false;
188 unsigned FunctionNo = 0;
190 SCCIdx != E; ++SCCIdx, ++FunctionNo) {
200 unsigned NumDirectRemoved = 0, NumIndirectRemoved = 0;
210 CallSites.
count(
I->first) ||
216 assert(!CheckingMode &&
217 "CallGraphSCCPass did not update the CallGraph correctly!");
220 if (
I->second->getFunction() == 0)
221 ++NumIndirectRemoved;
227 bool WasLast =
I + 1 == E;
239 assert(!CallSites.
count(
I->first) &&
240 "Call site occurs in node multiple times");
241 CallSites.
insert(std::make_pair(
I->first,
I->second));
247 unsigned NumDirectAdded = 0, NumIndirectAdded = 0;
253 Function *Callee = CS.getCalledFunction();
259 CallSites.
find(CS.getInstruction());
260 if (ExistingIt != CallSites.
end()) {
264 CallSites.
erase(ExistingIt);
267 if (ExistingNode->
getFunction() == CS.getCalledFunction())
275 if (CheckingMode && CS.getCalledFunction() &&
279 assert(!CheckingMode &&
280 "CallGraphSCCPass did not update the CallGraph correctly!");
285 if (
Function *Callee = CS.getCalledFunction()) {
290 DevirtualizedCall =
true;
291 DEBUG(
dbgs() <<
" CGSCCPASSMGR: Devirtualized call to '"
292 << Callee->
getName() <<
"'\n");
304 assert(!CheckingMode &&
305 "CallGraphSCCPass did not update the CallGraph correctly!");
309 if (
Function *Callee = CS.getCalledFunction()) {
331 if (NumIndirectRemoved > NumIndirectAdded &&
332 NumDirectRemoved < NumDirectAdded)
333 DevirtualizedCall =
true;
338 assert(CallSites.
empty() &&
"Dangling pointers found in call sites map");
342 if ((FunctionNo & 15) == 15)
346 DEBUG(
if (MadeChange) {
347 dbgs() <<
"CGSCCPASSMGR: Refreshed SCC is now:\n";
351 if (DevirtualizedCall)
352 dbgs() <<
"CGSCCPASSMGR: Refresh devirtualized a call!\n";
355 dbgs() <<
"CGSCCPASSMGR: SCC Refresh didn't change call graph.\n";
360 return DevirtualizedCall;
367 bool &DevirtualizedCall) {
368 bool Changed =
false;
377 bool CallGraphUpToDate =
true;
380 for (
unsigned PassNo = 0, e = getNumContainedPasses();
381 PassNo != e; ++PassNo) {
382 Pass *P = getContainedPass(PassNo);
386 if (isPassDebuggingExecutionsOrMore()) {
387 std::string Functions;
392 if (
I != CurSCC.
begin()) OS <<
", ";
401 initializeAnalysisImpl(P);
404 Changed |= RunPassOnSCC(P, CurSCC, CG,
405 CallGraphUpToDate, DevirtualizedCall);
411 verifyPreservedAnalysis(P);
412 removeNotPreservedAnalysis(P);
413 recordAvailableAnalysis(P);
419 if (!CallGraphUpToDate)
420 DevirtualizedCall |= RefreshCallGraph(CurSCC, CG,
false);
426 bool CGPassManager::runOnModule(
Module &M) {
427 CallGraph &CG = getAnalysis<CallGraph>();
428 bool Changed = doInitialization(CG);
437 std::vector<CallGraphNode*> &NodeVec = *CGI;
438 CurSCC.
initialize(&NodeVec[0], &NodeVec[0]+NodeVec.size());
453 unsigned Iteration = 0;
454 bool DevirtualizedCall =
false;
457 dbgs() <<
" SCCPASSMGR: Re-visiting SCC, iteration #"
458 << Iteration <<
'\n');
459 DevirtualizedCall =
false;
460 Changed |= RunAllPassesOnSCC(CurSCC, CG, DevirtualizedCall);
463 if (DevirtualizedCall)
464 DEBUG(
dbgs() <<
" CGSCCPASSMGR: Stopped iteration after " << Iteration
465 <<
" times, due to -max-cg-scc-iterations\n");
467 if (Iteration > MaxSCCIterations)
468 MaxSCCIterations = Iteration;
471 Changed |= doFinalization(CG);
477 bool CGPassManager::doInitialization(
CallGraph &CG) {
478 bool Changed =
false;
479 for (
unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
480 if (
PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
482 "Invalid CGPassManager member");
492 bool CGPassManager::doFinalization(
CallGraph &CG) {
493 bool Changed =
false;
494 for (
unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) {
495 if (
PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) {
497 "Invalid CGPassManager member");
513 assert(Old != New &&
"Should not replace node with self");
514 for (
unsigned i = 0; ; ++i) {
515 assert(i != Nodes.size() &&
"Node not in SCC");
516 if (Nodes[i] != Old)
continue;
536 while (!PMS.
empty() &&
540 assert(!PMS.
empty() &&
"Unable to handle Call Graph Pass");
544 CGP = (CGPassManager*)PMS.
top();
547 assert(!PMS.
empty() &&
"Unable to create Call Graph Pass Manager");
551 CGP =
new CGPassManager();
591 PrintCallGraphPass(
const std::string &B,
raw_ostream &o)
601 (*I)->getFunction()->print(Out);
611 const std::string &Banner)
const {
612 return new PrintCallGraphPass(Banner, O);
AnalysisUsage & addPreserved()
virtual PMDataManager * getAsPMDataManager()
virtual void dumpPassStructure(unsigned Offset=0)
The main container class for the LLVM Intermediate Representation.
std::vector< CallGraphNode * >::const_iterator iterator
STATISTIC(MaxSCCIterations,"Maximum CGSCCPassMgr iterations on one SCC")
virtual void assignPassManager(PMStack &PMS, PassManagerType PMT)
Assign pass manager to manager this pass.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
virtual const char * getPassName() const
virtual PassManagerType getPassManagerType() const
Module & getModule() const
virtual void getAnalysisUsage(AnalysisUsage &Info) const
Timer * getPassTimer(Pass *)
If TimingInfo is enabled then start pass timer.
StringRef getName() const
Function * getFunction() const
void addCalledFunction(CallSite CS, CallGraphNode *M)
std::vector< CallRecord >::iterator iterator
void schedulePass(Pass *P)
AnalysisUsage & addRequired()
void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode)
virtual bool doFinalization(Module &)
ID
LLVM Calling Convention Representation.
scc_iterator< T > scc_begin(const T &G)
virtual bool doInitialization(Module &)
static cl::opt< unsigned > MaxIterations("max-cg-scc-iterations", cl::ReallyHidden, cl::init(4))
initializer< Ty > init(const Ty &Val)
void addIndirectPassManager(PMDataManager *Manager)
void ReplaceNode(NodeType *Old, NodeType *New)
bool count(const KeyT &Val) const
count - Return true if the specified key is in the map.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Pass * createPrinterPass(raw_ostream &O, const std::string &Banner) const
bool erase(const KeyT &Val)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
PMDataManager * top() const
void removeCallEdge(iterator I)
void ReplaceNode(CallGraphNode *Old, CallGraphNode *New)
bool isDeclaration() const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
void push(PMDataManager *PM)
virtual bool runOnSCC(CallGraphSCC &SCC)=0
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
CallGraphNode * getOrInsertFunction(const Function *F)
iterator find(const KeyT &Val)
void initialize(CallGraphNode *const *I, CallGraphNode *const *E)
CallGraphNode * getCallsExternalNode() const