| 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.h" | 5 #include "vm/flow_graph.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 // TODO(zerny): Set previous to the graph entry so it is accessible by | 97 // TODO(zerny): Set previous to the graph entry so it is accessible by |
| 98 // GetBlock. Remove this once there is a direct pointer to the block. | 98 // GetBlock. Remove this once there is a direct pointer to the block. |
| 99 defn->set_previous(graph_entry_); | 99 defn->set_previous(graph_entry_); |
| 100 graph_entry_->initial_definitions()->Add(defn); | 100 graph_entry_->initial_definitions()->Add(defn); |
| 101 } | 101 } |
| 102 | 102 |
| 103 | 103 |
| 104 void FlowGraph::InsertBefore(Instruction* next, | 104 void FlowGraph::InsertBefore(Instruction* next, |
| 105 Instruction* instr, | 105 Instruction* instr, |
| 106 Environment* env, | 106 Environment* env, |
| 107 Definition::UseKind use_kind) { | 107 UseKind use_kind) { |
| 108 InsertAfter(next->previous(), instr, env, use_kind); | 108 InsertAfter(next->previous(), instr, env, use_kind); |
| 109 } | 109 } |
| 110 | 110 |
| 111 | 111 |
| 112 void FlowGraph::InsertAfter(Instruction* prev, | 112 void FlowGraph::InsertAfter(Instruction* prev, |
| 113 Instruction* instr, | 113 Instruction* instr, |
| 114 Environment* env, | 114 Environment* env, |
| 115 Definition::UseKind use_kind) { | 115 UseKind use_kind) { |
| 116 if (use_kind == Definition::kValue) { | 116 if (use_kind == kValue) { |
| 117 ASSERT(instr->IsDefinition()); | 117 ASSERT(instr->IsDefinition()); |
| 118 AllocateSSAIndexes(instr->AsDefinition()); | 118 AllocateSSAIndexes(instr->AsDefinition()); |
| 119 } | 119 } |
| 120 instr->InsertAfter(prev); | 120 instr->InsertAfter(prev); |
| 121 ASSERT(instr->env() == NULL); | 121 ASSERT(instr->env() == NULL); |
| 122 if (env != NULL) env->DeepCopyTo(instr); | 122 if (env != NULL) env->DeepCopyTo(instr); |
| 123 } | 123 } |
| 124 | 124 |
| 125 | 125 |
| 126 Instruction* FlowGraph::AppendTo(Instruction* prev, | 126 Instruction* FlowGraph::AppendTo(Instruction* prev, |
| 127 Instruction* instr, | 127 Instruction* instr, |
| 128 Environment* env, | 128 Environment* env, |
| 129 Definition::UseKind use_kind) { | 129 UseKind use_kind) { |
| 130 if (use_kind == Definition::kValue) { | 130 if (use_kind == kValue) { |
| 131 ASSERT(instr->IsDefinition()); | 131 ASSERT(instr->IsDefinition()); |
| 132 AllocateSSAIndexes(instr->AsDefinition()); | 132 AllocateSSAIndexes(instr->AsDefinition()); |
| 133 } | 133 } |
| 134 ASSERT(instr->env() == NULL); | 134 ASSERT(instr->env() == NULL); |
| 135 if (env != NULL) env->DeepCopyTo(instr); | 135 if (env != NULL) env->DeepCopyTo(instr); |
| 136 return prev->AppendInstruction(instr); | 136 return prev->AppendInstruction(instr); |
| 137 } | 137 } |
| 138 | 138 |
| 139 | 139 |
| 140 void FlowGraph::DiscoverBlocks() { | 140 void FlowGraph::DiscoverBlocks() { |
| (...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 result = store->value()->definition(); | 885 result = store->value()->definition(); |
| 886 | 886 |
| 887 if (variable_liveness->IsStoreAlive(block_entry, store)) { | 887 if (variable_liveness->IsStoreAlive(block_entry, store)) { |
| 888 (*env)[index] = result; | 888 (*env)[index] = result; |
| 889 } else { | 889 } else { |
| 890 (*env)[index] = constant_dead(); | 890 (*env)[index] = constant_dead(); |
| 891 } | 891 } |
| 892 } else if (load != NULL) { | 892 } else if (load != NULL) { |
| 893 // The graph construction ensures we do not have an unused LoadLocal | 893 // The graph construction ensures we do not have an unused LoadLocal |
| 894 // computation. | 894 // computation. |
| 895 ASSERT(definition->is_used()); | 895 ASSERT(definition->HasTemp()); |
| 896 intptr_t index = load->local().BitIndexIn(num_non_copied_params_); | 896 intptr_t index = load->local().BitIndexIn(num_non_copied_params_); |
| 897 result = (*env)[index]; | 897 result = (*env)[index]; |
| 898 | 898 |
| 899 PhiInstr* phi = result->AsPhi(); | 899 PhiInstr* phi = result->AsPhi(); |
| 900 if ((phi != NULL) && !phi->is_alive()) { | 900 if ((phi != NULL) && !phi->is_alive()) { |
| 901 phi->mark_alive(); | 901 phi->mark_alive(); |
| 902 live_phis->Add(phi); | 902 live_phis->Add(phi); |
| 903 } | 903 } |
| 904 | 904 |
| 905 if (variable_liveness->IsLastLoad(block_entry, load)) { | 905 if (variable_liveness->IsLastLoad(block_entry, load)) { |
| 906 (*env)[index] = constant_dead(); | 906 (*env)[index] = constant_dead(); |
| 907 } | 907 } |
| 908 } else if (push != NULL) { | 908 } else if (push != NULL) { |
| 909 result = push->value()->definition(); | 909 result = push->value()->definition(); |
| 910 env->Add(result); | 910 env->Add(result); |
| 911 it.RemoveCurrentFromGraph(); | 911 it.RemoveCurrentFromGraph(); |
| 912 continue; | 912 continue; |
| 913 } else if (drop != NULL) { | 913 } else if (drop != NULL) { |
| 914 // Drop temps from the environment. | 914 // Drop temps from the environment. |
| 915 for (intptr_t j = 0; j < drop->num_temps(); j++) { | 915 for (intptr_t j = 0; j < drop->num_temps(); j++) { |
| 916 env->RemoveLast(); | 916 env->RemoveLast(); |
| 917 } | 917 } |
| 918 if (drop->value() != NULL) { | 918 if (drop->value() != NULL) { |
| 919 result = drop->value()->definition(); | 919 result = drop->value()->definition(); |
| 920 } | 920 } |
| 921 ASSERT((drop->value() != NULL) || !drop->is_used()); | 921 ASSERT((drop->value() != NULL) || !drop->HasTemp()); |
| 922 } else { | 922 } else { |
| 923 ASSERT(definition->is_used()); | 923 ASSERT(definition->HasTemp()); |
| 924 result = GetConstant(constant->value()); | 924 result = GetConstant(constant->value()); |
| 925 } | 925 } |
| 926 // Update expression stack or remove from graph. | 926 // Update expression stack or remove from graph. |
| 927 if (definition->is_used()) { | 927 if (definition->HasTemp()) { |
| 928 ASSERT(result != NULL); | 928 ASSERT(result != NULL); |
| 929 env->Add(result); | 929 env->Add(result); |
| 930 // We remove load/store/constant instructions when we find their | 930 // We remove load/store/constant instructions when we find their |
| 931 // use in 2a. | 931 // use in 2a. |
| 932 } else { | 932 } else { |
| 933 it.RemoveCurrentFromGraph(); | 933 it.RemoveCurrentFromGraph(); |
| 934 } | 934 } |
| 935 } else { | 935 } else { |
| 936 // Not a load, store, or constant. | 936 // Not a load, store, or constant. |
| 937 if (definition->is_used()) { | 937 if (definition->HasTemp()) { |
| 938 // Assign fresh SSA temporary and update expression stack. | 938 // Assign fresh SSA temporary and update expression stack. |
| 939 AllocateSSAIndexes(definition); | 939 AllocateSSAIndexes(definition); |
| 940 env->Add(definition); | 940 env->Add(definition); |
| 941 } | 941 } |
| 942 } | 942 } |
| 943 } | 943 } |
| 944 | 944 |
| 945 // 2c. Handle pushed argument. | 945 // 2c. Handle pushed argument. |
| 946 PushArgumentInstr* push = current->AsPushArgument(); | 946 PushArgumentInstr* push = current->AsPushArgument(); |
| 947 if (push != NULL) { | 947 if (push != NULL) { |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1228 } | 1228 } |
| 1229 | 1229 |
| 1230 | 1230 |
| 1231 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1231 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
| 1232 BlockEntryInstr* to) const { | 1232 BlockEntryInstr* to) const { |
| 1233 return available_at_[to->postorder_number()]->Contains( | 1233 return available_at_[to->postorder_number()]->Contains( |
| 1234 from->postorder_number()); | 1234 from->postorder_number()); |
| 1235 } | 1235 } |
| 1236 | 1236 |
| 1237 } // namespace dart | 1237 } // namespace dart |
| OLD | NEW |