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

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

Issue 28633003: Fix bugs in load elimination and type propagation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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
« no previous file with comments | « no previous file | runtime/vm/flow_graph_optimizer.cc » ('j') | runtime/vm/flow_graph_optimizer.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/block_scheduler.h" 10 #include "vm/block_scheduler.h"
(...skipping 26 matching lines...) Expand all
37 DEFINE_FLAG(bool, disassemble, false, "Disassemble dart code."); 37 DEFINE_FLAG(bool, disassemble, false, "Disassemble dart code.");
38 DEFINE_FLAG(bool, disassemble_optimized, false, "Disassemble optimized code."); 38 DEFINE_FLAG(bool, disassemble_optimized, false, "Disassemble optimized code.");
39 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); 39 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler.");
40 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); 40 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations.");
41 DEFINE_FLAG(bool, constant_propagation, true, 41 DEFINE_FLAG(bool, constant_propagation, true,
42 "Do conditional constant propagation/unreachable code elimination."); 42 "Do conditional constant propagation/unreachable code elimination.");
43 DEFINE_FLAG(bool, common_subexpression_elimination, true, 43 DEFINE_FLAG(bool, common_subexpression_elimination, true,
44 "Do common subexpression elimination."); 44 "Do common subexpression elimination.");
45 DEFINE_FLAG(bool, loop_invariant_code_motion, true, 45 DEFINE_FLAG(bool, loop_invariant_code_motion, true,
46 "Do loop invariant code motion."); 46 "Do loop invariant code motion.");
47 DEFINE_FLAG(bool, propagate_types, true, "Do static type propagation.");
48 DEFINE_FLAG(bool, allocation_sinking, true, 47 DEFINE_FLAG(bool, allocation_sinking, true,
49 "Attempt to sink temporary allocations to side exits"); 48 "Attempt to sink temporary allocations to side exits");
50 DEFINE_FLAG(int, deoptimization_counter_threshold, 16, 49 DEFINE_FLAG(int, deoptimization_counter_threshold, 16,
51 "How many times we allow deoptimization before we disallow optimization."); 50 "How many times we allow deoptimization before we disallow optimization.");
52 DEFINE_FLAG(int, deoptimization_counter_licm_threshold, 8, 51 DEFINE_FLAG(int, deoptimization_counter_licm_threshold, 8,
53 "How many times we allow deoptimization before we disable LICM."); 52 "How many times we allow deoptimization before we disable LICM.");
54 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); 53 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining");
55 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis"); 54 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis");
56 DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering."); 55 DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering.");
57 DEFINE_FLAG(bool, verify_compiler, false, 56 DEFINE_FLAG(bool, verify_compiler, false,
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 // TODO(srdjan): Moved before inlining until environment use list can 341 // TODO(srdjan): Moved before inlining until environment use list can
343 // be used to detect when shift-left is outside the scope of bit-and. 342 // be used to detect when shift-left is outside the scope of bit-and.
344 optimizer.TryOptimizeLeftShiftWithBitAndPattern(); 343 optimizer.TryOptimizeLeftShiftWithBitAndPattern();
345 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 344 DEBUG_ASSERT(flow_graph->VerifyUseLists());
346 345
347 // Inlining (mutates the flow graph) 346 // Inlining (mutates the flow graph)
348 if (FLAG_use_inlining) { 347 if (FLAG_use_inlining) {
349 TimerScope timer(FLAG_compiler_stats, 348 TimerScope timer(FLAG_compiler_stats,
350 &CompilerStats::graphinliner_timer); 349 &CompilerStats::graphinliner_timer);
351 // Propagate types to create more inlining opportunities. 350 // Propagate types to create more inlining opportunities.
352 if (FLAG_propagate_types) { 351 FlowGraphTypePropagator::Propagate(flow_graph);
353 FlowGraphTypePropagator propagator(flow_graph);
354 propagator.Propagate();
355 DEBUG_ASSERT(flow_graph->VerifyUseLists());
356 }
357 352
358 // Use propagated class-ids to create more inlining opportunities. 353 // Use propagated class-ids to create more inlining opportunities.
359 optimizer.ApplyClassIds(); 354 optimizer.ApplyClassIds();
360 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 355 DEBUG_ASSERT(flow_graph->VerifyUseLists());
361 356
362 FlowGraphInliner inliner(flow_graph); 357 FlowGraphInliner inliner(flow_graph);
363 inliner.Inline(); 358 inliner.Inline();
364 // Use lists are maintained and validated by the inliner. 359 // Use lists are maintained and validated by the inliner.
365 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 360 DEBUG_ASSERT(flow_graph->VerifyUseLists());
366 } 361 }
367 362
368 // Propagate types and eliminate more type tests. 363 // Propagate types and eliminate more type tests.
369 if (FLAG_propagate_types) { 364 FlowGraphTypePropagator::Propagate(flow_graph);
370 FlowGraphTypePropagator propagator(flow_graph);
371 propagator.Propagate();
372 DEBUG_ASSERT(flow_graph->VerifyUseLists());
373 }
374 365
375 // Use propagated class-ids to optimize further. 366 // Use propagated class-ids to optimize further.
376 optimizer.ApplyClassIds(); 367 optimizer.ApplyClassIds();
377 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 368 DEBUG_ASSERT(flow_graph->VerifyUseLists());
378 369
379 // Do optimizations that depend on the propagated type information. 370 // Do optimizations that depend on the propagated type information.
380 optimizer.Canonicalize(); 371 optimizer.Canonicalize();
381 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 372 DEBUG_ASSERT(flow_graph->VerifyUseLists());
382 373
383 BranchSimplifier::Simplify(flow_graph); 374 BranchSimplifier::Simplify(flow_graph);
384 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 375 DEBUG_ASSERT(flow_graph->VerifyUseLists());
385 376
386 IfConverter::Simplify(flow_graph); 377 IfConverter::Simplify(flow_graph);
387 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 378 DEBUG_ASSERT(flow_graph->VerifyUseLists());
388 379
389 if (FLAG_constant_propagation) { 380 if (FLAG_constant_propagation) {
390 ConstantPropagator::Optimize(flow_graph); 381 ConstantPropagator::Optimize(flow_graph);
391 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 382 DEBUG_ASSERT(flow_graph->VerifyUseLists());
392 // A canonicalization pass to remove e.g. smi checks on smi constants. 383 // A canonicalization pass to remove e.g. smi checks on smi constants.
393 optimizer.Canonicalize(); 384 optimizer.Canonicalize();
394 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 385 DEBUG_ASSERT(flow_graph->VerifyUseLists());
395 // Canonicalization introduced more opportunities for constant 386 // Canonicalization introduced more opportunities for constant
396 // propagation. 387 // propagation.
397 ConstantPropagator::Optimize(flow_graph); 388 ConstantPropagator::Optimize(flow_graph);
398 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 389 DEBUG_ASSERT(flow_graph->VerifyUseLists());
399 } 390 }
400 391
401 // Propagate types and eliminate even more type tests. 392 // Propagate types and eliminate even more type tests.
402 if (FLAG_propagate_types) { 393 // Recompute types after constant propagation to infer more precise
403 // Recompute types after constant propagation to infer more precise 394 // types for uses that were previously reached by now eliminated phis.
404 // types for uses that were previously reached by now eliminated phis. 395 FlowGraphTypePropagator::Propagate(flow_graph);
405 FlowGraphTypePropagator propagator(flow_graph);
406 propagator.Propagate();
407 DEBUG_ASSERT(flow_graph->VerifyUseLists());
408 }
409 396
410 // Unbox doubles. Performed after constant propagation to minimize 397 // Unbox doubles. Performed after constant propagation to minimize
411 // interference from phis merging double values and tagged 398 // interference from phis merging double values and tagged
412 // values comming from dead paths. 399 // values coming from dead paths.
413 optimizer.SelectRepresentations(); 400 optimizer.SelectRepresentations();
414 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 401 DEBUG_ASSERT(flow_graph->VerifyUseLists());
415 402
416 if (FLAG_common_subexpression_elimination || 403 if (FLAG_common_subexpression_elimination ||
417 FLAG_loop_invariant_code_motion) { 404 FLAG_loop_invariant_code_motion) {
418 flow_graph->ComputeBlockEffects(); 405 flow_graph->ComputeBlockEffects();
419 } 406 }
420 407
421 if (FLAG_common_subexpression_elimination) { 408 if (FLAG_common_subexpression_elimination) {
422 if (DominatorBasedCSE::Optimize(flow_graph)) { 409 if (DominatorBasedCSE::Optimize(flow_graph)) {
423 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 410 DEBUG_ASSERT(flow_graph->VerifyUseLists());
424 // Do another round of CSE to take secondary effects into account: 411 // Do another round of CSE to take secondary effects into account:
425 // e.g. when eliminating dependent loads (a.x[0] + a.x[0]) 412 // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
426 // TODO(fschneider): Change to a one-pass optimization pass. 413 // TODO(fschneider): Change to a one-pass optimization pass.
427 DominatorBasedCSE::Optimize(flow_graph); 414 DominatorBasedCSE::Optimize(flow_graph);
428 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 415 DEBUG_ASSERT(flow_graph->VerifyUseLists());
429 } 416 }
430 } 417 }
431 if (FLAG_loop_invariant_code_motion && 418 if (FLAG_loop_invariant_code_motion &&
432 (function.deoptimization_counter() < 419 (function.deoptimization_counter() <
433 FLAG_deoptimization_counter_licm_threshold)) { 420 FLAG_deoptimization_counter_licm_threshold)) {
434 LICM licm(flow_graph); 421 LICM licm(flow_graph);
435 licm.Optimize(); 422 licm.Optimize();
436 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 423 DEBUG_ASSERT(flow_graph->VerifyUseLists());
437 } 424 }
438 flow_graph->RemoveRedefinitions(); 425 flow_graph->RemoveRedefinitions();
439 426
440 if (FLAG_range_analysis) { 427 if (FLAG_range_analysis) {
441 if (FLAG_propagate_types) { 428 // Propagate types after store-load-forwarding. Some phis may have
442 // Propagate types after store-load-forwarding. Some phis may have 429 // become smi phis that can be processed by range analysis.
443 // become smi phis that can be processed by range analysis. 430 FlowGraphTypePropagator::Propagate(flow_graph);
444 FlowGraphTypePropagator propagator(flow_graph); 431
445 propagator.Propagate();
446 DEBUG_ASSERT(flow_graph->VerifyUseLists());
447 }
448 // We have to perform range analysis after LICM because it 432 // We have to perform range analysis after LICM because it
449 // optimistically moves CheckSmi through phis into loop preheaders 433 // optimistically moves CheckSmi through phis into loop preheaders
450 // making some phis smi. 434 // making some phis smi.
451 optimizer.InferSmiRanges(); 435 optimizer.InferSmiRanges();
452 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 436 DEBUG_ASSERT(flow_graph->VerifyUseLists());
453 } 437 }
454 438
455 if (FLAG_constant_propagation) { 439 if (FLAG_constant_propagation) {
456 // Constant propagation can use information from range analysis to 440 // Constant propagation can use information from range analysis to
457 // find unreachable branch targets. 441 // find unreachable branch targets.
458 ConstantPropagator::OptimizeBranches(flow_graph); 442 ConstantPropagator::OptimizeBranches(flow_graph);
459 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 443 DEBUG_ASSERT(flow_graph->VerifyUseLists());
460 } 444 }
461 445
462 if (FLAG_propagate_types) { 446 // Recompute types after code movement was done to ensure correct
463 // Recompute types after code movement was done to ensure correct 447 // reaching types for hoisted values.
464 // reaching types for hoisted values. 448 FlowGraphTypePropagator::Propagate(flow_graph);
465 FlowGraphTypePropagator propagator(flow_graph);
466 propagator.Propagate();
467 DEBUG_ASSERT(flow_graph->VerifyUseLists());
468 }
469 449
470 // Optimize try-blocks. 450 // Optimize try-blocks.
471 TryCatchAnalyzer::Optimize(flow_graph); 451 TryCatchAnalyzer::Optimize(flow_graph);
472 452
473 // Detach environments from the instructions that can't deoptimize. 453 // Detach environments from the instructions that can't deoptimize.
474 // Do it before we attempt to perform allocation sinking to minimize 454 // Do it before we attempt to perform allocation sinking to minimize
475 // amount of materializations it has to perform. 455 // amount of materializations it has to perform.
476 optimizer.EliminateEnvironments(); 456 optimizer.EliminateEnvironments();
477 457
478 // Attempt to sink allocations of temporary non-escaping objects to 458 // Attempt to sink allocations of temporary non-escaping objects to
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 Object::Handle(isolate->object_store()->sticky_error()); 923 Object::Handle(isolate->object_store()->sticky_error());
944 isolate->object_store()->clear_sticky_error(); 924 isolate->object_store()->clear_sticky_error();
945 isolate->set_long_jump_base(base); 925 isolate->set_long_jump_base(base);
946 return result.raw(); 926 return result.raw();
947 } 927 }
948 UNREACHABLE(); 928 UNREACHABLE();
949 return Object::null(); 929 return Object::null();
950 } 930 }
951 931
952 } // namespace dart 932 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_optimizer.cc » ('j') | runtime/vm/flow_graph_optimizer.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698