Remove interfaces implemented by dead pass from the list of available passes.
authorDevang Patel <dpatel@apple.com>
Mon, 6 Oct 2008 20:36:36 +0000 (20:36 +0000)
committerDevang Patel <dpatel@apple.com>
Mon, 6 Oct 2008 20:36:36 +0000 (20:36 +0000)
Patch By Matthijs Kooijman.

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

lib/VMCore/PassManager.cpp
test/Other/2008-10-06-RemoveDeadPass.ll [new file with mode: 0644]

index 29a6df0d6a7124cb51fbdccc9de36c99fd3a6f7d..e3d1c5364e95f5e8869e952a845a7c7528a8e7f0 100644 (file)
@@ -779,13 +779,23 @@ void PMDataManager::removeDeadPasses(Pass *P, const char *Msg,
     if (TheTimeInfo) TheTimeInfo->passStarted(*I);
     (*I)->releaseMemory();
     if (TheTimeInfo) TheTimeInfo->passEnded(*I);
-
-    std::map<AnalysisID, Pass*>::iterator Pos = 
-      AvailableAnalysis.find((*I)->getPassInfo());
-    
-    // It is possible that pass is already removed from the AvailableAnalysis
-    if (Pos != AvailableAnalysis.end())
-      AvailableAnalysis.erase(Pos);
+    if (const PassInfo *PI = (*I)->getPassInfo()) {
+      std::map<AnalysisID, Pass*>::iterator Pos =
+        AvailableAnalysis.find(PI);
+
+      // It is possible that pass is already removed from the AvailableAnalysis
+      if (Pos != AvailableAnalysis.end())
+        AvailableAnalysis.erase(Pos);
+
+      // Remove all interfaces this pass implements, for which it is also
+      // listed as the available implementation.
+      const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented();
+      for (unsigned i = 0, e = II.size(); i != e; ++i) {
+        Pos = AvailableAnalysis.find(II[i]);
+        if (Pos != AvailableAnalysis.end() && Pos->second == *I)
+          AvailableAnalysis.erase(Pos);
+      }
+    }
   }
 }
 
diff --git a/test/Other/2008-10-06-RemoveDeadPass.ll b/test/Other/2008-10-06-RemoveDeadPass.ll
new file mode 100644 (file)
index 0000000..a82d1b6
--- /dev/null
@@ -0,0 +1,11 @@
+; RUN: llvm-as < %s | opt -inline -internalize -disable-output
+define void @foo() nounwind {
+  ret void
+}
+
+define void @main(...) nounwind {
+  call void @foo()
+  ret void
+}
+
+