| Index: runtime/vm/intermediate_language.h
|
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
|
| index 46623eeaa6fa9e82fcf976871428df7532c2b4c4..039c438d6774e409ba05809d6283027e78c5678e 100644
|
| --- a/runtime/vm/intermediate_language.h
|
| +++ b/runtime/vm/intermediate_language.h
|
| @@ -241,10 +241,24 @@ class Computation : public ZoneAllocated {
|
|
|
| virtual ComputationKind computation_kind() const = 0;
|
|
|
| + // Returns representation expected for the input operand at the given index.
|
| + virtual Representation RequiredInputRepresentation(intptr_t idx) const {
|
| + return kTagged;
|
| + }
|
| +
|
| + // Representation of the value produced by this computation.
|
| virtual Representation representation() const {
|
| return kTagged;
|
| }
|
|
|
| + // Returns deoptimization id that corresponds to the deoptimization target
|
| + // that input operands conversions inserted for this instruction can jump
|
| + // to. Can return kNoDeoptId.
|
| + virtual intptr_t DeoptimizationTarget() const {
|
| + UNREACHABLE();
|
| + return Isolate::kNoDeoptId;
|
| + }
|
| +
|
| // Declare predicate for each computation.
|
| #define DECLARE_PREDICATE(ShortName, ClassName) \
|
| inline bool Is##ShortName() const; \
|
| @@ -253,6 +267,12 @@ class Computation : public ZoneAllocated {
|
| FOR_EACH_COMPUTATION(DECLARE_PREDICATE)
|
| #undef DECLARE_PREDICATE
|
|
|
| + protected:
|
| + // Fetch deopt id without checking if this computation can deoptimize.
|
| + intptr_t GetDeoptId() const {
|
| + return deopt_id_;
|
| + }
|
| +
|
| private:
|
| friend class BranchInstr;
|
|
|
| @@ -746,12 +766,24 @@ class EqualityCompareComp : public ComparisonComp {
|
|
|
| virtual void PrintOperandsTo(BufferFormatter* f) const;
|
|
|
| - virtual bool CanDeoptimize() const { return true; }
|
| + virtual bool CanDeoptimize() const {
|
| + return (receiver_class_id() != kDoubleCid);
|
| + }
|
| +
|
| virtual intptr_t ResultCid() const;
|
|
|
| virtual void EmitBranchCode(FlowGraphCompiler* compiler,
|
| BranchInstr* branch);
|
|
|
| + virtual intptr_t DeoptimizationTarget() const {
|
| + return GetDeoptId();
|
| + }
|
| +
|
| + virtual Representation RequiredInputRepresentation(intptr_t idx) const {
|
| + ASSERT((idx == 0) || (idx == 1));
|
| + return (receiver_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged;
|
| + }
|
| +
|
| private:
|
| const intptr_t token_pos_;
|
| intptr_t receiver_class_id_; // Set by optimizer.
|
| @@ -786,12 +818,25 @@ class RelationalOpComp : public ComparisonComp {
|
|
|
| virtual void PrintOperandsTo(BufferFormatter* f) const;
|
|
|
| - virtual bool CanDeoptimize() const { return true; }
|
| + virtual bool CanDeoptimize() const {
|
| + return operands_class_id() != kDoubleCid;
|
| + }
|
| +
|
| virtual intptr_t ResultCid() const;
|
|
|
| virtual void EmitBranchCode(FlowGraphCompiler* compiler,
|
| BranchInstr* branch);
|
|
|
| +
|
| + virtual intptr_t DeoptimizationTarget() const {
|
| + return GetDeoptId();
|
| + }
|
| +
|
| + virtual Representation RequiredInputRepresentation(intptr_t idx) const {
|
| + ASSERT((idx == 0) || (idx == 1));
|
| + return (operands_class_id() == kDoubleCid) ? kUnboxedDouble : kTagged;
|
| + }
|
| +
|
| private:
|
| const intptr_t token_pos_;
|
| intptr_t operands_class_id_; // class id of both operands.
|
| @@ -1598,22 +1643,30 @@ class CheckEitherNonSmiComp : public TemplateComputation<2> {
|
| class BoxDoubleComp : public TemplateComputation<1> {
|
| public:
|
| BoxDoubleComp(Value* value, InstanceCallComp* instance_call)
|
| - : instance_call_(instance_call) {
|
| + : token_pos_((instance_call != NULL) ? instance_call->token_pos() : 0) {
|
| ASSERT(value != NULL);
|
| inputs_[0] = value;
|
| }
|
|
|
| Value* value() const { return inputs_[0]; }
|
| - InstanceCallComp* instance_call() const { return instance_call_; }
|
| +
|
| + intptr_t token_pos() const { return token_pos_; }
|
|
|
| virtual bool CanDeoptimize() const { return false; }
|
| + virtual bool HasSideEffect() const { return false; }
|
| + virtual bool AttributesEqual(Computation* other) const { return true; }
|
|
|
| virtual intptr_t ResultCid() const;
|
|
|
| + virtual Representation RequiredInputRepresentation(intptr_t idx) const {
|
| + ASSERT(idx == 0);
|
| + return kUnboxedDouble;
|
| + }
|
| +
|
| DECLARE_COMPUTATION(BoxDouble)
|
|
|
| private:
|
| - InstanceCallComp* instance_call_;
|
| + const intptr_t token_pos_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(BoxDoubleComp);
|
| };
|
| @@ -1621,29 +1674,32 @@ class BoxDoubleComp : public TemplateComputation<1> {
|
|
|
| class UnboxDoubleComp : public TemplateComputation<1> {
|
| public:
|
| - UnboxDoubleComp(Value* value, InstanceCallComp* instance_call)
|
| - : instance_call_(instance_call) {
|
| + UnboxDoubleComp(Value* value, intptr_t deopt_id)
|
| + : deopt_id_(deopt_id) {
|
| ASSERT(value != NULL);
|
| inputs_[0] = value;
|
| }
|
|
|
| Value* value() const { return inputs_[0]; }
|
| - InstanceCallComp* instance_call() const { return instance_call_; }
|
|
|
| virtual bool CanDeoptimize() const {
|
| return value()->ResultCid() != kDoubleCid;
|
| }
|
| - // The output is not an instance.
|
| - virtual intptr_t ResultCid() const { return kDynamicCid; }
|
| +
|
| + // The output is not an instance but when it is boxed it becomes double.
|
| + virtual intptr_t ResultCid() const { return kDoubleCid; }
|
|
|
| virtual Representation representation() const {
|
| return kUnboxedDouble;
|
| }
|
|
|
| + virtual bool HasSideEffect() const { return false; }
|
| + virtual bool AttributesEqual(Computation* other) const { return true; }
|
| +
|
| DECLARE_COMPUTATION(UnboxDouble)
|
|
|
| private:
|
| - InstanceCallComp* instance_call_;
|
| + const intptr_t deopt_id_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(UnboxDoubleComp);
|
| };
|
| @@ -1653,8 +1709,9 @@ class UnboxedDoubleBinaryOpComp : public TemplateComputation<2> {
|
| public:
|
| UnboxedDoubleBinaryOpComp(Token::Kind op_kind,
|
| Value* left,
|
| - Value* right)
|
| - : op_kind_(op_kind) {
|
| + Value* right,
|
| + InstanceCallComp* call)
|
| + : op_kind_(op_kind), deopt_id_(call->deopt_id()) {
|
| ASSERT(left != NULL);
|
| ASSERT(right != NULL);
|
| inputs_[0] = left;
|
| @@ -1669,17 +1726,33 @@ class UnboxedDoubleBinaryOpComp : public TemplateComputation<2> {
|
| virtual void PrintOperandsTo(BufferFormatter* f) const;
|
|
|
| virtual bool CanDeoptimize() const { return false; }
|
| - // The output is not an instance.
|
| - virtual intptr_t ResultCid() const { return kDynamicCid; }
|
| + virtual bool HasSideEffect() const { return false; }
|
| +
|
| + virtual bool AttributesEqual(Computation* other) const {
|
| + return op_kind() == other->AsUnboxedDoubleBinaryOp()->op_kind();
|
| + }
|
| +
|
| + // The output is not an instance but when it is boxed it becomes double.
|
| + virtual intptr_t ResultCid() const { return kDoubleCid; }
|
|
|
| virtual Representation representation() const {
|
| return kUnboxedDouble;
|
| }
|
|
|
| + virtual Representation RequiredInputRepresentation(intptr_t idx) const {
|
| + ASSERT((idx == 0) || (idx == 1));
|
| + return kUnboxedDouble;
|
| + }
|
| +
|
| + virtual intptr_t DeoptimizationTarget() const {
|
| + return deopt_id_;
|
| + }
|
| +
|
| DECLARE_COMPUTATION(UnboxedDoubleBinaryOp)
|
|
|
| private:
|
| const Token::Kind op_kind_;
|
| + const intptr_t deopt_id_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(UnboxedDoubleBinaryOpComp);
|
| };
|
| @@ -2183,10 +2256,28 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
|
| lifetime_position_ = pos;
|
| }
|
|
|
| + // Returns representation expected for the input operand at the given index.
|
| + virtual Representation RequiredInputRepresentation(intptr_t idx) const {
|
| + return kTagged;
|
| + }
|
| +
|
| + // Representation of the value produced by this computation.
|
| virtual Representation representation() const {
|
| return kTagged;
|
| }
|
|
|
| + bool WasEliminated() const {
|
| + return next() == NULL;
|
| + }
|
| +
|
| + // Returns deoptimization id that corresponds to the deoptimization target
|
| + // that input operands conversions inserted for this instruction can jump
|
| + // to.
|
| + virtual intptr_t DeoptimizationTarget() const {
|
| + UNREACHABLE();
|
| + return Isolate::kNoDeoptId;
|
| + }
|
| +
|
| private:
|
| friend class BindInstr; // Needed for BindInstr::InsertBefore.
|
|
|
| @@ -2752,10 +2843,18 @@ class BindInstr : public Definition {
|
| // Insert this instruction after 'prev'.
|
| void InsertAfter(Instruction* prev);
|
|
|
| + virtual Representation RequiredInputRepresentation(intptr_t i) const {
|
| + return computation()->RequiredInputRepresentation(i);
|
| + }
|
| +
|
| virtual Representation representation() const {
|
| return computation()->representation();
|
| }
|
|
|
| + virtual intptr_t DeoptimizationTarget() const {
|
| + return computation()->DeoptimizationTarget();
|
| + }
|
| +
|
| private:
|
| Computation* computation_;
|
| const bool is_used_;
|
| @@ -2766,13 +2865,18 @@ class BindInstr : public Definition {
|
|
|
| class PhiInstr : public Definition {
|
| public:
|
| - explicit PhiInstr(intptr_t num_inputs)
|
| - : inputs_(num_inputs), is_alive_(false) {
|
| + explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
|
| + : block_(block),
|
| + inputs_(num_inputs),
|
| + is_alive_(false),
|
| + representation_(kTagged) {
|
| for (intptr_t i = 0; i < num_inputs; ++i) {
|
| inputs_.Add(NULL);
|
| }
|
| }
|
|
|
| + JoinEntryInstr* block() const { return block_; }
|
| +
|
| virtual RawAbstractType* CompileType() const;
|
| virtual intptr_t GetPropagatedCid() { return propagated_cid(); }
|
|
|
| @@ -2793,11 +2897,25 @@ class PhiInstr : public Definition {
|
| bool is_alive() const { return is_alive_; }
|
| void mark_alive() { is_alive_ = true; }
|
|
|
| + virtual Representation RequiredInputRepresentation(intptr_t i) const {
|
| + return representation_;
|
| + }
|
| +
|
| + virtual Representation representation() const {
|
| + return representation_;
|
| + }
|
| +
|
| + virtual void set_representation(Representation r) {
|
| + representation_ = r;
|
| + }
|
| +
|
| DECLARE_INSTRUCTION(Phi)
|
|
|
| private:
|
| + JoinEntryInstr* block_;
|
| GrowableArray<Value*> inputs_;
|
| bool is_alive_;
|
| + Representation representation_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(PhiInstr);
|
| };
|
| @@ -2872,10 +2990,6 @@ class PushArgumentInstr : public Definition {
|
|
|
| virtual bool CanDeoptimize() const { return false; }
|
|
|
| - bool WasEliminated() const {
|
| - return next() == NULL;
|
| - }
|
| -
|
| private:
|
| Value* value_;
|
| LocationSummary* locs_;
|
| @@ -3085,6 +3199,14 @@ class BranchInstr : public ControlInstruction {
|
| return computation_->locs_;
|
| }
|
|
|
| + virtual intptr_t DeoptimizationTarget() const {
|
| + return computation_->DeoptimizationTarget();
|
| + }
|
| +
|
| + virtual Representation RequiredInputRepresentation(intptr_t i) const {
|
| + return computation()->RequiredInputRepresentation(i);
|
| + }
|
| +
|
| private:
|
| ComparisonComp* computation_;
|
| LocationSummary* locs_;
|
|
|