Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 10377104: Compute assigned variables and dominance frontiers. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h"
7 #include "vm/object.h" 8 #include "vm/object.h"
8 #include "vm/os.h" 9 #include "vm/os.h"
9 #include "vm/scopes.h" 10 #include "vm/scopes.h"
10 11
11 namespace dart { 12 namespace dart {
12 13
13 // ==== Support for visiting flow graphs. 14 // ==== Support for visiting flow graphs.
14 #define DEFINE_ACCEPT(ShortName, ClassName) \ 15 #define DEFINE_ACCEPT(ShortName, ClassName) \
15 void ClassName::Accept(FlowGraphVisitor* visitor) { \ 16 void ClassName::Accept(FlowGraphVisitor* visitor) { \
16 visitor->Visit##ShortName(this); \ 17 visitor->Visit##ShortName(this); \
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 intptr_t TargetEntryInstr::InputCount() const { 186 intptr_t TargetEntryInstr::InputCount() const {
186 return 0; 187 return 0;
187 } 188 }
188 189
189 190
190 intptr_t JoinEntryInstr::InputCount() const { 191 intptr_t JoinEntryInstr::InputCount() const {
191 return 0; 192 return 0;
192 } 193 }
193 194
194 195
196 // ==== Recording assigned variables.
197 void Computation::RecordAssignedVars(BitVector* assigned_vars) {
198 // Nothing to do for the base class.
199 }
200
201
202 void StoreLocalComp::RecordAssignedVars(BitVector* assigned_vars) {
203 if (!local().is_captured()) {
204 int index = local().index();
205 // Parameters have positive indexes with the lowest index being 2.
206 // Locals and copied parameters have negative indexes with the lowest
207 // being -1.
208 if (index > 0) {
209 // Shift parameter indexes so that the lowest index is 0.
210 index -= 2;
srdjan 2012/05/12 00:00:55 Note that soon we will add a third word after ebp
Kevin Millikin (Google) 2012/05/15 11:51:44 Well, we either have to deal with the 'magic' extr
srdjan 2012/05/15 22:05:32 Can we put intelligence into LocalVariable? If you
211 } else {
212 // Store local and copied parameters backward from the end of the bit
213 // vector.
214 index = assigned_vars->length() + index; // Index is negative.
215 }
216 assigned_vars->Add(index);
217 }
218 }
219
220
221 void Instruction::RecordAssignedVars(BitVector* assigned_vars) {
222 // Nothing to do for the base class.
223 }
224
225
226 void DoInstr::RecordAssignedVars(BitVector* assigned_vars) {
227 computation()->RecordAssignedVars(assigned_vars);
228 }
229
230
231 void BindInstr::RecordAssignedVars(BitVector* assigned_vars) {
232 computation()->RecordAssignedVars(assigned_vars);
233 }
234
235
195 // ==== Postorder graph traversal. 236 // ==== Postorder graph traversal.
196 void JoinEntryInstr::DiscoverBlocks( 237 void BlockEntryInstr::DiscoverBlocks(
197 BlockEntryInstr* current_block, 238 BlockEntryInstr* current_block,
198 GrowableArray<BlockEntryInstr*>* preorder, 239 GrowableArray<BlockEntryInstr*>* preorder,
199 GrowableArray<BlockEntryInstr*>* postorder, 240 GrowableArray<BlockEntryInstr*>* postorder,
200 GrowableArray<intptr_t>* parent) { 241 GrowableArray<intptr_t>* parent,
242 GrowableArray<BitVector*>* assigned_vars,
243 intptr_t variable_count) {
201 // The global graph entry is a TargetEntryInstr, so we can assume 244 // The global graph entry is a TargetEntryInstr, so we can assume
202 // current_block is non-null and preorder array is non-empty. 245 // current_block is non-null and preorder array is non-empty.
203 ASSERT(current_block != NULL); 246 ASSERT(!IsJoinEntry() || (current_block != NULL));
204 ASSERT(!preorder->is_empty()); 247 ASSERT(!IsJoinEntry() || !preorder->is_empty());
205 248
206 // 1. Record control-flow-graph basic-block predecessors. 249 // 1. Record control-flow-graph basic-block predecessors.
207 predecessors_.Add(current_block); 250 AddPredecessor(current_block);
208 251
209 // 2. If the block has already been reached by the traversal, we are done. 252 // 2. If the block has already been reached by the traversal, we are
253 // done. Blocks with a single predecessor cannot have been reached
254 // before.
255 ASSERT(!IsTargetEntry() || (preorder_number() == -1));
210 if (preorder_number() >= 0) return; 256 if (preorder_number() >= 0) return;
211 257
212 // 3. The last entry in the preorder array is the spanning-tree parent. 258 // 3. The last entry in the preorder array is the spanning-tree parent.
213 intptr_t parent_number = preorder->length() - 1; 259 intptr_t parent_number = preorder->length() - 1;
214 parent->Add(parent_number); 260 parent->Add(parent_number);
215 261
216 // 4. Assign preorder number and add the block entry to the list. 262 // 4. Assign preorder number and add the block entry to the list.
263 // Allocate an empty set of assigned variables for the block.
217 set_preorder_number(parent_number + 1); 264 set_preorder_number(parent_number + 1);
218 preorder->Add(this); 265 preorder->Add(this);
219 // The preorder and parent arrays are both indexed by preorder block 266 BitVector* vars = (variable_count == 0)
220 // number, so they should stay in lockstep. 267 ? NULL
268 : new BitVector(variable_count, Isolate::Current()->current_zone());
269 assigned_vars->Add(vars);
270 // The preorder, parent, and assigned_vars arrays are all indexed by
271 // preorder block number, so they should stay in lockstep.
221 ASSERT(preorder->length() == parent->length()); 272 ASSERT(preorder->length() == parent->length());
273 ASSERT(preorder->length() == assigned_vars->length());
222 274
223 // 5. Iterate straight-line successors until a branch instruction or 275 // 5. Iterate straight-line successors until a branch instruction or
224 // another basic block entry instruction, and visit that instruction. 276 // another basic block entry instruction, and visit that instruction.
225 ASSERT(successor_ != NULL); 277 ASSERT(StraightLineSuccessor() != NULL);
226 Instruction* next = successor_; 278 Instruction* next = StraightLineSuccessor();
227 while ((next != NULL) && !next->IsBlockEntry() && !next->IsBranch()) { 279 if (next->IsBlockEntry()) {
228 set_last_instruction(next); 280 set_last_instruction(this);
229 next = next->StraightLineSuccessor(); 281 } else {
282 while ((next != NULL) && !next->IsBlockEntry() && !next->IsBranch()) {
283 next->RecordAssignedVars(assigned_vars->Last());
Florian Schneider 2012/05/11 13:19:37 assigned_vars->Last() == vars The one that's just
Kevin Millikin (Google) 2012/05/15 11:51:44 Well spotted. Done.
284 set_last_instruction(next);
285 next = next->StraightLineSuccessor();
286 }
230 } 287 }
231 if (next != NULL) { 288 if (next != NULL) {
232 next->DiscoverBlocks(this, preorder, postorder, parent); 289 next->DiscoverBlocks(this, preorder, postorder, parent, assigned_vars,
290 variable_count);
233 } 291 }
234 292
235 // 6. Assign postorder number and add the block entry to the list. 293 // 6. Assign postorder number and add the block entry to the list.
236 set_postorder_number(postorder->length());
237 postorder->Add(this);
238 }
239
240
241 void TargetEntryInstr::DiscoverBlocks(
242 BlockEntryInstr* current_block,
243 GrowableArray<BlockEntryInstr*>* preorder,
244 GrowableArray<BlockEntryInstr*>* postorder,
245 GrowableArray<intptr_t>* parent) {
246 // 1. Record control-flow-graph basic-block predecessors.
247 ASSERT(predecessor_ == NULL);
248 predecessor_ = current_block; // Might be NULL (for the graph entry).
249
250 // 2. There is a single predecessor, so we should only reach this block once.
251 ASSERT(preorder_number() == -1);
252
253 // 3. The last entry in the preorder array is the spanning-tree parent.
254 // The global graph entry has no parent, indicated by -1.
255 intptr_t parent_number = preorder->length() - 1;
256 parent->Add(parent_number);
257
258 // 4. Assign preorder number and add the block entry to the list.
259 set_preorder_number(parent_number + 1);
260 preorder->Add(this);
261 // The preorder and parent arrays are indexed by preorder block number, so
262 // they should stay in lockstep.
263 ASSERT(preorder->length() == parent->length());
264
265 // 5. Iterate straight-line successors until a branch instruction or
266 // another basic block entry instruction, and visit that instruction.
267 ASSERT(successor_ != NULL);
268 Instruction* next = successor_;
269 while ((next != NULL) && !next->IsBlockEntry() && !next->IsBranch()) {
270 set_last_instruction(next);
271 next = next->StraightLineSuccessor();
272 }
273 if (next != NULL) {
274 next->DiscoverBlocks(this, preorder, postorder, parent);
275 }
276
277 // 6. Assign postorder number and add the block entry to the list.
278 set_postorder_number(postorder->length()); 294 set_postorder_number(postorder->length());
279 postorder->Add(this); 295 postorder->Add(this);
280 } 296 }
281 297
282 298
283 void BranchInstr::DiscoverBlocks( 299 void BranchInstr::DiscoverBlocks(
284 BlockEntryInstr* current_block, 300 BlockEntryInstr* current_block,
285 GrowableArray<BlockEntryInstr*>* preorder, 301 GrowableArray<BlockEntryInstr*>* preorder,
286 GrowableArray<BlockEntryInstr*>* postorder, 302 GrowableArray<BlockEntryInstr*>* postorder,
287 GrowableArray<intptr_t>* parent) { 303 GrowableArray<intptr_t>* parent,
304 GrowableArray<BitVector*>* assigned_vars,
305 intptr_t variable_count) {
288 current_block->set_last_instruction(this); 306 current_block->set_last_instruction(this);
289 // Visit the false successor before the true successor so they appear in 307 // Visit the false successor before the true successor so they appear in
290 // true/false order in reverse postorder used as the block ordering in the 308 // true/false order in reverse postorder used as the block ordering in the
291 // nonoptimizing compiler. 309 // nonoptimizing compiler.
292 ASSERT(true_successor_ != NULL); 310 ASSERT(true_successor_ != NULL);
293 ASSERT(false_successor_ != NULL); 311 ASSERT(false_successor_ != NULL);
294 false_successor_->DiscoverBlocks(current_block, preorder, postorder, parent); 312 false_successor_->DiscoverBlocks(current_block, preorder, postorder, parent,
295 true_successor_->DiscoverBlocks(current_block, preorder, postorder, parent); 313 assigned_vars, variable_count);
314 true_successor_->DiscoverBlocks(current_block, preorder, postorder, parent,
315 assigned_vars, variable_count);
296 } 316 }
297 317
298 318
299 } // namespace dart 319 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698