Chromium Code Reviews| Index: runtime/vm/intermediate_language.h |
| diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
| index 8e7241a16ea15156018d79c145338e69f52eb7ea..c9dbbfb665c8e56867226e612f91ff076fab582a 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 { |
| @@ -2355,10 +2358,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_; } |
| @@ -2397,17 +2400,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: |
| @@ -2419,6 +2416,49 @@ class ComparisonInstr : public TemplateDefinition<2, NoThrow, Pure> { |
| }; |
| +class PureComparison: public ComparisonInstr { |
|
zra
2016/10/31 17:28:15
missing space before colon.
Florian Schneider
2016/10/31 18:48:16
Done.
|
| + public: |
| + virtual bool AllowsCSE() const { return true; } |
| + virtual EffectSet Dependencies() const { return EffectSet::None(); } |
| + |
| + virtual EffectSet Effects() const { return EffectSet::None(); } |
| + |
| + protected: |
| + explicit PureComparison(TokenPosition token_pos, |
|
zra
2016/10/31 17:28:14
explicit not needed.
Florian Schneider
2016/10/31 18:48:16
Done.
|
| + 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) |
| @@ -2977,7 +3017,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, |
| @@ -3019,14 +3059,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); |
| @@ -3054,24 +3096,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_; |
| } |
| @@ -3111,7 +3150,7 @@ class TestCidsInstr : public ComparisonInstr { |
| }; |
| -class EqualityCompareInstr : public ComparisonInstr { |
| +class EqualityCompareInstr : public TemplateComparison<2, NoThrow, Pure> { |
| public: |
| EqualityCompareInstr(TokenPosition token_pos, |
| Token::Kind kind, |
| @@ -3119,8 +3158,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); |
| } |
| @@ -3152,7 +3193,7 @@ class EqualityCompareInstr : public ComparisonInstr { |
| }; |
| -class RelationalOpInstr : public ComparisonInstr { |
| +class RelationalOpInstr : public TemplateComparison<2, NoThrow, Pure> { |
| public: |
| RelationalOpInstr(TokenPosition token_pos, |
| Token::Kind kind, |
| @@ -3160,8 +3201,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); |
| } |
| @@ -5344,24 +5387,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 { |
| @@ -5369,12 +5409,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) |
| @@ -5383,12 +5417,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); |
| }; |