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 1124 matching lines...) Loading... | |
1135 | 1135 |
1136 bool TryGuaranteeRange(HValue* upper_bound); | 1136 bool TryGuaranteeRange(HValue* upper_bound); |
1137 virtual bool TryDecompose(DecompositionResult* decomposition) { | 1137 virtual bool TryDecompose(DecompositionResult* decomposition) { |
1138 if (RedefinedOperand() != NULL) { | 1138 if (RedefinedOperand() != NULL) { |
1139 return RedefinedOperand()->TryDecompose(decomposition); | 1139 return RedefinedOperand()->TryDecompose(decomposition); |
1140 } else { | 1140 } else { |
1141 return false; | 1141 return false; |
1142 } | 1142 } |
1143 } | 1143 } |
1144 | 1144 |
1145 // Returns true conservatively if the program might be able to observe a | |
1146 // ToString() operation on this value. | |
1147 bool ToStringCanBeObserved() const { | |
1148 if (type().IsUninitialized()) { | |
1149 // If the type is not known, use the representation as a hint. | |
1150 return representation().IsSmiOrInteger32() || representation().IsDouble(); | |
Michael Starzinger
2013/07/26 08:03:03
Discusssed with Sven: This whole line should be ne
| |
1151 } | |
1152 return !type().IsNonPrimitive(); | |
Michael Starzinger
2013/07/26 08:03:03
Discusssed with Sven: What happens for type().IsTa
| |
1153 } | |
1154 | |
1155 // Returns true conservatively if the program might be able to observe a | |
1156 // ToNumber() operation on this value. | |
1157 bool ToNumberCanBeObserved() const { | |
1158 if (type().IsUninitialized()) { | |
1159 // If the type is not known, use the representation as a hint. | |
1160 return representation().IsSmiOrInteger32() || representation().IsDouble(); | |
Michael Starzinger
2013/07/26 08:03:03
Likewise.
| |
1161 } | |
1162 return !type().IsNonPrimitive(); | |
Michael Starzinger
2013/07/26 08:03:03
Likewise.
| |
1163 } | |
1164 | |
1145 protected: | 1165 protected: |
1146 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); | 1166 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); |
1147 | 1167 |
1148 enum RangeGuaranteeDirection { | 1168 enum RangeGuaranteeDirection { |
1149 DIRECTION_NONE = 0, | 1169 DIRECTION_NONE = 0, |
1150 DIRECTION_UPPER = 1, | 1170 DIRECTION_UPPER = 1, |
1151 DIRECTION_LOWER = 2, | 1171 DIRECTION_LOWER = 2, |
1152 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER | 1172 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER |
1153 }; | 1173 }; |
1154 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} | 1174 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} |
(...skipping 2174 matching lines...) Loading... | |
3329 int phi_id() { return phi_id_; } | 3349 int phi_id() { return phi_id_; } |
3330 | 3350 |
3331 static HPhi* cast(HValue* value) { | 3351 static HPhi* cast(HValue* value) { |
3332 ASSERT(value->IsPhi()); | 3352 ASSERT(value->IsPhi()); |
3333 return reinterpret_cast<HPhi*>(value); | 3353 return reinterpret_cast<HPhi*>(value); |
3334 } | 3354 } |
3335 virtual Opcode opcode() const { return HValue::kPhi; } | 3355 virtual Opcode opcode() const { return HValue::kPhi; } |
3336 | 3356 |
3337 void SimplifyConstantInputs(); | 3357 void SimplifyConstantInputs(); |
3338 | 3358 |
3339 // TODO(titzer): we can't eliminate the receiver for generating backtraces | |
3340 virtual bool IsDeletable() const { return !IsReceiver(); } | |
3341 | |
3342 protected: | 3359 protected: |
3343 virtual void DeleteFromGraph(); | 3360 virtual void DeleteFromGraph(); |
3344 virtual void InternalSetOperandAt(int index, HValue* value) { | 3361 virtual void InternalSetOperandAt(int index, HValue* value) { |
3345 inputs_[index] = value; | 3362 inputs_[index] = value; |
3346 } | 3363 } |
3347 | 3364 |
3348 virtual bool IsRelationTrueInternal(NumericRelation relation, | 3365 virtual bool IsRelationTrueInternal(NumericRelation relation, |
3349 HValue* other, | 3366 HValue* other, |
3350 int offset = 0, | 3367 int offset = 0, |
3351 int scale = 0); | 3368 int scale = 0); |
3352 | 3369 |
3353 private: | 3370 private: |
3354 ZoneList<HValue*> inputs_; | 3371 ZoneList<HValue*> inputs_; |
3355 int merged_index_; | 3372 int merged_index_; |
3356 | 3373 |
3357 int non_phi_uses_[Representation::kNumRepresentations]; | 3374 int non_phi_uses_[Representation::kNumRepresentations]; |
3358 int indirect_uses_[Representation::kNumRepresentations]; | 3375 int indirect_uses_[Representation::kNumRepresentations]; |
3359 int phi_id_; | 3376 int phi_id_; |
3360 InductionVariableData* induction_variable_data_; | 3377 InductionVariableData* induction_variable_data_; |
3378 | |
3379 // TODO(titzer): we can't eliminate the receiver for generating backtraces | |
3380 virtual bool IsDeletable() const { return !IsReceiver(); } | |
3361 }; | 3381 }; |
3362 | 3382 |
3363 | 3383 |
3364 class HInductionVariableAnnotation : public HUnaryOperation { | 3384 class HInductionVariableAnnotation : public HUnaryOperation { |
3365 public: | 3385 public: |
3366 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, | 3386 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, |
3367 NumericRelation relation, | 3387 NumericRelation relation, |
3368 int operand_index); | 3388 int operand_index); |
3369 | 3389 |
3370 NumericRelation relation() { return relation_; } | 3390 NumericRelation relation() { return relation_; } |
(...skipping 293 matching lines...) Loading... | |
3664 HBinaryOperation(HValue* context, HValue* left, HValue* right) | 3684 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
3665 : observed_output_representation_(Representation::None()) { | 3685 : observed_output_representation_(Representation::None()) { |
3666 ASSERT(left != NULL && right != NULL); | 3686 ASSERT(left != NULL && right != NULL); |
3667 SetOperandAt(0, context); | 3687 SetOperandAt(0, context); |
3668 SetOperandAt(1, left); | 3688 SetOperandAt(1, left); |
3669 SetOperandAt(2, right); | 3689 SetOperandAt(2, right); |
3670 observed_input_representation_[0] = Representation::None(); | 3690 observed_input_representation_[0] = Representation::None(); |
3671 observed_input_representation_[1] = Representation::None(); | 3691 observed_input_representation_[1] = Representation::None(); |
3672 } | 3692 } |
3673 | 3693 |
3674 HValue* context() { return OperandAt(0); } | 3694 HValue* context() const { return OperandAt(0); } |
3675 HValue* left() { return OperandAt(1); } | 3695 HValue* left() const { return OperandAt(1); } |
3676 HValue* right() { return OperandAt(2); } | 3696 HValue* right() const { return OperandAt(2); } |
3677 | 3697 |
3678 // True if switching left and right operands likely generates better code. | 3698 // True if switching left and right operands likely generates better code. |
3679 bool AreOperandsBetterSwitched() { | 3699 bool AreOperandsBetterSwitched() { |
3680 if (!IsCommutative()) return false; | 3700 if (!IsCommutative()) return false; |
3681 | 3701 |
3682 // Constant operands are better off on the right, they can be inlined in | 3702 // Constant operands are better off on the right, they can be inlined in |
3683 // many situations on most platforms. | 3703 // many situations on most platforms. |
3684 if (left()->IsConstant()) return true; | 3704 if (left()->IsConstant()) return true; |
3685 if (right()->IsConstant()) return false; | 3705 if (right()->IsConstant()) return false; |
3686 | 3706 |
(...skipping 229 matching lines...) Loading... | |
3916 base_ = index(); | 3936 base_ = index(); |
3917 offset_ = 0; | 3937 offset_ = 0; |
3918 scale_ = 0; | 3938 scale_ = 0; |
3919 return false; | 3939 return false; |
3920 } | 3940 } |
3921 } | 3941 } |
3922 | 3942 |
3923 virtual Representation RequiredInputRepresentation(int arg_index) { | 3943 virtual Representation RequiredInputRepresentation(int arg_index) { |
3924 return representation(); | 3944 return representation(); |
3925 } | 3945 } |
3926 virtual bool IsDeletable() const { | |
3927 return skip_check() && !FLAG_debug_code; | |
3928 } | |
3929 | 3946 |
3930 virtual bool IsRelationTrueInternal(NumericRelation relation, | 3947 virtual bool IsRelationTrueInternal(NumericRelation relation, |
3931 HValue* related_value, | 3948 HValue* related_value, |
3932 int offset = 0, | 3949 int offset = 0, |
3933 int scale = 0); | 3950 int scale = 0); |
3934 | 3951 |
3935 virtual void PrintDataTo(StringStream* stream); | 3952 virtual void PrintDataTo(StringStream* stream); |
3936 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); | 3953 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
3937 | 3954 |
3938 HValue* index() { return OperandAt(0); } | 3955 HValue* index() { return OperandAt(0); } |
(...skipping 16 matching lines...) Loading... | |
3955 } | 3972 } |
3956 | 3973 |
3957 virtual bool DataEquals(HValue* other) { return true; } | 3974 virtual bool DataEquals(HValue* other) { return true; } |
3958 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); | 3975 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); |
3959 bool skip_check_; | 3976 bool skip_check_; |
3960 HValue* base_; | 3977 HValue* base_; |
3961 int offset_; | 3978 int offset_; |
3962 int scale_; | 3979 int scale_; |
3963 RangeGuaranteeDirection responsibility_direction_; | 3980 RangeGuaranteeDirection responsibility_direction_; |
3964 bool allow_equality_; | 3981 bool allow_equality_; |
3982 | |
3983 private: | |
3984 virtual bool IsDeletable() const { | |
3985 return skip_check() && !FLAG_debug_code; | |
3986 } | |
3965 }; | 3987 }; |
3966 | 3988 |
3967 | 3989 |
3968 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { | 3990 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { |
3969 public: | 3991 public: |
3970 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { | 3992 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { |
3971 DecompositionResult decomposition; | 3993 DecompositionResult decomposition; |
3972 if (check->index()->TryDecompose(&decomposition)) { | 3994 if (check->index()->TryDecompose(&decomposition)) { |
3973 SetOperandAt(0, decomposition.base()); | 3995 SetOperandAt(0, decomposition.base()); |
3974 SetOperandAt(1, check); | 3996 SetOperandAt(1, check); |
(...skipping 2414 matching lines...) Loading... | |
6389 | 6411 |
6390 private: | 6412 private: |
6391 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) | 6413 HStringAdd(HValue* context, HValue* left, HValue* right, StringAddFlags flags) |
6392 : HBinaryOperation(context, left, right), flags_(flags) { | 6414 : HBinaryOperation(context, left, right), flags_(flags) { |
6393 set_representation(Representation::Tagged()); | 6415 set_representation(Representation::Tagged()); |
6394 SetFlag(kUseGVN); | 6416 SetFlag(kUseGVN); |
6395 SetGVNFlag(kDependsOnMaps); | 6417 SetGVNFlag(kDependsOnMaps); |
6396 SetGVNFlag(kChangesNewSpacePromotion); | 6418 SetGVNFlag(kChangesNewSpacePromotion); |
6397 } | 6419 } |
6398 | 6420 |
6399 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 6421 virtual bool IsDeletable() const { |
6400 // virtual bool IsDeletable() const { return true; } | 6422 if (flags_ == STRING_ADD_CHECK_NONE) return true; |
6423 return !left()->ToStringCanBeObserved() | |
6424 && !right()->ToStringCanBeObserved(); | |
6425 } | |
6401 | 6426 |
6402 const StringAddFlags flags_; | 6427 const StringAddFlags flags_; |
6403 }; | 6428 }; |
6404 | 6429 |
6405 | 6430 |
6406 class HStringCharCodeAt: public HTemplateInstruction<3> { | 6431 class HStringCharCodeAt: public HTemplateInstruction<3> { |
6407 public: | 6432 public: |
6408 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { | 6433 HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { |
6409 SetOperandAt(0, context); | 6434 SetOperandAt(0, context); |
6410 SetOperandAt(1, string); | 6435 SetOperandAt(1, string); |
6411 SetOperandAt(2, index); | 6436 SetOperandAt(2, index); |
6412 set_representation(Representation::Integer32()); | 6437 set_representation(Representation::Integer32()); |
6413 SetFlag(kUseGVN); | 6438 SetFlag(kUseGVN); |
6414 SetGVNFlag(kDependsOnMaps); | 6439 SetGVNFlag(kDependsOnMaps); |
6415 SetGVNFlag(kChangesNewSpacePromotion); | 6440 SetGVNFlag(kChangesNewSpacePromotion); |
6416 } | 6441 } |
6417 | 6442 |
6418 virtual Representation RequiredInputRepresentation(int index) { | 6443 virtual Representation RequiredInputRepresentation(int index) { |
6419 // The index is supposed to be Integer32. | 6444 // The index is supposed to be Integer32. |
6420 return index == 2 | 6445 return index == 2 |
6421 ? Representation::Integer32() | 6446 ? Representation::Integer32() |
6422 : Representation::Tagged(); | 6447 : Representation::Tagged(); |
6423 } | 6448 } |
6424 | 6449 |
6425 HValue* context() { return OperandAt(0); } | 6450 HValue* context() const { return OperandAt(0); } |
6426 HValue* string() { return OperandAt(1); } | 6451 HValue* string() const { return OperandAt(1); } |
6427 HValue* index() { return OperandAt(2); } | 6452 HValue* index() const { return OperandAt(2); } |
6428 | 6453 |
6429 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) | 6454 DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) |
6430 | 6455 |
6431 protected: | 6456 protected: |
6432 virtual bool DataEquals(HValue* other) { return true; } | 6457 virtual bool DataEquals(HValue* other) { return true; } |
6433 | 6458 |
6434 virtual Range* InferRange(Zone* zone) { | 6459 virtual Range* InferRange(Zone* zone) { |
6435 return new(zone) Range(0, String::kMaxUtf16CodeUnit); | 6460 return new(zone) Range(0, String::kMaxUtf16CodeUnit); |
6436 } | 6461 } |
6437 | 6462 |
6438 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 6463 private: |
6439 // private: | 6464 virtual bool IsDeletable() const { |
6440 // virtual bool IsDeletable() const { return true; } | 6465 // NOTE: we assume this instruction is dominated by a string typecheck. |
6466 return !index()->ToNumberCanBeObserved(); | |
6467 } | |
6441 }; | 6468 }; |
6442 | 6469 |
6443 | 6470 |
6444 class HStringCharFromCode: public HTemplateInstruction<2> { | 6471 class HStringCharFromCode: public HTemplateInstruction<2> { |
6445 public: | 6472 public: |
6446 static HInstruction* New(Zone* zone, | 6473 static HInstruction* New(Zone* zone, |
6447 HValue* context, | 6474 HValue* context, |
6448 HValue* char_code); | 6475 HValue* char_code); |
6449 | 6476 |
6450 virtual Representation RequiredInputRepresentation(int index) { | 6477 virtual Representation RequiredInputRepresentation(int index) { |
6451 return index == 0 | 6478 return index == 0 |
6452 ? Representation::Tagged() | 6479 ? Representation::Tagged() |
6453 : Representation::Integer32(); | 6480 : Representation::Integer32(); |
6454 } | 6481 } |
6455 virtual HType CalculateInferredType(); | 6482 virtual HType CalculateInferredType() { return HType::String(); } |
6456 | 6483 |
6457 HValue* context() { return OperandAt(0); } | 6484 HValue* context() const { return OperandAt(0); } |
6458 HValue* value() { return OperandAt(1); } | 6485 HValue* value() const { return OperandAt(1); } |
6459 | 6486 |
6460 virtual bool DataEquals(HValue* other) { return true; } | 6487 virtual bool DataEquals(HValue* other) { return true; } |
6461 | 6488 |
6462 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) | 6489 DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) |
6463 | 6490 |
6464 private: | 6491 private: |
6465 HStringCharFromCode(HValue* context, HValue* char_code) { | 6492 HStringCharFromCode(HValue* context, HValue* char_code) { |
6466 SetOperandAt(0, context); | 6493 SetOperandAt(0, context); |
6467 SetOperandAt(1, char_code); | 6494 SetOperandAt(1, char_code); |
6468 set_representation(Representation::Tagged()); | 6495 set_representation(Representation::Tagged()); |
6469 SetFlag(kUseGVN); | 6496 SetFlag(kUseGVN); |
6470 SetGVNFlag(kChangesNewSpacePromotion); | 6497 SetGVNFlag(kChangesNewSpacePromotion); |
6471 } | 6498 } |
6472 | 6499 |
6473 // TODO(svenpanne) Might be safe, but leave it out until we know for sure. | 6500 virtual bool IsDeletable() const { |
6474 // virtual bool IsDeletable() const { return true; } | 6501 return !value()->ToNumberCanBeObserved(); |
6502 } | |
6475 }; | 6503 }; |
6476 | 6504 |
6477 | 6505 |
6478 class HStringLength: public HUnaryOperation { | 6506 class HStringLength: public HUnaryOperation { |
6479 public: | 6507 public: |
6480 static HInstruction* New(Zone* zone, HValue* string); | 6508 static HInstruction* New(Zone* zone, HValue* string); |
6481 | 6509 |
6482 virtual Representation RequiredInputRepresentation(int index) { | 6510 virtual Representation RequiredInputRepresentation(int index) { |
6483 return Representation::Tagged(); | 6511 return Representation::Tagged(); |
6484 } | 6512 } |
(...skipping 388 matching lines...) Loading... | |
6873 virtual bool IsDeletable() const { return true; } | 6901 virtual bool IsDeletable() const { return true; } |
6874 }; | 6902 }; |
6875 | 6903 |
6876 | 6904 |
6877 #undef DECLARE_INSTRUCTION | 6905 #undef DECLARE_INSTRUCTION |
6878 #undef DECLARE_CONCRETE_INSTRUCTION | 6906 #undef DECLARE_CONCRETE_INSTRUCTION |
6879 | 6907 |
6880 } } // namespace v8::internal | 6908 } } // namespace v8::internal |
6881 | 6909 |
6882 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6910 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |