CACAO
LoopTreePrinterPass.cpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/LoopTreePrinterPass.cpp - LoopTreePrinterPass
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 
36 
37 #include "toolbox/GraphPrinter.hpp"
38 #include "vm/class.hpp"
39 #include "vm/jit/jit.hpp"
40 
41 #include <sstream>
42 
43 namespace cacao {
44 namespace jit {
45 namespace compiler2 {
46 
47 namespace {
48 
49 class LoopTreeGraph : public PrintableGraph<Method*,Loop*> {
50 private:
51  struct insert_loop : std::unary_function<void,Loop*> {
52  LoopTreeGraph *parent;
53  explicit insert_loop(LoopTreeGraph *parent) : parent(parent) {}
54  void operator()(Loop* loop) {
55  parent->nodes.insert(loop);
56  std::for_each(loop->loop_begin(),loop->loop_end(),insert_loop(parent));
57  Loop *p = loop->get_parent();
58  if(p) {
59  parent->edges.insert(std::make_pair(loop,p));
60  }
61  }
62  };
63 public:
64 
65  LoopTreeGraph(const Method &M, LoopTree *LT, bool verbose = false) {
66  std::for_each(LT->loop_begin(),LT->loop_end(),insert_loop(this));
67  #if 0
68  for(Method::BBListTy::const_iterator i = M.bb_begin(),
69  e = M.bb_end(); i != e; ++i) {
70  BeginInst *BI = *i;
71  if (BI == NULL)
72  continue;
73  nodes.insert(BI);
74  Loop loop = LT->get_Loop(BI);
75  if (idom) {
76  EdgeType edge = std::make_pair(idom,BI);
77  edges.insert(edge);
78  }
79  }
80  #endif
81  }
82 
83  virtual OStream& getGraphName(OStream& OS) const {
84  return OS << "LoopTreeGraph";
85  }
86 
87  virtual OStream& getNodeLabel(OStream& OS, Loop *const &node) const {
88  return OS << node;
89  }
90 
91 };
92 
93 } // end anonymous namespace
94 
96  PU.add_requires<LoopPass>();
97  return PU;
98 }
99 // the address of this variable is used to identify the pass
100 char LoopTreePrinterPass::ID = 0;
101 
102 Option<bool> LoopTreePrinterPass::enabled("LoopTreePrinterPass","compiler2: enable LoopTreePrinterPass",false,::cacao::option::xx_root());
103 
104 // register pass
105 static PassRegistry<LoopTreePrinterPass> X("LoopTreePrinterPass");
106 
107 namespace {
108 std::string get_filename(methodinfo *m, jitdata *jd, std::string prefix = "cfg_", std::string suffix=".dot");
109 std::string get_filename(methodinfo *m, jitdata *jd, std::string prefix, std::string suffix)
110 {
111  std::string filename = prefix;
112  filename += Utf8String(m->clazz->name).begin();
113  filename += ".";
114  filename += Utf8String(m->name).begin();
115  filename += Utf8String(m->descriptor).begin();
116  filename += suffix;
117  /* replace unprintable chars */
118  for (size_t i = filename.find_first_of('/');
119  i != std::string::npos;
120  i = filename.find_first_of('/',i+1)) {
121  filename.replace(i,1,1,'.');
122  }
123  const char *unchar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.";
124  for (size_t i = filename.find_first_not_of(unchar);
125  i != std::string::npos;
126  i = filename.find_first_not_of(unchar,i+1)) {
127  filename.replace(i,1,1,'_');
128  }
129 
130  return filename;
131 }
132 } // end anonymous namespace
133 
134 // run pass
136  // get dominator tree
137  LoopTree *LT = get_Pass<LoopPass>();
138  assert(LT);
139  std::string name = get_filename(JD.get_jitdata()->m,JD.get_jitdata(),"looptree_");
140  GraphPrinter<LoopTreeGraph>::print(name.c_str(), LoopTreeGraph(*(JD.get_Method()),LT));
141  return true;
142 }
143 
144 } // end namespace cacao
145 } // end namespace jit
146 } // end namespace compiler2
147 
148 
149 /*
150  * These are local overrides for various environment variables in Emacs.
151  * Please do not remove this and leave it at the end of the file, where
152  * Emacs will automagically detect them.
153  * ---------------------------------------------------------------------
154  * Local variables:
155  * mode: c++
156  * indent-tabs-mode: t
157  * c-basic-offset: 4
158  * tab-width: 4
159  * End:
160  * vim:noexpandtab:sw=4:ts=4:
161  */
Utf8String name
Definition: method.hpp:71
Definition: jit.hpp:126
static void print(const char *filename, const PrintableGraphTy &G)
LoopTreeBase< BeginInst > LoopTree
Definition: Loop.hpp:38
MachineLoop * loop
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
virtual bool run(JITData &JD)
Run the Pass.
classinfo * clazz
Definition: method.hpp:80
Utf8String name
Definition: class.hpp:91
Stores the interdependencies of a pass.
Definition: PassUsage.hpp:55
MIIterator i
virtual PassUsage & get_PassUsage(PassUsage &PA) const
Set the requirements for the pass.
LoopBase< BeginInst > Loop
Definition: Loop.hpp:35
OStream & OS
MIIterator e
Calculate the Loop Tree.
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")
LoopTreeGraph * parent
void add_requires()
PassName is required.
Definition: PassUsage.hpp:78