| 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/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1073 Instruction* current = it.Current(); | 1073 Instruction* current = it.Current(); |
| 1074 | 1074 |
| 1075 // Attach current environment to the instructions that need it. | 1075 // Attach current environment to the instructions that need it. |
| 1076 if (current->NeedsEnvironment()) { | 1076 if (current->NeedsEnvironment()) { |
| 1077 AttachEnvironment(current, env); | 1077 AttachEnvironment(current, env); |
| 1078 } | 1078 } |
| 1079 | 1079 |
| 1080 // 2a. Handle uses: | 1080 // 2a. Handle uses: |
| 1081 // Update the expression stack renaming environment for each use by | 1081 // Update the expression stack renaming environment for each use by |
| 1082 // removing the renamed value. | 1082 // removing the renamed value. |
| 1083 // For each use of a LoadLocal, StoreLocal, or Constant: Replace it with | 1083 // For each use of a LoadLocal, StoreLocal, DropTemps or Constant: Replace |
| 1084 // the renamed value. | 1084 // it with the renamed value. |
| 1085 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) { | 1085 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) { |
| 1086 Value* v = current->InputAt(i); | 1086 Value* v = current->InputAt(i); |
| 1087 // Update expression stack. | 1087 // Update expression stack. |
| 1088 ASSERT(env->length() > variable_count()); | 1088 ASSERT(env->length() > variable_count()); |
| 1089 | 1089 |
| 1090 Definition* reaching_defn = env->RemoveLast(); | 1090 Definition* reaching_defn = env->RemoveLast(); |
| 1091 Definition* input_defn = v->definition(); | 1091 Definition* input_defn = v->definition(); |
| 1092 if (input_defn->IsLoadLocal() || | 1092 if (input_defn != reaching_defn) { |
| 1093 input_defn->IsStoreLocal() || | 1093 ASSERT(input_defn->IsLoadLocal() || |
| 1094 input_defn->IsPushTemp() || | 1094 input_defn->IsStoreLocal() || |
| 1095 input_defn->IsDropTemps() || | 1095 input_defn->IsDropTemps() || |
| 1096 input_defn->IsConstant()) { | 1096 input_defn->IsConstant()); |
| 1097 // Remove the load/store from the graph. | |
| 1098 input_defn->RemoveFromGraph(); | |
| 1099 // Assert we are not referencing nulls in the initial environment. | 1097 // Assert we are not referencing nulls in the initial environment. |
| 1100 ASSERT(reaching_defn->ssa_temp_index() != -1); | 1098 ASSERT(reaching_defn->ssa_temp_index() != -1); |
| 1101 v->set_definition(reaching_defn); | 1099 v->set_definition(reaching_defn); |
| 1102 input_defn = reaching_defn; | 1100 input_defn = reaching_defn; |
| 1103 } | 1101 } |
| 1104 input_defn->AddInputUse(v); | 1102 input_defn->AddInputUse(v); |
| 1105 } | 1103 } |
| 1106 | 1104 |
| 1107 // Drop pushed arguments for calls. | 1105 // Drop pushed arguments for calls. |
| 1108 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { | 1106 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { |
| 1109 env->RemoveLast(); | 1107 env->RemoveLast(); |
| 1110 } | 1108 } |
| 1111 | 1109 |
| 1112 // 2b. Handle LoadLocal, StoreLocal, and Constant. | 1110 // 2b. Handle LoadLocal, StoreLocal, DropTemps and Constant. |
| 1113 Definition* definition = current->AsDefinition(); | 1111 Definition* definition = current->AsDefinition(); |
| 1114 if (definition != NULL) { | 1112 if (definition != NULL) { |
| 1115 LoadLocalInstr* load = definition->AsLoadLocal(); | 1113 LoadLocalInstr* load = definition->AsLoadLocal(); |
| 1116 StoreLocalInstr* store = definition->AsStoreLocal(); | 1114 StoreLocalInstr* store = definition->AsStoreLocal(); |
| 1117 PushTempInstr* push = definition->AsPushTemp(); | |
| 1118 DropTempsInstr* drop = definition->AsDropTemps(); | 1115 DropTempsInstr* drop = definition->AsDropTemps(); |
| 1119 ConstantInstr* constant = definition->AsConstant(); | 1116 ConstantInstr* constant = definition->AsConstant(); |
| 1120 if ((load != NULL) || | 1117 if ((load != NULL) || |
| 1121 (store != NULL) || | 1118 (store != NULL) || |
| 1122 (push != NULL) || | |
| 1123 (drop != NULL) || | 1119 (drop != NULL) || |
| 1124 (constant != NULL)) { | 1120 (constant != NULL)) { |
| 1125 Definition* result = NULL; | 1121 Definition* result = NULL; |
| 1126 if (store != NULL) { | 1122 if (store != NULL) { |
| 1127 // Update renaming environment. | 1123 // Update renaming environment. |
| 1128 intptr_t index = store->local().BitIndexIn(num_non_copied_params_); | 1124 intptr_t index = store->local().BitIndexIn(num_non_copied_params_); |
| 1129 result = store->value()->definition(); | 1125 result = store->value()->definition(); |
| 1130 | 1126 |
| 1131 if (!FLAG_prune_dead_locals || | 1127 if (!FLAG_prune_dead_locals || |
| 1132 variable_liveness->IsStoreAlive(block_entry, store)) { | 1128 variable_liveness->IsStoreAlive(block_entry, store)) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1151 variable_liveness->IsLastLoad(block_entry, load)) { | 1147 variable_liveness->IsLastLoad(block_entry, load)) { |
| 1152 (*env)[index] = constant_dead(); | 1148 (*env)[index] = constant_dead(); |
| 1153 } | 1149 } |
| 1154 | 1150 |
| 1155 // Record captured parameters so that they can be skipped when | 1151 // Record captured parameters so that they can be skipped when |
| 1156 // emitting sync code inside optimized try-blocks. | 1152 // emitting sync code inside optimized try-blocks. |
| 1157 if (load->local().is_captured_parameter()) { | 1153 if (load->local().is_captured_parameter()) { |
| 1158 intptr_t index = load->local().BitIndexIn(num_non_copied_params_); | 1154 intptr_t index = load->local().BitIndexIn(num_non_copied_params_); |
| 1159 captured_parameters_->Add(index); | 1155 captured_parameters_->Add(index); |
| 1160 } | 1156 } |
| 1161 | |
| 1162 } else if (push != NULL) { | |
| 1163 result = push->value()->definition(); | |
| 1164 env->Add(result); | |
| 1165 it.RemoveCurrentFromGraph(); | |
| 1166 continue; | |
| 1167 } else if (drop != NULL) { | 1157 } else if (drop != NULL) { |
| 1168 // Drop temps from the environment. | 1158 // Drop temps from the environment. |
| 1169 for (intptr_t j = 0; j < drop->num_temps(); j++) { | 1159 for (intptr_t j = 0; j < drop->num_temps(); j++) { |
| 1170 env->RemoveLast(); | 1160 env->RemoveLast(); |
| 1171 } | 1161 } |
| 1172 if (drop->value() != NULL) { | 1162 if (drop->value() != NULL) { |
| 1173 result = drop->value()->definition(); | 1163 result = drop->value()->definition(); |
| 1174 } | 1164 } |
| 1175 ASSERT((drop->value() != NULL) || !drop->HasTemp()); | 1165 ASSERT((drop->value() != NULL) || !drop->HasTemp()); |
| 1176 } else { | 1166 } else { |
| 1177 ASSERT(definition->HasTemp()); | 1167 ASSERT(definition->HasTemp()); |
| 1178 result = GetConstant(constant->value()); | 1168 result = GetConstant(constant->value()); |
| 1179 } | 1169 } |
| 1180 // Update expression stack or remove from graph. | 1170 // Update expression stack or remove from graph. |
| 1181 if (definition->HasTemp()) { | 1171 if (definition->HasTemp()) { |
| 1182 ASSERT(result != NULL); | 1172 ASSERT(result != NULL); |
| 1183 env->Add(result); | 1173 env->Add(result); |
| 1184 // We remove load/store/constant instructions when we find their | |
| 1185 // use in 2a. | |
| 1186 } else { | |
| 1187 it.RemoveCurrentFromGraph(); | |
| 1188 } | 1174 } |
| 1175 it.RemoveCurrentFromGraph(); |
| 1189 } else { | 1176 } else { |
| 1190 // Not a load, store, or constant. | 1177 // Not a load, store, drop or constant. |
| 1191 if (definition->HasTemp()) { | 1178 if (definition->HasTemp()) { |
| 1192 // Assign fresh SSA temporary and update expression stack. | 1179 // Assign fresh SSA temporary and update expression stack. |
| 1193 AllocateSSAIndexes(definition); | 1180 AllocateSSAIndexes(definition); |
| 1194 env->Add(definition); | 1181 env->Add(definition); |
| 1195 } | 1182 } |
| 1196 } | 1183 } |
| 1197 } | 1184 } |
| 1198 | 1185 |
| 1199 // 2c. Handle pushed argument. | 1186 // 2c. Handle pushed argument. |
| 1200 PushArgumentInstr* push = current->AsPushArgument(); | 1187 PushArgumentInstr* push = current->AsPushArgument(); |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2060 ReplaceCurrentInstruction(&it, current, replacement); | 2047 ReplaceCurrentInstruction(&it, current, replacement); |
| 2061 changed = true; | 2048 changed = true; |
| 2062 } | 2049 } |
| 2063 } | 2050 } |
| 2064 } | 2051 } |
| 2065 return changed; | 2052 return changed; |
| 2066 } | 2053 } |
| 2067 | 2054 |
| 2068 | 2055 |
| 2069 } // namespace dart | 2056 } // namespace dart |
| OLD | NEW |