CACAO
dominator.cpp
Go to the documentation of this file.
1 /* src/vm/jit/loop/dominator.cpp
2 
3  Copyright (C) 1996-2012
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 #include <cassert>
26 
27 #include "dominator.hpp"
28 #include "toolbox/logging.hpp"
29 #include "vm/method.hpp"
30 
31 
34 void link(basicblock* v, basicblock* w);
36 void compress(basicblock*);
37 
38 
40 {
41  assert(jd->basicblocks);
42 
43  // Create a new basicblock and initialize all fields that will be used.
44  jd->ld->root = new basicblock;
45  jd->ld->root->nr = ROOT_NUMBER;
46  jd->ld->root->type = basicblock::TYPE_STD;
47  jd->ld->root->successorcount = 1; // at least 1 arrayslot for jd->basicblocks
48 
49  // Find all exception handling basicblocks.
50  for (basicblock* block = jd->basicblocks->next; block != 0; block = block->next)
51  {
52  if (block->type == basicblock::TYPE_EXH)
53  jd->ld->root->successorcount++;
54  }
55 
56  // Allocate and fill successor array with all found basicblocks.
57  jd->ld->root->successors = new basicblock*[jd->ld->root->successorcount];
58  jd->ld->root->successors[0] = jd->basicblocks;
59  s4 index = 1;
60  for (basicblock* block = jd->basicblocks->next; block != 0; block = block->next)
61  {
62  if (block->type == basicblock::TYPE_EXH)
63  {
64  jd->ld->root->successors[index] = block;
65  index++;
66  }
67  }
68 }
69 
70 /**
71  * Calculates the immediate dominators of all basicblocks.
72  */
74 {
75  assert(jd->ld->root);
76 
77  /******************
78  * Step 1 *
79  ******************/
80 
81  // Insert an arbitrary element so that the first real item has index 1. This simplifies the implementation.
82  jd->ld->vertex.push_back(0);
83 
84  assert(jd->ld->vertex.size() == 1);
85 
86  for (basicblock* block = jd->basicblocks; block != 0; block = block->next)
87  {
88  block->ld = new BasicblockLoopData;
89  }
90 
91  // jd->ld->root is not contained in the linked list jd->basicblocks.
92  jd->ld->root->ld = new BasicblockLoopData;
93 
94  depthFirstTraversal(jd, jd->ld->root);
95 
96  assert(static_cast<s4>(jd->ld->vertex.size()) == jd->ld->n + 1);
97  for (s4 i = jd->ld->n; i >= 2; i--)
98  {
99  basicblock* w = jd->ld->vertex[i];
100 
101  /******************
102  * Step 2 *
103  ******************/
104 
105  typedef std::vector<basicblock*>::iterator Iterator;
106 
107  for (Iterator it = w->ld->pred.begin(); it != w->ld->pred.end(); ++it)
108  {
109  basicblock* v = *it;
110 
111  basicblock* u = eval(v);
112  if (u->ld->semi < w->ld->semi)
113  w->ld->semi = u->ld->semi;
114  }
115 
116  jd->ld->vertex[w->ld->semi]->ld->bucket.push_back(w);
117  link(w->ld->parent, w);
118 
119  /******************
120  * Step 3 *
121  ******************/
122 
123  std::vector<basicblock*>& bucket = w->ld->parent->ld->bucket;
124  for (Iterator it = bucket.begin(); it != bucket.end(); ++it)
125  {
126  basicblock* v = *it;
127 
128  basicblock* u = eval(v);
129  if (u->ld->semi < v->ld->semi)
130  v->ld->dom = u;
131  else
132  v->ld->dom = w->ld->parent;
133  }
134  bucket.clear();
135  }
136 
137  /******************
138  * Step 4 *
139  ******************/
140 
141  for (s4 i = 2; i <= jd->ld->n; i++)
142  {
143  basicblock* w = jd->ld->vertex[i];
144 
145  if (w->ld->dom != jd->ld->vertex[w->ld->semi])
146  w->ld->dom = w->ld->dom->ld->dom;
147  }
148  jd->ld->root->ld->dom = 0;
149 }
150 
152 {
153  block->ld->semi = ++jd->ld->n;
154  jd->ld->vertex.push_back(block);
155  block->ld->label = block;
156 
157  // Check if jd->ld->vertex[jd->ld->n] == block
158  assert(static_cast<s4>(jd->ld->vertex.size()) == jd->ld->n + 1);
159 
160  for (s4 i = 0; i < block->successorcount; i++)
161  {
162  basicblock* successor = block->successors[i];
163 
164  if (successor->ld->semi == 0) // visited the first time?
165  {
166  successor->ld->parent = block;
167  depthFirstTraversal(jd, successor);
168  }
169  else // back edge found
170  {
171  jd->ld->depthBackEdges.push_back(Edge(block, successor));
172  }
173 
174  successor->ld->pred.push_back(block);
175  }
176 }
177 
179 {
180  assert(v);
181  assert(w);
182 
183  w->ld->ancestor = v;
184 }
185 
187 {
188  assert(block);
189 
190  if (block->ld->ancestor == 0)
191  {
192  return block;
193  }
194  else
195  {
196  compress(block);
197  return block->ld->label;
198  }
199 }
200 
202 {
203  basicblock* ancestor = block->ld->ancestor;
204 
205  assert(ancestor != 0);
206 
207  if (ancestor->ld->ancestor != 0)
208  {
209  compress(ancestor);
210  if (ancestor->ld->label->ld->semi < block->ld->label->ld->semi)
211  {
212  block->ld->label = ancestor->ld->label;
213  }
214  block->ld->ancestor = ancestor->ld->ancestor;
215  }
216 }
217 
218 /**
219  * Uses the immediate dominators to build a dominator tree which can be traversed from the root to the leaves.
220  */
222 {
223  for (basicblock* block = jd->basicblocks; block != 0; block = block->next)
224  {
225  if (block->ld->dom)
226  {
227  std::vector<basicblock*>& children = block->ld->dom->ld->children;
228 
229  // Every basicblock has a pointer to the next sibling in the dominator tree.
230  if (!children.empty())
231  children.back()->ld->nextSibling = block;
232 
233  children.push_back(block);
234  }
235  }
236 }
237 
238 /*
239  * These are local overrides for various environment variables in Emacs.
240  * Please do not remove this and leave it at the end of the file, where
241  * Emacs will automagically detect them.
242  * ---------------------------------------------------------------------
243  * Local variables:
244  * mode: c++
245  * indent-tabs-mode: t
246  * c-basic-offset: 4
247  * tab-width: 4
248  * End:
249  * vim:noexpandtab:sw=4:ts=4:
250  */
251 
basicblock * eval(basicblock *)
Definition: dominator.cpp:186
std::size_t index
basicblock * basicblocks
Definition: jit.hpp:141
Definition: jit.hpp:126
basicblock * next
Definition: jit.hpp:337
s4 successorcount
Definition: jit.hpp:331
void printBasicBlocks(jitdata *)
void createRoot(jitdata *jd)
Definition: dominator.cpp:39
void link(basicblock *v, basicblock *w)
Definition: dominator.cpp:178
BeginInst *& block
struct Edge Edge
Definition: loop.hpp:32
void compress(basicblock *)
Definition: dominator.cpp:201
void buildDominatorTree(jitdata *jd)
Uses the immediate dominators to build a dominator tree which can be traversed from the root to the l...
Definition: dominator.cpp:221
MIIterator i
#define ROOT_NUMBER
Definition: dominator.hpp:31
int32_t s4
Definition: types.hpp:45
struct BasicblockLoopData BasicblockLoopData
Definition: loop.hpp:30
void depthFirstTraversal(jitdata *jd, basicblock *block)
Definition: dominator.cpp:151
basicblock ** successors
Definition: jit.hpp:333
void calculateDominators(jitdata *jd)
Calculates the immediate dominators of all basicblocks.
Definition: dominator.cpp:73