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 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 void ConstantPropagator::VisitIfThenElse(IfThenElseInstr* instr) { | 424 void ConstantPropagator::VisitIfThenElse(IfThenElseInstr* instr) { |
425 instr->comparison()->Accept(this); | 425 instr->comparison()->Accept(this); |
426 const Object& value = instr->comparison()->constant_value(); | 426 const Object& value = instr->comparison()->constant_value(); |
427 if (IsNonConstant(value)) { | 427 if (IsNonConstant(value)) { |
428 SetValue(instr, non_constant_); | 428 SetValue(instr, non_constant_); |
429 } else if (IsConstant(value)) { | 429 } else if (IsConstant(value)) { |
430 ASSERT(!value.IsNull()); | 430 ASSERT(!value.IsNull()); |
431 ASSERT(value.IsBool()); | 431 ASSERT(value.IsBool()); |
432 bool result = Bool::Cast(value).value(); | 432 bool result = Bool::Cast(value).value(); |
433 SetValue(instr, | 433 SetValue(instr, |
434 Smi::Handle(I, Smi::New( | 434 Smi::Handle(Z, Smi::New( |
435 result ? instr->if_true() : instr->if_false()))); | 435 result ? instr->if_true() : instr->if_false()))); |
436 } | 436 } |
437 } | 437 } |
438 | 438 |
439 | 439 |
440 void ConstantPropagator::VisitStrictCompare(StrictCompareInstr* instr) { | 440 void ConstantPropagator::VisitStrictCompare(StrictCompareInstr* instr) { |
441 Definition* left_defn = instr->left()->definition(); | 441 Definition* left_defn = instr->left()->definition(); |
442 Definition* right_defn = instr->right()->definition(); | 442 Definition* right_defn = instr->right()->definition(); |
443 | 443 |
444 Definition* unwrapped_left_defn = UnwrapPhi(left_defn); | 444 Definition* unwrapped_left_defn = UnwrapPhi(left_defn); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 const Object& left = instr->left()->definition()->constant_value(); | 514 const Object& left = instr->left()->definition()->constant_value(); |
515 const Object& right = instr->right()->definition()->constant_value(); | 515 const Object& right = instr->right()->definition()->constant_value(); |
516 if (IsNonConstant(left) || IsNonConstant(right)) { | 516 if (IsNonConstant(left) || IsNonConstant(right)) { |
517 SetValue(instr, non_constant_); | 517 SetValue(instr, non_constant_); |
518 } else if (IsConstant(left) && IsConstant(right)) { | 518 } else if (IsConstant(left) && IsConstant(right)) { |
519 // BitOp does not work on Bigints. | 519 // BitOp does not work on Bigints. |
520 if (left.IsInteger() && right.IsInteger() && | 520 if (left.IsInteger() && right.IsInteger() && |
521 !left.IsBigint() && !right.IsBigint()) { | 521 !left.IsBigint() && !right.IsBigint()) { |
522 const bool result = CompareIntegers( | 522 const bool result = CompareIntegers( |
523 instr->kind(), | 523 instr->kind(), |
524 Integer::Handle(I, Integer::Cast(left).BitOp(Token::kBIT_AND, | 524 Integer::Handle(Z, Integer::Cast(left).BitOp(Token::kBIT_AND, |
525 Integer::Cast(right))), | 525 Integer::Cast(right))), |
526 Smi::Handle(I, Smi::New(0))); | 526 Smi::Handle(Z, Smi::New(0))); |
527 SetValue(instr, result ? Bool::True() : Bool::False()); | 527 SetValue(instr, result ? Bool::True() : Bool::False()); |
528 } else { | 528 } else { |
529 SetValue(instr, non_constant_); | 529 SetValue(instr, non_constant_); |
530 } | 530 } |
531 } | 531 } |
532 } | 532 } |
533 | 533 |
534 | 534 |
535 void ConstantPropagator::VisitTestCids(TestCidsInstr* instr) { | 535 void ConstantPropagator::VisitTestCids(TestCidsInstr* instr) { |
536 SetValue(instr, non_constant_); | 536 SetValue(instr, non_constant_); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 if (!index_obj.IsSmi()) { | 655 if (!index_obj.IsSmi()) { |
656 // Should not occur. | 656 // Should not occur. |
657 SetValue(instr, non_constant_); | 657 SetValue(instr, non_constant_); |
658 return; | 658 return; |
659 } | 659 } |
660 const intptr_t index = Smi::Cast(index_obj).Value(); | 660 const intptr_t index = Smi::Cast(index_obj).Value(); |
661 if (index >= 0) { | 661 if (index >= 0) { |
662 if (array_obj.IsString()) { | 662 if (array_obj.IsString()) { |
663 const String& str = String::Cast(array_obj); | 663 const String& str = String::Cast(array_obj); |
664 if (str.Length() > index) { | 664 if (str.Length() > index) { |
665 SetValue(instr, Smi::Handle(I, | 665 SetValue(instr, Smi::Handle(Z, |
666 Smi::New(static_cast<intptr_t>(str.CharAt(index))))); | 666 Smi::New(static_cast<intptr_t>(str.CharAt(index))))); |
667 return; | 667 return; |
668 } | 668 } |
669 } else if (array_obj.IsArray()) { | 669 } else if (array_obj.IsArray()) { |
670 const Array& a = Array::Cast(array_obj); | 670 const Array& a = Array::Cast(array_obj); |
671 if ((a.Length() > index) && a.IsImmutable()) { | 671 if ((a.Length() > index) && a.IsImmutable()) { |
672 Instance& result = Instance::Handle(I); | 672 Instance& result = Instance::Handle(Z); |
673 result ^= a.At(index); | 673 result ^= a.At(index); |
674 SetValue(instr, result); | 674 SetValue(instr, result); |
675 return; | 675 return; |
676 } | 676 } |
677 } | 677 } |
678 } | 678 } |
679 SetValue(instr, non_constant_); | 679 SetValue(instr, non_constant_); |
680 } | 680 } |
681 } | 681 } |
682 | 682 |
(...skipping 16 matching lines...) Expand all Loading... |
699 | 699 |
700 | 700 |
701 void ConstantPropagator::VisitInitStaticField(InitStaticFieldInstr* instr) { | 701 void ConstantPropagator::VisitInitStaticField(InitStaticFieldInstr* instr) { |
702 // Nothing to do. | 702 // Nothing to do. |
703 } | 703 } |
704 | 704 |
705 | 705 |
706 void ConstantPropagator::VisitLoadStaticField(LoadStaticFieldInstr* instr) { | 706 void ConstantPropagator::VisitLoadStaticField(LoadStaticFieldInstr* instr) { |
707 const Field& field = instr->StaticField(); | 707 const Field& field = instr->StaticField(); |
708 ASSERT(field.is_static()); | 708 ASSERT(field.is_static()); |
709 Instance& obj = Instance::Handle(I, field.StaticValue()); | 709 Instance& obj = Instance::Handle(Z, field.StaticValue()); |
710 if (field.is_final() && (obj.raw() != Object::sentinel().raw()) && | 710 if (field.is_final() && (obj.raw() != Object::sentinel().raw()) && |
711 (obj.raw() != Object::transition_sentinel().raw())) { | 711 (obj.raw() != Object::transition_sentinel().raw())) { |
712 if (obj.IsSmi() || obj.IsOld()) { | 712 if (obj.IsSmi() || obj.IsOld()) { |
713 SetValue(instr, obj); | 713 SetValue(instr, obj); |
714 return; | 714 return; |
715 } | 715 } |
716 } | 716 } |
717 SetValue(instr, non_constant_); | 717 SetValue(instr, non_constant_); |
718 } | 718 } |
719 | 719 |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 | 917 |
918 | 918 |
919 void ConstantPropagator::VisitBinaryIntegerOp(BinaryIntegerOpInstr* binary_op) { | 919 void ConstantPropagator::VisitBinaryIntegerOp(BinaryIntegerOpInstr* binary_op) { |
920 const Object& left = binary_op->left()->definition()->constant_value(); | 920 const Object& left = binary_op->left()->definition()->constant_value(); |
921 const Object& right = binary_op->right()->definition()->constant_value(); | 921 const Object& right = binary_op->right()->definition()->constant_value(); |
922 if (IsConstant(left) && IsConstant(right)) { | 922 if (IsConstant(left) && IsConstant(right)) { |
923 if (left.IsInteger() && right.IsInteger()) { | 923 if (left.IsInteger() && right.IsInteger()) { |
924 const Integer& left_int = Integer::Cast(left); | 924 const Integer& left_int = Integer::Cast(left); |
925 const Integer& right_int = Integer::Cast(right); | 925 const Integer& right_int = Integer::Cast(right); |
926 const Integer& result = | 926 const Integer& result = |
927 Integer::Handle(I, binary_op->Evaluate(left_int, right_int)); | 927 Integer::Handle(Z, binary_op->Evaluate(left_int, right_int)); |
928 if (!result.IsNull()) { | 928 if (!result.IsNull()) { |
929 SetValue(binary_op, Integer::ZoneHandle(Z, result.raw())); | 929 SetValue(binary_op, Integer::ZoneHandle(Z, result.raw())); |
930 return; | 930 return; |
931 } | 931 } |
932 } | 932 } |
933 } | 933 } |
934 | 934 |
935 SetValue(binary_op, non_constant_); | 935 SetValue(binary_op, non_constant_); |
936 } | 936 } |
937 | 937 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 // TODO(kmillikin): Handle unbox operation. | 976 // TODO(kmillikin): Handle unbox operation. |
977 SetValue(instr, non_constant_); | 977 SetValue(instr, non_constant_); |
978 } | 978 } |
979 | 979 |
980 | 980 |
981 void ConstantPropagator::VisitUnaryIntegerOp(UnaryIntegerOpInstr* unary_op) { | 981 void ConstantPropagator::VisitUnaryIntegerOp(UnaryIntegerOpInstr* unary_op) { |
982 const Object& value = unary_op->value()->definition()->constant_value(); | 982 const Object& value = unary_op->value()->definition()->constant_value(); |
983 if (IsConstant(value) && value.IsInteger()) { | 983 if (IsConstant(value) && value.IsInteger()) { |
984 const Integer& value_int = Integer::Cast(value); | 984 const Integer& value_int = Integer::Cast(value); |
985 const Integer& result = | 985 const Integer& result = |
986 Integer::Handle(I, unary_op->Evaluate(value_int)); | 986 Integer::Handle(Z, unary_op->Evaluate(value_int)); |
987 if (!result.IsNull()) { | 987 if (!result.IsNull()) { |
988 SetValue(unary_op, Integer::ZoneHandle(Z, result.raw())); | 988 SetValue(unary_op, Integer::ZoneHandle(Z, result.raw())); |
989 return; | 989 return; |
990 } | 990 } |
991 } | 991 } |
992 | 992 |
993 SetValue(unary_op, non_constant_); | 993 SetValue(unary_op, non_constant_); |
994 } | 994 } |
995 | 995 |
996 | 996 |
(...skipping 14 matching lines...) Expand all Loading... |
1011 } else if (IsConstant(value)) { | 1011 } else if (IsConstant(value)) { |
1012 // TODO(kmillikin): Handle unary operations. | 1012 // TODO(kmillikin): Handle unary operations. |
1013 SetValue(instr, non_constant_); | 1013 SetValue(instr, non_constant_); |
1014 } | 1014 } |
1015 } | 1015 } |
1016 | 1016 |
1017 | 1017 |
1018 void ConstantPropagator::VisitSmiToDouble(SmiToDoubleInstr* instr) { | 1018 void ConstantPropagator::VisitSmiToDouble(SmiToDoubleInstr* instr) { |
1019 const Object& value = instr->value()->definition()->constant_value(); | 1019 const Object& value = instr->value()->definition()->constant_value(); |
1020 if (IsConstant(value) && value.IsInteger()) { | 1020 if (IsConstant(value) && value.IsInteger()) { |
1021 SetValue(instr, Double::Handle(I, | 1021 SetValue(instr, Double::Handle(Z, |
1022 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); | 1022 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); |
1023 } else if (!IsUnknown(value)) { | 1023 } else if (!IsUnknown(value)) { |
1024 SetValue(instr, non_constant_); | 1024 SetValue(instr, non_constant_); |
1025 } | 1025 } |
1026 } | 1026 } |
1027 | 1027 |
1028 | 1028 |
1029 void ConstantPropagator::VisitMintToDouble(MintToDoubleInstr* instr) { | 1029 void ConstantPropagator::VisitMintToDouble(MintToDoubleInstr* instr) { |
1030 const Object& value = instr->value()->definition()->constant_value(); | 1030 const Object& value = instr->value()->definition()->constant_value(); |
1031 if (IsConstant(value) && value.IsInteger()) { | 1031 if (IsConstant(value) && value.IsInteger()) { |
1032 SetValue(instr, Double::Handle(I, | 1032 SetValue(instr, Double::Handle(Z, |
1033 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); | 1033 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); |
1034 } else if (!IsUnknown(value)) { | 1034 } else if (!IsUnknown(value)) { |
1035 SetValue(instr, non_constant_); | 1035 SetValue(instr, non_constant_); |
1036 } | 1036 } |
1037 } | 1037 } |
1038 | 1038 |
1039 | 1039 |
1040 void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) { | 1040 void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) { |
1041 const Object& value = instr->value()->definition()->constant_value(); | 1041 const Object& value = instr->value()->definition()->constant_value(); |
1042 if (IsConstant(value) && value.IsInteger()) { | 1042 if (IsConstant(value) && value.IsInteger()) { |
1043 SetValue(instr, Double::Handle(I, | 1043 SetValue(instr, Double::Handle(Z, |
1044 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); | 1044 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); |
1045 } else if (!IsUnknown(value)) { | 1045 } else if (!IsUnknown(value)) { |
1046 SetValue(instr, non_constant_); | 1046 SetValue(instr, non_constant_); |
1047 } | 1047 } |
1048 } | 1048 } |
1049 | 1049 |
1050 | 1050 |
1051 void ConstantPropagator::VisitDoubleToInteger(DoubleToIntegerInstr* instr) { | 1051 void ConstantPropagator::VisitDoubleToInteger(DoubleToIntegerInstr* instr) { |
1052 // TODO(kmillikin): Handle conversion. | 1052 // TODO(kmillikin): Handle conversion. |
1053 SetValue(instr, non_constant_); | 1053 SetValue(instr, non_constant_); |
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1679 graph_->MergeBlocks(); | 1679 graph_->MergeBlocks(); |
1680 GrowableArray<BitVector*> dominance_frontier; | 1680 GrowableArray<BitVector*> dominance_frontier; |
1681 graph_->ComputeDominators(&dominance_frontier); | 1681 graph_->ComputeDominators(&dominance_frontier); |
1682 | 1682 |
1683 if (FLAG_trace_constant_propagation) { | 1683 if (FLAG_trace_constant_propagation) { |
1684 FlowGraphPrinter::PrintGraph("After CP", graph_); | 1684 FlowGraphPrinter::PrintGraph("After CP", graph_); |
1685 } | 1685 } |
1686 } | 1686 } |
1687 | 1687 |
1688 } // namespace dart | 1688 } // namespace dart |
OLD | NEW |