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_; |