~ubuntu-branches/ubuntu/feisty/clamav/feisty

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/Analysis/RegionPrinter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-02-20 10:33:44 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20070220103344-zgcu2psnx9d98fpa
Tags: upstream-0.90
ImportĀ upstreamĀ versionĀ 0.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//===- RegionPrinter.cpp - Print regions tree pass ------------------------===//
2
 
//
3
 
//                     The LLVM Compiler Infrastructure
4
 
//
5
 
// This file is distributed under the University of Illinois Open Source
6
 
// License. See LICENSE.TXT for details.
7
 
//
8
 
//===----------------------------------------------------------------------===//
9
 
// Print out the region tree of a function using dotty/graphviz.
10
 
//===----------------------------------------------------------------------===//
11
 
 
12
 
#include "llvm/Analysis/RegionInfo.h"
13
 
#include "llvm/Analysis/RegionIterator.h"
14
 
#include "llvm/Analysis/RegionPrinter.h"
15
 
#include "llvm/Analysis/Passes.h"
16
 
#include "llvm/Analysis/DOTGraphTraitsPass.h"
17
 
#include "llvm/ADT/Statistic.h"
18
 
#include "llvm/ADT/PostOrderIterator.h"
19
 
#include "llvm/ADT/DepthFirstIterator.h"
20
 
#include "llvm/Support/Debug.h"
21
 
#include "llvm/Support/CommandLine.h"
22
 
#include "llvm/Support/raw_ostream.h"
23
 
 
24
 
using namespace llvm;
25
 
 
26
 
//===----------------------------------------------------------------------===//
27
 
/// onlySimpleRegion - Show only the simple regions in the RegionViewer.
28
 
static cl::opt<bool>
29
 
onlySimpleRegions("only-simple-regions",
30
 
                  cl::desc("Show only simple regions in the graphviz viewer"),
31
 
                  cl::Hidden,
32
 
                  cl::init(false));
33
 
 
34
 
namespace llvm {
35
 
template<>
36
 
struct DOTGraphTraits<RegionNode*> : public DefaultDOTGraphTraits {
37
 
 
38
 
  DOTGraphTraits (bool isSimple=false)
39
 
    : DefaultDOTGraphTraits(isSimple) {}
40
 
 
41
 
  std::string getNodeLabel(RegionNode *Node, RegionNode *Graph) {
42
 
 
43
 
    if (!Node->isSubRegion()) {
44
 
      BasicBlock *BB = Node->getNodeAs<BasicBlock>();
45
 
 
46
 
      if (isSimple())
47
 
        return DOTGraphTraits<const Function*>
48
 
          ::getSimpleNodeLabel(BB, BB->getParent());
49
 
      else
50
 
        return DOTGraphTraits<const Function*>
51
 
          ::getCompleteNodeLabel(BB, BB->getParent());
52
 
    }
53
 
 
54
 
    return "Not implemented";
55
 
  }
56
 
};
57
 
 
58
 
template<>
59
 
struct DOTGraphTraits<RegionInfo*> : public DOTGraphTraits<RegionNode*> {
60
 
 
61
 
  DOTGraphTraits (bool isSimple=false)
62
 
    : DOTGraphTraits<RegionNode*>(isSimple) {}
63
 
 
64
 
  static std::string getGraphName(RegionInfo *DT) {
65
 
    return "Region Graph";
66
 
  }
67
 
 
68
 
  std::string getNodeLabel(RegionNode *Node, RegionInfo *G) {
69
 
    return DOTGraphTraits<RegionNode*>::getNodeLabel(Node,
70
 
                                                     G->getTopLevelRegion());
71
 
  }
72
 
 
73
 
  // Print the cluster of the subregions. This groups the single basic blocks
74
 
  // and adds a different background color for each group.
75
 
  static void printRegionCluster(const Region *R, GraphWriter<RegionInfo*> &GW,
76
 
                                 unsigned depth = 0) {
77
 
    raw_ostream &O = GW.getOStream();
78
 
    O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(R)
79
 
      << " {\n";
80
 
    O.indent(2 * (depth + 1)) << "label = \"\";\n";
81
 
 
82
 
    if (!onlySimpleRegions || R->isSimple()) {
83
 
      O.indent(2 * (depth + 1)) << "style = filled;\n";
84
 
      O.indent(2 * (depth + 1)) << "color = "
85
 
        << ((R->getDepth() * 2 % 12) + 1) << "\n";
86
 
 
87
 
    } else {
88
 
      O.indent(2 * (depth + 1)) << "style = solid;\n";
89
 
      O.indent(2 * (depth + 1)) << "color = "
90
 
        << ((R->getDepth() * 2 % 12) + 2) << "\n";
91
 
    }
92
 
 
93
 
    for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI)
94
 
      printRegionCluster(*RI, GW, depth + 1);
95
 
 
96
 
    RegionInfo *RI = R->getRegionInfo();
97
 
 
98
 
    for (Region::const_block_iterator BI = R->block_begin(),
99
 
         BE = R->block_end(); BI != BE; ++BI) {
100
 
      BasicBlock *BB = (*BI)->getNodeAs<BasicBlock>();
101
 
      if (RI->getRegionFor(BB) == R)
102
 
        O.indent(2 * (depth + 1)) << "Node"
103
 
          << static_cast<const void*>(RI->getTopLevelRegion()->getBBNode(BB))
104
 
          << ";\n";
105
 
    }
106
 
 
107
 
    O.indent(2 * depth) << "}\n";
108
 
  }
109
 
 
110
 
  static void addCustomGraphFeatures(const RegionInfo* RI,
111
 
                                     GraphWriter<RegionInfo*> &GW) {
112
 
    raw_ostream &O = GW.getOStream();
113
 
    O << "\tcolorscheme = \"paired12\"\n";
114
 
    printRegionCluster(RI->getTopLevelRegion(), GW, 4);
115
 
  }
116
 
};
117
 
} //end namespace llvm
118
 
 
119
 
namespace {
120
 
 
121
 
struct RegionViewer
122
 
  : public DOTGraphTraitsViewer<RegionInfo, false> {
123
 
  static char ID;
124
 
  RegionViewer() : DOTGraphTraitsViewer<RegionInfo, false>("reg", ID){}
125
 
};
126
 
 
127
 
char RegionViewer::ID = 0;
128
 
INITIALIZE_PASS(RegionViewer, "view-regions", "View regions of function",
129
 
                true, true);
130
 
 
131
 
struct RegionOnlyViewer
132
 
  : public DOTGraphTraitsViewer<RegionInfo, true> {
133
 
  static char ID;
134
 
  RegionOnlyViewer() : DOTGraphTraitsViewer<RegionInfo, true>("regonly", ID){}
135
 
};
136
 
 
137
 
char RegionOnlyViewer::ID = 0;
138
 
INITIALIZE_PASS(RegionOnlyViewer, "view-regions-only",
139
 
                "View regions of function (with no function bodies)",
140
 
                true, true);
141
 
 
142
 
struct RegionPrinter
143
 
  : public DOTGraphTraitsPrinter<RegionInfo, false> {
144
 
  static char ID;
145
 
  RegionPrinter() :
146
 
    DOTGraphTraitsPrinter<RegionInfo, false>("reg", ID) {}
147
 
};
148
 
} //end anonymous namespace
149
 
 
150
 
char RegionPrinter::ID = 0;
151
 
INITIALIZE_PASS(RegionPrinter, "dot-regions",
152
 
                "Print regions of function to 'dot' file", true, true);
153
 
 
154
 
namespace {
155
 
 
156
 
struct RegionOnlyPrinter
157
 
  : public DOTGraphTraitsPrinter<RegionInfo, true> {
158
 
  static char ID;
159
 
  RegionOnlyPrinter() :
160
 
    DOTGraphTraitsPrinter<RegionInfo, true>("reg", ID) {}
161
 
};
162
 
 
163
 
}
164
 
 
165
 
char RegionOnlyPrinter::ID = 0;
166
 
INITIALIZE_PASS(RegionOnlyPrinter, "dot-regions-only",
167
 
                "Print regions of function to 'dot' file "
168
 
                "(with no function bodies)",
169
 
                true, true);
170
 
 
171
 
FunctionPass* llvm::createRegionViewerPass() {
172
 
  return new RegionViewer();
173
 
}
174
 
 
175
 
FunctionPass* llvm::createRegionOnlyViewerPass() {
176
 
  return new RegionOnlyViewer();
177
 
}
178
 
 
179
 
FunctionPass* llvm::createRegionPrinterPass() {
180
 
  return new RegionPrinter();
181
 
}
182
 
 
183
 
FunctionPass* llvm::createRegionOnlyPrinterPass() {
184
 
  return new RegionOnlyPrinter();
185
 
}
186