1f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//===- RegionPrinter.cpp - Print regions tree pass ------------------------===//
2f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//
3f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//                     The LLVM Compiler Infrastructure
4f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//
5f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// This file is distributed under the University of Illinois Open Source
6f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// License. See LICENSE.TXT for details.
7f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//
8f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//===----------------------------------------------------------------------===//
9f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser// Print out the region tree of a function using dotty/graphviz.
10f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//===----------------------------------------------------------------------===//
11f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
12d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Analysis/Passes.h"
13d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/DepthFirstIterator.h"
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/PostOrderIterator.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Analysis/DOTGraphTraitsPass.h"
17f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Analysis/RegionInfo.h"
18f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Analysis/RegionIterator.h"
19f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Analysis/RegionPrinter.h"
20f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Support/CommandLine.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Debug.h"
22f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser#include "llvm/Support/raw_ostream.h"
23f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
24f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserusing namespace llvm;
25f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
26f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser//===----------------------------------------------------------------------===//
27f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser/// onlySimpleRegion - Show only the simple regions in the RegionViewer.
28f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserstatic cl::opt<bool>
29f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosseronlySimpleRegions("only-simple-regions",
30f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                  cl::desc("Show only simple regions in the graphviz viewer"),
31f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                  cl::Hidden,
32f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                  cl::init(false));
33f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
34f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grossernamespace llvm {
35f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grossertemplate<>
36f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserstruct DOTGraphTraits<RegionNode*> : public DefaultDOTGraphTraits {
37f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
38f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  DOTGraphTraits (bool isSimple=false)
39f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    : DefaultDOTGraphTraits(isSimple) {}
40f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
41f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) {
42f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
43f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (!Node->isSubRegion()) {
44f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      BasicBlock *BB = Node->getNodeAs<BasicBlock>();
45f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
46f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      if (isSimple())
47f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        return DOTGraphTraits<const Function*>
48f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser          ::getSimpleNodeLabel(BB, BB->getParent());
49f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      else
50f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        return DOTGraphTraits<const Function*>
51f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser          ::getCompleteNodeLabel(BB, BB->getParent());
52f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    }
53f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
54f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return "Not implemented";
55f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
56f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser};
57f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
58f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grossertemplate<>
59f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserstruct DOTGraphTraits<RegionInfo*> : public DOTGraphTraits<RegionNode*> {
60f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
61f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  DOTGraphTraits (bool isSimple=false)
62f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    : DOTGraphTraits<RegionNode*>(isSimple) {}
63f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
64f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  static std::string getGraphName(RegionInfo *DT) {
65f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return "Region Graph";
66f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
67f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
68f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  std::string getNodeLabel(RegionNode *Node, RegionInfo *G) {
69f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    return DOTGraphTraits<RegionNode*>::getNodeLabel(Node,
70f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                                                     G->getTopLevelRegion());
71f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
72f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
733091c92eedfbaeec352413b34f78f48889960361Tobias Grosser  std::string getEdgeAttributes(RegionNode *srcNode,
743091c92eedfbaeec352413b34f78f48889960361Tobias Grosser    GraphTraits<RegionInfo*>::ChildIteratorType CI, RegionInfo *RI) {
753091c92eedfbaeec352413b34f78f48889960361Tobias Grosser
763091c92eedfbaeec352413b34f78f48889960361Tobias Grosser    RegionNode *destNode = *CI;
773091c92eedfbaeec352413b34f78f48889960361Tobias Grosser
783091c92eedfbaeec352413b34f78f48889960361Tobias Grosser    if (srcNode->isSubRegion() || destNode->isSubRegion())
793091c92eedfbaeec352413b34f78f48889960361Tobias Grosser      return "";
803091c92eedfbaeec352413b34f78f48889960361Tobias Grosser
813091c92eedfbaeec352413b34f78f48889960361Tobias Grosser    // In case of a backedge, do not use it to define the layout of the nodes.
823091c92eedfbaeec352413b34f78f48889960361Tobias Grosser    BasicBlock *srcBB = srcNode->getNodeAs<BasicBlock>();
833091c92eedfbaeec352413b34f78f48889960361Tobias Grosser    BasicBlock *destBB = destNode->getNodeAs<BasicBlock>();
843091c92eedfbaeec352413b34f78f48889960361Tobias Grosser
853091c92eedfbaeec352413b34f78f48889960361Tobias Grosser    Region *R = RI->getRegionFor(destBB);
863091c92eedfbaeec352413b34f78f48889960361Tobias Grosser
873091c92eedfbaeec352413b34f78f48889960361Tobias Grosser    while (R && R->getParent())
883091c92eedfbaeec352413b34f78f48889960361Tobias Grosser      if (R->getParent()->getEntry() == destBB)
893091c92eedfbaeec352413b34f78f48889960361Tobias Grosser        R = R->getParent();
903091c92eedfbaeec352413b34f78f48889960361Tobias Grosser      else
913091c92eedfbaeec352413b34f78f48889960361Tobias Grosser        break;
923091c92eedfbaeec352413b34f78f48889960361Tobias Grosser
933091c92eedfbaeec352413b34f78f48889960361Tobias Grosser    if (R->getEntry() == destBB && R->contains(srcBB))
943091c92eedfbaeec352413b34f78f48889960361Tobias Grosser      return "constraint=false";
953091c92eedfbaeec352413b34f78f48889960361Tobias Grosser
963091c92eedfbaeec352413b34f78f48889960361Tobias Grosser    return "";
973091c92eedfbaeec352413b34f78f48889960361Tobias Grosser  }
983091c92eedfbaeec352413b34f78f48889960361Tobias Grosser
99f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // Print the cluster of the subregions. This groups the single basic blocks
100f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  // and adds a different background color for each group.
101f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  static void printRegionCluster(const Region *R, GraphWriter<RegionInfo*> &GW,
102f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                                 unsigned depth = 0) {
103f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    raw_ostream &O = GW.getOStream();
104f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(R)
105f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      << " {\n";
106f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    O.indent(2 * (depth + 1)) << "label = \"\";\n";
107f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
108f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    if (!onlySimpleRegions || R->isSimple()) {
109f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      O.indent(2 * (depth + 1)) << "style = filled;\n";
110f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      O.indent(2 * (depth + 1)) << "color = "
111f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        << ((R->getDepth() * 2 % 12) + 1) << "\n";
112f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
113f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    } else {
114f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      O.indent(2 * (depth + 1)) << "style = solid;\n";
115f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      O.indent(2 * (depth + 1)) << "color = "
116f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        << ((R->getDepth() * 2 % 12) + 2) << "\n";
117f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    }
118f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
119f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI)
120f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser      printRegionCluster(*RI, GW, depth + 1);
121f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
122f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    RegionInfo *RI = R->getRegionInfo();
123f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
124f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    for (Region::const_block_iterator BI = R->block_begin(),
1257c52c97a2232756bbcc2fb4e664892bdb8b2d90cChandler Carruth         BE = R->block_end(); BI != BE; ++BI)
1267c52c97a2232756bbcc2fb4e664892bdb8b2d90cChandler Carruth      if (RI->getRegionFor(*BI) == R)
127f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser        O.indent(2 * (depth + 1)) << "Node"
1287c52c97a2232756bbcc2fb4e664892bdb8b2d90cChandler Carruth          << static_cast<const void*>(RI->getTopLevelRegion()->getBBNode(*BI))
129f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser          << ";\n";
130f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
131f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    O.indent(2 * depth) << "}\n";
132f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
133f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
134f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  static void addCustomGraphFeatures(const RegionInfo* RI,
135f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                                     GraphWriter<RegionInfo*> &GW) {
136f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    raw_ostream &O = GW.getOStream();
137f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    O << "\tcolorscheme = \"paired12\"\n";
138f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser    printRegionCluster(RI->getTopLevelRegion(), GW, 4);
139f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  }
140f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser};
141f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser} //end namespace llvm
142f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
143f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grossernamespace {
144f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
145f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserstruct RegionViewer
146f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  : public DOTGraphTraitsViewer<RegionInfo, false> {
147f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  static char ID;
148081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson  RegionViewer() : DOTGraphTraitsViewer<RegionInfo, false>("reg", ID){
149081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    initializeRegionViewerPass(*PassRegistry::getPassRegistry());
150081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson  }
151f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser};
152f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserchar RegionViewer::ID = 0;
153f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
154f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserstruct RegionOnlyViewer
155f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  : public DOTGraphTraitsViewer<RegionInfo, true> {
156f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  static char ID;
157081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson  RegionOnlyViewer() : DOTGraphTraitsViewer<RegionInfo, true>("regonly", ID) {
158081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    initializeRegionOnlyViewerPass(*PassRegistry::getPassRegistry());
159081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson  }
160f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser};
161f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserchar RegionOnlyViewer::ID = 0;
162f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
163f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserstruct RegionPrinter
164f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  : public DOTGraphTraitsPrinter<RegionInfo, false> {
165f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  static char ID;
166f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  RegionPrinter() :
167081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    DOTGraphTraitsPrinter<RegionInfo, false>("reg", ID) {
168081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson      initializeRegionPrinterPass(*PassRegistry::getPassRegistry());
169081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    }
170f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser};
17171802344fcb224a89e4e636c1ec47f3730969be7Owen Andersonchar RegionPrinter::ID = 0;
172f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser} //end anonymous namespace
173f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
174f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserINITIALIZE_PASS(RegionPrinter, "dot-regions",
175ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson                "Print regions of function to 'dot' file", true, true)
176f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
17771802344fcb224a89e4e636c1ec47f3730969be7Owen AndersonINITIALIZE_PASS(RegionViewer, "view-regions", "View regions of function",
178ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson                true, true)
17971802344fcb224a89e4e636c1ec47f3730969be7Owen Anderson
18071802344fcb224a89e4e636c1ec47f3730969be7Owen AndersonINITIALIZE_PASS(RegionOnlyViewer, "view-regions-only",
18171802344fcb224a89e4e636c1ec47f3730969be7Owen Anderson                "View regions of function (with no function bodies)",
182ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson                true, true)
18371802344fcb224a89e4e636c1ec47f3730969be7Owen Anderson
184811edc1f1a0672d28cd7c938e478a92543e68a51Dan Gohmannamespace {
185811edc1f1a0672d28cd7c938e478a92543e68a51Dan Gohman
186f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserstruct RegionOnlyPrinter
187f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  : public DOTGraphTraitsPrinter<RegionInfo, true> {
188f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  static char ID;
189f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  RegionOnlyPrinter() :
190081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    DOTGraphTraitsPrinter<RegionInfo, true>("reg", ID) {
191081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson      initializeRegionOnlyPrinterPass(*PassRegistry::getPassRegistry());
192081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    }
193f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser};
194f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
195811edc1f1a0672d28cd7c938e478a92543e68a51Dan Gohman}
196811edc1f1a0672d28cd7c938e478a92543e68a51Dan Gohman
197f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosserchar RegionOnlyPrinter::ID = 0;
198f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserINITIALIZE_PASS(RegionOnlyPrinter, "dot-regions-only",
199f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                "Print regions of function to 'dot' file "
200f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser                "(with no function bodies)",
201ce665bd2e2b581ab0858d1afe359192bac96b868Owen Anderson                true, true)
202f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
203f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserFunctionPass* llvm::createRegionViewerPass() {
204f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return new RegionViewer();
205f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
206f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
207f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserFunctionPass* llvm::createRegionOnlyViewerPass() {
208f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return new RegionOnlyViewer();
209f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
210f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
211f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserFunctionPass* llvm::createRegionPrinterPass() {
212f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return new RegionPrinter();
213f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
214f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
215f96b0063674e6bf72da5429bd49097e33c2325c7Tobias GrosserFunctionPass* llvm::createRegionOnlyPrinterPass() {
216f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser  return new RegionOnlyPrinter();
217f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser}
218f96b0063674e6bf72da5429bd49097e33c2325c7Tobias Grosser
219