Index: runtime/vm/intermediate_language.h |
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
index 57b98b75071a22271a6713d9e30180bba30b6b22..57f302180caf8005890828b728ddbfd026cc4fef 100644 |
--- a/runtime/vm/intermediate_language.h |
+++ b/runtime/vm/intermediate_language.h |
@@ -910,6 +910,9 @@ FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
} |
private: |
+ friend class BranchInstr; // For RawSetInputAt. |
+ friend class IfThenElseInstr; // For RawSetInputAt. |
+ |
virtual void RawSetInputAt(intptr_t i, Value* value) = 0; |
enum { |
@@ -2354,10 +2357,10 @@ class IndirectGotoInstr : public TemplateInstruction<1, NoThrow> { |
}; |
-class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { |
+class ComparisonInstr : public Definition { |
public: |
- Value* left() const { return inputs_[0]; } |
- Value* right() const { return inputs_[1]; } |
+ Value* left() const { return InputAt(0); } |
+ Value* right() const { return InputAt(1); } |
virtual TokenPosition token_pos() const { return token_pos_; } |
Token::Kind kind() const { return kind_; } |
@@ -2396,17 +2399,11 @@ class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { |
protected: |
ComparisonInstr(TokenPosition token_pos, |
Token::Kind kind, |
- Value* left, |
- Value* right, |
intptr_t deopt_id = Thread::kNoDeoptId) |
- : TemplateDefinition(deopt_id), |
+ : Definition(deopt_id), |
token_pos_(token_pos), |
kind_(kind), |
operation_cid_(kIllegalCid) { |
- SetInputAt(0, left); |
- if (right != NULL) { |
- SetInputAt(1, right); |
- } |
} |
private: |
@@ -2418,6 +2415,47 @@ class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { |
}; |
+class PureComparison : public ComparisonInstr { |
+ public: |
+ virtual bool AllowsCSE() const { return true; } |
+ virtual EffectSet Dependencies() const { return EffectSet::None(); } |
+ |
+ virtual EffectSet Effects() const { return EffectSet::None(); } |
+ |
+ protected: |
+ PureComparison(TokenPosition token_pos, Token::Kind kind, intptr_t deopt_id) |
+ : ComparisonInstr(token_pos, kind, deopt_id) { } |
+}; |
+ |
+ |
+template<intptr_t N, |
+ typename ThrowsTrait, |
+ template<typename Impure, typename Pure> class CSETrait = NoCSE> |
+class TemplateComparison : public CSETrait< |
+ ComparisonInstr, PureComparison>::Base { |
+ public: |
+ TemplateComparison(TokenPosition token_pos, |
+ Token::Kind kind, |
+ intptr_t deopt_id = Thread::kNoDeoptId) |
+ : CSETrait<ComparisonInstr, PureComparison>::Base( |
+ token_pos, kind, deopt_id), |
+ inputs_() { } |
+ |
+ virtual intptr_t InputCount() const { return N; } |
+ virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } |
+ |
+ virtual bool MayThrow() const { return ThrowsTrait::kCanThrow; } |
+ |
+ protected: |
+ EmbeddedArray<Value*, N> inputs_; |
+ |
+ private: |
+ virtual void RawSetInputAt(intptr_t i, Value* value) { |
+ inputs_[i] = value; |
+ } |
+}; |
+ |
+ |
class BranchInstr : public Instruction { |
public: |
explicit BranchInstr(ComparisonInstr* comparison) |
@@ -2976,7 +3014,7 @@ class PolymorphicInstanceCallInstr : public TemplateDefinition<0, Throws> { |
}; |
-class StrictCompareInstr : public ComparisonInstr { |
+class StrictCompareInstr : public TemplateComparison<2, NoThrow, Pure> { |
public: |
StrictCompareInstr(TokenPosition token_pos, |
Token::Kind kind, |
@@ -3018,14 +3056,16 @@ class StrictCompareInstr : public ComparisonInstr { |
// Comparison instruction that is equivalent to the (left & right) == 0 |
// comparison pattern. |
-class TestSmiInstr : public ComparisonInstr { |
+class TestSmiInstr : public TemplateComparison<2, NoThrow, Pure> { |
public: |
TestSmiInstr(TokenPosition token_pos, |
Token::Kind kind, |
Value* left, |
Value* right) |
- : ComparisonInstr(token_pos, kind, left, right) { |
+ : TemplateComparison(token_pos, kind) { |
ASSERT(kind == Token::kEQ || kind == Token::kNE); |
+ SetInputAt(0, left); |
+ SetInputAt(1, right); |
} |
DECLARE_INSTRUCTION(TestSmi); |
@@ -3053,24 +3093,21 @@ class TestSmiInstr : public ComparisonInstr { |
// Checks the input value cid against cids stored in a table and returns either |
// a result or deoptimizes. |
-// TODO(srdjan): Modify ComparisonInstr to allow 1 or 2 arguments, since |
-// TestCidInstr needs only one argument |
-class TestCidsInstr : public ComparisonInstr { |
+class TestCidsInstr : public TemplateComparison<1, NoThrow, Pure> { |
public: |
TestCidsInstr(TokenPosition token_pos, |
Token::Kind kind, |
Value* value, |
const ZoneGrowableArray<intptr_t>& cid_results, |
intptr_t deopt_id) |
- : ComparisonInstr(token_pos, kind, value, NULL, deopt_id), |
+ : TemplateComparison(token_pos, kind, deopt_id), |
cid_results_(cid_results), |
licm_hoisted_(false) { |
ASSERT((kind == Token::kIS) || (kind == Token::kISNOT)); |
+ SetInputAt(0, value); |
set_operation_cid(kObjectCid); |
} |
- virtual intptr_t InputCount() const { return 1; } |
- |
const ZoneGrowableArray<intptr_t>& cid_results() const { |
return cid_results_; |
} |
@@ -3110,7 +3147,7 @@ class TestCidsInstr : public ComparisonInstr { |
}; |
-class EqualityCompareInstr : public ComparisonInstr { |
+class EqualityCompareInstr : public TemplateComparison<2, NoThrow, Pure> { |
public: |
EqualityCompareInstr(TokenPosition token_pos, |
Token::Kind kind, |
@@ -3118,8 +3155,10 @@ class EqualityCompareInstr : public ComparisonInstr { |
Value* right, |
intptr_t cid, |
intptr_t deopt_id) |
- : ComparisonInstr(token_pos, kind, left, right, deopt_id) { |
+ : TemplateComparison(token_pos, kind, deopt_id) { |
ASSERT(Token::IsEqualityOperator(kind)); |
+ SetInputAt(0, left); |
+ SetInputAt(1, right); |
set_operation_cid(cid); |
} |
@@ -3151,7 +3190,7 @@ class EqualityCompareInstr : public ComparisonInstr { |
}; |
-class RelationalOpInstr : public ComparisonInstr { |
+class RelationalOpInstr : public TemplateComparison<2, NoThrow, Pure> { |
public: |
RelationalOpInstr(TokenPosition token_pos, |
Token::Kind kind, |
@@ -3159,8 +3198,10 @@ class RelationalOpInstr : public ComparisonInstr { |
Value* right, |
intptr_t cid, |
intptr_t deopt_id) |
- : ComparisonInstr(token_pos, kind, left, right, deopt_id) { |
+ : TemplateComparison(token_pos, kind, deopt_id) { |
ASSERT(Token::IsRelationalOperator(kind)); |
+ SetInputAt(0, left); |
+ SetInputAt(1, right); |
set_operation_cid(cid); |
} |
@@ -5343,24 +5384,21 @@ class BinaryDoubleOpInstr : public TemplateDefinition<2, NoThrow, Pure> { |
}; |
-class DoubleTestOpInstr : public TemplateDefinition<1, NoThrow, Pure> { |
+class DoubleTestOpInstr : public TemplateComparison<1, NoThrow, Pure> { |
public: |
DoubleTestOpInstr(MethodRecognizer::Kind op_kind, |
- Value* d, |
+ Value* value, |
intptr_t deopt_id, |
TokenPosition token_pos) |
- : TemplateDefinition(deopt_id), |
- op_kind_(op_kind), |
- token_pos_(token_pos) { |
- SetInputAt(0, d); |
+ : TemplateComparison(token_pos, Token::kEQ, deopt_id), |
+ op_kind_(op_kind) { |
+ SetInputAt(0, value); |
} |
- Value* value() const { return inputs_[0]; } |
+ Value* value() const { return InputAt(0); } |
MethodRecognizer::Kind op_kind() const { return op_kind_; } |
- virtual TokenPosition token_pos() const { return token_pos_; } |
- |
virtual bool CanDeoptimize() const { return false; } |
virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
@@ -5368,12 +5406,6 @@ class DoubleTestOpInstr : public TemplateDefinition<1, NoThrow, Pure> { |
return kUnboxedDouble; |
} |
- virtual intptr_t DeoptimizationTarget() const { |
- // Direct access since this instruction cannot deoptimize, and the deopt-id |
- // was inherited from another instruction that could deoptimize. |
- return GetDeoptId(); |
- } |
- |
PRINT_OPERANDS_TO_SUPPORT |
DECLARE_INSTRUCTION(DoubleTestOp) |
@@ -5382,12 +5414,20 @@ class DoubleTestOpInstr : public TemplateDefinition<1, NoThrow, Pure> { |
virtual Definition* Canonicalize(FlowGraph* flow_graph); |
virtual bool AttributesEqual(Instruction* other) const { |
- return op_kind_ == other->AsDoubleTestOp()->op_kind(); |
+ return op_kind_ == other->AsDoubleTestOp()->op_kind() |
+ && ComparisonInstr::AttributesEqual(other); |
} |
+ virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right); |
+ |
+ virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
+ BranchInstr* branch); |
+ |
+ virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler, |
+ BranchLabels labels); |
+ |
private: |
const MethodRecognizer::Kind op_kind_; |
- const TokenPosition token_pos_; |
DISALLOW_COPY_AND_ASSIGN(DoubleTestOpInstr); |
}; |