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

Side by Side Diff: vm/flow_graph_builder.cc

Issue 10539108: First step to SSA construction: Phi insertion. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 6 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/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "vm/ast_printer.h" 7 #include "vm/ast_printer.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 exit()->SetSuccessor(other_fragment.entry()); 52 exit()->SetSuccessor(other_fragment.entry());
53 exit_ = other_fragment.exit(); 53 exit_ = other_fragment.exit();
54 } 54 }
55 temp_index_ = other_fragment.temp_index(); 55 temp_index_ = other_fragment.temp_index();
56 } 56 }
57 57
58 58
59 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { 59 void EffectGraphVisitor::AddInstruction(Instruction* instruction) {
60 ASSERT(is_open()); 60 ASSERT(is_open());
61 DeallocateTempIndex(instruction->InputCount()); 61 DeallocateTempIndex(instruction->InputCount());
62 if (instruction->IsBindInstr()) { 62 if (instruction->IsDefinition()) {
63 instruction->AsBindInstr()->set_temp_index(AllocateTempIndex()); 63 instruction->AsDefinition()->set_temp_index(AllocateTempIndex());
64 } 64 }
65 if (is_empty()) { 65 if (is_empty()) {
66 entry_ = exit_ = instruction; 66 entry_ = exit_ = instruction;
67 } else { 67 } else {
68 exit()->SetSuccessor(instruction); 68 exit()->SetSuccessor(instruction);
69 exit_ = instruction; 69 exit_ = instruction;
70 } 70 }
71 } 71 }
72 72
73 73
(...skipping 2256 matching lines...) Expand 10 before | Expand all | Expand 10 after
2330 &assigned_vars, 2330 &assigned_vars,
2331 variable_count); 2331 variable_count);
2332 // Number blocks in reverse postorder. 2332 // Number blocks in reverse postorder.
2333 intptr_t block_count = postorder_block_entries_.length(); 2333 intptr_t block_count = postorder_block_entries_.length();
2334 for (intptr_t i = 0; i < block_count; ++i) { 2334 for (intptr_t i = 0; i < block_count; ++i) {
2335 postorder_block_entries_[i]->set_block_id(block_count - i - 1); 2335 postorder_block_entries_[i]->set_block_id(block_count - i - 1);
2336 } 2336 }
2337 if (for_optimized) { 2337 if (for_optimized) {
2338 GrowableArray<BitVector*> dominance_frontier; 2338 GrowableArray<BitVector*> dominance_frontier;
2339 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier); 2339 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier);
2340 InsertPhis(&preorder_block_entries_,
2341 &assigned_vars,
2342 variable_count,
2343 &dominance_frontier);
2344 // TODO(fschneider): Perform SSA renaming.
2340 } 2345 }
2341 if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) { 2346 if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) {
2342 intptr_t length = postorder_block_entries_.length(); 2347 intptr_t length = postorder_block_entries_.length();
2343 GrowableArray<BlockEntryInstr*> reverse_postorder(length); 2348 GrowableArray<BlockEntryInstr*> reverse_postorder(length);
2344 for (intptr_t i = length - 1; i >= 0; --i) { 2349 for (intptr_t i = length - 1; i >= 0; --i) {
2345 reverse_postorder.Add(postorder_block_entries_[i]); 2350 reverse_postorder.Add(postorder_block_entries_[i]);
2346 } 2351 }
2347 if (FLAG_print_flow_graph) { 2352 if (FLAG_print_flow_graph) {
2348 // Print flow graph to stdout. 2353 // Print flow graph to stdout.
2349 FlowGraphPrinter printer(function, reverse_postorder); 2354 FlowGraphPrinter printer(function, reverse_postorder);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
2438 2443
2439 // 2. Compute the immediate dominators as the nearest common ancestor of 2444 // 2. Compute the immediate dominators as the nearest common ancestor of
2440 // spanning tree parent and semidominator, for all blocks except the entry. 2445 // spanning tree parent and semidominator, for all blocks except the entry.
2441 for (intptr_t block_index = 1; block_index < size; ++block_index) { 2446 for (intptr_t block_index = 1; block_index < size; ++block_index) {
2442 intptr_t dom_index = idom[block_index]; 2447 intptr_t dom_index = idom[block_index];
2443 while (dom_index > semi[block_index]) { 2448 while (dom_index > semi[block_index]) {
2444 dom_index = idom[dom_index]; 2449 dom_index = idom[dom_index];
2445 } 2450 }
2446 idom[block_index] = dom_index; 2451 idom[block_index] = dom_index;
2447 (*preorder)[block_index]->set_dominator((*preorder)[dom_index]); 2452 (*preorder)[block_index]->set_dominator((*preorder)[dom_index]);
2453 (*preorder)[dom_index]->dominated_blocks()->Add((*preorder)[block_index]);
2448 } 2454 }
2449 2455
2450 // 3. Now compute the dominance frontier for all blocks. This is 2456 // 3. Now compute the dominance frontier for all blocks. This is
2451 // algorithm in "A Simple, Fast Dominance Algorithm" (Figure 5), which is 2457 // algorithm in "A Simple, Fast Dominance Algorithm" (Figure 5), which is
2452 // attributed to a paper by Ferrante et al. There is no bookkeeping 2458 // attributed to a paper by Ferrante et al. There is no bookkeeping
2453 // required to avoid adding a block twice to the same block's dominance 2459 // required to avoid adding a block twice to the same block's dominance
2454 // frontier because we use a set to represent the dominance frontier. 2460 // frontier because we use a set to represent the dominance frontier.
2455 for (intptr_t block_index = 0; block_index < size; ++block_index) { 2461 for (intptr_t block_index = 0; block_index < size; ++block_index) {
2456 BlockEntryInstr* block = (*preorder)[block_index]; 2462 BlockEntryInstr* block = (*preorder)[block_index];
2457 intptr_t count = block->PredecessorCount(); 2463 intptr_t count = block->PredecessorCount();
(...skipping 16 matching lines...) Expand all
2474 intptr_t next_index = (*parent)[current_index]; 2480 intptr_t next_index = (*parent)[current_index];
2475 if (next_index > start_index) { 2481 if (next_index > start_index) {
2476 CompressPath(start_index, next_index, parent, label); 2482 CompressPath(start_index, next_index, parent, label);
2477 (*label)[current_index] = 2483 (*label)[current_index] =
2478 Utils::Minimum((*label)[current_index], (*label)[next_index]); 2484 Utils::Minimum((*label)[current_index], (*label)[next_index]);
2479 (*parent)[current_index] = (*parent)[next_index]; 2485 (*parent)[current_index] = (*parent)[next_index];
2480 } 2486 }
2481 } 2487 }
2482 2488
2483 2489
2490 void FlowGraphBuilder::InsertPhis(GrowableArray<BlockEntryInstr*>* preorder,
srdjan 2012/06/12 17:34:37 const GrowableArray<BlockEntryInstr>&
Florian Schneider 2012/06/13 10:53:40 Done.
2491 GrowableArray<BitVector*>* assigned_vars,
srdjan 2012/06/12 17:34:37 const GrowableArray<BitVector>&
Florian Schneider 2012/06/13 10:53:40 Done.
2492 intptr_t var_count,
2493 GrowableArray<BitVector*>* dom_frontier) {
srdjan 2012/06/12 17:34:37 ditto
Florian Schneider 2012/06/13 10:53:40 Done.
2494 int block_count = preorder->length();
srdjan 2012/06/12 17:34:37 const intptr_t
Florian Schneider 2012/06/13 10:53:40 Done.
Florian Schneider 2012/06/13 10:53:40 Done.
2495 // Map preorder block number to the highest variable index that has a phi
2496 // in that block. Use it to avoid inserting multiple phis for the same
2497 // variable.
2498 int* has_already = new int[block_count];
srdjan 2012/06/12 17:34:37 Allocation in C++ heap should be avoided (memory l
Florian Schneider 2012/06/13 10:53:40 Done.
2499 // Map preorder block number to the highest variable index for which the
2500 // block went on the worklist. Use it to avoid adding the same block to
2501 // the worklist more than once for the same variable.
2502 int* work = new int[block_count];
2503
2504 // Initialize has_already and work.
2505 for (intptr_t block_index = 0; block_index < block_count; ++block_index) {
2506 has_already[block_index] = -1;
2507 work[block_index] = -1;
2508 }
2509
2510 // Insert phis for each variable in turn.
2511 GrowableArray<BlockEntryInstr*> worklist;
2512 for (intptr_t var_index = 0; var_index < var_count; ++var_index) {
2513 // Add to the worklist each block containing an assignment.
2514 for (intptr_t block_index = 0; block_index < block_count; ++block_index) {
2515 if ((*assigned_vars)[block_index]->Contains(var_index)) {
2516 work[block_index] = var_index;
2517 worklist.Add((*preorder)[block_index]);
2518 }
2519 }
2520
2521 while (!worklist.is_empty()) {
2522 BlockEntryInstr* current = worklist.Last();
2523 worklist.RemoveLast();
2524 // Ensure a phi for each block in the dominance frontier of current.
2525 for (BitVector::Iterator it((*dom_frontier)[current->preorder_number()]);
2526 !it.Done();
2527 it.Advance()) {
2528 int index = it.Current();
2529 if (has_already[index] < var_index) {
2530 BlockEntryInstr* block = (*preorder)[index];
2531 ASSERT(block->IsJoinEntry());
2532 block->AsJoinEntry()->InsertPhi(var_index, var_count);
2533 has_already[index] = var_index;
2534 if (work[index] < var_index) {
2535 work[index] = var_index;
2536 worklist.Add(block);
2537 }
2538 }
2539 }
2540 }
2541 }
2542
2543 delete[] work;
2544 delete[] has_already;
2545 }
2546
2547
2484 void FlowGraphBuilder::Bailout(const char* reason) { 2548 void FlowGraphBuilder::Bailout(const char* reason) {
2485 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 2549 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
2486 const char* function_name = parsed_function_.function().ToCString(); 2550 const char* function_name = parsed_function_.function().ToCString();
2487 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2551 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2488 char* chars = reinterpret_cast<char*>( 2552 char* chars = reinterpret_cast<char*>(
2489 Isolate::Current()->current_zone()->Allocate(len)); 2553 Isolate::Current()->current_zone()->Allocate(len));
2490 OS::SNPrint(chars, len, kFormat, function_name, reason); 2554 OS::SNPrint(chars, len, kFormat, function_name, reason);
2491 const Error& error = Error::Handle( 2555 const Error& error = Error::Handle(
2492 LanguageError::New(String::Handle(String::New(chars)))); 2556 LanguageError::New(String::Handle(String::New(chars))));
2493 Isolate::Current()->long_jump_base()->Jump(1, error); 2557 Isolate::Current()->long_jump_base()->Jump(1, error);
2494 } 2558 }
2495 2559
2496 2560
2497 } // namespace dart 2561 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698