| 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 &&
|
| + ((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:
|
|
|