Index: runtime/vm/intermediate_language.h |
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h |
index 1b004138c83945117f66436c0aa1cbd9a7447255..5220543e73aeb741fe2ed03612bf9613c6cbbf0b 100644 |
--- a/runtime/vm/intermediate_language.h |
+++ b/runtime/vm/intermediate_language.h |
@@ -504,6 +504,7 @@ class EmbeddedArray<T, 0> { |
M(InvokeMathCFunction) \ |
M(GuardField) \ |
M(IfThenElse) \ |
+ M(TestSmi) \ |
#define FORWARD_DECLARATION(type) class type##Instr; |
FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) |
@@ -2486,6 +2487,10 @@ class ComparisonInstr : public TemplateDefinition<2> { |
deopt_id_ = deopt_id; |
} |
+ virtual bool IsSmiEquality() const { |
+ return false; |
+ } |
+ |
protected: |
Token::Kind kind_; |
}; |
@@ -2585,6 +2590,40 @@ class StrictCompareInstr : public ComparisonInstr { |
}; |
+// Comparison instruction that is equivalent to the (left & right) == 0 |
+// comparison pattern. |
+class TestSmiInstr : public ComparisonInstr { |
+ public: |
+ TestSmiInstr(Token::Kind kind, Value* left, Value* right) |
+ : ComparisonInstr(kind, left, right) { |
+ } |
+ |
+ DECLARE_INSTRUCTION(TestSmi); |
+ |
+ virtual CompileType ComputeType() const { |
+ return CompileType::Bool(); |
+ } |
+ |
+ virtual bool CanDeoptimize() const { |
+ return false; |
+ } |
+ |
+ virtual bool HasSideEffect() const { |
+ return false; |
+ } |
+ |
+ virtual void EmitBranchCode(FlowGraphCompiler* compiler, |
+ BranchInstr* branch); |
+ |
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const { |
+ return kTagged; |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(TestSmiInstr); |
+}; |
+ |
+ |
class EqualityCompareInstr : public ComparisonInstr { |
public: |
EqualityCompareInstr(intptr_t token_pos, |
@@ -2647,6 +2686,10 @@ class EqualityCompareInstr : public ComparisonInstr { |
bool IsPolymorphic() const; |
+ virtual bool IsSmiEquality() const { |
+ return receiver_class_id() == kSmiCid; |
+ } |
+ |
private: |
const ICData* ic_data_; |
const intptr_t token_pos_; |