Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: runtime/vm/compiler.cc

Issue 12529008: Collect type feedback for fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: ensure that not-null constraints are recomputed correctly Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 if (FLAG_trace_compiler) { 103 if (FLAG_trace_compiler) {
104 OS::Print("--> patching entry %#"Px"\n", 104 OS::Print("--> patching entry %#"Px"\n",
105 Code::Handle(function.CurrentCode()).EntryPoint()); 105 Code::Handle(function.CurrentCode()).EntryPoint());
106 } 106 }
107 function.SwitchToUnoptimizedCode(); 107 function.SwitchToUnoptimizedCode();
108 if (FLAG_trace_compiler) { 108 if (FLAG_trace_compiler) {
109 OS::Print("--> restoring entry at %#"Px"\n", 109 OS::Print("--> restoring entry at %#"Px"\n",
110 Code::Handle(function.unoptimized_code()).EntryPoint()); 110 Code::Handle(function.unoptimized_code()).EntryPoint());
111 } 111 }
112 } 112 }
113 113
srdjan 2013/03/18 18:54:35 why the deleted line?
Vyacheslav Egorov (Google) 2013/03/18 19:41:18 Done.
114
115 // Return false if bailed out. 114 // Return false if bailed out.
116 static bool CompileParsedFunctionHelper(const ParsedFunction& parsed_function, 115 static bool CompileParsedFunctionHelper(const ParsedFunction& parsed_function,
117 bool optimized) { 116 bool optimized) {
118 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); 117 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer);
119 bool is_compiled = false; 118 bool is_compiled = false;
120 Isolate* isolate = Isolate::Current(); 119 Isolate* isolate = Isolate::Current();
121 HANDLESCOPE(isolate); 120 HANDLESCOPE(isolate);
122 ASSERT(isolate->ic_data_array() == Array::null()); // Must be reset to null. 121 ASSERT(isolate->ic_data_array() == Array::null()); // Must be reset to null.
123 const intptr_t prev_deopt_id = isolate->deopt_id(); 122 const intptr_t prev_deopt_id = isolate->deopt_id();
124 isolate->set_deopt_id(0); 123 isolate->set_deopt_id(0);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 // Transform to SSA (virtual register 0 and no inlining arguments). 159 // Transform to SSA (virtual register 0 and no inlining arguments).
161 flow_graph->ComputeSSA(0, NULL); 160 flow_graph->ComputeSSA(0, NULL);
162 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 161 DEBUG_ASSERT(flow_graph->VerifyUseLists());
163 } 162 }
164 163
165 if (FLAG_print_flow_graph || 164 if (FLAG_print_flow_graph ||
166 (optimized && FLAG_print_flow_graph_optimized)) { 165 (optimized && FLAG_print_flow_graph_optimized)) {
167 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); 166 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
168 } 167 }
169 168
169 ZoneGrowableArray<Field*>* guarded_fields = NULL;
170
170 if (optimized) { 171 if (optimized) {
171 TimerScope timer(FLAG_compiler_stats, 172 TimerScope timer(FLAG_compiler_stats,
172 &CompilerStats::graphoptimizer_timer, 173 &CompilerStats::graphoptimizer_timer,
173 isolate); 174 isolate);
174 175
175 FlowGraphOptimizer optimizer(flow_graph); 176 FlowGraphOptimizer optimizer(flow_graph);
176 optimizer.ApplyICData(); 177 optimizer.ApplyICData();
177 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 178 DEBUG_ASSERT(flow_graph->VerifyUseLists());
178 179
179 // Optimize (a << b) & c patterns. Must occur before 180 // Optimize (a << b) & c patterns. Must occur before
180 // 'SelectRepresentations' which inserts conversion nodes. 181 // 'SelectRepresentations' which inserts conversion nodes.
181 // TODO(srdjan): Moved before inlining until environment use list can 182 // TODO(srdjan): Moved before inlining until environment use list can
182 // be used to detect when shift-left is outside the scope of bit-and. 183 // be used to detect when shift-left is outside the scope of bit-and.
183 optimizer.TryOptimizeLeftShiftWithBitAndPattern(); 184 optimizer.TryOptimizeLeftShiftWithBitAndPattern();
184 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 185 DEBUG_ASSERT(flow_graph->VerifyUseLists());
185 186
186 // Inlining (mutates the flow graph) 187 // Inlining (mutates the flow graph)
187 if (FLAG_use_inlining) { 188 if (FLAG_use_inlining) {
188 TimerScope timer(FLAG_compiler_stats, 189 TimerScope timer(FLAG_compiler_stats,
189 &CompilerStats::graphinliner_timer); 190 &CompilerStats::graphinliner_timer);
190 FlowGraphInliner inliner(flow_graph); 191 FlowGraphInliner inliner(flow_graph);
191 inliner.Inline(); 192 inliner.Inline();
192 // Use lists are maintained and validated by the inliner. 193 // Use lists are maintained and validated by the inliner.
193 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 194 DEBUG_ASSERT(flow_graph->VerifyUseLists());
194 } 195 }
195 196
197 guarded_fields = flow_graph->FieldDependencies();
198
196 // Propagate types and eliminate more type tests. 199 // Propagate types and eliminate more type tests.
197 if (FLAG_propagate_types) { 200 if (FLAG_propagate_types) {
198 FlowGraphTypePropagator propagator(flow_graph); 201 FlowGraphTypePropagator propagator(flow_graph);
199 propagator.Propagate(); 202 propagator.Propagate();
200 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 203 DEBUG_ASSERT(flow_graph->VerifyUseLists());
201 } 204 }
202 205
203 // Use propagated class-ids to optimize further. 206 // Use propagated class-ids to optimize further.
204 optimizer.ApplyClassIds(); 207 optimizer.ApplyClassIds();
205 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 208 DEBUG_ASSERT(flow_graph->VerifyUseLists());
206 209
207 // Do optimizations that depend on the propagated type information. 210 // Do optimizations that depend on the propagated type information.
208 optimizer.Canonicalize(); 211 optimizer.Canonicalize();
209 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 212 DEBUG_ASSERT(flow_graph->VerifyUseLists());
210 213
211 BranchSimplifier::Simplify(flow_graph); 214 BranchSimplifier::Simplify(flow_graph);
212 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 215 DEBUG_ASSERT(flow_graph->VerifyUseLists());
213 216
214 if (FLAG_constant_propagation) { 217 if (FLAG_constant_propagation) {
215 ConstantPropagator::Optimize(flow_graph); 218 ConstantPropagator::Optimize(flow_graph);
216 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 219 DEBUG_ASSERT(flow_graph->VerifyUseLists());
217 // A canonicalization pass to remove e.g. smi checks on smi constants. 220 // A canonicalization pass to remove e.g. smi checks on smi constants.
218 optimizer.Canonicalize(); 221 optimizer.Canonicalize();
219 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 222 DEBUG_ASSERT(flow_graph->VerifyUseLists());
220 } 223 }
221 224
222 // Propagate types and eliminate even more type tests. 225 // Propagate types and eliminate even more type tests.
223 if (FLAG_propagate_types) { 226 if (FLAG_propagate_types) {
227 // Recompute types after constant propagation to infer more precise
228 // types for uses that were previously reached by now eliminated phis.
224 FlowGraphTypePropagator propagator(flow_graph); 229 FlowGraphTypePropagator propagator(flow_graph);
225 propagator.Propagate(); 230 propagator.Propagate();
226 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 231 DEBUG_ASSERT(flow_graph->VerifyUseLists());
227 } 232 }
228 233
229 // Unbox doubles. Performed after constant propagation to minimize 234 // Unbox doubles. Performed after constant propagation to minimize
230 // interference from phis merging double values and tagged 235 // interference from phis merging double values and tagged
231 // values comming from dead paths. 236 // values comming from dead paths.
232 optimizer.SelectRepresentations(); 237 optimizer.SelectRepresentations();
233 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 238 DEBUG_ASSERT(flow_graph->VerifyUseLists());
(...skipping 18 matching lines...) Expand all
252 257
253 if (FLAG_range_analysis) { 258 if (FLAG_range_analysis) {
254 // We have to perform range analysis after LICM because it 259 // We have to perform range analysis after LICM because it
255 // optimistically moves CheckSmi through phis into loop preheaders 260 // optimistically moves CheckSmi through phis into loop preheaders
256 // making some phis smi. 261 // making some phis smi.
257 optimizer.InferSmiRanges(); 262 optimizer.InferSmiRanges();
258 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 263 DEBUG_ASSERT(flow_graph->VerifyUseLists());
259 } 264 }
260 265
261 // The final canonicalization pass before the code generation. 266 // The final canonicalization pass before the code generation.
267 if (FLAG_propagate_types) {
268 // Propagate types one more time after code movement phases.
269 // This recomputes types of values that became dominated by
270 // hoisted checks.
271 FlowGraphTypePropagator propagator(flow_graph);
272 propagator.Propagate();
273 DEBUG_ASSERT(flow_graph->VerifyUseLists());
274 }
262 optimizer.Canonicalize(); 275 optimizer.Canonicalize();
263 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 276 DEBUG_ASSERT(flow_graph->VerifyUseLists());
264 277
265 // Perform register allocation on the SSA graph. 278 // Perform register allocation on the SSA graph.
266 FlowGraphAllocator allocator(*flow_graph); 279 FlowGraphAllocator allocator(*flow_graph);
267 allocator.AllocateRegisters(); 280 allocator.AllocateRegisters();
268 281
269 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { 282 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
270 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); 283 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
271 } 284 }
(...skipping 17 matching lines...) Expand all
289 const Code& code = Code::Handle( 302 const Code& code = Code::Handle(
290 Code::FinalizeCode(function, &assembler, optimized)); 303 Code::FinalizeCode(function, &assembler, optimized));
291 code.set_is_optimized(optimized); 304 code.set_is_optimized(optimized);
292 graph_compiler.FinalizePcDescriptors(code); 305 graph_compiler.FinalizePcDescriptors(code);
293 graph_compiler.FinalizeDeoptInfo(code); 306 graph_compiler.FinalizeDeoptInfo(code);
294 graph_compiler.FinalizeStackmaps(code); 307 graph_compiler.FinalizeStackmaps(code);
295 graph_compiler.FinalizeVarDescriptors(code); 308 graph_compiler.FinalizeVarDescriptors(code);
296 graph_compiler.FinalizeExceptionHandlers(code); 309 graph_compiler.FinalizeExceptionHandlers(code);
297 graph_compiler.FinalizeComments(code); 310 graph_compiler.FinalizeComments(code);
298 graph_compiler.FinalizeStaticCallTargetsTable(code); 311 graph_compiler.FinalizeStaticCallTargetsTable(code);
312
299 if (optimized) { 313 if (optimized) {
300 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); 314 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode()));
301 function.SetCode(code); 315 function.SetCode(code);
302 if (FLAG_trace_compiler) { 316 if (FLAG_trace_compiler) {
303 OS::Print("--> patching entry %#"Px"\n", 317 OS::Print("--> patching entry %#"Px"\n",
304 Code::Handle(function.unoptimized_code()).EntryPoint()); 318 Code::Handle(function.unoptimized_code()).EntryPoint());
305 } 319 }
320
321 for (intptr_t i = 0; i < guarded_fields->length(); i++) {
322 const Field& field = *(*guarded_fields)[i];
323 field.RegisterDependentCode(code);
324 }
306 } else { 325 } else {
307 function.set_unoptimized_code(code); 326 function.set_unoptimized_code(code);
308 function.SetCode(code); 327 function.SetCode(code);
309 ASSERT(CodePatcher::CodeIsPatchable(code)); 328 ASSERT(CodePatcher::CodeIsPatchable(code));
310 } 329 }
311 } 330 }
312 is_compiled = true; 331 is_compiled = true;
313 } else { 332 } else {
314 // We bailed out. 333 // We bailed out.
315 Error& bailout_error = Error::Handle( 334 Error& bailout_error = Error::Handle(
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 Object::Handle(isolate->object_store()->sticky_error()); 680 Object::Handle(isolate->object_store()->sticky_error());
662 isolate->object_store()->clear_sticky_error(); 681 isolate->object_store()->clear_sticky_error();
663 isolate->set_long_jump_base(base); 682 isolate->set_long_jump_base(base);
664 return result.raw(); 683 return result.raw();
665 } 684 }
666 UNREACHABLE(); 685 UNREACHABLE();
667 return Object::null(); 686 return Object::null();
668 } 687 }
669 688
670 } // namespace dart 689 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698