| Index: src/hydrogen-instructions.h
|
| diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
|
| index ecfb3f98346a2bcdc87c2ea32424d9cdc8acbcd2..a2be2d0ec2251470647d440b6573dd33c6c772f5 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));
|
| @@ -1715,7 +1718,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 +1728,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 +2630,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:
|
| @@ -3444,13 +3450,13 @@ class HBinaryOperation: public HTemplateInstruction<3> {
|
|
|
| // Constant operands are better off on the right, they can be inlined in
|
| // many situations on most platforms.
|
| - if (left()->IsConstant()) return true;
|
| if (right()->IsConstant()) return false;
|
| + if (left()->IsConstant()) return true;
|
|
|
| // 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 left()->UseCount() > 1 && right()->UseCount() == 1;
|
| }
|
|
|
| HValue* BetterLeftOperand() {
|
| @@ -3475,24 +3481,29 @@ 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();
|
| + if (!FLAG_smi_binop) {
|
| + if (new_rep.IsSmi()) new_rep = Representation::Integer32();
|
| }
|
| HValue::UpdateRepresentation(new_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,15 @@ class HMod: public HArithmeticBinaryOperation {
|
|
|
| virtual HValue* Canonicalize();
|
|
|
| + virtual void UpdateRepresentation(Representation new_rep,
|
| + HInferRepresentationPhase* h_infer,
|
| + const char* reason) {
|
| + if (!FLAG_smi_binop) {
|
| + if (new_rep.IsSmi()) new_rep = Representation::Integer32();
|
| + }
|
| + HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
|
| + }
|
| +
|
| DECLARE_CONCRETE_INSTRUCTION(Mod)
|
|
|
| protected:
|
| @@ -4506,6 +4526,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 +4573,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 +4632,11 @@ 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);
|
| + if (op == Token::BIT_AND &&
|
| + ((left->IsConstant() && left->representation().IsSmi()) ||
|
| + (right->IsConstant() && right->representation().IsSmi()))) {
|
| + SetFlag(kTruncatingToSmi);
|
| + }
|
| }
|
|
|
| Token::Value op_;
|
| @@ -4620,6 +4652,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 +4691,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 +4730,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 +4755,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:
|
| @@ -5929,6 +5989,9 @@ class HStoreKeyed
|
| // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
|
| if (elements_kind >= EXTERNAL_BYTE_ELEMENTS &&
|
| elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) {
|
| + if (elements_kind <= EXTERNAL_SHORT_ELEMENTS) {
|
| + SetFlag(kTruncatingToSmi);
|
| + }
|
| SetFlag(kTruncatingToInt32);
|
| }
|
| }
|
|
|