diff options
author | Chris Lattner <sabre@nondot.org> | 2009-09-01 18:32:03 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-09-01 18:32:03 +0000 |
commit | 5a6a363527f9f66ff23f2d281f4fdc6c2084f2d3 (patch) | |
tree | d60cc27ecba8cbcec2d20dc54586d6c508750aa7 /lib/Analysis/IPA/CallGraphSCCPass.cpp | |
parent | 7ab42aec4266ef1b474ae03f3cb94ce509aa94a7 (diff) | |
download | external_llvm-5a6a363527f9f66ff23f2d281f4fdc6c2084f2d3.zip external_llvm-5a6a363527f9f66ff23f2d281f4fdc6c2084f2d3.tar.gz external_llvm-5a6a363527f9f66ff23f2d281f4fdc6c2084f2d3.tar.bz2 |
doxygenate RefreshCallGraph, add a new 'verification mode', and run it after
CGSCC passes make change to ensure they are updating the callgraph correctly
(when assertions are enabled).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80698 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/IPA/CallGraphSCCPass.cpp')
-rw-r--r-- | lib/Analysis/IPA/CallGraphSCCPass.cpp | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/lib/Analysis/IPA/CallGraphSCCPass.cpp b/lib/Analysis/IPA/CallGraphSCCPass.cpp index 7e9fd30..a7d1183 100644 --- a/lib/Analysis/IPA/CallGraphSCCPass.cpp +++ b/lib/Analysis/IPA/CallGraphSCCPass.cpp @@ -78,7 +78,8 @@ public: private: bool RunPassOnSCC(Pass *P, std::vector<CallGraphNode*> &CurSCC, CallGraph &CG, bool &CallGraphUpToDate); - void RefreshCallGraph(std::vector<CallGraphNode*> &CurSCC, CallGraph &CG); + void RefreshCallGraph(std::vector<CallGraphNode*> &CurSCC, CallGraph &CG, + bool IsCheckingMode); }; } // end anonymous namespace. @@ -90,13 +91,21 @@ bool CGPassManager::RunPassOnSCC(Pass *P, std::vector<CallGraphNode*> &CurSCC, bool Changed = false; if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass*>(P)) { if (!CallGraphUpToDate) { - RefreshCallGraph(CurSCC, CG); + RefreshCallGraph(CurSCC, CG, false); CallGraphUpToDate = true; } StartPassTimer(P); Changed = CGSP->runOnSCC(CurSCC); StopPassTimer(P); + + // After the CGSCCPass is done, when assertions are enabled, use + // RefreshCallGraph to verify that the callgraph was correctly updated. +#ifndef NDEBUG + if (Changed) + RefreshCallGraph(CurSCC, CG, true); +#endif + return Changed; } @@ -123,8 +132,14 @@ bool CGPassManager::RunPassOnSCC(Pass *P, std::vector<CallGraphNode*> &CurSCC, return Changed; } + +/// RefreshCallGraph - Scan the functions in the specified CFG and resync the +/// callgraph with the call sites found in it. This is used after +/// FunctionPasses have potentially munged the callgraph, and can be used after +/// CallGraphSCC passes to verify that they correctly updated the callgraph. +/// void CGPassManager::RefreshCallGraph(std::vector<CallGraphNode*> &CurSCC, - CallGraph &CG) { + CallGraph &CG, bool CheckingMode) { DenseMap<Value*, CallGraphNode*> CallSites; DEBUG(errs() << "CGSCCPASSMGR: Refreshing SCC with " << CurSCC.size() @@ -158,6 +173,9 @@ void CGPassManager::RefreshCallGraph(std::vector<CallGraphNode*> &CurSCC, // pass RAUW'd a call with another value. This can happen when // constant folding happens of well known functions etc. CallSite::get(I->first).getInstruction() == 0) { + assert(!CheckingMode && + "CallGraphSCCPass did not update the CallGraph correctly!"); + // Just remove the edge from the set of callees. CGN->removeCallEdge(I); E = CGN->end(); @@ -190,6 +208,18 @@ void CGPassManager::RefreshCallGraph(std::vector<CallGraphNode*> &CurSCC, if (ExistingNode->getFunction() == CS.getCalledFunction()) continue; + // If we are in checking mode, we are not allowed to actually mutate + // the callgraph. If this is a case where we can infer that the + // callgraph is less precise than it could be (e.g. an indirect call + // site could be turned direct), don't reject it in checking mode, and + // don't tweak it to be more precise. + if (CheckingMode && CS.getCalledFunction() && + ExistingNode->getFunction() == 0) + continue; + + assert(!CheckingMode && + "CallGraphSCCPass did not update the CallGraph correctly!"); + // If not, we either went from a direct call to indirect, indirect to // direct, or direct to different direct. CallGraphNode *CalleeNode; @@ -203,6 +233,9 @@ void CGPassManager::RefreshCallGraph(std::vector<CallGraphNode*> &CurSCC, continue; } + assert(!CheckingMode && + "CallGraphSCCPass did not update the CallGraph correctly!"); + // If the call site didn't exist in the CGN yet, add it. We assume that // newly introduced call sites won't be indirect. This could be fixed // in the future. @@ -289,7 +322,7 @@ bool CGPassManager::runOnModule(Module &M) { // If the callgraph was left out of date (because the last pass run was a // functionpass), refresh it before we move on to the next SCC. if (!CallGraphUpToDate) - RefreshCallGraph(CurSCC, CG); + RefreshCallGraph(CurSCC, CG, false); } Changed |= doFinalization(CG); return Changed; |