[CallGraph] Port -print-callgraph-sccs to new pass manager
authorArthur Eubanks <aeubanks@google.com>
Fri, 7 Oct 2022 21:08:43 +0000 (14:08 -0700)
committerArthur Eubanks <aeubanks@google.com>
Tue, 11 Oct 2022 21:43:16 +0000 (14:43 -0700)
And remove the legacy opt-specific pass.

Reviewed By: asbirlea

Differential Revision: https://reviews.llvm.org/D135487

llvm/include/llvm/Analysis/CallGraph.h
llvm/lib/Analysis/CallGraph.cpp
llvm/lib/Passes/PassRegistry.def
llvm/test/Analysis/CallGraph/printer.ll [new file with mode: 0644]
llvm/tools/opt/PrintSCC.cpp

index 88d5678..df38ea4 100644 (file)
@@ -326,6 +326,17 @@ public:
   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
 };
 
+/// Printer pass for the summarized \c CallGraphAnalysis results.
+class CallGraphSCCsPrinterPass
+    : public PassInfoMixin<CallGraphSCCsPrinterPass> {
+  raw_ostream &OS;
+
+public:
+  explicit CallGraphSCCsPrinterPass(raw_ostream &OS) : OS(OS) {}
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
 /// The \c ModulePass which wraps up a \c CallGraph and the logic to
 /// build it.
 ///
index f855271..8a5242e 100644 (file)
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Analysis/CallGraph.h"
+#include "llvm/ADT/SCCIterator.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Config/llvm-config.h"
@@ -312,6 +313,34 @@ PreservedAnalyses CallGraphPrinterPass::run(Module &M,
   return PreservedAnalyses::all();
 }
 
+PreservedAnalyses CallGraphSCCsPrinterPass::run(Module &M,
+                                                ModuleAnalysisManager &AM) {
+  auto &CG = AM.getResult<CallGraphAnalysis>(M);
+  unsigned sccNum = 0;
+  OS << "SCCs for the program in PostOrder:";
+  for (scc_iterator<CallGraph *> SCCI = scc_begin(&CG); !SCCI.isAtEnd();
+       ++SCCI) {
+    const std::vector<CallGraphNode *> &nextSCC = *SCCI;
+    OS << "\nSCC #" << ++sccNum << ": ";
+    bool First = true;
+    for (std::vector<CallGraphNode *>::const_iterator I = nextSCC.begin(),
+                                                      E = nextSCC.end();
+         I != E; ++I) {
+      if (First)
+        First = false;
+      else
+        OS << ", ";
+      OS << ((*I)->getFunction() ? (*I)->getFunction()->getName()
+                                 : "external node");
+    }
+
+    if (nextSCC.size() == 1 && SCCI.hasCycle())
+      OS << " (Has self-loop).";
+  }
+  OS << "\n";
+  return PreservedAnalyses::all();
+}
+
 //===----------------------------------------------------------------------===//
 // Out-of-line definitions of CallGraphAnalysis class members.
 //
index 8cfb9d6..76fc890 100644 (file)
@@ -92,6 +92,7 @@ MODULE_PASS("pgo-instr-gen", PGOInstrumentationGen())
 MODULE_PASS("pgo-instr-use", PGOInstrumentationUse())
 MODULE_PASS("print-profile-summary", ProfileSummaryPrinterPass(dbgs()))
 MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs()))
+MODULE_PASS("print-callgraph-sccs", CallGraphSCCsPrinterPass(dbgs()))
 MODULE_PASS("print", PrintModulePass(dbgs()))
 MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(dbgs()))
 MODULE_PASS("print-lcg-dot", LazyCallGraphDOTPrinterPass(dbgs()))
diff --git a/llvm/test/Analysis/CallGraph/printer.ll b/llvm/test/Analysis/CallGraph/printer.ll
new file mode 100644 (file)
index 0000000..c177d3b
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: opt -S -passes=print-callgraph-sccs -disable-output < %s 2>&1 | FileCheck %s
+; CHECK: SCC #1: g, f
+; CHECK: SCC #2: h
+; CHECK: SCC #3: external node
+
+define void @f() {
+  call void @g()
+  ret void
+}
+
+define void @g() {
+  call void @f()
+  ret void
+}
+
+define void @h() {
+  call void @f()
+  ret void
+}
index 1ca5274..f9daa24 100644 (file)
@@ -25,7 +25,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/SCCIterator.h"
-#include "llvm/Analysis/CallGraph.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Pass.h"
@@ -44,32 +43,12 @@ namespace {
       AU.setPreservesAll();
     }
   };
-
-  struct CallGraphSCC : public ModulePass {
-    static char ID;  // Pass identification, replacement for typeid
-    CallGraphSCC() : ModulePass(ID) {}
-
-    // run - Print out SCCs in the call graph for the specified module.
-    bool runOnModule(Module &M) override;
-
-    void print(raw_ostream &O, const Module* = nullptr) const override { }
-
-    // getAnalysisUsage - This pass requires the CallGraph.
-    void getAnalysisUsage(AnalysisUsage &AU) const override {
-      AU.setPreservesAll();
-      AU.addRequired<CallGraphWrapperPass>();
-    }
-  };
 }
 
 char CFGSCC::ID = 0;
 static RegisterPass<CFGSCC>
 Y("print-cfg-sccs", "Print SCCs of each function CFG");
 
-char CallGraphSCC::ID = 0;
-static RegisterPass<CallGraphSCC>
-Z("print-callgraph-sccs", "Print SCCs of the Call Graph");
-
 bool CFGSCC::runOnFunction(Function &F) {
   unsigned sccNum = 0;
   errs() << "SCCs for Function " << F.getName() << " in PostOrder:";
@@ -87,25 +66,3 @@ bool CFGSCC::runOnFunction(Function &F) {
 
   return true;
 }
-
-
-// run - Print out SCCs in the call graph for the specified module.
-bool CallGraphSCC::runOnModule(Module &M) {
-  CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
-  unsigned sccNum = 0;
-  errs() << "SCCs for the program in PostOrder:";
-  for (scc_iterator<CallGraph*> SCCI = scc_begin(&CG); !SCCI.isAtEnd();
-       ++SCCI) {
-    const std::vector<CallGraphNode*> &nextSCC = *SCCI;
-    errs() << "\nSCC #" << ++sccNum << " : ";
-    for (std::vector<CallGraphNode*>::const_iterator I = nextSCC.begin(),
-           E = nextSCC.end(); I != E; ++I)
-      errs() << ((*I)->getFunction() ? (*I)->getFunction()->getName()
-                                     : "external node") << ", ";
-    if (nextSCC.size() == 1 && SCCI.hasCycle())
-      errs() << " (Has self-loop).";
-  }
-  errs() << "\n";
-
-  return true;
-}