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

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: addressed comments, fixed bug in BitVector::Contains 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
« no previous file with comments | « vm/flow_graph_builder.h ('k') | vm/il_printer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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]->AddDominatedBlock((*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(
2491 const GrowableArray<BlockEntryInstr*>& preorder,
2492 const GrowableArray<BitVector*>& assigned_vars,
2493 const intptr_t var_count,
2494 const GrowableArray<BitVector*>& dom_frontier) {
2495 const intptr_t block_count = preorder.length();
2496 // Map preorder block number to the highest variable index that has a phi
2497 // in that block. Use it to avoid inserting multiple phis for the same
2498 // variable.
2499 GrowableArray<intptr_t> has_already(block_count);
2500 // Map preorder block number to the highest variable index for which the
2501 // block went on the worklist. Use it to avoid adding the same block to
2502 // the worklist more than once for the same variable.
2503 GrowableArray<intptr_t> work(block_count);
2504
2505 // Initialize has_already and work.
2506 for (intptr_t block_index = 0; block_index < block_count; ++block_index) {
2507 has_already.Add(-1);
2508 work.Add(-1);
2509 }
2510
2511 // Insert phis for each variable in turn.
2512 GrowableArray<BlockEntryInstr*> worklist;
2513 for (intptr_t var_index = 0; var_index < var_count; ++var_index) {
2514 // Add to the worklist each block containing an assignment.
2515 for (intptr_t block_index = 0; block_index < block_count; ++block_index) {
2516 if (assigned_vars[block_index]->Contains(var_index)) {
2517 work[block_index] = var_index;
2518 worklist.Add(preorder[block_index]);
2519 }
2520 }
2521
2522 while (!worklist.is_empty()) {
2523 BlockEntryInstr* current = worklist.Last();
2524 worklist.RemoveLast();
2525 // Ensure a phi for each block in the dominance frontier of current.
2526 for (BitVector::Iterator it(dom_frontier[current->preorder_number()]);
2527 !it.Done();
2528 it.Advance()) {
2529 int index = it.Current();
2530 if (has_already[index] < var_index) {
2531 BlockEntryInstr* block = preorder[index];
2532 ASSERT(block->IsJoinEntry());
2533 block->AsJoinEntry()->InsertPhi(var_index, var_count);
2534 has_already[index] = var_index;
2535 if (work[index] < var_index) {
2536 work[index] = var_index;
2537 worklist.Add(block);
2538 }
2539 }
2540 }
2541 }
2542 }
2543 }
2544
2545
2484 void FlowGraphBuilder::Bailout(const char* reason) { 2546 void FlowGraphBuilder::Bailout(const char* reason) {
2485 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 2547 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
2486 const char* function_name = parsed_function_.function().ToCString(); 2548 const char* function_name = parsed_function_.function().ToCString();
2487 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2549 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2488 char* chars = reinterpret_cast<char*>( 2550 char* chars = reinterpret_cast<char*>(
2489 Isolate::Current()->current_zone()->Allocate(len)); 2551 Isolate::Current()->current_zone()->Allocate(len));
2490 OS::SNPrint(chars, len, kFormat, function_name, reason); 2552 OS::SNPrint(chars, len, kFormat, function_name, reason);
2491 const Error& error = Error::Handle( 2553 const Error& error = Error::Handle(
2492 LanguageError::New(String::Handle(String::New(chars)))); 2554 LanguageError::New(String::Handle(String::New(chars))));
2493 Isolate::Current()->long_jump_base()->Jump(1, error); 2555 Isolate::Current()->long_jump_base()->Jump(1, error);
2494 } 2556 }
2495 2557
2496 2558
2497 } // namespace dart 2559 } // namespace dart
OLDNEW
« no previous file with comments | « vm/flow_graph_builder.h ('k') | vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698