CACAO
DomTreePrinterPass.cpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/DomTreePrinterPass.cpp - DomTreePrinterPass
2 
3  Copyright (C) 2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
31 
35 
36 #include "toolbox/GraphPrinter.hpp"
37 #include "vm/class.hpp"
38 #include "vm/jit/jit.hpp"
39 
40 #include <sstream>
41 
42 namespace cacao {
43 namespace jit {
44 namespace compiler2 {
45 
46 namespace {
47 
48 class DomTreeGraph : public PrintableGraph<Method*,BeginInst*> {
49 protected:
50  const Method &M;
51  bool verbose;
52  DominatorTree &DT;
53  const DFSTraversal<BeginInst> dfs;
54 
55 public:
56 
57  DomTreeGraph(const Method &M, DominatorTree &DT, bool verbose = false) :
58  M(M), verbose(verbose), DT(DT), dfs(M.get_init_bb()) {
59  for(Method::BBListTy::const_iterator i = M.bb_begin(),
60  e = M.bb_end(); i != e; ++i) {
61  BeginInst *BI = *i;
62  if (BI == NULL)
63  continue;
64  nodes.insert(BI);
65  BeginInst *idom = DT.get_idominator(BI);
66  if (idom) {
67  EdgeType edge = std::make_pair(idom,BI);
68  edges.insert(edge);
69  }
70  }
71  }
72 
73  virtual OStream& getGraphName(OStream& OS) const {
74  return OS << "DomTreeGraph";
75  }
76 
77  virtual OStream& getNodeLabel(OStream& OS, BeginInst *const &node) const {
78  return OS << *node;
79  }
80 
81 };
82 
83 } // end anonymous namespace
84 
87  return PU;
88 }
89 // the address of this variable is used to identify the pass
90 char DomTreePrinterPass::ID = 0;
91 
92 Option<bool> DomTreePrinterPass::enabled("DomTreePrinterPass","compiler2: enable DomTreePrinterPass",false,::cacao::option::xx_root());
93 
94 // register pass
95 static PassRegistry<DomTreePrinterPass> X("DomTreePrinterPass");
96 
97 namespace {
98 std::string get_filename(methodinfo *m, jitdata *jd, std::string prefix = "cfg_", std::string suffix=".dot");
99 std::string get_filename(methodinfo *m, jitdata *jd, std::string prefix, std::string suffix)
100 {
101  std::string filename = prefix;
102  filename += Utf8String(m->clazz->name).begin();
103  filename += ".";
104  filename += Utf8String(m->name).begin();
105  filename += Utf8String(m->descriptor).begin();
106  filename += suffix;
107  /* replace unprintable chars */
108  for (size_t i = filename.find_first_of('/');
109  i != std::string::npos;
110  i = filename.find_first_of('/',i+1)) {
111  filename.replace(i,1,1,'.');
112  }
113  const char *unchar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.";
114  for (size_t i = filename.find_first_not_of(unchar);
115  i != std::string::npos;
116  i = filename.find_first_not_of(unchar,i+1)) {
117  filename.replace(i,1,1,'_');
118  }
119 
120  return filename;
121 }
122 } // end anonymous namespace
123 
124 // run pass
126  // get dominator tree
127  DominatorTree *DT = get_Pass<DominatorPass>();
128  assert(DT);
129  std::string name = get_filename(JD.get_jitdata()->m,JD.get_jitdata(),"domtree_");
130  GraphPrinter<DomTreeGraph>::print(name.c_str(), DomTreeGraph(*(JD.get_Method()),*DT));
131  return true;
132 }
133 
134 } // end namespace cacao
135 } // end namespace jit
136 } // end namespace compiler2
137 
138 
139 /*
140  * These are local overrides for various environment variables in Emacs.
141  * Please do not remove this and leave it at the end of the file, where
142  * Emacs will automagically detect them.
143  * ---------------------------------------------------------------------
144  * Local variables:
145  * mode: c++
146  * indent-tabs-mode: t
147  * c-basic-offset: 4
148  * tab-width: 4
149  * End:
150  * vim:noexpandtab:sw=4:ts=4:
151  */
Utf8String name
Definition: method.hpp:71
virtual PassUsage & get_PassUsage(PassUsage &PU) const
Set the requirements for the pass.
Definition: jit.hpp:126
DominatorTree & DT
static void print(const char *filename, const PrintableGraphTy &G)
const DFSTraversal< BeginInst > dfs
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
jitdata * get_jitdata() const
Definition: JITData.hpp:51
std::set< EdgeType > & edges
Utf8String descriptor
Definition: method.hpp:72
classinfo * clazz
Definition: method.hpp:80
Utf8String name
Definition: class.hpp:91
Stores the interdependencies of a pass.
Definition: PassUsage.hpp:55
MIIterator i
OStream & OS
virtual bool run(JITData &JD)
Run the Pass.
MIIterator e
bool verbose
byte_iterator begin() const
Definition: utf8.hpp:106
methodinfo * m
Definition: jit.hpp:127
OptionPrefix & xx_root()
Definition: Option.cpp:39
const Method & M
static PassRegistry< BasicBlockSchedulingPass > X("BasicBlockSchedulingPass")
void add_requires()
PassName is required.
Definition: PassUsage.hpp:78
Calculate the Dominator Tree.