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

Side by Side Diff: vm/flow_graph_builder.cc

Issue 10583014: Fix a bug in 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 | « no previous file | 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 2586 matching lines...) Expand 10 before | Expand all | Expand 10 after
2597 if (join_block->PredecessorAt(i) == predecessor) return i; 2597 if (join_block->PredecessorAt(i) == predecessor) return i;
2598 } 2598 }
2599 UNREACHABLE(); 2599 UNREACHABLE();
2600 return -1; 2600 return -1;
2601 } 2601 }
2602 2602
2603 2603
2604 void FlowGraphBuilder::RenameRecursive(BlockEntryInstr* block_entry, 2604 void FlowGraphBuilder::RenameRecursive(BlockEntryInstr* block_entry,
2605 ZoneGrowableArray<Value*>* env, 2605 ZoneGrowableArray<Value*>* env,
2606 intptr_t var_count) { 2606 intptr_t var_count) {
2607 // Iterate over instructions. 2607 // 1. Process phis first.
2608 // 1. Handle phis first.
2609 if (block_entry->IsJoinEntry()) { 2608 if (block_entry->IsJoinEntry()) {
2610 JoinEntryInstr* join = block_entry->AsJoinEntry(); 2609 JoinEntryInstr* join = block_entry->AsJoinEntry();
2611 if (join->phis() != NULL) { 2610 if (join->phis() != NULL) {
2612 for (intptr_t i = 0; i < join->phis()->length(); ++i) { 2611 for (intptr_t i = 0; i < join->phis()->length(); ++i) {
2613 PhiInstr* phi = (*join->phis())[i]; 2612 PhiInstr* phi = (*join->phis())[i];
2614 if (phi != NULL) { 2613 if (phi != NULL) {
2615 (*env)[i] = new UseVal(phi); 2614 (*env)[i] = new UseVal(phi);
2616 phi->set_ssa_temp_index(current_ssa_temp_index_++); // New SSA temp. 2615 phi->set_ssa_temp_index(current_ssa_temp_index_++); // New SSA temp.
2617 } 2616 }
2618 } 2617 }
2619 } 2618 }
2620 } 2619 }
2621 2620
2622 // 2. Handle normal instructions. 2621 // 2. Process normal instructions.
2623 Instruction* current = block_entry->StraightLineSuccessor(); 2622 Instruction* current = block_entry->StraightLineSuccessor();
2624 Instruction* prev = block_entry; 2623 Instruction* prev = block_entry;
2625 while ((current != NULL) && !current->IsBlockEntry()) { 2624 while ((current != NULL) && !current->IsBlockEntry()) {
2626 // 2a. Handle LoadLocal and StoreLocal. 2625 // 2a. Handle uses of LoadLocal / StoreLocal
2627 // LoadLocal should not be present in an effect context. 2626 // For each use of a LoadLocal or StoreLocal: Replace it with the value
2628 ASSERT(!current->IsDo() || 2627 // from the environment.
2629 !current->AsDo()->computation()->IsLoadLocal());
2630 LoadLocalComp* load = NULL;
2631 if (current->IsBind() &&
2632 current->AsBind()->computation()->IsLoadLocal()) {
2633 load = current->AsBind()->computation()->AsLoadLocal();
2634 }
2635 StoreLocalComp* store = NULL;
2636 if (current->IsDo() &&
2637 current->AsDo()->computation()->IsStoreLocal()) {
2638 store = current->AsDo()->computation()->AsStoreLocal();
2639 } else if (current->IsBind() &&
2640 current->AsBind()->computation()->IsStoreLocal()) {
2641 store = current->AsBind()->computation()->AsStoreLocal();
2642 }
2643
2644 if ((load != NULL) || (store != NULL)) {
2645 // Remove instruction with LoadLocal or StoreLocal.
2646 prev->SetSuccessor(current->StraightLineSuccessor());
2647 // Update renaming environment for StoreLocal.
2648 if (store != NULL) {
2649 (*env)[store->local().BitIndexIn(var_count)] = store->value();
2650 }
2651 } else {
2652 // Assign new SSA temporary.
2653 if (current->IsBind()) {
2654 current->AsDefinition()->set_ssa_temp_index(current_ssa_temp_index_++);
2655 }
2656 }
2657
2658 // 2b. Handle uses of LoadLocal / StoreLocal
2659 for (intptr_t i = 0; i < current->InputCount(); ++i) { 2628 for (intptr_t i = 0; i < current->InputCount(); ++i) {
2660 // For each use of a LoadLocal/StoreLocal: Replace it with the definition
2661 // from the environment.
2662 Value* v = current->InputAt(i); 2629 Value* v = current->InputAt(i);
2663 if (v->IsUse() && 2630 if (v->IsUse() &&
2664 v->AsUse()->definition()->IsBind() && 2631 v->AsUse()->definition()->IsBind() &&
2665 v->AsUse()->definition()->AsBind()->computation()->IsLoadLocal()) { 2632 v->AsUse()->definition()->AsBind()->computation()->IsLoadLocal()) {
2666 Computation* comp = v->AsUse()->definition()->AsBind()->computation(); 2633 Computation* comp = v->AsUse()->definition()->AsBind()->computation();
2667 intptr_t index = comp->AsLoadLocal()->local().BitIndexIn(var_count); 2634 intptr_t index = comp->AsLoadLocal()->local().BitIndexIn(var_count);
2668 Value* new_value = (*env)[index]; 2635 Value* new_value = (*env)[index];
2669 // Make a copy if it is a UseVal. 2636 // Make a copy if it is a UseVal.
2670 if (new_value->IsUse()) { 2637 if (new_value->IsUse()) {
2671 new_value = new UseVal(new_value->AsUse()->definition()); 2638 new_value = new UseVal(new_value->AsUse()->definition());
2672 } 2639 }
2673 current->SetInputAt(i, new_value); 2640 current->SetInputAt(i, new_value);
2674 } 2641 }
2675 if (v->IsUse() && 2642 if (v->IsUse() &&
2676 v->AsUse()->definition()->IsBind() && 2643 v->AsUse()->definition()->IsBind() &&
2677 v->AsUse()->definition()->AsBind()->computation()->IsStoreLocal()) { 2644 v->AsUse()->definition()->AsBind()->computation()->IsStoreLocal()) {
2678 // For each use of a LoadLocal: Replace LoadLocal with the definition 2645 // For each use of a StoreLocal: Replace it with the value from the
2679 // from the enviroment. 2646 // environment.
2680 Computation* comp = v->AsUse()->definition()->AsBind()->computation(); 2647 Computation* comp = v->AsUse()->definition()->AsBind()->computation();
2681 intptr_t index = comp->AsStoreLocal()->local().BitIndexIn(var_count); 2648 intptr_t index = comp->AsStoreLocal()->local().BitIndexIn(var_count);
2682 Value* new_value = (*env)[index]; 2649 Value* new_value = (*env)[index];
2683 // Make a copy if it is a UseVal. 2650 // Make a copy if it is a UseVal.
2684 if (new_value->IsUse()) { 2651 if (new_value->IsUse()) {
2685 new_value = new UseVal(new_value->AsUse()->definition()); 2652 new_value = new UseVal(new_value->AsUse()->definition());
2686 } 2653 }
2687 current->SetInputAt(i, new_value); 2654 current->SetInputAt(i, new_value);
2688 } 2655 }
2689 } 2656 }
2690 2657
2691 // Update previous only if no instruction was removed from the graph. 2658 // 2b. Handle LoadLocal and StoreLocal.
2692 if ((load == NULL) && (store == NULL)) { 2659 // For each LoadLocal: Remove it from the graph.
2660 // For each StoreLocal: Remove it from the graph and update the environment.
2661 ASSERT(!current->IsDo() ||
2662 !current->AsDo()->computation()->IsLoadLocal()); // Not possible.
2663 LoadLocalComp* load = NULL;
2664 if (current->IsBind() &&
2665 current->AsBind()->computation()->IsLoadLocal()) {
2666 load = current->AsBind()->computation()->AsLoadLocal();
2667 }
2668 StoreLocalComp* store = NULL;
2669 if (current->IsDo() &&
2670 current->AsDo()->computation()->IsStoreLocal()) {
2671 store = current->AsDo()->computation()->AsStoreLocal();
2672 } else if (current->IsBind() &&
2673 current->AsBind()->computation()->IsStoreLocal()) {
2674 store = current->AsBind()->computation()->AsStoreLocal();
2675 }
2676
2677 if (load != NULL) {
2678 // Remove instruction.
2679 prev->SetSuccessor(current->StraightLineSuccessor());
2680 } else if (store != NULL) {
2681 // Remove instruction and update renaming environment.
2682 prev->SetSuccessor(current->StraightLineSuccessor());
2683 (*env)[store->local().BitIndexIn(var_count)] = store->value();
2684 } else {
2685 // Assign new SSA temporary.
2686 if (current->IsBind()) {
2687 current->AsDefinition()->set_ssa_temp_index(current_ssa_temp_index_++);
2688 }
2689 // Update previous only if no instruction was removed from the graph.
2693 prev = current; 2690 prev = current;
2694 } 2691 }
2695 current = current->StraightLineSuccessor(); 2692 current = current->StraightLineSuccessor();
2696 } 2693 }
2697 2694
2698 // 3. Process dominated blocks. 2695 // 3. Process dominated blocks.
2699 for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) { 2696 for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) {
2700 BlockEntryInstr* block = block_entry->dominated_blocks()[i]; 2697 BlockEntryInstr* block = block_entry->dominated_blocks()[i];
2701 ZoneGrowableArray<Value*>* new_env = 2698 ZoneGrowableArray<Value*>* new_env =
2702 new ZoneGrowableArray<Value*>(var_count); 2699 new ZoneGrowableArray<Value*>(var_count);
2703 new_env->AddArray(*env); 2700 new_env->AddArray(*env);
2704 RenameRecursive(block, new_env, var_count); 2701 RenameRecursive(block, new_env, var_count);
2705 } 2702 }
2706 2703
2707 // 4. Process successor block. We have edge-split form, so that only blocks 2704 // 4. Process successor block. We have edge-split form, so that only blocks
2708 // with one successor can have a join block as successor. 2705 // with one successor can have a join block as successor.
2709 if ((block_entry->last_instruction()->SuccessorCount() == 1) && 2706 if ((block_entry->last_instruction()->SuccessorCount() == 1) &&
2710 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { 2707 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) {
2711 JoinEntryInstr* successor = 2708 JoinEntryInstr* successor =
2712 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); 2709 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry();
2713 intptr_t pred_index = WhichPred(block_entry, successor); 2710 intptr_t pred_index = WhichPred(block_entry, successor);
2714 if (successor->phis() != NULL) { 2711 if (successor->phis() != NULL) {
2715 for (intptr_t i = 0; i < successor->phis()->length(); ++i) { 2712 for (intptr_t i = 0; i < successor->phis()->length(); ++i) {
2716 PhiInstr* phi = (*successor->phis())[i]; 2713 PhiInstr* phi = (*successor->phis())[i];
2717 if (phi != NULL) phi->SetInputAt(pred_index, (*env)[i]); 2714 if (phi != NULL) {
2715 // Rename input operand and make a copy if it is a UseVal.
2716 Value* new_val = (*env)[i]->IsUse()
2717 ? new UseVal((*env)[i]->AsUse()->definition())
2718 : (*env)[i];
2719 phi->SetInputAt(pred_index, new_val);
2720 }
2718 } 2721 }
2719 } 2722 }
2720 } 2723 }
2721 } 2724 }
2722 2725
2723 2726
2724 void FlowGraphBuilder::Bailout(const char* reason) { 2727 void FlowGraphBuilder::Bailout(const char* reason) {
2725 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 2728 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
2726 const char* function_name = parsed_function_.function().ToCString(); 2729 const char* function_name = parsed_function_.function().ToCString();
2727 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2730 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2728 char* chars = reinterpret_cast<char*>( 2731 char* chars = reinterpret_cast<char*>(
2729 Isolate::Current()->current_zone()->Allocate(len)); 2732 Isolate::Current()->current_zone()->Allocate(len));
2730 OS::SNPrint(chars, len, kFormat, function_name, reason); 2733 OS::SNPrint(chars, len, kFormat, function_name, reason);
2731 const Error& error = Error::Handle( 2734 const Error& error = Error::Handle(
2732 LanguageError::New(String::Handle(String::New(chars)))); 2735 LanguageError::New(String::Handle(String::New(chars))));
2733 Isolate::Current()->long_jump_base()->Jump(1, error); 2736 Isolate::Current()->long_jump_base()->Jump(1, error);
2734 } 2737 }
2735 2738
2736 2739
2737 } // namespace dart 2740 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698