Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 671 // "((x + other_offset) >> other_scale) other_relation y". | 671 // "((x + other_offset) >> other_scale) other_relation y". |
| 672 bool CompoundImplies(NumericRelation other_relation, | 672 bool CompoundImplies(NumericRelation other_relation, |
| 673 int my_offset, | 673 int my_offset, |
| 674 int my_scale, | 674 int my_scale, |
| 675 int other_offset = 0, | 675 int other_offset = 0, |
| 676 int other_scale = 0) { | 676 int other_scale = 0) { |
| 677 return Implies(other_relation) && ComponentsImply( | 677 return Implies(other_relation) && ComponentsImply( |
| 678 my_offset, my_scale, other_offset, other_scale); | 678 my_offset, my_scale, other_offset, other_scale); |
| 679 } | 679 } |
| 680 | 680 |
| 681 // CanBeChained returns true when | |
| 682 // "((x + offset) >> scale) rel limit" and "x other_relation y" imply | |
| 683 // "((y + offset) >> scale) rel limit". | |
| 684 // In other words, rel and other_relation go "in the same direction" | |
| 685 // and therefore can be "chained". | |
| 686 bool CanBeChained(NumericRelation other_relation) { | |
| 687 switch (kind_) { | |
| 688 case NONE: return false; | |
| 689 case EQ: return (other_relation.kind_ == EQ); | |
| 690 case GT: | |
| 691 case GE: | |
| 692 return (other_relation.kind_ == GT) || (other_relation.kind_ == GE); | |
| 693 case LT: | |
| 694 case LE: | |
| 695 return (other_relation.kind_ == LT) || (other_relation.kind_ == LE); | |
| 696 case NE: return false; | |
| 697 } | |
| 698 UNREACHABLE(); | |
| 699 return false; | |
| 700 } | |
| 701 | |
| 702 bool ApplyToValues(int32_t value, int32_t other_value) { | |
| 703 switch (kind_) { | |
| 704 case NONE: return false; | |
| 705 case EQ: return value == other_value; | |
| 706 case GT: return value > other_value; | |
| 707 case GE: return value >= other_value; | |
| 708 case LT: return value < other_value; | |
| 709 case LE: return value <= other_value; | |
| 710 case NE: return value != other_value; | |
| 711 } | |
| 712 UNREACHABLE(); | |
| 713 return false; | |
| 714 } | |
| 715 | |
| 681 private: | 716 private: |
| 682 // ComponentsImply returns true when | 717 // ComponentsImply returns true when |
| 683 // "((x + my_offset) >> my_scale) rel y" implies | 718 // "((x + my_offset) >> my_scale) rel y" implies |
| 684 // "((x + other_offset) >> other_scale) rel y". | 719 // "((x + other_offset) >> other_scale) rel y". |
| 685 bool ComponentsImply(int my_offset, | 720 bool ComponentsImply(int my_offset, |
| 686 int my_scale, | 721 int my_scale, |
| 687 int other_offset, | 722 int other_offset, |
| 688 int other_scale) { | 723 int other_scale) { |
| 689 switch (kind_) { | 724 switch (kind_) { |
| 690 case NONE: break; // Fall through to UNREACHABLE(). | 725 case NONE: break; // Fall through to UNREACHABLE(). |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 745 } | 780 } |
| 746 | 781 |
| 747 HValue* base_; | 782 HValue* base_; |
| 748 int offset_; | 783 int offset_; |
| 749 int scale_; | 784 int scale_; |
| 750 }; | 785 }; |
| 751 | 786 |
| 752 | 787 |
| 753 class RangeEvaluationContext BASE_EMBEDDED { | 788 class RangeEvaluationContext BASE_EMBEDDED { |
| 754 public: | 789 public: |
| 755 RangeEvaluationContext(HValue* value, HValue* upper); | 790 RangeEvaluationContext(HValue* value, |
| 791 HValue* upper, | |
| 792 HBasicBlock* starting_block); | |
| 756 | 793 |
| 794 HBasicBlock* starting_block() { return starting_block_; } | |
| 757 HValue* lower_bound() { return lower_bound_; } | 795 HValue* lower_bound() { return lower_bound_; } |
| 758 HValue* lower_bound_guarantee() { return lower_bound_guarantee_; } | 796 HValue* lower_bound_guarantee() { return lower_bound_guarantee_; } |
| 759 HValue* candidate() { return candidate_; } | 797 HValue* candidate() { return candidate_; } |
| 760 HValue* upper_bound() { return upper_bound_; } | 798 HValue* upper_bound() { return upper_bound_; } |
| 761 HValue* upper_bound_guarantee() { return upper_bound_guarantee_; } | 799 HValue* upper_bound_guarantee() { return upper_bound_guarantee_; } |
| 762 int offset() { return offset_; } | 800 int offset() { return offset_; } |
| 763 int scale() { return scale_; } | 801 int scale() { return scale_; } |
| 764 | 802 |
| 765 bool is_range_satisfied() { | 803 bool is_range_satisfied() { |
| 766 return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL; | 804 return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL; |
| 767 } | 805 } |
| 768 | 806 |
| 769 void set_lower_bound_guarantee(HValue* guarantee) { | 807 void set_lower_bound_guarantee(HValue* guarantee) { |
| 770 lower_bound_guarantee_ = ConvertGuarantee(guarantee); | 808 lower_bound_guarantee_ = ConvertGuarantee(guarantee); |
| 771 } | 809 } |
| 772 void set_upper_bound_guarantee(HValue* guarantee) { | 810 void set_upper_bound_guarantee(HValue* guarantee) { |
| 773 upper_bound_guarantee_ = ConvertGuarantee(guarantee); | 811 upper_bound_guarantee_ = ConvertGuarantee(guarantee); |
| 774 } | 812 } |
| 775 | 813 |
| 776 void swap_candidate(DecompositionResult* other_candicate) { | 814 void swap_candidate(DecompositionResult* other_candicate) { |
| 777 other_candicate->SwapValues(&candidate_, &offset_, &scale_); | 815 other_candicate->SwapValues(&candidate_, &offset_, &scale_); |
| 778 } | 816 } |
| 779 | 817 |
| 780 private: | 818 private: |
| 781 HValue* ConvertGuarantee(HValue* guarantee); | 819 HValue* ConvertGuarantee(HValue* guarantee); |
| 782 | 820 |
| 821 HBasicBlock* starting_block_; | |
| 783 HValue* lower_bound_; | 822 HValue* lower_bound_; |
| 784 HValue* lower_bound_guarantee_; | 823 HValue* lower_bound_guarantee_; |
| 785 HValue* candidate_; | 824 HValue* candidate_; |
| 786 HValue* upper_bound_; | 825 HValue* upper_bound_; |
| 787 HValue* upper_bound_guarantee_; | 826 HValue* upper_bound_guarantee_; |
| 788 int offset_; | 827 int offset_; |
| 789 int scale_; | 828 int scale_; |
| 790 }; | 829 }; |
| 791 | 830 |
| 792 | 831 |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1093 | 1132 |
| 1094 #ifdef DEBUG | 1133 #ifdef DEBUG |
| 1095 virtual void Verify() = 0; | 1134 virtual void Verify() = 0; |
| 1096 #endif | 1135 #endif |
| 1097 | 1136 |
| 1098 bool IsRelationTrue(NumericRelation relation, | 1137 bool IsRelationTrue(NumericRelation relation, |
| 1099 HValue* other, | 1138 HValue* other, |
| 1100 int offset = 0, | 1139 int offset = 0, |
| 1101 int scale = 0); | 1140 int scale = 0); |
| 1102 | 1141 |
| 1103 bool TryGuaranteeRange(HValue* upper_bound); | 1142 bool TryGuaranteeRange(HValue* upper_bound, |
| 1143 HBasicBlock* starting_block_for_hoisting = NULL); | |
| 1104 virtual bool TryDecompose(DecompositionResult* decomposition) { | 1144 virtual bool TryDecompose(DecompositionResult* decomposition) { |
| 1105 if (RedefinedOperand() != NULL) { | 1145 if (RedefinedOperand() != NULL) { |
| 1106 return RedefinedOperand()->TryDecompose(decomposition); | 1146 return RedefinedOperand()->TryDecompose(decomposition); |
| 1107 } else { | 1147 } else { |
| 1108 return false; | 1148 return false; |
| 1109 } | 1149 } |
| 1110 } | 1150 } |
| 1111 | 1151 |
| 1112 protected: | 1152 protected: |
| 1113 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); | 1153 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1415 | 1455 |
| 1416 DECLARE_CONCRETE_INSTRUCTION(DummyUse); | 1456 DECLARE_CONCRETE_INSTRUCTION(DummyUse); |
| 1417 }; | 1457 }; |
| 1418 | 1458 |
| 1419 | 1459 |
| 1420 class HNumericConstraint : public HTemplateInstruction<2> { | 1460 class HNumericConstraint : public HTemplateInstruction<2> { |
| 1421 public: | 1461 public: |
| 1422 static HNumericConstraint* AddToGraph(HValue* constrained_value, | 1462 static HNumericConstraint* AddToGraph(HValue* constrained_value, |
| 1423 NumericRelation relation, | 1463 NumericRelation relation, |
| 1424 HValue* related_value, | 1464 HValue* related_value, |
| 1425 HInstruction* insertion_point = NULL); | 1465 HInstruction* insertion_point = NULL, |
| 1466 HBasicBlock* other_block = NULL); | |
|
Jakob Kummerow
2013/04/17 11:34:15
I think "other_block" either needs a comment or a
Massi
2013/05/07 11:32:03
Done.
| |
| 1426 | 1467 |
| 1427 HValue* constrained_value() { return OperandAt(0); } | 1468 HValue* constrained_value() { return OperandAt(0); } |
| 1428 HValue* related_value() { return OperandAt(1); } | 1469 HValue* related_value() { return OperandAt(1); } |
| 1429 NumericRelation relation() { return relation_; } | 1470 NumericRelation relation() { return relation_; } |
| 1471 HBasicBlock* other_block() { return other_block_; } | |
| 1430 | 1472 |
| 1431 virtual int RedefinedOperandIndex() { return 0; } | 1473 virtual int RedefinedOperandIndex() { return 0; } |
| 1432 virtual bool IsPurelyInformativeDefinition() { return true; } | 1474 virtual bool IsPurelyInformativeDefinition() { return true; } |
| 1433 | 1475 |
| 1434 virtual Representation RequiredInputRepresentation(int index) { | 1476 virtual Representation RequiredInputRepresentation(int index) { |
| 1435 return representation(); | 1477 return representation(); |
| 1436 } | 1478 } |
| 1437 | 1479 |
| 1438 virtual void PrintDataTo(StringStream* stream); | 1480 virtual void PrintDataTo(StringStream* stream); |
| 1439 | 1481 |
| 1440 virtual bool IsRelationTrueInternal(NumericRelation other_relation, | 1482 virtual bool IsRelationTrueInternal(NumericRelation other_relation, |
| 1441 HValue* other_related_value, | 1483 HValue* other_related_value, |
| 1442 int offset = 0, | 1484 int offset = 0, |
| 1443 int scale = 0) { | 1485 int scale = 0) { |
| 1444 if (related_value() == other_related_value) { | 1486 if (related_value() == other_related_value) { |
| 1445 return relation().CompoundImplies(other_relation, offset, scale); | 1487 return relation().CompoundImplies(other_relation, offset, scale); |
| 1446 } else { | 1488 } else { |
| 1447 return false; | 1489 if (relation().CanBeChained(other_relation)) { |
| 1490 return related_value()->IsRelationTrue( | |
| 1491 other_relation, other_related_value, offset, scale); | |
| 1492 } else { | |
| 1493 return false; | |
| 1494 } | |
| 1448 } | 1495 } |
| 1449 } | 1496 } |
| 1450 | 1497 |
| 1451 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint) | 1498 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint) |
| 1452 | 1499 |
| 1453 private: | 1500 private: |
| 1454 HNumericConstraint(HValue* constrained_value, | 1501 HNumericConstraint(HValue* constrained_value, |
| 1455 NumericRelation relation, | 1502 NumericRelation relation, |
| 1456 HValue* related_value) | 1503 HValue* related_value, |
| 1457 : relation_(relation) { | 1504 HBasicBlock* other_block) |
| 1505 : relation_(relation), other_block_(other_block) { | |
|
Jakob Kummerow
2013/04/17 11:34:15
nit: indentation
Massi
2013/05/07 11:32:03
Done.
| |
| 1458 SetOperandAt(0, constrained_value); | 1506 SetOperandAt(0, constrained_value); |
| 1459 SetOperandAt(1, related_value); | 1507 SetOperandAt(1, related_value); |
| 1460 } | 1508 } |
| 1461 | 1509 |
| 1462 NumericRelation relation_; | 1510 NumericRelation relation_; |
| 1511 HBasicBlock* other_block_; | |
| 1463 }; | 1512 }; |
| 1464 | 1513 |
| 1465 | 1514 |
| 1466 // We insert soft-deoptimize when we hit code with unknown typefeedback, | 1515 // We insert soft-deoptimize when we hit code with unknown typefeedback, |
| 1467 // so that we get a chance of re-optimizing with useful typefeedback. | 1516 // so that we get a chance of re-optimizing with useful typefeedback. |
| 1468 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. | 1517 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. |
| 1469 class HSoftDeoptimize: public HTemplateInstruction<0> { | 1518 class HSoftDeoptimize: public HTemplateInstruction<0> { |
| 1470 public: | 1519 public: |
| 1471 virtual Representation RequiredInputRepresentation(int index) { | 1520 virtual Representation RequiredInputRepresentation(int index) { |
| 1472 return Representation::None(); | 1521 return Representation::None(); |
| (...skipping 1621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3094 int merged_index_; | 3143 int merged_index_; |
| 3095 | 3144 |
| 3096 int non_phi_uses_[Representation::kNumRepresentations]; | 3145 int non_phi_uses_[Representation::kNumRepresentations]; |
| 3097 int indirect_uses_[Representation::kNumRepresentations]; | 3146 int indirect_uses_[Representation::kNumRepresentations]; |
| 3098 int phi_id_; | 3147 int phi_id_; |
| 3099 bool is_live_; | 3148 bool is_live_; |
| 3100 bool is_convertible_to_integer_; | 3149 bool is_convertible_to_integer_; |
| 3101 }; | 3150 }; |
| 3102 | 3151 |
| 3103 | 3152 |
| 3153 class HBoundsCheck; | |
| 3154 | |
| 3155 | |
| 3104 class HInductionVariableAnnotation : public HUnaryOperation { | 3156 class HInductionVariableAnnotation : public HUnaryOperation { |
| 3105 public: | 3157 public: |
| 3106 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, | 3158 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, |
| 3107 NumericRelation relation, | 3159 NumericRelation relation, |
| 3108 int operand_index); | 3160 int operand_index); |
| 3109 | 3161 |
| 3110 NumericRelation relation() { return relation_; } | 3162 NumericRelation relation() { return relation_; } |
| 3111 HValue* induction_base() { return phi_->OperandAt(operand_index_); } | 3163 HValue* induction_base() { return phi_->OperandAt(operand_index_); } |
| 3112 | 3164 |
| 3113 virtual int RedefinedOperandIndex() { return 0; } | 3165 virtual int RedefinedOperandIndex() { return 0; } |
| 3114 virtual bool IsPurelyInformativeDefinition() { return true; } | 3166 virtual bool IsPurelyInformativeDefinition() { return true; } |
| 3115 virtual Representation RequiredInputRepresentation(int index) { | 3167 virtual Representation RequiredInputRepresentation(int index) { |
| 3116 return representation(); | 3168 return representation(); |
| 3117 } | 3169 } |
| 3118 | 3170 |
| 3171 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); | |
| 3119 virtual void PrintDataTo(StringStream* stream); | 3172 virtual void PrintDataTo(StringStream* stream); |
| 3120 | 3173 |
| 3121 virtual bool IsRelationTrueInternal(NumericRelation other_relation, | 3174 virtual bool IsRelationTrueInternal(NumericRelation other_relation, |
| 3122 HValue* other_related_value, | 3175 HValue* other_related_value, |
| 3123 int offset = 0, | 3176 int offset = 0, |
| 3124 int scale = 0) { | 3177 int scale = 0) { |
| 3125 if (induction_base() == other_related_value) { | 3178 if (induction_base() == other_related_value) { |
| 3126 return relation().CompoundImplies(other_relation, offset, scale); | 3179 return relation().CompoundImplies(other_relation, offset, scale); |
| 3127 } else { | 3180 } else { |
| 3128 return false; | 3181 if (relation().CanBeChained(other_relation)) { |
| 3182 return induction_base()->IsRelationTrue( | |
| 3183 other_relation, other_related_value, offset, scale); | |
| 3184 } else { | |
| 3185 return false; | |
| 3186 } | |
| 3129 } | 3187 } |
| 3130 } | 3188 } |
| 3131 | 3189 |
| 3190 const ZoneList<HBoundsCheck*>* hoisted_checks() const { | |
| 3191 return &hoisted_checks_; | |
| 3192 } | |
| 3193 void AddHoistedCheck(HBoundsCheck* check); | |
| 3194 | |
| 3132 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation) | 3195 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation) |
| 3133 | 3196 |
| 3134 private: | 3197 private: |
| 3135 HInductionVariableAnnotation(HPhi* phi, | 3198 HInductionVariableAnnotation(HPhi* phi, |
| 3136 NumericRelation relation, | 3199 NumericRelation relation, |
| 3137 int operand_index) | 3200 int operand_index, |
| 3138 : HUnaryOperation(phi), | 3201 Zone* zone); |
| 3139 phi_(phi), relation_(relation), operand_index_(operand_index) { | |
| 3140 } | |
| 3141 | 3202 |
| 3142 // We need to store the phi both here and in the instruction operand because | 3203 // We need to store the phi both here and in the instruction operand because |
| 3143 // the operand can change if a new idef of the phi is added between the phi | 3204 // the operand can change if a new idef of the phi is added between the phi |
| 3144 // and this instruction (inserting an idef updates every use). | 3205 // and this instruction (inserting an idef updates every use). |
| 3145 HPhi* phi_; | 3206 HPhi* phi_; |
| 3146 NumericRelation relation_; | 3207 NumericRelation relation_; |
| 3147 int operand_index_; | 3208 int operand_index_; |
| 3209 ZoneList<HBoundsCheck*> hoisted_checks_; | |
| 3148 }; | 3210 }; |
| 3149 | 3211 |
| 3150 | 3212 |
| 3151 class HArgumentsObject: public HTemplateInstruction<0> { | 3213 class HArgumentsObject: public HTemplateInstruction<0> { |
| 3152 public: | 3214 public: |
| 3153 HArgumentsObject() { | 3215 HArgumentsObject() { |
| 3154 set_representation(Representation::Tagged()); | 3216 set_representation(Representation::Tagged()); |
| 3155 SetFlag(kIsArguments); | 3217 SetFlag(kIsArguments); |
| 3156 } | 3218 } |
| 3157 | 3219 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3285 bool HasInternalizedStringValue() const { | 3347 bool HasInternalizedStringValue() const { |
| 3286 return HasStringValue() && is_internalized_string_; | 3348 return HasStringValue() && is_internalized_string_; |
| 3287 } | 3349 } |
| 3288 | 3350 |
| 3289 bool BooleanValue() const { return boolean_value_; } | 3351 bool BooleanValue() const { return boolean_value_; } |
| 3290 | 3352 |
| 3291 bool IsUint32() { | 3353 bool IsUint32() { |
| 3292 return HasInteger32Value() && (Integer32Value() >= 0); | 3354 return HasInteger32Value() && (Integer32Value() >= 0); |
| 3293 } | 3355 } |
| 3294 | 3356 |
| 3357 virtual bool IsRelationTrueInternal(NumericRelation relation, | |
| 3358 HValue* related_value, | |
| 3359 int offset = 0, | |
| 3360 int scale = 0) { | |
| 3361 if (HasInteger32Value() | |
| 3362 && related_value->IsInteger32Constant()) { | |
|
Jakob Kummerow
2013/04/17 11:34:15
nit: we're pretty consistent about putting binary
Massi
2013/05/07 11:32:03
Done.
| |
| 3363 int32_t value = (Integer32Value() + offset) >> scale; | |
| 3364 int32_t other_value = related_value->GetInteger32Constant(); | |
| 3365 return relation.ApplyToValues(value, other_value); | |
| 3366 } else { | |
| 3367 return false; | |
| 3368 } | |
| 3369 } | |
| 3370 | |
| 3295 virtual intptr_t Hashcode() { | 3371 virtual intptr_t Hashcode() { |
| 3296 ASSERT_ALLOCATION_DISABLED; | 3372 ASSERT_ALLOCATION_DISABLED; |
| 3297 intptr_t hash; | 3373 intptr_t hash; |
| 3298 | 3374 |
| 3299 if (has_int32_value_) { | 3375 if (has_int32_value_) { |
| 3300 hash = static_cast<intptr_t>(int32_value_); | 3376 hash = static_cast<intptr_t>(int32_value_); |
| 3301 } else if (has_double_value_) { | 3377 } else if (has_double_value_) { |
| 3302 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_)); | 3378 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_)); |
| 3303 } else { | 3379 } else { |
| 3304 ASSERT(!handle_.is_null()); | 3380 ASSERT(!handle_.is_null()); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3568 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with | 3644 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with |
| 3569 // a HCheckSmiOrInt32 check. | 3645 // a HCheckSmiOrInt32 check. |
| 3570 // However when building stubs, where we know that the arguments are Int32, | 3646 // However when building stubs, where we know that the arguments are Int32, |
| 3571 // it makes sense to invoke this constructor directly. | 3647 // it makes sense to invoke this constructor directly. |
| 3572 HBoundsCheck(HValue* index, | 3648 HBoundsCheck(HValue* index, |
| 3573 HValue* length, | 3649 HValue* length, |
| 3574 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY, | 3650 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY, |
| 3575 Representation r = Representation::None()) | 3651 Representation r = Representation::None()) |
| 3576 : key_mode_(key_mode), skip_check_(false), | 3652 : key_mode_(key_mode), skip_check_(false), |
| 3577 base_(NULL), offset_(0), scale_(0), | 3653 base_(NULL), offset_(0), scale_(0), |
| 3578 responsibility_direction_(DIRECTION_NONE) { | 3654 responsibility_direction_(DIRECTION_NONE), |
| 3655 allow_equality_(false) { | |
| 3579 SetOperandAt(0, index); | 3656 SetOperandAt(0, index); |
| 3580 SetOperandAt(1, length); | 3657 SetOperandAt(1, length); |
| 3581 if (r.IsNone()) { | 3658 if (r.IsNone()) { |
| 3582 // In the normal compilation pipeline the representation is flexible | 3659 // In the normal compilation pipeline the representation is flexible |
| 3583 // (see InferRepresentation). | 3660 // (see InferRepresentation). |
| 3584 SetFlag(kFlexibleRepresentation); | 3661 SetFlag(kFlexibleRepresentation); |
| 3585 } else { | 3662 } else { |
| 3586 // When compiling stubs we want to set the representation explicitly | 3663 // When compiling stubs we want to set the representation explicitly |
| 3587 // so the compilation pipeline can skip the HInferRepresentation phase. | 3664 // so the compilation pipeline can skip the HInferRepresentation phase. |
| 3588 set_representation(r); | 3665 set_representation(r); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3630 virtual bool IsRelationTrueInternal(NumericRelation relation, | 3707 virtual bool IsRelationTrueInternal(NumericRelation relation, |
| 3631 HValue* related_value, | 3708 HValue* related_value, |
| 3632 int offset = 0, | 3709 int offset = 0, |
| 3633 int scale = 0); | 3710 int scale = 0); |
| 3634 | 3711 |
| 3635 virtual void PrintDataTo(StringStream* stream); | 3712 virtual void PrintDataTo(StringStream* stream); |
| 3636 virtual void InferRepresentation(HInferRepresentation* h_infer); | 3713 virtual void InferRepresentation(HInferRepresentation* h_infer); |
| 3637 | 3714 |
| 3638 HValue* index() { return OperandAt(0); } | 3715 HValue* index() { return OperandAt(0); } |
| 3639 HValue* length() { return OperandAt(1); } | 3716 HValue* length() { return OperandAt(1); } |
| 3717 bool allow_equality() { return allow_equality_; } | |
| 3718 void set_allow_equality(bool v) { allow_equality_ = v; } | |
| 3640 | 3719 |
| 3641 virtual int RedefinedOperandIndex() { return 0; } | 3720 virtual int RedefinedOperandIndex() { return 0; } |
| 3642 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } | 3721 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } |
| 3643 virtual void AddInformativeDefinitions(); | 3722 virtual void AddInformativeDefinitions(); |
| 3644 | 3723 |
| 3645 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | 3724 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) |
| 3646 | 3725 |
| 3647 protected: | 3726 protected: |
| 3648 friend class HBoundsCheckBaseIndexInformation; | 3727 friend class HBoundsCheckBaseIndexInformation; |
| 3649 | 3728 |
| 3650 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) { | 3729 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) { |
| 3651 responsibility_direction_ = static_cast<RangeGuaranteeDirection>( | 3730 responsibility_direction_ = static_cast<RangeGuaranteeDirection>( |
| 3652 responsibility_direction_ | direction); | 3731 responsibility_direction_ | direction); |
| 3653 } | 3732 } |
| 3654 | 3733 |
| 3655 virtual bool DataEquals(HValue* other) { return true; } | 3734 virtual bool DataEquals(HValue* other) { return true; } |
| 3656 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); | 3735 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); |
| 3657 BoundsCheckKeyMode key_mode_; | 3736 BoundsCheckKeyMode key_mode_; |
| 3658 bool skip_check_; | 3737 bool skip_check_; |
| 3659 HValue* base_; | 3738 HValue* base_; |
| 3660 int offset_; | 3739 int offset_; |
| 3661 int scale_; | 3740 int scale_; |
| 3662 RangeGuaranteeDirection responsibility_direction_; | 3741 RangeGuaranteeDirection responsibility_direction_; |
| 3742 bool allow_equality_; | |
| 3663 }; | 3743 }; |
| 3664 | 3744 |
| 3665 | 3745 |
| 3666 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { | 3746 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { |
| 3667 public: | 3747 public: |
| 3668 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { | 3748 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { |
| 3669 DecompositionResult decomposition; | 3749 DecompositionResult decomposition; |
| 3670 if (check->index()->TryDecompose(&decomposition)) { | 3750 if (check->index()->TryDecompose(&decomposition)) { |
| 3671 SetOperandAt(0, decomposition.base()); | 3751 SetOperandAt(0, decomposition.base()); |
| 3672 SetOperandAt(1, check); | 3752 SetOperandAt(1, check); |
| 3673 } else { | 3753 } else { |
| 3674 UNREACHABLE(); | 3754 UNREACHABLE(); |
| 3675 } | 3755 } |
| 3676 } | 3756 } |
| 3677 | 3757 |
| 3678 HValue* base_index() { return OperandAt(0); } | 3758 HValue* base_index() { return OperandAt(0); } |
| 3679 HBoundsCheck* bounds_check() { return HBoundsCheck::cast(OperandAt(1)); } | 3759 HBoundsCheck* bounds_check() { |
| 3760 return OperandAt(1)->IsBoundsCheck() | |
| 3761 ? HBoundsCheck::cast(OperandAt(1)) : NULL; | |
| 3762 } | |
| 3680 | 3763 |
| 3681 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation) | 3764 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation) |
| 3682 | 3765 |
| 3683 virtual Representation RequiredInputRepresentation(int arg_index) { | 3766 virtual Representation RequiredInputRepresentation(int arg_index) { |
| 3684 return representation(); | 3767 return representation(); |
| 3685 } | 3768 } |
| 3686 | 3769 |
| 3687 virtual bool IsRelationTrueInternal(NumericRelation relation, | 3770 virtual bool IsRelationTrueInternal(NumericRelation relation, |
| 3688 HValue* related_value, | 3771 HValue* related_value, |
| 3689 int offset = 0, | 3772 int offset = 0, |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4297 decomposition->Apply(right(), left()->GetInteger32Constant()); | 4380 decomposition->Apply(right(), left()->GetInteger32Constant()); |
| 4298 return true; | 4381 return true; |
| 4299 } else if (right()->IsInteger32Constant()) { | 4382 } else if (right()->IsInteger32Constant()) { |
| 4300 decomposition->Apply(left(), right()->GetInteger32Constant()); | 4383 decomposition->Apply(left(), right()->GetInteger32Constant()); |
| 4301 return true; | 4384 return true; |
| 4302 } else { | 4385 } else { |
| 4303 return false; | 4386 return false; |
| 4304 } | 4387 } |
| 4305 } | 4388 } |
| 4306 | 4389 |
| 4390 virtual bool IsRelationTrueInternal(NumericRelation relation, | |
| 4391 HValue* other, | |
| 4392 int offset = 0, | |
| 4393 int scale = 0); | |
| 4394 | |
| 4307 DECLARE_CONCRETE_INSTRUCTION(Add) | 4395 DECLARE_CONCRETE_INSTRUCTION(Add) |
| 4308 | 4396 |
| 4309 protected: | 4397 protected: |
| 4310 virtual bool DataEquals(HValue* other) { return true; } | 4398 virtual bool DataEquals(HValue* other) { return true; } |
| 4311 | 4399 |
| 4312 virtual Range* InferRange(Zone* zone); | 4400 virtual Range* InferRange(Zone* zone); |
| 4313 | 4401 |
| 4314 private: | 4402 private: |
| 4315 HAdd(HValue* context, HValue* left, HValue* right) | 4403 HAdd(HValue* context, HValue* left, HValue* right) |
| 4316 : HArithmeticBinaryOperation(context, left, right) { | 4404 : HArithmeticBinaryOperation(context, left, right) { |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4541 }; | 4629 }; |
| 4542 | 4630 |
| 4543 | 4631 |
| 4544 class HShl: public HBitwiseBinaryOperation { | 4632 class HShl: public HBitwiseBinaryOperation { |
| 4545 public: | 4633 public: |
| 4546 static HInstruction* New(Zone* zone, | 4634 static HInstruction* New(Zone* zone, |
| 4547 HValue* context, | 4635 HValue* context, |
| 4548 HValue* left, | 4636 HValue* left, |
| 4549 HValue* right); | 4637 HValue* right); |
| 4550 | 4638 |
| 4639 virtual bool TryDecompose(DecompositionResult* decomposition) { | |
| 4640 if (right()->IsInteger32Constant() | |
| 4641 && right()->GetInteger32Constant() <= 1) { | |
|
Jakob Kummerow
2013/04/17 11:34:15
As discussed, I think you need an additional check
Massi
2013/05/07 11:32:03
Done.
| |
| 4642 if (decomposition->Apply(left(), 0, - right()->GetInteger32Constant())) { | |
| 4643 // This is intended to look for HAdd and HSub, to handle compounds | |
| 4644 // like ((base + offset) >> scale) with one single decomposition. | |
|
Jakob Kummerow
2013/04/17 11:34:15
s/>>/<</ ?
Massi
2013/05/07 11:32:03
Done.
| |
| 4645 left()->TryDecompose(decomposition); | |
| 4646 return true; | |
| 4647 } | |
| 4648 } | |
| 4649 return false; | |
| 4650 } | |
| 4651 | |
| 4551 virtual Range* InferRange(Zone* zone); | 4652 virtual Range* InferRange(Zone* zone); |
| 4552 | 4653 |
| 4553 DECLARE_CONCRETE_INSTRUCTION(Shl) | 4654 DECLARE_CONCRETE_INSTRUCTION(Shl) |
| 4554 | 4655 |
| 4555 protected: | 4656 protected: |
| 4556 virtual bool DataEquals(HValue* other) { return true; } | 4657 virtual bool DataEquals(HValue* other) { return true; } |
| 4557 | 4658 |
| 4558 private: | 4659 private: |
| 4559 HShl(HValue* context, HValue* left, HValue* right) | 4660 HShl(HValue* context, HValue* left, HValue* right) |
| 4560 : HBitwiseBinaryOperation(context, left, right) { } | 4661 : HBitwiseBinaryOperation(context, left, right) { } |
| (...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6432 virtual bool IsDeletable() const { return true; } | 6533 virtual bool IsDeletable() const { return true; } |
| 6433 }; | 6534 }; |
| 6434 | 6535 |
| 6435 | 6536 |
| 6436 #undef DECLARE_INSTRUCTION | 6537 #undef DECLARE_INSTRUCTION |
| 6437 #undef DECLARE_CONCRETE_INSTRUCTION | 6538 #undef DECLARE_CONCRETE_INSTRUCTION |
| 6438 | 6539 |
| 6439 } } // namespace v8::internal | 6540 } } // namespace v8::internal |
| 6440 | 6541 |
| 6441 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6542 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |