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 |