| 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) {
|
|
|