Chromium Code Reviews| 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_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/cha.h" | 7 #include "vm/cha.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/hash_map.h" | 9 #include "vm/hash_map.h" |
| 10 #include "vm/il_printer.h" | 10 #include "vm/il_printer.h" |
| (...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1138 LocationSummary* locs = it.Current()->locs(); | 1138 LocationSummary* locs = it.Current()->locs(); |
| 1139 if ((locs != NULL) && locs->can_call()) { | 1139 if ((locs != NULL) && locs->can_call()) { |
| 1140 is_leaf_ = false; | 1140 is_leaf_ = false; |
| 1141 return; | 1141 return; |
| 1142 } | 1142 } |
| 1143 } | 1143 } |
| 1144 } | 1144 } |
| 1145 } | 1145 } |
| 1146 | 1146 |
| 1147 | 1147 |
| 1148 static BlockEntryInstr* FindPreHeader(BlockEntryInstr* header) { | |
| 1149 for (intptr_t j = 0; j < header->PredecessorCount(); ++j) { | |
| 1150 BlockEntryInstr* candidate = header->PredecessorAt(j); | |
|
Kevin Millikin (Google)
2012/09/06 12:42:42
Extra space!
Florian Schneider
2012/09/06 13:05:53
Done.
| |
| 1151 if (header->dominator() == candidate) { | |
| 1152 return candidate; | |
| 1153 } | |
| 1154 } | |
| 1155 return NULL; | |
| 1156 } | |
| 1157 | |
| 1158 | |
| 1159 void LICM::Optimize(FlowGraph* flow_graph) { | |
| 1160 GrowableArray<BlockEntryInstr*> loop_headers; | |
| 1161 flow_graph->ComputeLoops(&loop_headers); | |
| 1162 | |
| 1163 for (intptr_t i = 0; i < loop_headers.length(); ++i) { | |
| 1164 BlockEntryInstr* header = loop_headers[i]; | |
| 1165 // Skip loop that don't have a pre-header block. | |
| 1166 BlockEntryInstr* pre_header = FindPreHeader(header); | |
| 1167 if (pre_header == NULL) continue; | |
| 1168 | |
| 1169 for (intptr_t j = 0; j < header->loop_info()->length(); ++j) { | |
| 1170 BlockEntryInstr* block = (*header->loop_info())[j]; | |
| 1171 for (ForwardInstructionIterator it(block); | |
| 1172 !it.Done(); | |
| 1173 it.Advance()) { | |
| 1174 Definition* current = it.Current()->AsDefinition(); | |
| 1175 if (current != NULL && | |
| 1176 !current->IsPushArgument() && | |
| 1177 !current->HasSideEffect()) { | |
| 1178 bool inputs_loop_invariant = true; | |
| 1179 for (int i = 0; i < current->InputCount(); ++i) { | |
| 1180 Definition* input_def = current->InputAt(i)->definition(); | |
| 1181 if (!input_def->GetBlock()->Dominates(pre_header)) { | |
| 1182 inputs_loop_invariant = false; | |
| 1183 break; | |
| 1184 } | |
| 1185 } | |
| 1186 if (inputs_loop_invariant) { | |
| 1187 // TODO(fschneider): Avoid repeated deoptimization when | |
| 1188 // speculatively hoisting checks. | |
| 1189 if (FLAG_trace_optimization) { | |
| 1190 OS::Print("Hoisting instruction %s:%"Pd" from B%"Pd" to B%"Pd"\n", | |
| 1191 current->DebugName(), | |
| 1192 current->deopt_id(), | |
| 1193 current->GetBlock()->block_id(), | |
| 1194 pre_header->block_id()); | |
| 1195 } | |
| 1196 // Move the instruction out of the loop. | |
| 1197 it.RemoveCurrentFromGraph(); | |
| 1198 GotoInstr* last = pre_header->last_instruction()->AsGoto(); | |
| 1199 current->InsertBefore(last); | |
| 1200 // Attach the environment of the Goto instruction to the hoisted | |
| 1201 // instruction. | |
| 1202 ASSERT(last->env() != NULL); | |
| 1203 last->env()->CopyTo(current); | |
| 1204 current->deopt_id_ = last->GetDeoptId(); | |
| 1205 } | |
| 1206 } | |
| 1207 } | |
| 1208 } | |
| 1209 } | |
| 1210 } | |
| 1211 | |
| 1212 | |
| 1148 void DominatorBasedCSE::Optimize(BlockEntryInstr* graph_entry) { | 1213 void DominatorBasedCSE::Optimize(BlockEntryInstr* graph_entry) { |
| 1149 ASSERT(graph_entry->IsGraphEntry()); | 1214 ASSERT(graph_entry->IsGraphEntry()); |
| 1150 DirectChainedHashMap<Definition*> map; | 1215 DirectChainedHashMap<Definition*> map; |
| 1151 OptimizeRecursive(graph_entry, &map); | 1216 OptimizeRecursive(graph_entry, &map); |
| 1152 } | 1217 } |
| 1153 | 1218 |
| 1154 | 1219 |
| 1155 void DominatorBasedCSE::OptimizeRecursive( | 1220 void DominatorBasedCSE::OptimizeRecursive( |
| 1156 BlockEntryInstr* block, | 1221 BlockEntryInstr* block, |
| 1157 DirectChainedHashMap<Definition*>* map) { | 1222 DirectChainedHashMap<Definition*>* map) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1181 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. | 1246 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. |
| 1182 OptimizeRecursive(child, &child_map); | 1247 OptimizeRecursive(child, &child_map); |
| 1183 } else { | 1248 } else { |
| 1184 OptimizeRecursive(child, map); // Reuse map for the last child. | 1249 OptimizeRecursive(child, map); // Reuse map for the last child. |
| 1185 } | 1250 } |
| 1186 } | 1251 } |
| 1187 } | 1252 } |
| 1188 | 1253 |
| 1189 | 1254 |
| 1190 } // namespace dart | 1255 } // namespace dart |
| OLD | NEW |