CACAO
LoopBase.hpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/LoopBase.hpp - LoopBase
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 
25 #ifndef _JIT_COMPILER2_LOOPBASE
26 #define _JIT_COMPILER2_LOOPBASE
27 
28 #include <cstddef> // for NULL
30 
34 
35 namespace cacao {
36 
37 // forward declaration
38 class OStream;
39 
40 namespace jit {
41 namespace compiler2 {
42 
43 template <class _T>
44 class LoopBase {
45 public:
46  typedef _T NodeType;
49 private:
54 public:
55  LoopBase(NodeType *header, NodeType *exit) : header(header), exit(exit), parent(NULL) {}
56  NodeType *get_header() const {
57  return header;
58  }
59  NodeType *get_exit() const {
60  return exit;
61  }
62  LoopBase *get_parent() const {
63  return parent;
64  }
66  return inner_loops.begin();
67  }
69  return inner_loops.end();
70  }
71  void add_inner_loop(LoopBase* inner_loop) {
72  if(!inner_loop->parent) {
73  inner_loop->parent = this;
74  inner_loops.insert(inner_loop);
75  }
76  }
77  void set_parent(LoopBase* outer_loop) {
78  if (outer_loop) {
79  outer_loop->add_inner_loop(this);
80  }
81  }
82 };
83 
84 template <class _T>
85 class LoopTreeBase {
86 public:
87  typedef _T NodeType;
89  // Note vector needed for std::sort!
90  typedef typename LoopType::LoopSetTy LoopSetTy;
93  typedef std::pair<const_loop_iterator, const_loop_iterator> ConstLoopIteratorPair;
94 
96  typedef typename LoopListTy::iterator iterator;
97  typedef typename LoopListTy::reverse_iterator reverse_iterator;
98 protected:
99  bool reducible;
104 
105  void set_loop(NodeType* node, LoopType* loop) {
106  loop_map[node] = loop;
107  }
109  loop_header_map[node].insert(loop);
110  }
112  return loops.begin();
113  }
115  return loops.end();
116  }
118  return loops.rbegin();
119  }
121  return loops.rend();
122  }
123 public:
125 
126  bool is_reducible() const {
127  return reducible;
128  }
129  LoopType *add_loop(NodeType* header, NodeType *exit) {
130  LoopType *loop =new LoopType(header,exit);
131  loops.push_back(loop);
132  return loop;
133  }
135  if(loop) {
136  top_loops.insert(loop);
137  }
138  }
140  return top_loops.begin();
141  }
143  return top_loops.end();
144  }
145  /**
146  * Get the inner most loop which contains BI or NULL if not contained in any loop
147  */
150  if (it == loop_map.end()) {
151  return NULL;
152  }
153  return it->second;
154  }
155  bool is_loop_header(NodeType *BI) const {
157  if (it == loop_header_map.end()) {
158  return false;
159  }
160  return true;
161  }
164  if (it == loop_header_map.end()) {
165  // TODO there must be a better approach...
166  static LoopSetTy empty;
167  return std::make_pair(empty.begin(),empty.end());
168  }
169  return std::make_pair(it->second.begin(),it->second.end());
170  }
171  bool is_backedge(NodeType *src, NodeType *header) const {
173  it.first != it.second; ++it.first) {
174  LoopType *loop = *it.first;
175  if(loop->get_exit() == src) {
176  return true;
177  }
178  }
179 
180  return false;
181  }
182  /**
183  * Test if a loop is a strictly inner loop of another loop.
184  *
185  * Note that a loop is not an inner loop of itself!
186  */
187  bool is_inner_loop(LoopType *inner, LoopType *outer) const {
188  if (!inner || inner == outer) {
189  return false;
190  }
191  if (!outer) {
192  // every loop is a inner loop of no loop
193  return true;
194  }
195  while((inner = inner->get_parent())) {
196  if (inner == outer) {
197  return true;
198  }
199  }
200  return false;
201  }
202  /**
203  * TODO: cache?
204  */
205  int loop_nest(LoopType *loop) const {
206  if(!loop)
207  return -1;
208  unsigned nest = 0;
209  while((loop = loop->get_parent())) {
210  ++nest;
211  }
212  return nest;
213  }
214  virtual ~LoopTreeBase() {
215  for (typename LoopListTy::iterator i = loops.begin(), e = loops.end();
216  i != e; ++i) {
217  delete *i;
218  }
219  }
220 
221 };
222 
223 } // end namespace compiler2
224 } // end namespace jit
225 } // end namespace cacao
226 
227 #endif /* _JIT_COMPILER2_LOOPBASE */
228 
229 
230 /*
231  * These are local overrides for various environment variables in Emacs.
232  * Please do not remove this and leave it at the end of the file, where
233  * Emacs will automagically detect them.
234  * ---------------------------------------------------------------------
235  * Local variables:
236  * mode: c++
237  * indent-tabs-mode: t
238  * c-basic-offset: 4
239  * tab-width: 4
240  * End:
241  * vim:noexpandtab:sw=4:ts=4:
242  */
void set_parent(LoopBase *outer_loop)
Definition: LoopBase.hpp:77
bool is_inner_loop(LoopType *inner, LoopType *outer) const
Test if a loop is a strictly inner loop of another loop.
Definition: LoopBase.hpp:187
bool is_loop_header(NodeType *BI) const
Definition: LoopBase.hpp:155
LoopType * add_loop(NodeType *header, NodeType *exit)
Definition: LoopBase.hpp:129
LoopBase(NodeType *header, NodeType *exit)
Definition: LoopBase.hpp:55
void add_top_loop(LoopType *loop)
Definition: LoopBase.hpp:134
NodeType * get_exit() const
Definition: LoopBase.hpp:59
void insert_loop_header(NodeType *node, LoopType *loop)
Definition: LoopBase.hpp:108
alloc::vector< LoopType * >::type LoopListTy
Definition: LoopBase.hpp:95
MachineLoop * loop
_Base::const_iterator const_iterator
LoopListTy::reverse_iterator reverse_iterator
Definition: LoopBase.hpp:97
return true
Definition: PatcherNew.cpp:104
void add_inner_loop(LoopBase *inner_loop)
Definition: LoopBase.hpp:71
alloc::map< NodeType *, LoopType * >::type loop_map
Definition: LoopBase.hpp:102
LoopBase< NodeType > LoopType
Definition: LoopBase.hpp:88
LoopType::LoopSetTy LoopSetTy
Definition: LoopBase.hpp:90
LoopSetTy::iterator loop_iterator
Definition: LoopBase.hpp:48
LoopBase * get_parent() const
Definition: LoopBase.hpp:62
std::vector< T, Allocator< T > > type
Definition: vector.hpp:38
bool is_backedge(NodeType *src, NodeType *header) const
Definition: LoopBase.hpp:171
LoopSetTy::iterator loop_iterator
Definition: LoopBase.hpp:91
MIIterator i
LoopSetTy::const_iterator const_loop_iterator
Definition: LoopBase.hpp:92
MIIterator e
_Base::iterator iterator
alloc::map< NodeType *, LoopSetTy >::type loop_header_map
Definition: LoopBase.hpp:103
LoopListTy::iterator iterator
Definition: LoopBase.hpp:96
std::pair< const_loop_iterator, const_loop_iterator > ConstLoopIteratorPair
Definition: LoopBase.hpp:93
int loop_nest(LoopType *loop) const
TODO: cache?
Definition: LoopBase.hpp:205
NodeType * get_header() const
Definition: LoopBase.hpp:56
void set_loop(NodeType *node, LoopType *loop)
Definition: LoopBase.hpp:105
alloc::unordered_set< LoopBase * >::type LoopSetTy
Definition: LoopBase.hpp:47
LoopType * get_Loop(NodeType *BI) const
Get the inner most loop which contains BI or NULL if not contained in any loop.
Definition: LoopBase.hpp:148
ConstLoopIteratorPair get_Loops_from_header(NodeType *BI) const
Definition: LoopBase.hpp:162