| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/constant_propagator.h" | 5 #include "vm/constant_propagator.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/flow_graph_compiler.h" | 9 #include "vm/flow_graph_compiler.h" |
| 10 #include "vm/flow_graph_range_analysis.h" | 10 #include "vm/flow_graph_range_analysis.h" |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 } | 289 } |
| 290 | 290 |
| 291 | 291 |
| 292 // -------------------------------------------------------------------------- | 292 // -------------------------------------------------------------------------- |
| 293 // Analysis of definitions. Compute the constant value. If it has changed | 293 // Analysis of definitions. Compute the constant value. If it has changed |
| 294 // and the definition has input uses, add the definition to the definition | 294 // and the definition has input uses, add the definition to the definition |
| 295 // worklist so that the used can be processed. | 295 // worklist so that the used can be processed. |
| 296 void ConstantPropagator::VisitPhi(PhiInstr* instr) { | 296 void ConstantPropagator::VisitPhi(PhiInstr* instr) { |
| 297 // Compute the join over all the reachable predecessor values. | 297 // Compute the join over all the reachable predecessor values. |
| 298 JoinEntryInstr* block = instr->block(); | 298 JoinEntryInstr* block = instr->block(); |
| 299 Object& value = Object::ZoneHandle(I, Unknown()); | 299 Object& value = Object::ZoneHandle(Z, Unknown()); |
| 300 for (intptr_t pred_idx = 0; pred_idx < instr->InputCount(); ++pred_idx) { | 300 for (intptr_t pred_idx = 0; pred_idx < instr->InputCount(); ++pred_idx) { |
| 301 if (reachable_->Contains( | 301 if (reachable_->Contains( |
| 302 block->PredecessorAt(pred_idx)->preorder_number())) { | 302 block->PredecessorAt(pred_idx)->preorder_number())) { |
| 303 Join(&value, | 303 Join(&value, |
| 304 instr->InputAt(pred_idx)->definition()->constant_value()); | 304 instr->InputAt(pred_idx)->definition()->constant_value()); |
| 305 } | 305 } |
| 306 } | 306 } |
| 307 if (!SetValue(instr, value) && | 307 if (!SetValue(instr, value) && |
| 308 marked_phis_->Contains(instr->ssa_temp_index())) { | 308 marked_phis_->Contains(instr->ssa_temp_index())) { |
| 309 marked_phis_->Remove(instr->ssa_temp_index()); | 309 marked_phis_->Remove(instr->ssa_temp_index()); |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 void ConstantPropagator::VisitStringFromCharCode( | 594 void ConstantPropagator::VisitStringFromCharCode( |
| 595 StringFromCharCodeInstr* instr) { | 595 StringFromCharCodeInstr* instr) { |
| 596 const Object& o = instr->char_code()->definition()->constant_value(); | 596 const Object& o = instr->char_code()->definition()->constant_value(); |
| 597 if (o.IsNull() || IsNonConstant(o)) { | 597 if (o.IsNull() || IsNonConstant(o)) { |
| 598 SetValue(instr, non_constant_); | 598 SetValue(instr, non_constant_); |
| 599 } else if (IsConstant(o)) { | 599 } else if (IsConstant(o)) { |
| 600 const intptr_t ch_code = Smi::Cast(o).Value(); | 600 const intptr_t ch_code = Smi::Cast(o).Value(); |
| 601 ASSERT(ch_code >= 0); | 601 ASSERT(ch_code >= 0); |
| 602 if (ch_code < Symbols::kMaxOneCharCodeSymbol) { | 602 if (ch_code < Symbols::kMaxOneCharCodeSymbol) { |
| 603 RawString** table = Symbols::PredefinedAddress(); | 603 RawString** table = Symbols::PredefinedAddress(); |
| 604 SetValue(instr, String::ZoneHandle(I, table[ch_code])); | 604 SetValue(instr, String::ZoneHandle(Z, table[ch_code])); |
| 605 } else { | 605 } else { |
| 606 SetValue(instr, non_constant_); | 606 SetValue(instr, non_constant_); |
| 607 } | 607 } |
| 608 } | 608 } |
| 609 } | 609 } |
| 610 | 610 |
| 611 | 611 |
| 612 void ConstantPropagator::VisitStringToCharCode(StringToCharCodeInstr* instr) { | 612 void ConstantPropagator::VisitStringToCharCode(StringToCharCodeInstr* instr) { |
| 613 const Object& o = instr->str()->definition()->constant_value(); | 613 const Object& o = instr->str()->definition()->constant_value(); |
| 614 if (o.IsNull() || IsNonConstant(o)) { | 614 if (o.IsNull() || IsNonConstant(o)) { |
| 615 SetValue(instr, non_constant_); | 615 SetValue(instr, non_constant_); |
| 616 } else if (IsConstant(o)) { | 616 } else if (IsConstant(o)) { |
| 617 const String& str = String::Cast(o); | 617 const String& str = String::Cast(o); |
| 618 const intptr_t result = | 618 const intptr_t result = |
| 619 (str.Length() == 1) ? static_cast<intptr_t>(str.CharAt(0)) : -1; | 619 (str.Length() == 1) ? static_cast<intptr_t>(str.CharAt(0)) : -1; |
| 620 SetValue(instr, Smi::ZoneHandle(I, Smi::New(result))); | 620 SetValue(instr, Smi::ZoneHandle(Z, Smi::New(result))); |
| 621 } | 621 } |
| 622 } | 622 } |
| 623 | 623 |
| 624 | 624 |
| 625 void ConstantPropagator::VisitStringInterpolate(StringInterpolateInstr* instr) { | 625 void ConstantPropagator::VisitStringInterpolate(StringInterpolateInstr* instr) { |
| 626 SetValue(instr, non_constant_); | 626 SetValue(instr, non_constant_); |
| 627 } | 627 } |
| 628 | 628 |
| 629 | 629 |
| 630 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { | 630 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 | 773 |
| 774 | 774 |
| 775 void ConstantPropagator::VisitLoadUntagged(LoadUntaggedInstr* instr) { | 775 void ConstantPropagator::VisitLoadUntagged(LoadUntaggedInstr* instr) { |
| 776 SetValue(instr, non_constant_); | 776 SetValue(instr, non_constant_); |
| 777 } | 777 } |
| 778 | 778 |
| 779 | 779 |
| 780 void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) { | 780 void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) { |
| 781 intptr_t cid = instr->object()->Type()->ToCid(); | 781 intptr_t cid = instr->object()->Type()->ToCid(); |
| 782 if (cid != kDynamicCid) { | 782 if (cid != kDynamicCid) { |
| 783 SetValue(instr, Smi::ZoneHandle(I, Smi::New(cid))); | 783 SetValue(instr, Smi::ZoneHandle(Z, Smi::New(cid))); |
| 784 return; | 784 return; |
| 785 } | 785 } |
| 786 const Object& object = instr->object()->definition()->constant_value(); | 786 const Object& object = instr->object()->definition()->constant_value(); |
| 787 if (IsConstant(object)) { | 787 if (IsConstant(object)) { |
| 788 SetValue(instr, Smi::ZoneHandle(I, Smi::New(object.GetClassId()))); | 788 SetValue(instr, Smi::ZoneHandle(Z, Smi::New(object.GetClassId()))); |
| 789 return; | 789 return; |
| 790 } | 790 } |
| 791 SetValue(instr, non_constant_); | 791 SetValue(instr, non_constant_); |
| 792 } | 792 } |
| 793 | 793 |
| 794 | 794 |
| 795 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { | 795 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { |
| 796 Value* instance = instr->instance(); | 796 Value* instance = instr->instance(); |
| 797 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) && | 797 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) && |
| 798 instance->definition()->OriginalDefinition()->IsCreateArray()) { | 798 instance->definition()->OriginalDefinition()->IsCreateArray()) { |
| 799 Value* num_elements = instance->definition()->OriginalDefinition() | 799 Value* num_elements = instance->definition()->OriginalDefinition() |
| 800 ->AsCreateArray()->num_elements(); | 800 ->AsCreateArray()->num_elements(); |
| 801 if (num_elements->BindsToConstant() && | 801 if (num_elements->BindsToConstant() && |
| 802 num_elements->BoundConstant().IsSmi()) { | 802 num_elements->BoundConstant().IsSmi()) { |
| 803 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); | 803 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); |
| 804 const Object& result = Smi::ZoneHandle(I, Smi::New(length)); | 804 const Object& result = Smi::ZoneHandle(Z, Smi::New(length)); |
| 805 SetValue(instr, result); | 805 SetValue(instr, result); |
| 806 return; | 806 return; |
| 807 } | 807 } |
| 808 } | 808 } |
| 809 | 809 |
| 810 if (instr->IsImmutableLengthLoad()) { | 810 if (instr->IsImmutableLengthLoad()) { |
| 811 ConstantInstr* constant = | 811 ConstantInstr* constant = |
| 812 instance->definition()->OriginalDefinition()->AsConstant(); | 812 instance->definition()->OriginalDefinition()->AsConstant(); |
| 813 if (constant != NULL) { | 813 if (constant != NULL) { |
| 814 if (constant->value().IsString()) { | 814 if (constant->value().IsString()) { |
| 815 SetValue(instr, Smi::ZoneHandle(I, | 815 SetValue(instr, Smi::ZoneHandle(Z, |
| 816 Smi::New(String::Cast(constant->value()).Length()))); | 816 Smi::New(String::Cast(constant->value()).Length()))); |
| 817 return; | 817 return; |
| 818 } | 818 } |
| 819 if (constant->value().IsArray()) { | 819 if (constant->value().IsArray()) { |
| 820 SetValue(instr, Smi::ZoneHandle(I, | 820 SetValue(instr, Smi::ZoneHandle(Z, |
| 821 Smi::New(Array::Cast(constant->value()).Length()))); | 821 Smi::New(Array::Cast(constant->value()).Length()))); |
| 822 return; | 822 return; |
| 823 } | 823 } |
| 824 if (constant->value().IsTypedData()) { | 824 if (constant->value().IsTypedData()) { |
| 825 SetValue(instr, Smi::ZoneHandle(I, | 825 SetValue(instr, Smi::ZoneHandle(Z, |
| 826 Smi::New(TypedData::Cast(constant->value()).Length()))); | 826 Smi::New(TypedData::Cast(constant->value()).Length()))); |
| 827 return; | 827 return; |
| 828 } | 828 } |
| 829 } | 829 } |
| 830 } | 830 } |
| 831 SetValue(instr, non_constant_); | 831 SetValue(instr, non_constant_); |
| 832 } | 832 } |
| 833 | 833 |
| 834 | 834 |
| 835 void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) { | 835 void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) { |
| 836 const Object& object = | 836 const Object& object = |
| 837 instr->instantiator()->definition()->constant_value(); | 837 instr->instantiator()->definition()->constant_value(); |
| 838 if (IsNonConstant(object)) { | 838 if (IsNonConstant(object)) { |
| 839 SetValue(instr, non_constant_); | 839 SetValue(instr, non_constant_); |
| 840 return; | 840 return; |
| 841 } | 841 } |
| 842 if (IsConstant(object)) { | 842 if (IsConstant(object)) { |
| 843 if (instr->type().IsTypeParameter()) { | 843 if (instr->type().IsTypeParameter()) { |
| 844 if (object.IsNull()) { | 844 if (object.IsNull()) { |
| 845 SetValue(instr, Type::ZoneHandle(I, Type::DynamicType())); | 845 SetValue(instr, Type::ZoneHandle(Z, Type::DynamicType())); |
| 846 return; | 846 return; |
| 847 } | 847 } |
| 848 // We could try to instantiate the type parameter and return it if no | 848 // We could try to instantiate the type parameter and return it if no |
| 849 // malformed error is reported. | 849 // malformed error is reported. |
| 850 } | 850 } |
| 851 SetValue(instr, non_constant_); | 851 SetValue(instr, non_constant_); |
| 852 } | 852 } |
| 853 } | 853 } |
| 854 | 854 |
| 855 | 855 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 898 void ConstantPropagator::VisitBinaryIntegerOp(BinaryIntegerOpInstr* binary_op) { | 898 void ConstantPropagator::VisitBinaryIntegerOp(BinaryIntegerOpInstr* binary_op) { |
| 899 const Object& left = binary_op->left()->definition()->constant_value(); | 899 const Object& left = binary_op->left()->definition()->constant_value(); |
| 900 const Object& right = binary_op->right()->definition()->constant_value(); | 900 const Object& right = binary_op->right()->definition()->constant_value(); |
| 901 if (IsConstant(left) && IsConstant(right)) { | 901 if (IsConstant(left) && IsConstant(right)) { |
| 902 if (left.IsInteger() && right.IsInteger()) { | 902 if (left.IsInteger() && right.IsInteger()) { |
| 903 const Integer& left_int = Integer::Cast(left); | 903 const Integer& left_int = Integer::Cast(left); |
| 904 const Integer& right_int = Integer::Cast(right); | 904 const Integer& right_int = Integer::Cast(right); |
| 905 const Integer& result = | 905 const Integer& result = |
| 906 Integer::Handle(I, binary_op->Evaluate(left_int, right_int)); | 906 Integer::Handle(I, binary_op->Evaluate(left_int, right_int)); |
| 907 if (!result.IsNull()) { | 907 if (!result.IsNull()) { |
| 908 SetValue(binary_op, Integer::ZoneHandle(I, result.raw())); | 908 SetValue(binary_op, Integer::ZoneHandle(Z, result.raw())); |
| 909 return; | 909 return; |
| 910 } | 910 } |
| 911 } | 911 } |
| 912 } | 912 } |
| 913 | 913 |
| 914 SetValue(binary_op, non_constant_); | 914 SetValue(binary_op, non_constant_); |
| 915 } | 915 } |
| 916 | 916 |
| 917 | 917 |
| 918 void ConstantPropagator::VisitBinarySmiOp(BinarySmiOpInstr* instr) { | 918 void ConstantPropagator::VisitBinarySmiOp(BinarySmiOpInstr* instr) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 } | 957 } |
| 958 | 958 |
| 959 | 959 |
| 960 void ConstantPropagator::VisitUnaryIntegerOp(UnaryIntegerOpInstr* unary_op) { | 960 void ConstantPropagator::VisitUnaryIntegerOp(UnaryIntegerOpInstr* unary_op) { |
| 961 const Object& value = unary_op->value()->definition()->constant_value(); | 961 const Object& value = unary_op->value()->definition()->constant_value(); |
| 962 if (IsConstant(value) && value.IsInteger()) { | 962 if (IsConstant(value) && value.IsInteger()) { |
| 963 const Integer& value_int = Integer::Cast(value); | 963 const Integer& value_int = Integer::Cast(value); |
| 964 const Integer& result = | 964 const Integer& result = |
| 965 Integer::Handle(I, unary_op->Evaluate(value_int)); | 965 Integer::Handle(I, unary_op->Evaluate(value_int)); |
| 966 if (!result.IsNull()) { | 966 if (!result.IsNull()) { |
| 967 SetValue(unary_op, Integer::ZoneHandle(I, result.raw())); | 967 SetValue(unary_op, Integer::ZoneHandle(Z, result.raw())); |
| 968 return; | 968 return; |
| 969 } | 969 } |
| 970 } | 970 } |
| 971 | 971 |
| 972 SetValue(unary_op, non_constant_); | 972 SetValue(unary_op, non_constant_); |
| 973 } | 973 } |
| 974 | 974 |
| 975 | 975 |
| 976 void ConstantPropagator::VisitUnaryMintOp(UnaryMintOpInstr* instr) { | 976 void ConstantPropagator::VisitUnaryMintOp(UnaryMintOpInstr* instr) { |
| 977 VisitUnaryIntegerOp(instr); | 977 VisitUnaryIntegerOp(instr); |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1658 graph_->MergeBlocks(); | 1658 graph_->MergeBlocks(); |
| 1659 GrowableArray<BitVector*> dominance_frontier; | 1659 GrowableArray<BitVector*> dominance_frontier; |
| 1660 graph_->ComputeDominators(&dominance_frontier); | 1660 graph_->ComputeDominators(&dominance_frontier); |
| 1661 | 1661 |
| 1662 if (FLAG_trace_constant_propagation) { | 1662 if (FLAG_trace_constant_propagation) { |
| 1663 FlowGraphPrinter::PrintGraph("After CP", graph_); | 1663 FlowGraphPrinter::PrintGraph("After CP", graph_); |
| 1664 } | 1664 } |
| 1665 } | 1665 } |
| 1666 | 1666 |
| 1667 } // namespace dart | 1667 } // namespace dart |
| OLD | NEW |