Chromium Code Reviews

Side by Side Diff: src/hydrogen-instructions.h

Issue 20241005: Fix IsDeletable() for HStringAdd, HStringCharCodeAt, HStringCharFromCode. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix predicate for ToStringCanBeObserved() and private-ness of IsDeletable() Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
« no previous file with comments | « no previous file | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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...)
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...)
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...)
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...)
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...)
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...)
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...)
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_
OLDNEW
« no previous file with comments | « no previous file | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine