| 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/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 3048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3059 | 3059 |
| 3060 void ConstantPropagator::VisitStoreLocal(StoreLocalInstr* instr) { | 3060 void ConstantPropagator::VisitStoreLocal(StoreLocalInstr* instr) { |
| 3061 // Instruction is eliminated when translating to SSA. | 3061 // Instruction is eliminated when translating to SSA. |
| 3062 UNREACHABLE(); | 3062 UNREACHABLE(); |
| 3063 } | 3063 } |
| 3064 | 3064 |
| 3065 | 3065 |
| 3066 void ConstantPropagator::VisitStrictCompare(StrictCompareInstr* instr) { | 3066 void ConstantPropagator::VisitStrictCompare(StrictCompareInstr* instr) { |
| 3067 const Object& left = instr->left()->definition()->constant_value(); | 3067 const Object& left = instr->left()->definition()->constant_value(); |
| 3068 const Object& right = instr->right()->definition()->constant_value(); | 3068 const Object& right = instr->right()->definition()->constant_value(); |
| 3069 |
| 3069 if (IsNonConstant(left) || IsNonConstant(right)) { | 3070 if (IsNonConstant(left) || IsNonConstant(right)) { |
| 3070 SetValue(instr, non_constant_); | 3071 // TODO(vegorov): incorporate nullability information into the lattice. |
| 3072 if ((left.IsNull() && (instr->right()->ResultCid() != kDynamicCid)) || |
| 3073 (right.IsNull() && (instr->left()->ResultCid() != kDynamicCid))) { |
| 3074 bool result = left.IsNull() ? (instr->right()->ResultCid() == kNullCid) |
| 3075 : (instr->left()->ResultCid() == kNullCid); |
| 3076 if (instr->kind() == Token::kNE_STRICT) result = !result; |
| 3077 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); |
| 3078 } else { |
| 3079 SetValue(instr, non_constant_); |
| 3080 } |
| 3071 } else if (IsConstant(left) && IsConstant(right)) { | 3081 } else if (IsConstant(left) && IsConstant(right)) { |
| 3072 bool result = (left.raw() == right.raw()); | 3082 bool result = (left.raw() == right.raw()); |
| 3073 if (instr->kind() == Token::kNE_STRICT) result = !result; | 3083 if (instr->kind() == Token::kNE_STRICT) result = !result; |
| 3074 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); | 3084 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); |
| 3075 } | 3085 } |
| 3076 } | 3086 } |
| 3077 | 3087 |
| 3078 | 3088 |
| 3079 void ConstantPropagator::VisitEqualityCompare(EqualityCompareInstr* instr) { | 3089 void ConstantPropagator::VisitEqualityCompare(EqualityCompareInstr* instr) { |
| 3080 const Object& left = instr->left()->definition()->constant_value(); | 3090 const Object& left = instr->left()->definition()->constant_value(); |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3397 } | 3407 } |
| 3398 | 3408 |
| 3399 | 3409 |
| 3400 void ConstantPropagator::Transform() { | 3410 void ConstantPropagator::Transform() { |
| 3401 if (FLAG_trace_constant_propagation) { | 3411 if (FLAG_trace_constant_propagation) { |
| 3402 OS::Print("\n==== Before constant propagation ====\n"); | 3412 OS::Print("\n==== Before constant propagation ====\n"); |
| 3403 FlowGraphPrinter printer(*graph_); | 3413 FlowGraphPrinter printer(*graph_); |
| 3404 printer.PrintBlocks(); | 3414 printer.PrintBlocks(); |
| 3405 } | 3415 } |
| 3406 | 3416 |
| 3417 GrowableArray<PhiInstr*> redundant_phis(10); |
| 3418 |
| 3407 // We will recompute dominators, block ordering, block ids, block last | 3419 // We will recompute dominators, block ordering, block ids, block last |
| 3408 // instructions, previous pointers, predecessors, etc. after eliminating | 3420 // instructions, previous pointers, predecessors, etc. after eliminating |
| 3409 // unreachable code. We do not maintain those properties during the | 3421 // unreachable code. We do not maintain those properties during the |
| 3410 // transformation. | 3422 // transformation. |
| 3411 for (BlockIterator b = graph_->reverse_postorder_iterator(); | 3423 for (BlockIterator b = graph_->reverse_postorder_iterator(); |
| 3412 !b.Done(); | 3424 !b.Done(); |
| 3413 b.Advance()) { | 3425 b.Advance()) { |
| 3414 BlockEntryInstr* block = b.Current(); | 3426 BlockEntryInstr* block = b.Current(); |
| 3415 if (!reachable_->Contains(block->preorder_number())) { | 3427 if (!reachable_->Contains(block->preorder_number())) { |
| 3416 if (FLAG_trace_constant_propagation) { | 3428 if (FLAG_trace_constant_propagation) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3439 } | 3451 } |
| 3440 } | 3452 } |
| 3441 ++live_count; | 3453 ++live_count; |
| 3442 } | 3454 } |
| 3443 } | 3455 } |
| 3444 if (live_count < pred_count) { | 3456 if (live_count < pred_count) { |
| 3445 for (intptr_t phi_idx = 0; phi_idx < phis->length(); ++phi_idx) { | 3457 for (intptr_t phi_idx = 0; phi_idx < phis->length(); ++phi_idx) { |
| 3446 PhiInstr* phi = (*phis)[phi_idx]; | 3458 PhiInstr* phi = (*phis)[phi_idx]; |
| 3447 if (phi == NULL) continue; | 3459 if (phi == NULL) continue; |
| 3448 phi->inputs_.TruncateTo(live_count); | 3460 phi->inputs_.TruncateTo(live_count); |
| 3461 if (live_count == 1) redundant_phis.Add(phi); |
| 3449 } | 3462 } |
| 3450 } | 3463 } |
| 3451 } | 3464 } |
| 3452 } | 3465 } |
| 3453 | 3466 |
| 3454 for (ForwardInstructionIterator i(block); !i.Done(); i.Advance()) { | 3467 for (ForwardInstructionIterator i(block); !i.Done(); i.Advance()) { |
| 3455 Definition* defn = i.Current()->AsDefinition(); | 3468 Definition* defn = i.Current()->AsDefinition(); |
| 3456 // Replace constant-valued instructions without observable side | 3469 // Replace constant-valued instructions without observable side |
| 3457 // effects. Do this for smis only to avoid having to copy other | 3470 // effects. Do this for smis only to avoid having to copy other |
| 3458 // objects into the heap's old generation. | 3471 // objects into the heap's old generation. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3514 join->LinkTo(next); | 3527 join->LinkTo(next); |
| 3515 } | 3528 } |
| 3516 } | 3529 } |
| 3517 } | 3530 } |
| 3518 | 3531 |
| 3519 graph_->DiscoverBlocks(); | 3532 graph_->DiscoverBlocks(); |
| 3520 GrowableArray<BitVector*> dominance_frontier; | 3533 GrowableArray<BitVector*> dominance_frontier; |
| 3521 graph_->ComputeDominators(&dominance_frontier); | 3534 graph_->ComputeDominators(&dominance_frontier); |
| 3522 graph_->ComputeUseLists(); | 3535 graph_->ComputeUseLists(); |
| 3523 | 3536 |
| 3537 for (intptr_t i = 0; i < redundant_phis.length(); i++) { |
| 3538 PhiInstr* phi = redundant_phis[i]; |
| 3539 phi->ReplaceUsesWith(phi->InputAt(0)->definition()); |
| 3540 phi->mark_dead(); |
| 3541 } |
| 3542 |
| 3524 if (FLAG_trace_constant_propagation) { | 3543 if (FLAG_trace_constant_propagation) { |
| 3525 OS::Print("\n==== After constant propagation ====\n"); | 3544 OS::Print("\n==== After constant propagation ====\n"); |
| 3526 FlowGraphPrinter printer(*graph_); | 3545 FlowGraphPrinter printer(*graph_); |
| 3527 printer.PrintBlocks(); | 3546 printer.PrintBlocks(); |
| 3528 } | 3547 } |
| 3529 } | 3548 } |
| 3530 | 3549 |
| 3531 | 3550 |
| 3532 } // namespace dart | 3551 } // namespace dart |
| OLD | NEW |