| OLD | NEW |
| 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 2635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2646 static intptr_t WhichPred(BlockEntryInstr* predecessor, | 2646 static intptr_t WhichPred(BlockEntryInstr* predecessor, |
| 2647 JoinEntryInstr* join_block) { | 2647 JoinEntryInstr* join_block) { |
| 2648 for (intptr_t i = 0; i < join_block->PredecessorCount(); ++i) { | 2648 for (intptr_t i = 0; i < join_block->PredecessorCount(); ++i) { |
| 2649 if (join_block->PredecessorAt(i) == predecessor) return i; | 2649 if (join_block->PredecessorAt(i) == predecessor) return i; |
| 2650 } | 2650 } |
| 2651 UNREACHABLE(); | 2651 UNREACHABLE(); |
| 2652 return -1; | 2652 return -1; |
| 2653 } | 2653 } |
| 2654 | 2654 |
| 2655 | 2655 |
| 2656 // Helper to a copy a value iff it is a UseVal. |
| 2657 static Value* CopyValue(Value* value) { |
| 2658 return value->IsUse() |
| 2659 ? new UseVal(value->AsUse()->definition()) |
| 2660 : value; |
| 2661 } |
| 2662 |
| 2663 |
| 2656 void FlowGraphBuilder::RenameRecursive(BlockEntryInstr* block_entry, | 2664 void FlowGraphBuilder::RenameRecursive(BlockEntryInstr* block_entry, |
| 2657 ZoneGrowableArray<Value*>* env, | 2665 ZoneGrowableArray<Value*>* env, |
| 2658 intptr_t var_count) { | 2666 intptr_t var_count) { |
| 2659 // 1. Process phis first. | 2667 // 1. Process phis first. |
| 2660 if (block_entry->IsJoinEntry()) { | 2668 if (block_entry->IsJoinEntry()) { |
| 2661 JoinEntryInstr* join = block_entry->AsJoinEntry(); | 2669 JoinEntryInstr* join = block_entry->AsJoinEntry(); |
| 2662 if (join->phis() != NULL) { | 2670 if (join->phis() != NULL) { |
| 2663 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 2671 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 2664 PhiInstr* phi = (*join->phis())[i]; | 2672 PhiInstr* phi = (*join->phis())[i]; |
| 2665 if (phi != NULL) { | 2673 if (phi != NULL) { |
| 2666 (*env)[i] = new UseVal(phi); | 2674 (*env)[i] = new UseVal(phi); |
| 2667 phi->set_ssa_temp_index(current_ssa_temp_index_++); // New SSA temp. | 2675 phi->set_ssa_temp_index(current_ssa_temp_index_++); // New SSA temp. |
| 2668 } | 2676 } |
| 2669 } | 2677 } |
| 2670 } | 2678 } |
| 2671 } | 2679 } |
| 2672 | 2680 |
| 2673 // 2. Process normal instructions. | 2681 // 2. Process normal instructions. |
| 2674 Instruction* current = block_entry->successor(); | 2682 Instruction* current = block_entry->successor(); |
| 2675 while ((current != NULL) && !current->IsBlockEntry()) { | 2683 while ((current != NULL) && !current->IsBlockEntry()) { |
| 2676 // 2a. Handle uses of LoadLocal / StoreLocal | 2684 // Attach current environment to the instruction. |
| 2685 // TODO(fschneider): Currently each instruction gets a full copy of the |
| 2686 // enviroment. This should be optimized: Only instructions that can |
| 2687 // deoptimize will should have uses of the environment values. |
| 2688 current->set_env(new Environment(env)); |
| 2689 |
| 2690 // 2a. Handle uses: |
| 2691 // Update expression stack environment for each use. |
| 2677 // For each use of a LoadLocal or StoreLocal: Replace it with the value | 2692 // For each use of a LoadLocal or StoreLocal: Replace it with the value |
| 2678 // from the environment. | 2693 // from the environment. |
| 2679 for (intptr_t i = 0; i < current->InputCount(); ++i) { | 2694 for (intptr_t i = 0; i < current->InputCount(); ++i) { |
| 2680 Value* v = current->InputAt(i); | 2695 Value* v = current->InputAt(i); |
| 2681 if (v->IsUse() && | 2696 if (!v->IsUse()) continue; |
| 2682 v->AsUse()->definition()->IsBind() && | 2697 // Update expression stack. |
| 2698 ASSERT(env->length() > var_count); |
| 2699 env->RemoveLast(); |
| 2700 if (v->AsUse()->definition()->IsBind() && |
| 2683 v->AsUse()->definition()->AsBind()->computation()->IsLoadLocal()) { | 2701 v->AsUse()->definition()->AsBind()->computation()->IsLoadLocal()) { |
| 2684 Computation* comp = v->AsUse()->definition()->AsBind()->computation(); | 2702 Computation* comp = v->AsUse()->definition()->AsBind()->computation(); |
| 2685 intptr_t index = comp->AsLoadLocal()->local().BitIndexIn(var_count); | 2703 intptr_t index = comp->AsLoadLocal()->local().BitIndexIn(var_count); |
| 2686 Value* new_value = (*env)[index]; | 2704 current->SetInputAt(i, CopyValue((*env)[index])); |
| 2687 // Make a copy if it is a UseVal. | |
| 2688 if (new_value->IsUse()) { | |
| 2689 new_value = new UseVal(new_value->AsUse()->definition()); | |
| 2690 } | |
| 2691 current->SetInputAt(i, new_value); | |
| 2692 } | 2705 } |
| 2693 if (v->IsUse() && | 2706 if (v->AsUse()->definition()->IsBind() && |
| 2694 v->AsUse()->definition()->IsBind() && | |
| 2695 v->AsUse()->definition()->AsBind()->computation()->IsStoreLocal()) { | 2707 v->AsUse()->definition()->AsBind()->computation()->IsStoreLocal()) { |
| 2696 // For each use of a StoreLocal: Replace it with the value from the | 2708 // For each use of a StoreLocal: Replace it with the value from the |
| 2697 // environment. | 2709 // environment. |
| 2698 Computation* comp = v->AsUse()->definition()->AsBind()->computation(); | 2710 Computation* comp = v->AsUse()->definition()->AsBind()->computation(); |
| 2699 intptr_t index = comp->AsStoreLocal()->local().BitIndexIn(var_count); | 2711 intptr_t index = comp->AsStoreLocal()->local().BitIndexIn(var_count); |
| 2700 Value* new_value = (*env)[index]; | 2712 current->SetInputAt(i, CopyValue((*env)[index])); |
| 2701 // Make a copy if it is a UseVal. | |
| 2702 if (new_value->IsUse()) { | |
| 2703 new_value = new UseVal(new_value->AsUse()->definition()); | |
| 2704 } | |
| 2705 current->SetInputAt(i, new_value); | |
| 2706 } | 2713 } |
| 2707 } | 2714 } |
| 2708 | 2715 |
| 2709 // 2b. Handle LoadLocal and StoreLocal. | 2716 // 2b. Handle LoadLocal and StoreLocal. |
| 2710 // For each LoadLocal: Remove it from the graph. | 2717 // For each LoadLocal: Remove it from the graph. |
| 2711 // For each StoreLocal: Remove it from the graph and update the environment. | 2718 // For each StoreLocal: Remove it from the graph and update the environment. |
| 2712 ASSERT(!current->IsDo() || | 2719 ASSERT(!current->IsDo() || |
| 2713 !current->AsDo()->computation()->IsLoadLocal()); // Not possible. | 2720 !current->AsDo()->computation()->IsLoadLocal()); // Not possible. |
| 2714 LoadLocalComp* load = NULL; | 2721 LoadLocalComp* load = NULL; |
| 2715 if (current->IsBind() && | 2722 if (current->IsBind() && |
| 2716 current->AsBind()->computation()->IsLoadLocal()) { | 2723 current->AsBind()->computation()->IsLoadLocal()) { |
| 2717 load = current->AsBind()->computation()->AsLoadLocal(); | 2724 load = current->AsBind()->computation()->AsLoadLocal(); |
| 2718 } | 2725 } |
| 2719 StoreLocalComp* store = NULL; | 2726 StoreLocalComp* store = NULL; |
| 2720 if (current->IsDo() && | 2727 if (current->IsDo() && |
| 2721 current->AsDo()->computation()->IsStoreLocal()) { | 2728 current->AsDo()->computation()->IsStoreLocal()) { |
| 2722 store = current->AsDo()->computation()->AsStoreLocal(); | 2729 store = current->AsDo()->computation()->AsStoreLocal(); |
| 2723 } else if (current->IsBind() && | 2730 } else if (current->IsBind() && |
| 2724 current->AsBind()->computation()->IsStoreLocal()) { | 2731 current->AsBind()->computation()->IsStoreLocal()) { |
| 2725 store = current->AsBind()->computation()->AsStoreLocal(); | 2732 store = current->AsBind()->computation()->AsStoreLocal(); |
| 2726 } | 2733 } |
| 2727 | 2734 |
| 2728 if (load != NULL) { | 2735 if (load != NULL) { |
| 2736 ASSERT(current->IsBind()); |
| 2737 // Update expression stack. |
| 2738 intptr_t index = load->local().BitIndexIn(var_count); |
| 2739 env->Add(CopyValue((*env)[index])); |
| 2729 // Remove instruction. | 2740 // Remove instruction. |
| 2730 current = current->RemoveFromGraph(); | 2741 current = current->RemoveFromGraph(); |
| 2731 } else if (store != NULL) { | 2742 } else if (store != NULL) { |
| 2743 // Update renaming environment. |
| 2744 (*env)[store->local().BitIndexIn(var_count)] = store->value(); |
| 2745 if (current->IsBind()) { |
| 2746 // Update expression stack. |
| 2747 intptr_t index = store->local().BitIndexIn(var_count); |
| 2748 env->Add(CopyValue((*env)[index])); |
| 2749 } |
| 2732 // Remove instruction and update renaming environment. | 2750 // Remove instruction and update renaming environment. |
| 2733 current = current->RemoveFromGraph(); | 2751 current = current->RemoveFromGraph(); |
| 2734 (*env)[store->local().BitIndexIn(var_count)] = store->value(); | |
| 2735 } else { | 2752 } else { |
| 2736 if (current->IsBind()) { | 2753 if (current->IsBind()) { |
| 2737 // Assign new SSA temporary. | 2754 // Assign new SSA temporary. |
| 2738 current->AsDefinition()->set_ssa_temp_index(current_ssa_temp_index_++); | 2755 current->AsDefinition()->set_ssa_temp_index(current_ssa_temp_index_++); |
| 2756 // Update expression stack. |
| 2757 env->Add(new UseVal(current->AsDefinition())); |
| 2739 } | 2758 } |
| 2740 current = current->successor(); | 2759 current = current->successor(); |
| 2741 } | 2760 } |
| 2742 } | 2761 } |
| 2743 | 2762 |
| 2744 // 3. Process dominated blocks. | 2763 // 3. Process dominated blocks. |
| 2745 for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) { | 2764 for (intptr_t i = 0; i < block_entry->dominated_blocks().length(); ++i) { |
| 2746 BlockEntryInstr* block = block_entry->dominated_blocks()[i]; | 2765 BlockEntryInstr* block = block_entry->dominated_blocks()[i]; |
| 2747 ZoneGrowableArray<Value*>* new_env = | 2766 ZoneGrowableArray<Value*>* new_env = |
| 2748 new ZoneGrowableArray<Value*>(var_count); | 2767 new ZoneGrowableArray<Value*>(var_count); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2780 char* chars = reinterpret_cast<char*>( | 2799 char* chars = reinterpret_cast<char*>( |
| 2781 Isolate::Current()->current_zone()->Allocate(len)); | 2800 Isolate::Current()->current_zone()->Allocate(len)); |
| 2782 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2801 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2783 const Error& error = Error::Handle( | 2802 const Error& error = Error::Handle( |
| 2784 LanguageError::New(String::Handle(String::New(chars)))); | 2803 LanguageError::New(String::Handle(String::New(chars)))); |
| 2785 Isolate::Current()->long_jump_base()->Jump(1, error); | 2804 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2786 } | 2805 } |
| 2787 | 2806 |
| 2788 | 2807 |
| 2789 } // namespace dart | 2808 } // namespace dart |
| OLD | NEW |