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 |