X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fopt%2FPrintSCC.cpp;h=a0aa4e90e7f9fd1faa234d9cda371d6e9bb44064;hb=b6dec1bdd6f6d33310879e6bbc3120f719c97483;hp=7affce61317fddb1088246f752b7e01ff3fb0f74;hpb=6c5fd8e0551f99ce46908fedd502b0dbf5864c74;p=oota-llvm.git diff --git a/tools/opt/PrintSCC.cpp b/tools/opt/PrintSCC.cpp index 7affce61317..a0aa4e90e7f 100644 --- a/tools/opt/PrintSCC.cpp +++ b/tools/opt/PrintSCC.cpp @@ -1,19 +1,27 @@ //===- PrintSCC.cpp - Enumerate SCCs in some key graphs -------------------===// // +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// // This file provides passes to print out SCCs in a CFG or a CallGraph. // Normally, you would not use these passes; instead, you would use the -// TarjanSCCIterator directly to enumerate SCCs and process them in some way. -// These passes serve three purposes: -// (1) As a reference for how to use the TarjanSCCIterator. +// scc_iterator directly to enumerate SCCs and process them in some way. These +// passes serve three purposes: +// +// (1) As a reference for how to use the scc_iterator. // (2) To print out the SCCs for a CFG or a CallGraph: -// analyze -cfgscc to print the SCCs in each CFG of a module. -// analyze -cfgscc -stats to print the #SCCs and the maximum SCC size. -// analyze -cfgscc -debug > /dev/null to watch the algorithm in action. -// +// analyze -print-cfg-sccs to print the SCCs in each CFG of a module. +// analyze -print-cfg-sccs -stats to print the #SCCs and the maximum SCC size. +// analyze -print-cfg-sccs -debug > /dev/null to watch the algorithm in action. +// // and similarly: -// analyze -callscc [-stats] [-debug] to print SCCs in the CallGraph -// -// (3) To test the TarjanSCCIterator. +// analyze -print-callgraph-sccs [-stats] [-debug] to print SCCs in the CallGraph +// +// (3) To test the scc_iterator. // //===----------------------------------------------------------------------===// @@ -21,24 +29,31 @@ #include "llvm/Module.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Support/CFG.h" -#include "Support/TarjanSCCIterator.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/SCCIterator.h" +using namespace llvm; namespace { struct CFGSCC : public FunctionPass { + static char ID; // Pass identification, replacement for typeid + CFGSCC() : FunctionPass(&ID) {} bool runOnFunction(Function& func); - void print(std::ostream &O) const { } + void print(std::ostream &O, const Module* = 0) const { } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } }; - struct CallGraphSCC : public Pass { + 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 run(Module &M); + bool runOnModule(Module &M); - void print(std::ostream &O) const { } + void print(std::ostream &O, const Module* = 0) const { } // getAnalysisUsage - This pass requires the CallGraph. virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -47,49 +62,51 @@ namespace { } }; - RegisterAnalysis - Y("cfgscc", "Print SCCs of each function CFG"); + char CFGSCC::ID = 0; + RegisterPass + Y("print-cfg-sccs", "Print SCCs of each function CFG"); - RegisterAnalysis - Z("callscc", "Print SCCs of the Call Graph"); + char CallGraphSCC::ID = 0; + RegisterPass + Z("print-callgraph-sccs", "Print SCCs of the Call Graph"); } bool CFGSCC::runOnFunction(Function &F) { unsigned sccNum = 0; - std::cout << "SCCs for Function " << F.getName() << " in PostOrder:"; - for (TarjanSCC_iterator I = tarj_begin(&F), - E = tarj_end(&F); I != E; ++I) { - SCC &nextSCC = *I; - std::cout << "\nSCC #" << ++sccNum << " : "; - for (SCC::const_iterator I = nextSCC.begin(), + outs() << "SCCs for Function " << F.getName() << " in PostOrder:"; + for (scc_iterator SCCI = scc_begin(&F), + E = scc_end(&F); SCCI != E; ++SCCI) { + std::vector &nextSCC = *SCCI; + outs() << "\nSCC #" << ++sccNum << " : "; + for (std::vector::const_iterator I = nextSCC.begin(), E = nextSCC.end(); I != E; ++I) - std::cout << (*I)->getName() << ", "; - if (nextSCC.size() == 1 && nextSCC.HasLoop()) - std::cout << " (Has self-loop)."; + outs() << (*I)->getName() << ", "; + if (nextSCC.size() == 1 && SCCI.hasLoop()) + outs() << " (Has self-loop)."; } - std::cout << "\n"; + outs() << "\n"; return true; } // run - Print out SCCs in the call graph for the specified module. -bool CallGraphSCC::run(Module &M) { +bool CallGraphSCC::runOnModule(Module &M) { CallGraphNode* rootNode = getAnalysis().getRoot(); unsigned sccNum = 0; - std::cout << "SCCs for the program in PostOrder:"; - for (TarjanSCC_iterator SCCI = tarj_begin(rootNode), - E = tarj_end(rootNode); SCCI != E; ++SCCI) { - const SCC &nextSCC = *SCCI; - std::cout << "\nSCC #" << ++sccNum << " : "; - for (SCC::const_iterator I = nextSCC.begin(), + outs() << "SCCs for the program in PostOrder:"; + for (scc_iterator SCCI = scc_begin(rootNode), + E = scc_end(rootNode); SCCI != E; ++SCCI) { + const std::vector &nextSCC = *SCCI; + outs() << "\nSCC #" << ++sccNum << " : "; + for (std::vector::const_iterator I = nextSCC.begin(), E = nextSCC.end(); I != E; ++I) - std::cout << ((*I)->getFunction() ? (*I)->getFunction()->getName() - : std::string("Indirect CallGraph node")) << ", "; - if (nextSCC.size() == 1 && nextSCC.HasLoop()) - std::cout << " (Has self-loop)."; + outs() << ((*I)->getFunction() ? (*I)->getFunction()->getNameStr() + : std::string("Indirect CallGraph node")) << ", "; + if (nextSCC.size() == 1 && SCCI.hasLoop()) + outs() << " (Has self-loop)."; } - std::cout << "\n"; + outs() << "\n"; return true; }