CACAO
PassDependencyGraphPrinter.cpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/PassDependencyGraphPrinter.cpp - PassDependencyGraphPrinter
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 
26 #include "toolbox/GraphPrinter.hpp"
30 #include "toolbox/logging.hpp"
31 #include <algorithm>
34 
35 #define DEBUG_NAME "compiler2/PassDependencyGraphPrinter"
36 
37 namespace cacao {
38 namespace jit {
39 namespace compiler2 {
40 
41 namespace {
42 
43 struct AddEdge : public std::unary_function<PassInfo::IDTy,void> {
44  typedef std::pair<argument_type,argument_type> EdgeType;
45  std::set<EdgeType> &edges;
46  alloc::set<EdgeType>::type &set;
47  argument_type from;
48  bool reverse;
49  // constructor
50  AddEdge(std::set<EdgeType> &edges, alloc::set<EdgeType>::type &set, argument_type from, bool reverse=false)
51  : edges(edges), set(set), from(from), reverse(reverse) {}
52  // call operator
53  void operator()(const argument_type &to) {
54  EdgeType edge;
55  if (reverse) {
56  edge = std::make_pair(to,from);
57  }
58  else {
59  edge = std::make_pair(from,to);
60  }
61  edges.insert(edge);
62  set.insert(edge);
63  }
64 };
65 
66 template <class InputIterator, class ValueType>
67 inline bool contains(InputIterator begin, InputIterator end, const ValueType &val) {
68  return std::find(begin,end,val) != end;
69 }
70 
71 class PassDependencyGraphPrinter : public PrintableGraph<PassManager,PassInfo::IDTy> {
72 private:
73  alloc::map<PassInfo::IDTy,const char*>::type names;
74  alloc::set<EdgeType>::type req;
75  alloc::set<EdgeType>::type mod;
76  alloc::set<EdgeType>::type dstr;
77  alloc::set<EdgeType>::type schedule_after;
78  alloc::set<EdgeType>::type run_before;
79  alloc::set<EdgeType>::type schedule_before;
80 public:
81 
82  PassDependencyGraphPrinter(PassManager &PM) {
83  for(PassManager::PassInfoMapTy::const_iterator i = PM.registered_begin(),
84  e = PM.registered_end(); i != e; ++i) {
85  PassInfo::IDTy PI = i->first;
86  names[PI] = i->second->get_name();
87  nodes.insert(i->first);
88 
89  LOG("Pass: " << i->second->get_name() << " ID: " << PI << nl);
90 
91  // create Pass
92  Pass *pass = i->second->create_Pass();
93  PassUsage PU;
94  pass->get_PassUsage(PU);
95  delete pass;
96  std::for_each(PU.requires_begin(), PU.requires_end(),AddEdge(edges,req,PI));
97  std::for_each(PU.modifies_begin(), PU.modifies_end(),AddEdge(edges,mod,PI));
98  std::for_each(PU.destroys_begin(), PU.destroys_end(),AddEdge(edges,dstr,PI));
99  std::for_each(PU.schedule_after_begin(), PU.schedule_after_end(),AddEdge(edges,schedule_after,PI));
100  std::for_each(PU.run_before_begin(), PU.run_before_end(),AddEdge(edges,run_before,PI,true));
101  std::for_each(PU.schedule_before_begin(), PU.schedule_before_end(),AddEdge(edges,schedule_before,PI,true));
102  }
103  }
104 
105  virtual OStream& getGraphName(OStream& OS) const {
106  return OS << "PassDependencyGraph";
107  }
108 
109  virtual OStream& getNodeLabel(OStream& OS, const PassInfo::IDTy &node) const {
110  return OS << names.find(node)->second;
111  }
112  virtual OStream& getEdgeLabel(OStream& OS, const EdgeType &edge) const {
113  if (contains(req.begin(),req.end(),edge)) OS << "r";
114  if (contains(mod.begin(),mod.end(),edge)) OS << "m";
115  if (contains(dstr.begin(),dstr.end(),edge)) OS << "d";
116  if (contains(schedule_after.begin(),schedule_after.end(),edge)) OS << "a";
117  if (contains(run_before.begin(),run_before.end(),edge)) OS << "b";
118  if (contains(schedule_before.begin(),schedule_before.end(),edge)) OS << "s";
119  return OS;
120  }
121 
122 };
123 
124 } // end anonymous namespace
125 
126 // run pass
128  GraphPrinter<PassDependencyGraphPrinter>::print("PassDependencyGraph.dot", PassDependencyGraphPrinter(PM));
129 }
130 
131 } // end namespace cacao
132 } // end namespace jit
133 } // end namespace compiler2
134 
135 
136 /*
137  * These are local overrides for various environment variables in Emacs.
138  * Please do not remove this and leave it at the end of the file, where
139  * Emacs will automagically detect them.
140  * ---------------------------------------------------------------------
141  * Local variables:
142  * mode: c++
143  * indent-tabs-mode: t
144  * c-basic-offset: 4
145  * tab-width: 4
146  * End:
147  * vim:noexpandtab:sw=4:ts=4:
148  */
alloc::set< EdgeType >::type run_before
alloc::set< EdgeType >::type req
static void print(const char *filename, const PrintableGraphTy &G)
argument_type from
void print_PassDependencyGraph(PassManager &PM)
alloc::set< EdgeType >::type mod
_Base::const_iterator const_iterator
alloc::set< EdgeType >::type schedule_after
alloc::set< EdgeType >::type & set
std::set< EdgeType > & edges
alloc::set< EdgeType >::type dstr
Definition: set.cpp:44
MIIterator i
OStream & OS
Manage the execution of compiler passes.
Definition: PassManager.hpp:75
MIIterator e
#define LOG(STMT)
Analogous to DEBUG.
Definition: logging.hpp:91
alloc::map< PassInfo::IDTy, const char * >::type names
Nl nl
Definition: OStream.cpp:56
alloc::set< EdgeType >::type schedule_before