| Index: runtime/vm/intermediate_language.h
|
| ===================================================================
|
| --- runtime/vm/intermediate_language.h (revision 12765)
|
| +++ runtime/vm/intermediate_language.h (working copy)
|
| @@ -132,7 +132,9 @@
|
|
|
|
|
| enum Representation {
|
| - kTagged, kUnboxedDouble
|
| + kTagged,
|
| + kUnboxedDouble,
|
| + kUnboxedInteger
|
| };
|
|
|
|
|
| @@ -241,7 +243,6 @@
|
| M(CloneContext) \
|
| M(CatchEntry) \
|
| M(BinarySmiOp) \
|
| - M(BinaryMintOp) \
|
| M(UnarySmiOp) \
|
| M(CheckStackOverflow) \
|
| M(DoubleToDouble) \
|
| @@ -254,6 +255,9 @@
|
| M(MathSqrt) \
|
| M(UnboxDouble) \
|
| M(BoxDouble) \
|
| + M(UnboxInteger) \
|
| + M(BoxInteger) \
|
| + M(UnboxedMintBinaryOp) \
|
| M(CheckArrayBound) \
|
| M(Constraint) \
|
|
|
| @@ -499,8 +503,10 @@
|
| friend class Definition; // Needed for InsertBefore, InsertAfter.
|
|
|
| // Classes that set deopt_id_.
|
| + friend class UnboxIntegerInstr;
|
| friend class UnboxDoubleInstr;
|
| friend class UnboxedDoubleBinaryOpInstr;
|
| + friend class UnboxedMintBinaryOpInstr;
|
| friend class MathSqrtInstr;
|
| friend class CheckClassInstr;
|
| friend class CheckSmiInstr;
|
| @@ -2286,7 +2292,9 @@
|
|
|
| virtual Representation RequiredInputRepresentation(intptr_t idx) const {
|
| ASSERT((idx == 0) || (idx == 1));
|
| - return (receiver_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged;
|
| + if (receiver_class_id() == kDoubleCid) return kUnboxedDouble;
|
| + if (receiver_class_id() == kMintCid) return kUnboxedInteger;
|
| + return kTagged;
|
| }
|
|
|
| private:
|
| @@ -3282,6 +3290,37 @@
|
| };
|
|
|
|
|
| +class BoxIntegerInstr : public TemplateDefinition<1> {
|
| + public:
|
| + explicit BoxIntegerInstr(Value* value) {
|
| + ASSERT(value != NULL);
|
| + inputs_[0] = value;
|
| + }
|
| +
|
| + Value* value() const { return inputs_[0]; }
|
| +
|
| + virtual bool CanDeoptimize() const { return false; }
|
| +
|
| + virtual bool HasSideEffect() const { return false; }
|
| +
|
| + virtual bool AffectedBySideEffect() const { return false; }
|
| + virtual bool AttributesEqual(Instruction* other) const { return true; }
|
| +
|
| + virtual intptr_t ResultCid() const;
|
| +
|
| + virtual Representation RequiredInputRepresentation(intptr_t idx) const {
|
| + ASSERT(idx == 0);
|
| + return kUnboxedInteger;
|
| + }
|
| +
|
| + DECLARE_INSTRUCTION(BoxInteger)
|
| + virtual RawAbstractType* CompileType() const;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr);
|
| +};
|
| +
|
| +
|
| class UnboxDoubleInstr : public TemplateDefinition<1> {
|
| public:
|
| UnboxDoubleInstr(Value* value, intptr_t deopt_id) {
|
| @@ -3317,6 +3356,41 @@
|
| };
|
|
|
|
|
| +class UnboxIntegerInstr : public TemplateDefinition<1> {
|
| + public:
|
| + UnboxIntegerInstr(Value* value, intptr_t deopt_id) {
|
| + ASSERT(value != NULL);
|
| + inputs_[0] = value;
|
| + deopt_id_ = deopt_id;
|
| + }
|
| +
|
| + Value* value() const { return inputs_[0]; }
|
| +
|
| + virtual bool CanDeoptimize() const {
|
| + return (value()->ResultCid() != kMintCid)
|
| + && (value()->ResultCid() != kSmiCid);
|
| + }
|
| +
|
| + virtual bool HasSideEffect() const { return false; }
|
| +
|
| + virtual intptr_t ResultCid() const;
|
| +
|
| + virtual RawAbstractType* CompileType() const;
|
| +
|
| + virtual Representation representation() const {
|
| + return kUnboxedInteger;
|
| + }
|
| +
|
| + virtual bool AffectedBySideEffect() const { return false; }
|
| + virtual bool AttributesEqual(Instruction* other) const { return true; }
|
| +
|
| + DECLARE_INSTRUCTION(UnboxInteger)
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr);
|
| +};
|
| +
|
| +
|
| class MathSqrtInstr : public TemplateDefinition<1> {
|
| public:
|
| MathSqrtInstr(Value* value, StaticCallInstr* instance_call) {
|
| @@ -3420,19 +3494,18 @@
|
| };
|
|
|
|
|
| -class BinarySmiOpInstr : public TemplateDefinition<2> {
|
| +class UnboxedMintBinaryOpInstr : public TemplateDefinition<2> {
|
| public:
|
| - BinarySmiOpInstr(Token::Kind op_kind,
|
| - InstanceCallInstr* instance_call,
|
| - Value* left,
|
| - Value* right)
|
| - : op_kind_(op_kind),
|
| - instance_call_(instance_call),
|
| - overflow_(true) {
|
| + UnboxedMintBinaryOpInstr(Token::Kind op_kind,
|
| + Value* left,
|
| + Value* right,
|
| + InstanceCallInstr* instance_call)
|
| + : op_kind_(op_kind) {
|
| ASSERT(left != NULL);
|
| ASSERT(right != NULL);
|
| inputs_[0] = left;
|
| inputs_[1] = right;
|
| + deopt_id_ = instance_call->deopt_id();
|
| }
|
|
|
| Value* left() const { return inputs_[0]; }
|
| @@ -3440,49 +3513,54 @@
|
|
|
| Token::Kind op_kind() const { return op_kind_; }
|
|
|
| - InstanceCallInstr* instance_call() const { return instance_call_; }
|
| -
|
| - const ICData* ic_data() const { return instance_call()->ic_data(); }
|
| -
|
| virtual void PrintOperandsTo(BufferFormatter* f) const;
|
|
|
| - DECLARE_INSTRUCTION(BinarySmiOp)
|
| - virtual RawAbstractType* CompileType() const;
|
| + virtual bool CanDeoptimize() const { return false; }
|
|
|
| - virtual bool CanDeoptimize() const;
|
| -
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| virtual bool AffectedBySideEffect() const { return false; }
|
| - virtual bool AttributesEqual(Instruction* other) const;
|
|
|
| + virtual bool AttributesEqual(Instruction* other) const {
|
| + return op_kind() == other->AsUnboxedMintBinaryOp()->op_kind();
|
| + }
|
| +
|
| virtual intptr_t ResultCid() const;
|
| + virtual RawAbstractType* CompileType() const;
|
|
|
| - void set_overflow(bool overflow) {
|
| - overflow_ = overflow;
|
| + virtual Representation representation() const {
|
| + return kUnboxedInteger;
|
| }
|
|
|
| - void PrintTo(BufferFormatter* f) const;
|
| + virtual Representation RequiredInputRepresentation(intptr_t idx) const {
|
| + ASSERT((idx == 0) || (idx == 1));
|
| + return kUnboxedInteger;
|
| + }
|
|
|
| - virtual bool InferRange();
|
| + virtual intptr_t DeoptimizationTarget() const {
|
| + // Direct access since this instuction cannot deoptimize, and the deopt-id
|
| + // was inherited from another instuction that could deoptimize.
|
| + return deopt_id_;
|
| + }
|
|
|
| + DECLARE_INSTRUCTION(UnboxedMintBinaryOp)
|
| +
|
| private:
|
| const Token::Kind op_kind_;
|
| - InstanceCallInstr* instance_call_;
|
| - bool overflow_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr);
|
| + DISALLOW_COPY_AND_ASSIGN(UnboxedMintBinaryOpInstr);
|
| };
|
|
|
|
|
| -class BinaryMintOpInstr : public TemplateDefinition<2> {
|
| +class BinarySmiOpInstr : public TemplateDefinition<2> {
|
| public:
|
| - BinaryMintOpInstr(Token::Kind op_kind,
|
| - InstanceCallInstr* instance_call,
|
| - Value* left,
|
| - Value* right)
|
| + BinarySmiOpInstr(Token::Kind op_kind,
|
| + InstanceCallInstr* instance_call,
|
| + Value* left,
|
| + Value* right)
|
| : op_kind_(op_kind),
|
| - instance_call_(instance_call) {
|
| + instance_call_(instance_call),
|
| + overflow_(true) {
|
| ASSERT(left != NULL);
|
| ASSERT(right != NULL);
|
| inputs_[0] = left;
|
| @@ -3500,20 +3578,33 @@
|
|
|
| virtual void PrintOperandsTo(BufferFormatter* f) const;
|
|
|
| - DECLARE_INSTRUCTION(BinaryMintOp)
|
| + DECLARE_INSTRUCTION(BinarySmiOp)
|
| +
|
| + void set_overflow(bool overflow) {
|
| + overflow_ = overflow;
|
| + }
|
| +
|
| + void PrintTo(BufferFormatter* f) const;
|
| +
|
| + virtual bool InferRange();
|
| +
|
| virtual RawAbstractType* CompileType() const;
|
|
|
| - virtual bool CanDeoptimize() const { return true; }
|
| + virtual bool CanDeoptimize() const;
|
|
|
| virtual bool HasSideEffect() const { return false; }
|
|
|
| + virtual bool AffectedBySideEffect() const { return false; }
|
| + virtual bool AttributesEqual(Instruction* other) const;
|
| +
|
| virtual intptr_t ResultCid() const;
|
|
|
| private:
|
| const Token::Kind op_kind_;
|
| InstanceCallInstr* instance_call_;
|
| + bool overflow_;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr);
|
| + DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr);
|
| };
|
|
|
|
|
|
|