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

Side by Side Diff: vm/flow_graph_builder.cc

Issue 10544206: Second step for computing SSA: renaming. (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
« 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 17 matching lines...) Expand all
28 DECLARE_FLAG(bool, enable_type_checks); 28 DECLARE_FLAG(bool, enable_type_checks);
29 29
30 30
31 FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function) 31 FlowGraphBuilder::FlowGraphBuilder(const ParsedFunction& parsed_function)
32 : parsed_function_(parsed_function), 32 : parsed_function_(parsed_function),
33 preorder_block_entries_(), 33 preorder_block_entries_(),
34 postorder_block_entries_(), 34 postorder_block_entries_(),
35 context_level_(0), 35 context_level_(0),
36 last_used_try_index_(CatchClauseNode::kInvalidTryIndex), 36 last_used_try_index_(CatchClauseNode::kInvalidTryIndex),
37 try_index_(CatchClauseNode::kInvalidTryIndex), 37 try_index_(CatchClauseNode::kInvalidTryIndex),
38 graph_entry_(NULL) { } 38 graph_entry_(NULL),
39 current_ssa_temp_index_(0) { }
39 40
40 41
41 void FlowGraphBuilder::AddCatchEntry(TargetEntryInstr* entry) { 42 void FlowGraphBuilder::AddCatchEntry(TargetEntryInstr* entry) {
42 graph_entry_->AddCatchEntry(entry); 43 graph_entry_->AddCatchEntry(entry);
43 } 44 }
44 45
45 46
46 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { 47 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) {
47 ASSERT(is_open()); 48 ASSERT(is_open());
48 if (other_fragment.is_empty()) return; 49 if (other_fragment.is_empty()) return;
(...skipping 2292 matching lines...) Expand 10 before | Expand all | Expand 10 after
2341 for (intptr_t i = 0; i < block_count; ++i) { 2342 for (intptr_t i = 0; i < block_count; ++i) {
2342 postorder_block_entries_[i]->set_block_id(block_count - i - 1); 2343 postorder_block_entries_[i]->set_block_id(block_count - i - 1);
2343 } 2344 }
2344 if (for_optimized && FLAG_use_ssa) { 2345 if (for_optimized && FLAG_use_ssa) {
2345 GrowableArray<BitVector*> dominance_frontier; 2346 GrowableArray<BitVector*> dominance_frontier;
2346 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier); 2347 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier);
2347 InsertPhis(preorder_block_entries_, 2348 InsertPhis(preorder_block_entries_,
2348 assigned_vars, 2349 assigned_vars,
2349 variable_count, 2350 variable_count,
2350 dominance_frontier); 2351 dominance_frontier);
2351 // TODO(fschneider): Perform SSA renaming. 2352 Rename(variable_count);
2352 } 2353 }
2353 if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) { 2354 if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) {
2354 intptr_t length = postorder_block_entries_.length(); 2355 intptr_t length = postorder_block_entries_.length();
2355 GrowableArray<BlockEntryInstr*> reverse_postorder(length); 2356 GrowableArray<BlockEntryInstr*> reverse_postorder(length);
2356 for (intptr_t i = length - 1; i >= 0; --i) { 2357 for (intptr_t i = length - 1; i >= 0; --i) {
2357 reverse_postorder.Add(postorder_block_entries_[i]); 2358 reverse_postorder.Add(postorder_block_entries_[i]);
2358 } 2359 }
2359 if (FLAG_print_flow_graph) { 2360 if (FLAG_print_flow_graph) {
2360 // Print flow graph to stdout. 2361 // Print flow graph to stdout.
2361 FlowGraphPrinter printer(function, reverse_postorder); 2362 FlowGraphPrinter printer(function, reverse_postorder);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
2547 work[index] = var_index; 2548 work[index] = var_index;
2548 worklist.Add(block); 2549 worklist.Add(block);
2549 } 2550 }
2550 } 2551 }
2551 } 2552 }
2552 } 2553 }
2553 } 2554 }
2554 } 2555 }
2555 2556
2556 2557
2558 void FlowGraphBuilder::Rename(intptr_t var_count) {
2559 // Initialize start environment:
2560 // All locals are initialized with #null.
2561 // TODO(fschneider): Support parameters. All parameters are initially located
2562 // on the stack.
2563 // TODO(fschneider): Store var_count in the FlowGraphBuilder instead of
2564 // passing it around.
2565 ZoneGrowableArray<Value*>* start_env =
2566 new ZoneGrowableArray<Value*>(var_count);
2567 if (parsed_function().function().num_fixed_parameters() > 0) {
2568 Bailout("Fixed parameter support in SSA");
2569 }
2570 if (parsed_function().copied_parameter_count()) {
2571 Bailout("Copied parameter support in SSA");
2572 }
2573 Value* null_value = new ConstantVal(Object::ZoneHandle());
2574 // TODO(fschneider): Change this assert once parameters are supported.
2575 ASSERT(var_count == parsed_function().stack_local_count());
2576 for (intptr_t i = 0; i < var_count; i++) {
2577 start_env->Add(null_value);
2578 }
2579 graph_entry_->set_start_env(start_env);
2580
2581 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0);
2582 ASSERT(normal_entry != NULL); // Must have entry.
2583 ZoneGrowableArray<Value*>* env = new ZoneGrowableArray<Value*>(var_count);
2584 env->AddArray(*start_env);
2585 RenameRecursive(normal_entry, env, var_count);
2586 }
2587
2588
2589 static intptr_t WhichPred(BlockEntryInstr* predecessor,
2590 JoinEntryInstr* join_block) {
2591 for (intptr_t i = 0; i < join_block->PredecessorCount(); ++i) {
2592 if (join_block->PredecessorAt(i) == predecessor) return i;
2593 }
2594 UNREACHABLE();
2595 return -1;
2596 }
2597
2598
2599 void FlowGraphBuilder::RenameRecursive(BlockEntryInstr* block_entry,
2600 ZoneGrowableArray<Value*>* env,
2601 intptr_t var_count) {
2602 // Iterate over instructions.
2603 // 1. Handle phis first.
2604 if (block_entry->IsJoinEntry()) {
2605 JoinEntryInstr* join = block_entry->AsJoinEntry();
2606 if (join->phis() != NULL) {
2607 for (intptr_t i = 0; i < join->phis()->length(); ++i) {
2608 PhiInstr* phi = (*join->phis())[i];
2609 if (phi != NULL) {
2610 (*env)[i] = new UseVal(phi);
2611 phi->set_ssa_temp_index(current_ssa_temp_index_++); // New SSA temp.
2612 }
2613 }
2614 }
2615 }
2616
2617 // 2. Handle normal instructions.
2618 Instruction* current = block_entry->StraightLineSuccessor();
2619 Instruction* prev = block_entry;
2620 while ((current != NULL) && !current->IsBlockEntry()) {
2621 // 2a. Handle LoadLocal and StoreLocal.
2622 // LoadLocal should not be present in an effect context.
2623 ASSERT(!current->IsDo() ||
2624 !current->AsDo()->computation()->IsLoadLocal());
2625 LoadLocalComp* load = NULL;
2626 if (current->IsBind() &&
2627 current->AsBind()->computation()->IsLoadLocal()) {
2628 load = current->AsBind()->computation()->AsLoadLocal();
2629 }
2630 StoreLocalComp* store = NULL;
2631 if (current->IsDo() &&
2632 current->AsDo()->computation()->IsStoreLocal()) {
2633 store = current->AsDo()->computation()->AsStoreLocal();
2634 } else if (current->IsBind() &&
2635 current->AsBind()->computation()->IsStoreLocal()) {
2636 store = current->AsBind()->computation()->AsStoreLocal();
2637 }
2638
2639 if ((load != NULL) || (store != NULL)) {
2640 // Remove instruction with LoadLocal or StoreLocal.
2641 prev->SetSuccessor(current->StraightLineSuccessor());
2642 // Update renaming environment for StoreLocal.
2643 if (store != NULL) {
2644 (*env)[store->local().BitIndexIn(var_count)] = store->value();
2645 }
2646 } else {
2647 // Assign new SSA temporary.
2648 if (current->IsBind()) {
2649 current->AsDefinition()->set_ssa_temp_index(current_ssa_temp_index_++);
2650 }
2651 }
2652
2653 // 2b. Handle uses of LoadLocal / StoreLocal
2654 for (intptr_t i = 0; i < current->InputCount(); ++i) {
2655 // For each use of a LoadLocal/StoreLocal: Replace it with the definition
2656 // from the environment.
2657 Value* v = current->InputAt(i);
2658 if (v->IsUse() &&
2659 v->AsUse()->definition()->IsBind() &&
2660 v->AsUse()->definition()->AsBind()->computation()->IsLoadLocal()) {
2661 Computation* comp = v->AsUse()->definition()->AsBind()->computation();
2662 intptr_t index = comp->AsLoadLocal()->local().BitIndexIn(var_count);
2663 Value* new_value = (*env)[index];
2664 // Make a copy if it is a UseVal.
2665 if (new_value->IsUse()) {
2666 new_value = new UseVal(new_value->AsUse()->definition());
2667 }
2668 current->SetInputAt(i, new_value);
2669 }
2670 if (v->IsUse() &&
2671 v->AsUse()->definition()->IsBind() &&
2672 v->AsUse()->definition()->AsBind()->computation()->IsStoreLocal()) {
2673 // For each use of a LoadLocal: Replace LoadLocal with the definition
2674 // from the enviroment.
2675 Computation* comp = v->AsUse()->definition()->AsBind()->computation();
2676 intptr_t index = comp->AsStoreLocal()->local().BitIndexIn(var_count);
2677 Value* new_value = (*env)[index];
2678 // Make a copy if it is a UseVal.
2679 if (new_value->IsUse()) {
2680 new_value = new UseVal(new_value->AsUse()->definition());
2681 }
2682 current->SetInputAt(i, new_value);
2683 }
2684 }
2685
2686 // Update previous only if no instruction was removed from the graph.
2687 if ((load == NULL) && (store == NULL)) {
2688 prev = current;
2689 }
2690 current = current->StraightLineSuccessor();
2691 }
2692
2693 // 3. Process dominated blocks.
2694 for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) {
2695 BlockEntryInstr* block = block_entry->dominated_blocks()[i];
2696 ZoneGrowableArray<Value*>* new_env =
2697 new ZoneGrowableArray<Value*>(var_count);
2698 new_env->AddArray(*env);
2699 RenameRecursive(block, new_env, var_count);
2700 }
2701
2702 // 4. Process successor block. We have edge-split form, so that only blocks
2703 // with one successor can have a join block as successor.
2704 if ((block_entry->last_instruction()->SuccessorCount() == 1) &&
2705 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) {
2706 JoinEntryInstr* successor =
2707 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry();
2708 intptr_t pred_index = WhichPred(block_entry, successor);
2709 if (successor->phis() != NULL) {
2710 for (intptr_t i = 0; i < successor->phis()->length(); ++i) {
2711 PhiInstr* phi = (*successor->phis())[i];
2712 if (phi != NULL) phi->SetInputAt(pred_index, (*env)[i]);
2713 }
2714 }
2715 }
2716 }
2717
2718
2557 void FlowGraphBuilder::Bailout(const char* reason) { 2719 void FlowGraphBuilder::Bailout(const char* reason) {
2558 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 2720 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
2559 const char* function_name = parsed_function_.function().ToCString(); 2721 const char* function_name = parsed_function_.function().ToCString();
2560 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2722 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2561 char* chars = reinterpret_cast<char*>( 2723 char* chars = reinterpret_cast<char*>(
2562 Isolate::Current()->current_zone()->Allocate(len)); 2724 Isolate::Current()->current_zone()->Allocate(len));
2563 OS::SNPrint(chars, len, kFormat, function_name, reason); 2725 OS::SNPrint(chars, len, kFormat, function_name, reason);
2564 const Error& error = Error::Handle( 2726 const Error& error = Error::Handle(
2565 LanguageError::New(String::Handle(String::New(chars)))); 2727 LanguageError::New(String::Handle(String::New(chars))));
2566 Isolate::Current()->long_jump_base()->Jump(1, error); 2728 Isolate::Current()->long_jump_base()->Jump(1, error);
2567 } 2729 }
2568 2730
2569 2731
2570 } // namespace dart 2732 } // 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