Index: runtime/vm/intermediate_language_dbc.cc |
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc |
index 486322d269171804cbf0b9288f2a34e218c6530c..ea9c9d8018624e0de891a80c48c28b431b037863 100644 |
--- a/runtime/vm/intermediate_language_dbc.cc |
+++ b/runtime/vm/intermediate_language_dbc.cc |
@@ -483,14 +483,6 @@ static void EmitBranchOnCondition(FlowGraphCompiler* compiler, |
} |
-Condition StrictCompareInstr::GetNextInstructionCondition( |
- FlowGraphCompiler* compiler, |
- BranchLabels labels) { |
- return (labels.fall_through == labels.false_label) ? NEXT_IS_TRUE |
- : NEXT_IS_FALSE; |
-} |
- |
- |
Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
BranchLabels labels) { |
ASSERT((kind() == Token::kNE_STRICT) || (kind() == Token::kEQ_STRICT)); |
@@ -534,50 +526,43 @@ Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
} |
-DEFINE_MAKE_LOCATION_SUMMARY(StrictCompare, |
- 2, |
- Location::RequiresRegister(), |
- needs_number_check() ? LocationSummary::kCall |
- : LocationSummary::kNoCall) |
+void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
+ BranchInstr* branch) { |
+ ASSERT((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)); |
- |
-void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
- BranchInstr* branch) { |
BranchLabels labels = compiler->CreateBranchLabels(branch); |
Condition true_condition = EmitComparisonCode(compiler, labels); |
- if (true_condition != INVALID_CONDITION) { |
- EmitBranchOnCondition(compiler, true_condition, labels); |
- } |
+ EmitBranchOnCondition(compiler, true_condition, labels); |
} |
-void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+EMIT_NATIVE_CODE(StrictCompare, |
+ 2, |
+ Location::RequiresRegister(), |
+ needs_number_check() ? LocationSummary::kCall |
+ : LocationSummary::kNoCall) { |
+ ASSERT((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT)); |
+ |
Label is_true, is_false; |
BranchLabels labels = {&is_true, &is_false, &is_false}; |
- Condition true_condition = |
- this->GetNextInstructionCondition(compiler, labels); |
- if (true_condition == INVALID_CONDITION || !compiler->is_optimizing() || |
- is_true.IsLinked() || is_false.IsLinked()) { |
- Condition actual_condition = EmitComparisonCode(compiler, labels); |
- ASSERT(actual_condition == true_condition); |
- if (true_condition != INVALID_CONDITION) { |
- EmitBranchOnCondition(compiler, true_condition, labels); |
- } |
- Label done; |
+ Condition true_condition = EmitComparisonCode(compiler, labels); |
+ EmitBranchOnCondition(compiler, true_condition, labels); |
+ Label done; |
+ if (compiler->is_optimizing()) { |
+ const Register result = locs()->out(0).reg(); |
+ __ Bind(&is_false); |
+ __ LoadConstant(result, Bool::False()); |
+ __ Jump(&done); |
+ __ Bind(&is_true); |
+ __ LoadConstant(result, Bool::True()); |
+ __ Bind(&done); |
+ } else { |
__ Bind(&is_false); |
__ PushConstant(Bool::False()); |
__ Jump(&done); |
__ Bind(&is_true); |
__ PushConstant(Bool::True()); |
__ Bind(&done); |
- } else { |
- const Register result = this->locs()->out(0).reg(); |
- __ LoadConstant( |
- result, true_condition == NEXT_IS_TRUE ? Bool::False() : Bool::True()); |
- Condition actual_condition = EmitComparisonCode(compiler, labels); |
- ASSERT(actual_condition == true_condition); |
- __ LoadConstant( |
- result, true_condition == NEXT_IS_TRUE ? Bool::True() : Bool::False()); |
} |
} |
@@ -616,13 +601,6 @@ EMIT_NATIVE_CODE(Goto, 0) { |
} |
-Condition TestSmiInstr::GetNextInstructionCondition(FlowGraphCompiler* compiler, |
- BranchLabels labels) { |
- ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); |
- return (kind() == Token::kEQ) ? NEXT_IS_TRUE : NEXT_IS_FALSE; |
-} |
- |
- |
Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
BranchLabels labels) { |
ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); |
@@ -633,10 +611,21 @@ Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
} |
-DEFINE_MAKE_LOCATION_SUMMARY(TestSmi, |
- 2, |
- Location::RequiresRegister(), |
- LocationSummary::kNoCall) |
+void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
+ BranchInstr* branch) { |
+ BranchLabels labels = compiler->CreateBranchLabels(branch); |
+ Condition true_condition = EmitComparisonCode(compiler, labels); |
+ EmitBranchOnCondition(compiler, true_condition, labels); |
+} |
+ |
+ |
+EMIT_NATIVE_CODE(TestSmi, |
+ 2, |
+ Location::RequiresRegister(), |
+ LocationSummary::kNoCall) { |
+ // Never emitted outside of the BranchInstr. |
+ UNREACHABLE(); |
+} |
Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
@@ -673,17 +662,30 @@ Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
} |
-Condition TestCidsInstr::GetNextInstructionCondition( |
- FlowGraphCompiler* compiler, |
- BranchLabels labels) { |
- return NEXT_IS_TRUE; |
+void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
+ BranchInstr* branch) { |
+ BranchLabels labels = compiler->CreateBranchLabels(branch); |
+ Condition true_condition = EmitComparisonCode(compiler, labels); |
+ EmitBranchOnCondition(compiler, true_condition, labels); |
} |
-DEFINE_MAKE_LOCATION_SUMMARY(TestCids, |
- 1, |
- Location::RequiresRegister(), |
- LocationSummary::kNoCall) |
+EMIT_NATIVE_CODE(TestCids, |
+ 1, |
+ Location::RequiresRegister(), |
+ LocationSummary::kNoCall) { |
+ Register result_reg = locs()->out(0).reg(); |
+ Label is_true, is_false, done; |
+ BranchLabels labels = {&is_true, &is_false, &is_false}; |
+ EmitComparisonCode(compiler, labels); |
+ __ Jump(&is_true); |
+ __ Bind(&is_false); |
+ __ LoadConstant(result_reg, Bool::False()); |
+ __ Jump(&done); |
+ __ Bind(&is_true); |
+ __ LoadConstant(result_reg, Bool::True()); |
+ __ Bind(&done); |
+} |
EMIT_NATIVE_CODE(CreateArray, |
@@ -1751,7 +1753,15 @@ EMIT_NATIVE_CODE(BinaryDoubleOp, 2, Location::RequiresRegister()) { |
Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
BranchLabels labels) { |
+ UNREACHABLE(); |
+ return Condition(); |
+} |
+ |
+ |
+void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
+ BranchInstr* branch) { |
ASSERT(compiler->is_optimizing()); |
+ BranchLabels labels = compiler->CreateBranchLabels(branch); |
const Register value = locs()->in(0).reg(); |
switch (op_kind()) { |
case MethodRecognizer::kDouble_getIsNaN: |
@@ -1764,21 +1774,31 @@ Condition DoubleTestOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
UNREACHABLE(); |
} |
const bool is_negated = kind() != Token::kEQ; |
- return is_negated ? NEXT_IS_FALSE : NEXT_IS_TRUE; |
+ EmitBranchOnCondition(compiler, is_negated ? NEXT_IS_FALSE : NEXT_IS_TRUE, |
+ labels); |
} |
-Condition DoubleTestOpInstr::GetNextInstructionCondition( |
- FlowGraphCompiler* compiler, |
- BranchLabels labels) { |
+EMIT_NATIVE_CODE(DoubleTestOp, 1, Location::RequiresRegister()) { |
+ ASSERT(compiler->is_optimizing()); |
+ const Register value = locs()->in(0).reg(); |
+ const Register result = locs()->out(0).reg(); |
const bool is_negated = kind() != Token::kEQ; |
- return is_negated ? NEXT_IS_FALSE : NEXT_IS_TRUE; |
+ __ LoadConstant(result, is_negated ? Bool::True() : Bool::False()); |
+ switch (op_kind()) { |
+ case MethodRecognizer::kDouble_getIsNaN: |
+ __ DoubleIsNaN(value); |
+ break; |
+ case MethodRecognizer::kDouble_getIsInfinite: |
+ __ DoubleIsInfinite(value); |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ } |
+ __ LoadConstant(result, is_negated ? Bool::False() : Bool::True()); |
} |
-DEFINE_MAKE_LOCATION_SUMMARY(DoubleTestOp, 1, Location::RequiresRegister()) |
- |
- |
EMIT_NATIVE_CODE(UnaryDoubleOp, 1, Location::RequiresRegister()) { |
const Register value = locs()->in(0).reg(); |
const Register result = locs()->out(0).reg(); |
@@ -1953,8 +1973,7 @@ static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler, |
// If we aren't falling through to the false label, we can save a Jump |
// instruction in the case that the true case is the fall through by |
// flipping the sense of the test such that the instruction following the |
- // test is the Jump to the false label. In the case where both labels are |
- // null we don't flip the sense of the test. |
+ // test is the Jump to the false label. |
condition = NEXT_IS_FALSE; |
comparison = FlipCondition(kind); |
} |
@@ -1991,20 +2010,29 @@ Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
} |
-Condition EqualityCompareInstr::GetNextInstructionCondition( |
- FlowGraphCompiler* compiler, |
- BranchLabels labels) { |
- if (operation_cid() == kSmiCid) { |
- return (labels.fall_through != labels.false_label) ? NEXT_IS_FALSE |
- : NEXT_IS_TRUE; |
- } else { |
- ASSERT(operation_cid() == kDoubleCid); |
- return NEXT_IS_TRUE; |
- } |
+EMIT_NATIVE_CODE(EqualityCompare, 2, Location::RequiresRegister()) { |
+ ASSERT(compiler->is_optimizing()); |
+ ASSERT((kind() == Token::kEQ) || (kind() == Token::kNE)); |
+ Label is_true, is_false; |
+ // These labels are not used. They are arranged so that EmitComparisonCode |
+ // emits a test that executes the following instruction when the test |
+ // succeeds. |
+ BranchLabels labels = {&is_true, &is_false, &is_false}; |
+ const Register result = locs()->out(0).reg(); |
+ __ LoadConstant(result, Bool::False()); |
+ Condition true_condition = EmitComparisonCode(compiler, labels); |
+ ASSERT(true_condition == NEXT_IS_TRUE); |
+ __ LoadConstant(result, Bool::True()); |
} |
-DEFINE_MAKE_LOCATION_SUMMARY(EqualityCompare, 2, Location::RequiresRegister()); |
+void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
+ BranchInstr* branch) { |
+ ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); |
+ BranchLabels labels = compiler->CreateBranchLabels(branch); |
+ Condition true_condition = EmitComparisonCode(compiler, labels); |
+ EmitBranchOnCondition(compiler, true_condition, labels); |
+} |
Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
@@ -2018,20 +2046,24 @@ Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler, |
} |
-Condition RelationalOpInstr::GetNextInstructionCondition( |
- FlowGraphCompiler* compiler, |
- BranchLabels labels) { |
- if (operation_cid() == kSmiCid) { |
- return (labels.fall_through != labels.false_label) ? NEXT_IS_FALSE |
- : NEXT_IS_TRUE; |
- } else { |
- ASSERT(operation_cid() == kDoubleCid); |
- return NEXT_IS_TRUE; |
- } |
+EMIT_NATIVE_CODE(RelationalOp, 2, Location::RequiresRegister()) { |
+ ASSERT(compiler->is_optimizing()); |
+ Label is_true, is_false; |
+ BranchLabels labels = {&is_true, &is_false, &is_false}; |
+ const Register result = locs()->out(0).reg(); |
+ __ LoadConstant(result, Bool::False()); |
+ Condition true_condition = EmitComparisonCode(compiler, labels); |
+ ASSERT(true_condition == NEXT_IS_TRUE); |
+ __ LoadConstant(result, Bool::True()); |
} |
-DEFINE_MAKE_LOCATION_SUMMARY(RelationalOp, 2, Location::RequiresRegister()) |
+void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, |
+ BranchInstr* branch) { |
+ BranchLabels labels = compiler->CreateBranchLabels(branch); |
+ Condition true_condition = EmitComparisonCode(compiler, labels); |
+ EmitBranchOnCondition(compiler, true_condition, labels); |
+} |
EMIT_NATIVE_CODE(CheckArrayBound, 2) { |