summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2008-09-03 19:37:16 +0000
committerDuncan Sands <baldrick@free.fr>2008-09-03 19:37:16 +0000
commitee088a7093019c31f4792927d86e881890b88a4b (patch)
treecd864c76869ba441a7c93b54b81779b0c23bc48f /llvm/lib
parent924d9084d853d4a1ddb919576df739dfb86cfa98 (diff)
downloadbcm5719-llvm-ee088a7093019c31f4792927d86e881890b88a4b.tar.gz
bcm5719-llvm-ee088a7093019c31f4792927d86e881890b88a4b.zip
If a SCC has a node without a function, then the SCC
analysis would bail out without removing function records for other members of the SCC (which may exist if those functions read or wrote global variables). Since these are initialized to "readnone", this resulted in incorrect alias analysis results. llvm-svn: 55714
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/IPA/GlobalsModRef.cpp23
1 files changed, 14 insertions, 9 deletions
diff --git a/llvm/lib/Analysis/IPA/GlobalsModRef.cpp b/llvm/lib/Analysis/IPA/GlobalsModRef.cpp
index fe622f26404..9a7580b9c8d 100644
--- a/llvm/lib/Analysis/IPA/GlobalsModRef.cpp
+++ b/llvm/lib/Analysis/IPA/GlobalsModRef.cpp
@@ -354,13 +354,18 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
for (scc_iterator<CallGraph*> I = scc_begin(&CG), E = scc_end(&CG); I != E;
++I) {
std::vector<CallGraphNode *> &SCC = *I;
- assert(!SCC.empty() && "SCC with no functions?");
- if (!SCC[0]->getFunction())
- // Do not process the external node, assume the worst.
- continue;
+ FunctionRecord *FR = 0;
+ // Find a function record from the SCC (it doesn't matter which one).
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i)
+ if (Function *F = SCC[i]->getFunction()) {
+ FR = &FunctionInfo[F];
+ break;
+ }
- FunctionRecord &FR = FunctionInfo[SCC[0]->getFunction()];
+ if (!FR)
+ // Nothing to do.
+ continue;
bool KnowNothing = false;
unsigned FunctionEffect = 0;
@@ -384,7 +389,7 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
// mark all globals read somewhere as being read by this function.
for (std::set<GlobalValue*>::iterator GI = ReadGlobals.begin(),
E = ReadGlobals.end(); GI != E; ++GI)
- FR.GlobalInfo[*GI] |= Ref;
+ FR->GlobalInfo[*GI] |= Ref;
} else {
// Can't say anything useful.
KnowNothing = true;
@@ -403,7 +408,7 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
for (std::map<GlobalValue*, unsigned>::iterator GI =
CalleeFR->GlobalInfo.begin(), E = CalleeFR->GlobalInfo.end();
GI != E; ++GI)
- FR.GlobalInfo[GI->first] |= GI->second;
+ FR->GlobalInfo[GI->first] |= GI->second;
} else {
// Can't say anything about it. However, if it is inside our SCC,
// then nothing needs to be done.
@@ -440,12 +445,12 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
++NumReadMemFunctions;
if (FunctionEffect == 0)
++NumNoMemFunctions;
- FR.FunctionEffect = FunctionEffect;
+ FR->FunctionEffect = FunctionEffect;
// Finally, now that we know the full effect on this SCC, clone the
// information to each function in the SCC.
for (unsigned i = 1, e = SCC.size(); i != e; ++i)
- FunctionInfo[SCC[i]->getFunction()] = FR;
+ FunctionInfo[SCC[i]->getFunction()] = *FR;
}
}
OpenPOWER on IntegriCloud