If a SCC has a node without a function, then the SCC
authorDuncan Sands <baldrick@free.fr>
Wed, 3 Sep 2008 19:37:16 +0000 (19:37 +0000)
committerDuncan Sands <baldrick@free.fr>
Wed, 3 Sep 2008 19:37:16 +0000 (19:37 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55714 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/IPA/GlobalsModRef.cpp

index fe622f264043b4c8be523277d76aa07e53c8bc67..9a7580b9c8df29af5f040363d1f559913672e4a1 100644 (file)
@@ -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;
   }
 }