Index: src/hydrogen-instructions.h |
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
index 11e85a0c034ab6a689eaa4fdf55cb537f9af1035..9d95033080757ff489e43d7991e6a985995833f2 100644 |
--- a/src/hydrogen-instructions.h |
+++ b/src/hydrogen-instructions.h |
@@ -4830,11 +4830,21 @@ class HPower final : public HTemplateInstruction<2> { |
}; |
+enum ExternalAddType { |
+ AddOfExternalAndTagged, |
+ AddOfExternalAndInt32, |
+ NoExternalAdd |
+}; |
+ |
+ |
class HAdd final : public HArithmeticBinaryOperation { |
public: |
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context, |
HValue* left, HValue* right, |
Strength strength = Strength::WEAK); |
+ static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context, |
+ HValue* left, HValue* right, Strength strength, |
+ ExternalAddType external_add_type); |
// Add is only commutative if two integer values are added and not if two |
// tagged values are added (because it might be a String concatenation). |
@@ -4877,6 +4887,14 @@ class HAdd final : public HArithmeticBinaryOperation { |
Representation RequiredInputRepresentation(int index) override; |
+ bool IsConsistentExternalRepresentation() { |
+ return left()->representation().IsExternal() && |
+ ((external_add_type_ == AddOfExternalAndInt32 && |
+ right()->representation().IsInteger32()) || |
+ (external_add_type_ == AddOfExternalAndTagged && |
+ right()->representation().IsTagged())); |
+ } |
+ |
DECLARE_CONCRETE_INSTRUCTION(Add) |
protected: |
@@ -4885,10 +4903,35 @@ class HAdd final : public HArithmeticBinaryOperation { |
Range* InferRange(Zone* zone) override; |
private: |
- HAdd(HValue* context, HValue* left, HValue* right, Strength strength) |
- : HArithmeticBinaryOperation(context, left, right, strength) { |
+ HAdd(HValue* context, HValue* left, HValue* right, Strength strength, |
+ ExternalAddType external_add_type = NoExternalAdd) |
+ : HArithmeticBinaryOperation(context, left, right, strength), |
+ external_add_type_(external_add_type) { |
SetFlag(kCanOverflow); |
+ switch (external_add_type_) { |
+ case AddOfExternalAndTagged: |
+ DCHECK(left->representation().IsExternal()); |
+ DCHECK(right->representation().IsTagged()); |
+ SetDependsOnFlag(kNewSpacePromotion); |
+ break; |
+ |
+ case NoExternalAdd: |
+ // This is a bit of a hack: The call to this constructor is generated |
+ // by a macro that also supports sub and mul, so it doesn't pass in |
+ // a value for external_add_type but uses the default. |
+ if (left->representation().IsExternal()) { |
+ external_add_type_ = AddOfExternalAndInt32; |
+ } |
+ break; |
+ |
+ case AddOfExternalAndInt32: |
+ // See comment above. |
+ UNREACHABLE(); |
+ break; |
+ } |
} |
+ |
+ ExternalAddType external_add_type_; |
}; |