X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FRegionPrinter.cpp;h=acb218d5fea08f3e22e0a7d57c43055f09d2fd45;hb=44fb5881d8edf448d6231a5b8df583aecd6bcd42;hp=f39a08c57326925fd92d78c713ec90ae682605d3;hpb=71802344fcb224a89e4e636c1ec47f3730969be7;p=oota-llvm.git diff --git a/lib/Analysis/RegionPrinter.cpp b/lib/Analysis/RegionPrinter.cpp index f39a08c5732..acb218d5fea 100644 --- a/lib/Analysis/RegionPrinter.cpp +++ b/lib/Analysis/RegionPrinter.cpp @@ -9,17 +9,20 @@ // Print out the region tree of a function using dotty/graphviz. //===----------------------------------------------------------------------===// +#include "llvm/Analysis/Passes.h" +#include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/PostOrderIterator.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/DOTGraphTraitsPass.h" #include "llvm/Analysis/RegionInfo.h" #include "llvm/Analysis/RegionIterator.h" #include "llvm/Analysis/RegionPrinter.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/DOTGraphTraitsPass.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/PostOrderIterator.h" -#include "llvm/ADT/DepthFirstIterator.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#ifndef NDEBUG +#include "llvm/IR/LegacyPassManager.h" +#endif using namespace llvm; @@ -55,119 +58,167 @@ struct DOTGraphTraits : public DefaultDOTGraphTraits { } }; -template<> -struct DOTGraphTraits : public DOTGraphTraits { +template <> +struct DOTGraphTraits : public DOTGraphTraits { - DOTGraphTraits (bool isSimple=false) + DOTGraphTraits (bool isSimple = false) : DOTGraphTraits(isSimple) {} - static std::string getGraphName(RegionInfo *DT) { - return "Region Graph"; - } + static std::string getGraphName(const RegionInfo *) { return "Region Graph"; } std::string getNodeLabel(RegionNode *Node, RegionInfo *G) { - return DOTGraphTraits::getNodeLabel(Node, - G->getTopLevelRegion()); + return DOTGraphTraits::getNodeLabel( + Node, reinterpret_cast(G->getTopLevelRegion())); + } + + std::string getEdgeAttributes(RegionNode *srcNode, + GraphTraits::ChildIteratorType CI, + RegionInfo *G) { + RegionNode *destNode = *CI; + + if (srcNode->isSubRegion() || destNode->isSubRegion()) + return ""; + + // In case of a backedge, do not use it to define the layout of the nodes. + BasicBlock *srcBB = srcNode->getNodeAs(); + BasicBlock *destBB = destNode->getNodeAs(); + + Region *R = G->getRegionFor(destBB); + + while (R && R->getParent()) + if (R->getParent()->getEntry() == destBB) + R = R->getParent(); + else + break; + + if (R && R->getEntry() == destBB && R->contains(srcBB)) + return "constraint=false"; + + return ""; } // Print the cluster of the subregions. This groups the single basic blocks // and adds a different background color for each group. - static void printRegionCluster(const Region *R, GraphWriter &GW, + static void printRegionCluster(const Region &R, GraphWriter &GW, unsigned depth = 0) { raw_ostream &O = GW.getOStream(); - O.indent(2 * depth) << "subgraph cluster_" << static_cast(R) + O.indent(2 * depth) << "subgraph cluster_" << static_cast(&R) << " {\n"; O.indent(2 * (depth + 1)) << "label = \"\";\n"; - if (!onlySimpleRegions || R->isSimple()) { + if (!onlySimpleRegions || R.isSimple()) { O.indent(2 * (depth + 1)) << "style = filled;\n"; O.indent(2 * (depth + 1)) << "color = " - << ((R->getDepth() * 2 % 12) + 1) << "\n"; + << ((R.getDepth() * 2 % 12) + 1) << "\n"; } else { O.indent(2 * (depth + 1)) << "style = solid;\n"; O.indent(2 * (depth + 1)) << "color = " - << ((R->getDepth() * 2 % 12) + 2) << "\n"; + << ((R.getDepth() * 2 % 12) + 2) << "\n"; } - for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI) - printRegionCluster(*RI, GW, depth + 1); + for (Region::const_iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI) + printRegionCluster(**RI, GW, depth + 1); - RegionInfo *RI = R->getRegionInfo(); + const RegionInfo &RI = *static_cast(R.getRegionInfo()); - for (Region::const_block_iterator BI = R->block_begin(), - BE = R->block_end(); BI != BE; ++BI) { - BasicBlock *BB = (*BI)->getNodeAs(); - if (RI->getRegionFor(BB) == R) + for (auto *BB : R.blocks()) + if (RI.getRegionFor(BB) == &R) O.indent(2 * (depth + 1)) << "Node" - << static_cast(RI->getTopLevelRegion()->getBBNode(BB)) + << static_cast(RI.getTopLevelRegion()->getBBNode(BB)) << ";\n"; - } O.indent(2 * depth) << "}\n"; } - static void addCustomGraphFeatures(const RegionInfo* RI, - GraphWriter &GW) { + static void addCustomGraphFeatures(const RegionInfo *G, + GraphWriter &GW) { raw_ostream &O = GW.getOStream(); O << "\tcolorscheme = \"paired12\"\n"; - printRegionCluster(RI->getTopLevelRegion(), GW, 4); + printRegionCluster(*G->getTopLevelRegion(), GW, 4); } }; } //end namespace llvm namespace { +struct RegionInfoPassGraphTraits { + static RegionInfo *getGraph(RegionInfoPass *RIP) { + return &RIP->getRegionInfo(); + } +}; + +struct RegionPrinter + : public DOTGraphTraitsPrinter { + static char ID; + RegionPrinter() + : DOTGraphTraitsPrinter("reg", ID) { + initializeRegionPrinterPass(*PassRegistry::getPassRegistry()); + } +}; +char RegionPrinter::ID = 0; + +struct RegionOnlyPrinter + : public DOTGraphTraitsPrinter { + static char ID; + RegionOnlyPrinter() + : DOTGraphTraitsPrinter("reg", ID) { + initializeRegionOnlyPrinterPass(*PassRegistry::getPassRegistry()); + } +}; +char RegionOnlyPrinter::ID = 0; + struct RegionViewer - : public DOTGraphTraitsViewer { + : public DOTGraphTraitsViewer { static char ID; - RegionViewer() : DOTGraphTraitsViewer("reg", ID){} + RegionViewer() + : DOTGraphTraitsViewer("reg", ID) { + initializeRegionViewerPass(*PassRegistry::getPassRegistry()); + } }; char RegionViewer::ID = 0; struct RegionOnlyViewer - : public DOTGraphTraitsViewer { + : public DOTGraphTraitsViewer { static char ID; - RegionOnlyViewer() : DOTGraphTraitsViewer("regonly", ID){} + RegionOnlyViewer() + : DOTGraphTraitsViewer("regonly", ID) { + initializeRegionOnlyViewerPass(*PassRegistry::getPassRegistry()); + } }; char RegionOnlyViewer::ID = 0; -struct RegionPrinter - : public DOTGraphTraitsPrinter { - static char ID; - RegionPrinter() : - DOTGraphTraitsPrinter("reg", ID) {} -}; -char RegionPrinter::ID = 0; } //end anonymous namespace INITIALIZE_PASS(RegionPrinter, "dot-regions", - "Print regions of function to 'dot' file", true, true); + "Print regions of function to 'dot' file", true, true) + +INITIALIZE_PASS( + RegionOnlyPrinter, "dot-regions-only", + "Print regions of function to 'dot' file (with no function bodies)", true, + true) INITIALIZE_PASS(RegionViewer, "view-regions", "View regions of function", - true, true); - + true, true) + INITIALIZE_PASS(RegionOnlyViewer, "view-regions-only", "View regions of function (with no function bodies)", - true, true); + true, true) -namespace { - -struct RegionOnlyPrinter - : public DOTGraphTraitsPrinter { - static char ID; - RegionOnlyPrinter() : - DOTGraphTraitsPrinter("reg", ID) {} -}; +FunctionPass *llvm::createRegionPrinterPass() { return new RegionPrinter(); } +FunctionPass *llvm::createRegionOnlyPrinterPass() { + return new RegionOnlyPrinter(); } -char RegionOnlyPrinter::ID = 0; -INITIALIZE_PASS(RegionOnlyPrinter, "dot-regions-only", - "Print regions of function to 'dot' file " - "(with no function bodies)", - true, true); - FunctionPass* llvm::createRegionViewerPass() { return new RegionViewer(); } @@ -176,11 +227,41 @@ FunctionPass* llvm::createRegionOnlyViewerPass() { return new RegionOnlyViewer(); } -FunctionPass* llvm::createRegionPrinterPass() { - return new RegionPrinter(); +#ifndef NDEBUG +static void viewRegionInfo(RegionInfo *RI, bool ShortNames) { + assert(RI && "Argument must be non-null"); + + llvm::Function *F = RI->getTopLevelRegion()->getEntry()->getParent(); + std::string GraphName = DOTGraphTraits::getGraphName(RI); + + llvm::ViewGraph(RI, "reg", ShortNames, + Twine(GraphName) + " for '" + F->getName() + "' function"); +} + +static void invokeFunctionPass(const Function *F, FunctionPass *ViewerPass) { + assert(F && "Argument must be non-null"); + assert(!F->isDeclaration() && "Function must have an implementation"); + + // The viewer and analysis passes do not modify anything, so we can safely + // remove the const qualifier + auto NonConstF = const_cast(F); + + llvm::legacy::FunctionPassManager FPM(NonConstF->getParent()); + FPM.add(ViewerPass); + FPM.doInitialization(); + FPM.run(*NonConstF); + FPM.doFinalization(); } -FunctionPass* llvm::createRegionOnlyPrinterPass() { - return new RegionOnlyPrinter(); +void llvm::viewRegion(RegionInfo *RI) { viewRegionInfo(RI, false); } + +void llvm::viewRegion(const Function *F) { + invokeFunctionPass(F, createRegionViewerPass()); } +void llvm::viewRegionOnly(RegionInfo *RI) { viewRegionInfo(RI, true); } + +void llvm::viewRegionOnly(const Function *F) { + invokeFunctionPass(F, createRegionOnlyViewerPass()); +} +#endif