Chromium Code Reviews| Index: src/hydrogen-instructions.h |
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
| index ad274657687f14f1def2209166fcbd317fc3294f..fd4db3427869285a7c1ee7574df5e6c1f2fc3872 100644 |
| --- a/src/hydrogen-instructions.h |
| +++ b/src/hydrogen-instructions.h |
| @@ -295,9 +295,9 @@ class Range: public ZoneObject { |
| void AddConstant(int32_t value); |
| void Sar(int32_t value); |
| void Shl(int32_t value); |
| - bool AddAndCheckOverflow(Range* other); |
| - bool SubAndCheckOverflow(Range* other); |
| - bool MulAndCheckOverflow(Range* other); |
| + bool AddAndCheckOverflow(const Representation& r, Range* other); |
| + bool SubAndCheckOverflow(const Representation& r, Range* other); |
| + bool MulAndCheckOverflow(const Representation& r, Range* other); |
| private: |
| int32_t lower_; |
| @@ -806,6 +806,8 @@ class HValue: public ZoneObject { |
| kIsArguments, |
| kTruncatingToInt32, |
| kAllUsesTruncatingToInt32, |
| + kTruncatingToSmi, |
| + kAllUsesTruncatingToSmi, |
| // Set after an instruction is killed. |
| kIsDead, |
| // Instructions that are allowed to produce full range unsigned integer |
| @@ -892,6 +894,7 @@ class HValue: public ZoneObject { |
| HUseIterator uses() const { return HUseIterator(use_list_); } |
| virtual bool EmitAtUses() { return false; } |
| + |
| Representation representation() const { return representation_; } |
| void ChangeRepresentation(Representation r) { |
| ASSERT(CheckFlag(kFlexibleRepresentation)); |
| @@ -1167,6 +1170,7 @@ class HValue: public ZoneObject { |
| } |
| Representation RepresentationFromUses(); |
| Representation RepresentationFromUseRequirements(); |
| + bool HasNonSmiUse(); |
| virtual void UpdateRepresentation(Representation new_rep, |
| HInferRepresentationPhase* h_infer, |
| const char* reason); |
| @@ -1715,7 +1719,8 @@ class HChange: public HUnaryOperation { |
| public: |
| HChange(HValue* value, |
| Representation to, |
| - bool is_truncating, |
| + bool is_truncating_to_smi, |
| + bool is_truncating_to_int32, |
| bool allow_undefined_as_nan) |
| : HUnaryOperation(value) { |
| ASSERT(!value->representation().IsNone()); |
| @@ -1724,7 +1729,8 @@ class HChange: public HUnaryOperation { |
| set_representation(to); |
| SetFlag(kUseGVN); |
| if (allow_undefined_as_nan) SetFlag(kAllowUndefinedAsNaN); |
| - if (is_truncating) SetFlag(kTruncatingToInt32); |
| + if (is_truncating_to_smi) SetFlag(kTruncatingToSmi); |
| + if (is_truncating_to_int32) SetFlag(kTruncatingToInt32); |
| if (value->representation().IsSmi() || value->type().IsSmi()) { |
| set_type(HType::Smi()); |
| } else { |
| @@ -2625,6 +2631,7 @@ class HUnaryMathOperation: public HTemplateInstruction<2> { |
| switch (op) { |
| case kMathFloor: |
| case kMathRound: |
| + // TODO(verwaest): Set representation to flexible int starting as smi. |
| set_representation(Representation::Integer32()); |
| break; |
| case kMathAbs: |
| @@ -3288,7 +3295,7 @@ class HConstant: public HTemplateInstruction<0> { |
| } |
| virtual Representation KnownOptimalRepresentation() { |
| - if (HasSmiValue()) return Representation::Smi(); |
| + if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); |
| if (HasInteger32Value()) return Representation::Integer32(); |
| if (HasNumberValue()) return Representation::Double(); |
| return Representation::Tagged(); |
| @@ -3450,7 +3457,7 @@ class HBinaryOperation: public HTemplateInstruction<3> { |
| // Otherwise, if there is only one use of the right operand, it would be |
| // better off on the left for platforms that only have 2-arg arithmetic |
| // ops (e.g ia32, x64) that clobber the left operand. |
| - return (right()->UseCount() == 1); |
| + return right()->UseCount() == 1; |
| } |
| HValue* BetterLeftOperand() { |
| @@ -3475,24 +3482,28 @@ class HBinaryOperation: public HTemplateInstruction<3> { |
| return observed_input_representation_[index - 1]; |
| } |
| - virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
| - virtual Representation RepresentationFromInputs(); |
| - virtual void AssumeRepresentation(Representation r); |
| - |
| virtual void UpdateRepresentation(Representation new_rep, |
| HInferRepresentationPhase* h_infer, |
| const char* reason) { |
| - // By default, binary operations don't handle Smis. |
| - if (new_rep.IsSmi()) { |
| - new_rep = Representation::Integer32(); |
| - } |
| - HValue::UpdateRepresentation(new_rep, h_infer, reason); |
| + Representation rep = !FLAG_smi_binop && new_rep.IsSmi() |
| + ? Representation::Integer32() : new_rep; |
| + HValue::UpdateRepresentation(rep, h_infer, reason); |
| } |
| + virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
| + virtual Representation RepresentationFromInputs(); |
| + Representation RepresentationFromOutput(); |
| + virtual void AssumeRepresentation(Representation r); |
| + |
| virtual bool IsCommutative() const { return false; } |
| virtual void PrintDataTo(StringStream* stream); |
| + virtual Representation RequiredInputRepresentation(int index) { |
| + if (index == 0) return Representation::Tagged(); |
| + return representation(); |
| + } |
| + |
| DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) |
| private: |
| @@ -3771,15 +3782,9 @@ class HBitwiseBinaryOperation: public HBinaryOperation { |
| SetAllSideEffects(); |
| } |
| - virtual Representation RequiredInputRepresentation(int index) { |
| - return index == 0 |
| - ? Representation::Tagged() |
| - : representation(); |
| - } |
| - |
| virtual void RepresentationChanged(Representation to) { |
| if (!to.IsTagged()) { |
| - ASSERT(to.IsInteger32()); |
| + ASSERT(to.IsSmiOrInteger32()); |
| ClearAllSideEffects(); |
| SetFlag(kUseGVN); |
| } else { |
| @@ -3792,10 +3797,14 @@ class HBitwiseBinaryOperation: public HBinaryOperation { |
| HInferRepresentationPhase* h_infer, |
| const char* reason) { |
| // We only generate either int32 or generic tagged bitwise operations. |
| - if (new_rep.IsSmi() || new_rep.IsDouble()) { |
| - new_rep = Representation::Integer32(); |
| - } |
| - HValue::UpdateRepresentation(new_rep, h_infer, reason); |
| + if (new_rep.IsDouble()) new_rep = Representation::Integer32(); |
| + HBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| + } |
| + |
| + virtual Representation observed_input_representation(int index) { |
| + Representation r = HBinaryOperation::observed_input_representation(index); |
| + if (r.IsDouble()) return Representation::Integer32(); |
| + return r; |
| } |
| virtual void initialize_output_representation(Representation observed) { |
| @@ -3861,11 +3870,6 @@ class HArithmeticBinaryOperation: public HBinaryOperation { |
| } |
| virtual HType CalculateInferredType(); |
| - virtual Representation RequiredInputRepresentation(int index) { |
| - return index == 0 |
| - ? Representation::Tagged() |
| - : representation(); |
| - } |
| DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) |
| @@ -4425,6 +4429,13 @@ class HMul: public HArithmeticBinaryOperation { |
| return !representation().IsTagged(); |
| } |
| + virtual void UpdateRepresentation(Representation new_rep, |
| + HInferRepresentationPhase* h_infer, |
| + const char* reason) { |
| + if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| + HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| + } |
| + |
| DECLARE_CONCRETE_INSTRUCTION(Mul) |
| protected: |
| @@ -4464,6 +4475,13 @@ class HMod: public HArithmeticBinaryOperation { |
| virtual HValue* Canonicalize(); |
| + virtual void UpdateRepresentation(Representation new_rep, |
| + HInferRepresentationPhase* h_infer, |
| + const char* reason) { |
| + if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| + HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| + } |
| + |
| DECLARE_CONCRETE_INSTRUCTION(Mod) |
| protected: |
| @@ -4506,6 +4524,13 @@ class HDiv: public HArithmeticBinaryOperation { |
| virtual HValue* Canonicalize(); |
| + virtual void UpdateRepresentation(Representation new_rep, |
| + HInferRepresentationPhase* h_infer, |
| + const char* reason) { |
| + if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| + HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| + } |
| + |
| DECLARE_CONCRETE_INSTRUCTION(Div) |
| protected: |
| @@ -4546,11 +4571,11 @@ class HMathMinMax: public HArithmeticBinaryOperation { |
| virtual Representation RepresentationFromInputs() { |
| Representation left_rep = left()->representation(); |
| Representation right_rep = right()->representation(); |
| - if ((left_rep.IsNone() || left_rep.IsInteger32()) && |
| - (right_rep.IsNone() || right_rep.IsInteger32())) { |
| - return Representation::Integer32(); |
| - } |
| - return Representation::Double(); |
| + Representation result = Representation::Smi(); |
| + result = result.generalize(left_rep); |
| + result = result.generalize(right_rep); |
| + if (result.IsTagged()) return Representation::Double(); |
| + return result; |
| } |
| virtual bool IsCommutative() const { return true; } |
| @@ -4605,6 +4630,27 @@ class HBitwise: public HBitwiseBinaryOperation { |
| HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) |
| : HBitwiseBinaryOperation(context, left, right), op_(op) { |
| ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); |
| + // BIT_AND with a smi-range positive value will always unset the |
| + // entire sign-extension of the smi-sign. |
| + if (op == Token::BIT_AND && |
| + ((left->IsConstant() && |
| + left->representation().IsSmi() && |
| + HConstant::cast(left)->Integer32Value() >= 0) || |
| + (right->IsConstant() && |
| + right->representation().IsSmi() && |
| + HConstant::cast(right)->Integer32Value() >= 0))) { |
| + SetFlag(kTruncatingToSmi); |
| + // BIT_OR with a smi-range negative value will always set the entire |
| + // sign-extension of the smi-sign. |
| + } else if (op == Token::BIT_OR && |
|
Sven Panne
2013/07/25 06:05:58
Can we come up with a case for BIT_XOR? :-)
Toon Verwaest
2013/07/25 09:29:24
I guess not: Even if all the sign-extended bits ar
|
| + ((left->IsConstant() && |
| + left->representation().IsSmi() && |
| + HConstant::cast(left)->Integer32Value() < 0) || |
| + (right->IsConstant() && |
| + right->representation().IsSmi() && |
| + HConstant::cast(right)->Integer32Value() < 0))) { |
| + SetFlag(kTruncatingToSmi); |
| + } |
| } |
| Token::Value op_; |
| @@ -4620,6 +4666,13 @@ class HShl: public HBitwiseBinaryOperation { |
| virtual Range* InferRange(Zone* zone); |
| + virtual void UpdateRepresentation(Representation new_rep, |
| + HInferRepresentationPhase* h_infer, |
| + const char* reason) { |
| + if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| + HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| + } |
| + |
| DECLARE_CONCRETE_INSTRUCTION(Shl) |
| protected: |
| @@ -4652,6 +4705,13 @@ class HShr: public HBitwiseBinaryOperation { |
| virtual Range* InferRange(Zone* zone); |
| + virtual void UpdateRepresentation(Representation new_rep, |
| + HInferRepresentationPhase* h_infer, |
| + const char* reason) { |
| + if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| + HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| + } |
| + |
| DECLARE_CONCRETE_INSTRUCTION(Shr) |
| protected: |
| @@ -4684,6 +4744,13 @@ class HSar: public HBitwiseBinaryOperation { |
| virtual Range* InferRange(Zone* zone); |
| + virtual void UpdateRepresentation(Representation new_rep, |
| + HInferRepresentationPhase* h_infer, |
| + const char* reason) { |
| + if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| + HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| + } |
| + |
| DECLARE_CONCRETE_INSTRUCTION(Sar) |
| protected: |
| @@ -4702,6 +4769,13 @@ class HRor: public HBitwiseBinaryOperation { |
| ChangeRepresentation(Representation::Integer32()); |
| } |
| + virtual void UpdateRepresentation(Representation new_rep, |
| + HInferRepresentationPhase* h_infer, |
| + const char* reason) { |
| + if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| + HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| + } |
| + |
| DECLARE_CONCRETE_INSTRUCTION(Ror) |
| protected: |