| 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/compiler.h" | 5 #include "vm/compiler.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 | 8 |
| 9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
| 10 #include "vm/code_generator.h" | 10 #include "vm/code_generator.h" |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 // Transform to SSA (virtual register 0 and no inlining arguments). | 160 // Transform to SSA (virtual register 0 and no inlining arguments). |
| 161 flow_graph->ComputeSSA(0, NULL); | 161 flow_graph->ComputeSSA(0, NULL); |
| 162 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 162 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 163 } | 163 } |
| 164 | 164 |
| 165 if (FLAG_print_flow_graph || | 165 if (FLAG_print_flow_graph || |
| 166 (optimized && FLAG_print_flow_graph_optimized)) { | 166 (optimized && FLAG_print_flow_graph_optimized)) { |
| 167 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); | 167 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); |
| 168 } | 168 } |
| 169 | 169 |
| 170 const ZoneGrowableArray<Field*>* guarded_fields = NULL; | 170 // Collect all instance fields that are loaded in the graph and |
| 171 | 171 // have non-generic type feedback attached to them that can |
| 172 // potentially affect optimizations. |
| 173 GrowableArray<Field*> guarded_fields(10); |
| 172 if (optimized) { | 174 if (optimized) { |
| 173 TimerScope timer(FLAG_compiler_stats, | 175 TimerScope timer(FLAG_compiler_stats, |
| 174 &CompilerStats::graphoptimizer_timer, | 176 &CompilerStats::graphoptimizer_timer, |
| 175 isolate); | 177 isolate); |
| 176 | 178 |
| 177 FlowGraphOptimizer optimizer(flow_graph); | 179 FlowGraphOptimizer optimizer(flow_graph, &guarded_fields); |
| 178 optimizer.ApplyICData(); | 180 optimizer.ApplyICData(); |
| 179 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 181 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 180 | 182 |
| 181 // Optimize (a << b) & c patterns. Must occur before | 183 // Optimize (a << b) & c patterns. Must occur before |
| 182 // 'SelectRepresentations' which inserts conversion nodes. | 184 // 'SelectRepresentations' which inserts conversion nodes. |
| 183 // TODO(srdjan): Moved before inlining until environment use list can | 185 // TODO(srdjan): Moved before inlining until environment use list can |
| 184 // be used to detect when shift-left is outside the scope of bit-and. | 186 // be used to detect when shift-left is outside the scope of bit-and. |
| 185 optimizer.TryOptimizeLeftShiftWithBitAndPattern(); | 187 optimizer.TryOptimizeLeftShiftWithBitAndPattern(); |
| 186 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 188 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 187 | 189 |
| 188 // Inlining (mutates the flow graph) | 190 // Inlining (mutates the flow graph) |
| 189 if (FLAG_use_inlining) { | 191 if (FLAG_use_inlining) { |
| 190 TimerScope timer(FLAG_compiler_stats, | 192 TimerScope timer(FLAG_compiler_stats, |
| 191 &CompilerStats::graphinliner_timer); | 193 &CompilerStats::graphinliner_timer); |
| 192 FlowGraphInliner inliner(flow_graph); | 194 FlowGraphInliner inliner(flow_graph, &guarded_fields); |
| 193 inliner.Inline(); | 195 inliner.Inline(); |
| 194 // Use lists are maintained and validated by the inliner. | 196 // Use lists are maintained and validated by the inliner. |
| 195 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 197 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 196 } | 198 } |
| 197 | 199 |
| 198 guarded_fields = flow_graph->FieldDependencies(); | |
| 199 | |
| 200 // Propagate types and eliminate more type tests. | 200 // Propagate types and eliminate more type tests. |
| 201 if (FLAG_propagate_types) { | 201 if (FLAG_propagate_types) { |
| 202 FlowGraphTypePropagator propagator(flow_graph); | 202 FlowGraphTypePropagator propagator(flow_graph); |
| 203 propagator.Propagate(); | 203 propagator.Propagate(); |
| 204 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 204 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 205 } | 205 } |
| 206 | 206 |
| 207 // Use propagated class-ids to optimize further. | 207 // Use propagated class-ids to optimize further. |
| 208 optimizer.ApplyClassIds(); | 208 optimizer.ApplyClassIds(); |
| 209 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 209 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 318 graph_compiler.FinalizeStaticCallTargetsTable(code); | 318 graph_compiler.FinalizeStaticCallTargetsTable(code); |
| 319 | 319 |
| 320 if (optimized) { | 320 if (optimized) { |
| 321 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); | 321 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); |
| 322 function.SetCode(code); | 322 function.SetCode(code); |
| 323 if (FLAG_trace_compiler) { | 323 if (FLAG_trace_compiler) { |
| 324 OS::Print("--> patching entry %#"Px"\n", | 324 OS::Print("--> patching entry %#"Px"\n", |
| 325 Code::Handle(function.unoptimized_code()).EntryPoint()); | 325 Code::Handle(function.unoptimized_code()).EntryPoint()); |
| 326 } | 326 } |
| 327 | 327 |
| 328 for (intptr_t i = 0; i < guarded_fields->length(); i++) { | 328 for (intptr_t i = 0; i < guarded_fields.length(); i++) { |
| 329 const Field& field = *(*guarded_fields)[i]; | 329 const Field& field = *guarded_fields[i]; |
| 330 field.RegisterDependentCode(code); | 330 field.RegisterDependentCode(code); |
| 331 } | 331 } |
| 332 } else { | 332 } else { |
| 333 function.set_unoptimized_code(code); | 333 function.set_unoptimized_code(code); |
| 334 function.SetCode(code); | 334 function.SetCode(code); |
| 335 ASSERT(CodePatcher::CodeIsPatchable(code)); | 335 ASSERT(CodePatcher::CodeIsPatchable(code)); |
| 336 } | 336 } |
| 337 } | 337 } |
| 338 is_compiled = true; | 338 is_compiled = true; |
| 339 } else { | 339 } else { |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 Object::Handle(isolate->object_store()->sticky_error()); | 687 Object::Handle(isolate->object_store()->sticky_error()); |
| 688 isolate->object_store()->clear_sticky_error(); | 688 isolate->object_store()->clear_sticky_error(); |
| 689 isolate->set_long_jump_base(base); | 689 isolate->set_long_jump_base(base); |
| 690 return result.raw(); | 690 return result.raw(); |
| 691 } | 691 } |
| 692 UNREACHABLE(); | 692 UNREACHABLE(); |
| 693 return Object::null(); | 693 return Object::null(); |
| 694 } | 694 } |
| 695 | 695 |
| 696 } // namespace dart | 696 } // namespace dart |
| OLD | NEW |