| 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 2548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2559 } | 2559 } |
| 2560 | 2560 |
| 2561 | 2561 |
| 2562 void FlowGraphTypePropagator::VisitInstanceOf(InstanceOfInstr* instr) { | 2562 void FlowGraphTypePropagator::VisitInstanceOf(InstanceOfInstr* instr) { |
| 2563 bool is_null; | 2563 bool is_null; |
| 2564 bool is_instance = false; | 2564 bool is_instance = false; |
| 2565 if (FLAG_eliminate_type_checks && | 2565 if (FLAG_eliminate_type_checks && |
| 2566 instr->value()->CanComputeIsNull(&is_null) && | 2566 instr->value()->CanComputeIsNull(&is_null) && |
| 2567 (is_null || | 2567 (is_null || |
| 2568 instr->value()->CanComputeIsInstanceOf(instr->type(), &is_instance))) { | 2568 instr->value()->CanComputeIsInstanceOf(instr->type(), &is_instance))) { |
| 2569 Definition* result = new ConstantInstr(Bool::ZoneHandle(Bool::Get( | 2569 bool val = instr->negate_result() ? !is_instance : is_instance; |
| 2570 instr->negate_result() ? !is_instance : is_instance))); | 2570 Definition* result = new ConstantInstr(val ? Bool::True() : Bool::False()); |
| 2571 result->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); | 2571 result->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); |
| 2572 result->InsertBefore(instr); | 2572 result->InsertBefore(instr); |
| 2573 // Replace uses and remove the current instruction via the iterator. | 2573 // Replace uses and remove the current instruction via the iterator. |
| 2574 instr->ReplaceUsesWith(result); | 2574 instr->ReplaceUsesWith(result); |
| 2575 ASSERT(current_iterator()->Current() == instr); | 2575 ASSERT(current_iterator()->Current() == instr); |
| 2576 current_iterator()->RemoveCurrentFromGraph(); | 2576 current_iterator()->RemoveCurrentFromGraph(); |
| 2577 if (FLAG_trace_optimization) { | 2577 if (FLAG_trace_optimization) { |
| 2578 OS::Print("Replacing v%"Pd" with v%"Pd"\n", | 2578 OS::Print("Replacing v%"Pd" with v%"Pd"\n", |
| 2579 instr->ssa_temp_index(), | 2579 instr->ssa_temp_index(), |
| 2580 result->ssa_temp_index()); | 2580 result->ssa_temp_index()); |
| (...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3677 instr->comparison()->Accept(this); | 3677 instr->comparison()->Accept(this); |
| 3678 | 3678 |
| 3679 // The successors may be reachable, but only if this instruction is. (We | 3679 // The successors may be reachable, but only if this instruction is. (We |
| 3680 // might be analyzing it because the constant value of one of its inputs | 3680 // might be analyzing it because the constant value of one of its inputs |
| 3681 // has changed.) | 3681 // has changed.) |
| 3682 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { | 3682 if (reachable_->Contains(instr->GetBlock()->preorder_number())) { |
| 3683 const Object& value = instr->comparison()->constant_value(); | 3683 const Object& value = instr->comparison()->constant_value(); |
| 3684 if (IsNonConstant(value)) { | 3684 if (IsNonConstant(value)) { |
| 3685 SetReachable(instr->true_successor()); | 3685 SetReachable(instr->true_successor()); |
| 3686 SetReachable(instr->false_successor()); | 3686 SetReachable(instr->false_successor()); |
| 3687 } else if (value.raw() == Bool::True()) { | 3687 } else if (value.raw() == Bool::True().raw()) { |
| 3688 SetReachable(instr->true_successor()); | 3688 SetReachable(instr->true_successor()); |
| 3689 } else if (!IsUnknown(value)) { // Any other constant. | 3689 } else if (!IsUnknown(value)) { // Any other constant. |
| 3690 SetReachable(instr->false_successor()); | 3690 SetReachable(instr->false_successor()); |
| 3691 } | 3691 } |
| 3692 } | 3692 } |
| 3693 } | 3693 } |
| 3694 | 3694 |
| 3695 | 3695 |
| 3696 // -------------------------------------------------------------------------- | 3696 // -------------------------------------------------------------------------- |
| 3697 // Analysis of non-definition instructions. They do not have values so they | 3697 // Analysis of non-definition instructions. They do not have values so they |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3823 const Object& left = instr->left()->definition()->constant_value(); | 3823 const Object& left = instr->left()->definition()->constant_value(); |
| 3824 const Object& right = instr->right()->definition()->constant_value(); | 3824 const Object& right = instr->right()->definition()->constant_value(); |
| 3825 | 3825 |
| 3826 if (IsNonConstant(left) || IsNonConstant(right)) { | 3826 if (IsNonConstant(left) || IsNonConstant(right)) { |
| 3827 // TODO(vegorov): incorporate nullability information into the lattice. | 3827 // TODO(vegorov): incorporate nullability information into the lattice. |
| 3828 if ((left.IsNull() && (instr->right()->ResultCid() != kDynamicCid)) || | 3828 if ((left.IsNull() && (instr->right()->ResultCid() != kDynamicCid)) || |
| 3829 (right.IsNull() && (instr->left()->ResultCid() != kDynamicCid))) { | 3829 (right.IsNull() && (instr->left()->ResultCid() != kDynamicCid))) { |
| 3830 bool result = left.IsNull() ? (instr->right()->ResultCid() == kNullCid) | 3830 bool result = left.IsNull() ? (instr->right()->ResultCid() == kNullCid) |
| 3831 : (instr->left()->ResultCid() == kNullCid); | 3831 : (instr->left()->ResultCid() == kNullCid); |
| 3832 if (instr->kind() == Token::kNE_STRICT) result = !result; | 3832 if (instr->kind() == Token::kNE_STRICT) result = !result; |
| 3833 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); | 3833 SetValue(instr, result ? Bool::True() : Bool::False()); |
| 3834 } else { | 3834 } else { |
| 3835 SetValue(instr, non_constant_); | 3835 SetValue(instr, non_constant_); |
| 3836 } | 3836 } |
| 3837 } else if (IsConstant(left) && IsConstant(right)) { | 3837 } else if (IsConstant(left) && IsConstant(right)) { |
| 3838 bool result = (left.raw() == right.raw()); | 3838 bool result = (left.raw() == right.raw()); |
| 3839 if (instr->kind() == Token::kNE_STRICT) result = !result; | 3839 if (instr->kind() == Token::kNE_STRICT) result = !result; |
| 3840 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); | 3840 SetValue(instr, result ? Bool::True() : Bool::False()); |
| 3841 } | 3841 } |
| 3842 } | 3842 } |
| 3843 | 3843 |
| 3844 | 3844 |
| 3845 static bool CompareIntegers(Token::Kind kind, | 3845 static bool CompareIntegers(Token::Kind kind, |
| 3846 const Integer& left, | 3846 const Integer& left, |
| 3847 const Integer& right) { | 3847 const Integer& right) { |
| 3848 const int result = left.CompareWith(right); | 3848 const int result = left.CompareWith(right); |
| 3849 switch (kind) { | 3849 switch (kind) { |
| 3850 case Token::kEQ: return (result == 0); | 3850 case Token::kEQ: return (result == 0); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3863 void ConstantPropagator::VisitEqualityCompare(EqualityCompareInstr* instr) { | 3863 void ConstantPropagator::VisitEqualityCompare(EqualityCompareInstr* instr) { |
| 3864 const Object& left = instr->left()->definition()->constant_value(); | 3864 const Object& left = instr->left()->definition()->constant_value(); |
| 3865 const Object& right = instr->right()->definition()->constant_value(); | 3865 const Object& right = instr->right()->definition()->constant_value(); |
| 3866 if (IsNonConstant(left) || IsNonConstant(right)) { | 3866 if (IsNonConstant(left) || IsNonConstant(right)) { |
| 3867 SetValue(instr, non_constant_); | 3867 SetValue(instr, non_constant_); |
| 3868 } else if (IsConstant(left) && IsConstant(right)) { | 3868 } else if (IsConstant(left) && IsConstant(right)) { |
| 3869 if (left.IsInteger() && right.IsInteger()) { | 3869 if (left.IsInteger() && right.IsInteger()) { |
| 3870 const bool result = CompareIntegers(instr->kind(), | 3870 const bool result = CompareIntegers(instr->kind(), |
| 3871 Integer::Cast(left), | 3871 Integer::Cast(left), |
| 3872 Integer::Cast(right)); | 3872 Integer::Cast(right)); |
| 3873 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); | 3873 SetValue(instr, result ? Bool::True() : Bool::False()); |
| 3874 } else { | 3874 } else { |
| 3875 SetValue(instr, non_constant_); | 3875 SetValue(instr, non_constant_); |
| 3876 } | 3876 } |
| 3877 } | 3877 } |
| 3878 } | 3878 } |
| 3879 | 3879 |
| 3880 | 3880 |
| 3881 void ConstantPropagator::VisitRelationalOp(RelationalOpInstr* instr) { | 3881 void ConstantPropagator::VisitRelationalOp(RelationalOpInstr* instr) { |
| 3882 const Object& left = instr->left()->definition()->constant_value(); | 3882 const Object& left = instr->left()->definition()->constant_value(); |
| 3883 const Object& right = instr->right()->definition()->constant_value(); | 3883 const Object& right = instr->right()->definition()->constant_value(); |
| 3884 if (IsNonConstant(left) || IsNonConstant(right)) { | 3884 if (IsNonConstant(left) || IsNonConstant(right)) { |
| 3885 SetValue(instr, non_constant_); | 3885 SetValue(instr, non_constant_); |
| 3886 } else if (IsConstant(left) && IsConstant(right)) { | 3886 } else if (IsConstant(left) && IsConstant(right)) { |
| 3887 if (left.IsInteger() && right.IsInteger()) { | 3887 if (left.IsInteger() && right.IsInteger()) { |
| 3888 const bool result = CompareIntegers(instr->kind(), | 3888 const bool result = CompareIntegers(instr->kind(), |
| 3889 Integer::Cast(left), | 3889 Integer::Cast(left), |
| 3890 Integer::Cast(right)); | 3890 Integer::Cast(right)); |
| 3891 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); | 3891 SetValue(instr, result ? Bool::True() : Bool::False()); |
| 3892 } else { | 3892 } else { |
| 3893 SetValue(instr, non_constant_); | 3893 SetValue(instr, non_constant_); |
| 3894 } | 3894 } |
| 3895 } | 3895 } |
| 3896 } | 3896 } |
| 3897 | 3897 |
| 3898 | 3898 |
| 3899 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { | 3899 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { |
| 3900 SetValue(instr, non_constant_); | 3900 SetValue(instr, non_constant_); |
| 3901 } | 3901 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3936 void ConstantPropagator::VisitStoreStaticField(StoreStaticFieldInstr* instr) { | 3936 void ConstantPropagator::VisitStoreStaticField(StoreStaticFieldInstr* instr) { |
| 3937 SetValue(instr, instr->value()->definition()->constant_value()); | 3937 SetValue(instr, instr->value()->definition()->constant_value()); |
| 3938 } | 3938 } |
| 3939 | 3939 |
| 3940 | 3940 |
| 3941 void ConstantPropagator::VisitBooleanNegate(BooleanNegateInstr* instr) { | 3941 void ConstantPropagator::VisitBooleanNegate(BooleanNegateInstr* instr) { |
| 3942 const Object& value = instr->value()->definition()->constant_value(); | 3942 const Object& value = instr->value()->definition()->constant_value(); |
| 3943 if (IsNonConstant(value)) { | 3943 if (IsNonConstant(value)) { |
| 3944 SetValue(instr, non_constant_); | 3944 SetValue(instr, non_constant_); |
| 3945 } else if (IsConstant(value)) { | 3945 } else if (IsConstant(value)) { |
| 3946 SetValue(instr, Bool::ZoneHandle(Bool::Get(value.raw() != Bool::True()))); | 3946 bool val = value.raw() != Bool::True().raw(); |
| 3947 SetValue(instr, val ? Bool::True() : Bool::False()); |
| 3947 } | 3948 } |
| 3948 } | 3949 } |
| 3949 | 3950 |
| 3950 | 3951 |
| 3951 void ConstantPropagator::VisitInstanceOf(InstanceOfInstr* instr) { | 3952 void ConstantPropagator::VisitInstanceOf(InstanceOfInstr* instr) { |
| 3952 const Object& value = instr->value()->definition()->constant_value(); | 3953 const Object& value = instr->value()->definition()->constant_value(); |
| 3953 if (IsNonConstant(value)) { | 3954 if (IsNonConstant(value)) { |
| 3954 SetValue(instr, non_constant_); | 3955 SetValue(instr, non_constant_); |
| 3955 } else if (IsConstant(value)) { | 3956 } else if (IsConstant(value)) { |
| 3956 // TODO(kmillikin): Handle instanceof on constants. | 3957 // TODO(kmillikin): Handle instanceof on constants. |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4377 | 4378 |
| 4378 if (FLAG_trace_constant_propagation) { | 4379 if (FLAG_trace_constant_propagation) { |
| 4379 OS::Print("\n==== After constant propagation ====\n"); | 4380 OS::Print("\n==== After constant propagation ====\n"); |
| 4380 FlowGraphPrinter printer(*graph_); | 4381 FlowGraphPrinter printer(*graph_); |
| 4381 printer.PrintBlocks(); | 4382 printer.PrintBlocks(); |
| 4382 } | 4383 } |
| 4383 } | 4384 } |
| 4384 | 4385 |
| 4385 | 4386 |
| 4386 } // namespace dart | 4387 } // namespace dart |
| OLD | NEW |