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/compiler.h" | 5 #include "vm/compiler.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
| 10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
| 11 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
| 12 #include "vm/debugger.h" | 12 #include "vm/debugger.h" |
| 13 #include "vm/disassembler.h" | 13 #include "vm/disassembler.h" |
| 14 #include "vm/exceptions.h" | 14 #include "vm/exceptions.h" |
| 15 #include "vm/flags.h" | 15 #include "vm/flags.h" |
| 16 #include "vm/flow_graph.h" | |
| 16 #include "vm/flow_graph_allocator.h" | 17 #include "vm/flow_graph_allocator.h" |
| 17 #include "vm/flow_graph_builder.h" | 18 #include "vm/flow_graph_builder.h" |
| 18 #include "vm/flow_graph_compiler.h" | 19 #include "vm/flow_graph_compiler.h" |
| 19 #include "vm/flow_graph_optimizer.h" | 20 #include "vm/flow_graph_optimizer.h" |
| 20 #include "vm/il_printer.h" | 21 #include "vm/il_printer.h" |
| 21 #include "vm/longjump.h" | 22 #include "vm/longjump.h" |
| 22 #include "vm/object.h" | 23 #include "vm/object.h" |
| 23 #include "vm/object_store.h" | 24 #include "vm/object_store.h" |
| 24 #include "vm/os.h" | 25 #include "vm/os.h" |
| 25 #include "vm/parser.h" | 26 #include "vm/parser.h" |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); | 126 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); |
| 126 bool is_compiled = false; | 127 bool is_compiled = false; |
| 127 Isolate* isolate = Isolate::Current(); | 128 Isolate* isolate = Isolate::Current(); |
| 128 ASSERT(isolate->ic_data_array() == Array::null()); // Must be reset to null. | 129 ASSERT(isolate->ic_data_array() == Array::null()); // Must be reset to null. |
| 129 const intptr_t prev_deopt_id = isolate->deopt_id(); | 130 const intptr_t prev_deopt_id = isolate->deopt_id(); |
| 130 isolate->set_deopt_id(0); | 131 isolate->set_deopt_id(0); |
| 131 LongJump* old_base = isolate->long_jump_base(); | 132 LongJump* old_base = isolate->long_jump_base(); |
| 132 LongJump bailout_jump; | 133 LongJump bailout_jump; |
| 133 isolate->set_long_jump_base(&bailout_jump); | 134 isolate->set_long_jump_base(&bailout_jump); |
| 134 if (setjmp(*bailout_jump.Set()) == 0) { | 135 if (setjmp(*bailout_jump.Set()) == 0) { |
| 135 GrowableArray<BlockEntryInstr*> block_order; | 136 FlowGraph flow_graph(parsed_function); |
|
Kevin Millikin (Google)
2012/08/16 08:09:57
It's a bit strange (to me) that there is such a th
zerny-google
2012/08/16 11:52:27
Sure.
| |
| 136 // TimerScope needs an isolate to be properly terminated in case of a | 137 // TimerScope needs an isolate to be properly terminated in case of a |
| 137 // LongJump. | 138 // LongJump. |
| 138 { | 139 { |
| 139 TimerScope timer(FLAG_compiler_stats, | 140 TimerScope timer(FLAG_compiler_stats, |
| 140 &CompilerStats::graphbuilder_timer, | 141 &CompilerStats::graphbuilder_timer, |
| 141 isolate); | 142 isolate); |
| 142 if (optimized) { | 143 if (optimized) { |
| 143 // Transition to optimized code only from unoptimized code ... | 144 // Transition to optimized code only from unoptimized code ... |
| 144 // for now. | 145 // for now. |
| 145 ASSERT(parsed_function.function().HasCode()); | 146 ASSERT(parsed_function.function().HasCode()); |
| 146 ASSERT(!parsed_function.function().HasOptimizedCode()); | 147 ASSERT(!parsed_function.function().HasOptimizedCode()); |
| 147 // Extract type feedback before the graph is built, as the graph | 148 // Extract type feedback before the graph is built, as the graph |
| 148 // builder uses it to attach it to nodes. | 149 // builder uses it to attach it to nodes. |
| 149 // Do not use type feedback to optimize a function that was | 150 // Do not use type feedback to optimize a function that was |
| 150 // deoptimized too often. | 151 // deoptimized too often. |
| 151 if (parsed_function.function().deoptimization_counter() < | 152 if (parsed_function.function().deoptimization_counter() < |
| 152 FLAG_deoptimization_counter_threshold) { | 153 FLAG_deoptimization_counter_threshold) { |
| 153 const Code& unoptimized_code = | 154 const Code& unoptimized_code = |
| 154 Code::Handle(parsed_function.function().unoptimized_code()); | 155 Code::Handle(parsed_function.function().unoptimized_code()); |
| 155 isolate->set_ic_data_array( | 156 isolate->set_ic_data_array( |
| 156 ExtractTypeFeedbackArray(unoptimized_code)); | 157 ExtractTypeFeedbackArray(unoptimized_code)); |
| 157 } | 158 } |
| 158 } | 159 } |
| 159 FlowGraphBuilder graph_builder(parsed_function); | |
| 160 graph_builder.BuildGraph(optimized, use_ssa); | |
| 161 | 160 |
| 162 // The non-optimizing compiler compiles blocks in reverse postorder, | 161 // Build the flow graph. |
| 163 // because it is a 'natural' order for the human reader of the | 162 flow_graph.BuildGraph(); |
| 164 // generated code. | 163 |
| 165 intptr_t length = graph_builder.postorder_block_entries().length(); | 164 // Transform to SSA. |
| 166 for (intptr_t i = length - 1; i >= 0; --i) { | 165 if (optimized && use_ssa) flow_graph.ComputeSSA(); |
| 167 block_order.Add(graph_builder.postorder_block_entries()[i]); | 166 |
| 167 if (FLAG_print_flow_graph) { | |
| 168 // Print flow graph to stdout. | |
|
Kevin Millikin (Google)
2012/08/16 08:09:57
Did we lose a "Before Optimizations:\n" that used
zerny-google
2012/08/16 11:52:27
I can't seem to find that in git-svn, but will be
| |
| 169 FlowGraphPrinter printer(parsed_function.function(), | |
|
Kevin Millikin (Google)
2012/08/16 08:09:57
I seems like this constructor could just take the
zerny-google
2012/08/16 11:52:27
Yes. The other utilities should really take the gr
| |
| 170 flow_graph.reverse_postorder()); | |
| 171 printer.PrintBlocks(); | |
| 168 } | 172 } |
| 173 if (Dart::flow_graph_writer() != NULL) { | |
| 174 // Write flow graph to file. | |
| 175 FlowGraphVisualizer printer(parsed_function.function(), | |
|
Kevin Millikin (Google)
2012/08/16 08:09:57
Also here and most of the constructors below, the
zerny-google
2012/08/16 11:52:27
Yes.
| |
| 176 flow_graph.reverse_postorder()); | |
| 177 printer.PrintFunction(); | |
| 178 } | |
| 179 | |
| 169 if (optimized) { | 180 if (optimized) { |
| 170 FlowGraphOptimizer optimizer(block_order); | 181 FlowGraphOptimizer optimizer(flow_graph.reverse_postorder()); |
| 171 optimizer.ApplyICData(); | 182 optimizer.ApplyICData(); |
| 172 | 183 |
| 173 // Propagate types and eliminate more type tests. | 184 // Propagate types and eliminate more type tests. |
| 174 FlowGraphTypePropagator propagator(parsed_function, block_order); | 185 FlowGraphTypePropagator propagator(parsed_function, |
| 186 flow_graph.reverse_postorder()); | |
| 175 propagator.PropagateTypes(); | 187 propagator.PropagateTypes(); |
| 176 | 188 |
| 177 // Do optimizations that depend on the propagated type information. | 189 // Do optimizations that depend on the propagated type information. |
| 178 optimizer.OptimizeComputations(); | 190 optimizer.OptimizeComputations(); |
| 179 | 191 |
| 180 if (use_ssa) { | 192 if (use_ssa) { |
| 181 // Perform register allocation on the SSA graph. | 193 // Perform register allocation on the SSA graph. |
| 182 FlowGraphAllocator allocator(block_order, &graph_builder); | 194 FlowGraphAllocator allocator(&flow_graph); |
| 183 allocator.AllocateRegisters(); | 195 allocator.AllocateRegisters(); |
| 184 } | 196 } |
| 197 | |
| 185 if (FLAG_print_flow_graph) { | 198 if (FLAG_print_flow_graph) { |
| 186 OS::Print("After Optimizations:\n"); | 199 OS::Print("After Optimizations:\n"); |
| 187 FlowGraphPrinter printer(Function::Handle(), block_order); | 200 FlowGraphPrinter printer(Function::Handle(), |
| 201 flow_graph.reverse_postorder()); | |
| 188 printer.PrintBlocks(); | 202 printer.PrintBlocks(); |
| 189 } | 203 } |
| 190 } | 204 } |
| 191 } | 205 } |
| 192 | 206 |
| 193 bool is_leaf = false; | 207 bool is_leaf = false; |
| 194 if (optimized) { | 208 if (optimized) { |
| 195 FlowGraphAnalyzer analyzer(block_order); | 209 FlowGraphAnalyzer analyzer(flow_graph.reverse_postorder()); |
| 196 analyzer.Analyze(); | 210 analyzer.Analyze(); |
| 197 is_leaf = analyzer.is_leaf(); | 211 is_leaf = analyzer.is_leaf(); |
| 198 } | 212 } |
| 199 Assembler assembler; | 213 Assembler assembler; |
| 200 FlowGraphCompiler graph_compiler(&assembler, | 214 FlowGraphCompiler graph_compiler(&assembler, |
| 201 parsed_function, | 215 parsed_function, |
| 202 block_order, | 216 flow_graph.reverse_postorder(), |
| 203 optimized, | 217 optimized, |
| 204 optimized && use_ssa, | 218 optimized && use_ssa, |
| 205 is_leaf); | 219 is_leaf); |
| 206 { | 220 { |
| 207 TimerScope timer(FLAG_compiler_stats, | 221 TimerScope timer(FLAG_compiler_stats, |
| 208 &CompilerStats::graphcompiler_timer, | 222 &CompilerStats::graphcompiler_timer, |
| 209 isolate); | 223 isolate); |
| 210 graph_compiler.CompileGraph(); | 224 graph_compiler.CompileGraph(); |
| 211 } | 225 } |
| 212 { | 226 { |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 531 result = isolate->object_store()->sticky_error(); | 545 result = isolate->object_store()->sticky_error(); |
| 532 isolate->object_store()->clear_sticky_error(); | 546 isolate->object_store()->clear_sticky_error(); |
| 533 isolate->set_long_jump_base(base); | 547 isolate->set_long_jump_base(base); |
| 534 return result.raw(); | 548 return result.raw(); |
| 535 } | 549 } |
| 536 UNREACHABLE(); | 550 UNREACHABLE(); |
| 537 return Object::null(); | 551 return Object::null(); |
| 538 } | 552 } |
| 539 | 553 |
| 540 } // namespace dart | 554 } // namespace dart |
| OLD | NEW |