Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1384)

Unified Diff: runtime/vm/intermediate_language_dbc.cc

Issue 2947633002: VM-codegen: Clean up the way we emit code for comparison instructions. (Closed)
Patch Set: Simplify DBC ComparisonInstr::EmitNativeCode Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/intermediate_language_arm64.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_dbc.cc
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
index ea9c9d8018624e0de891a80c48c28b431b037863..00142af0cb1e7ebfc5964a0d64a205d2c04cb0c2 100644
--- a/runtime/vm/intermediate_language_dbc.cc
+++ b/runtime/vm/intermediate_language_dbc.cc
@@ -483,6 +483,14 @@ 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));
@@ -526,43 +534,68 @@ Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
}
-void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
- BranchInstr* branch) {
- ASSERT((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT));
+DEFINE_MAKE_LOCATION_SUMMARY(StrictCompare,
+ 2,
+ Location::RequiresRegister(),
+ needs_number_check() ? LocationSummary::kCall
+ : LocationSummary::kNoCall)
+
+void ComparisonInstr::EmitBranchCode(FlowGraphCompiler* compiler,
+ BranchInstr* branch) {
BranchLabels labels = compiler->CreateBranchLabels(branch);
Condition true_condition = EmitComparisonCode(compiler, labels);
- EmitBranchOnCondition(compiler, true_condition, labels);
+ if (true_condition != INVALID_CONDITION) {
+ EmitBranchOnCondition(compiler, true_condition, labels);
+ }
}
-EMIT_NATIVE_CODE(StrictCompare,
- 2,
- Location::RequiresRegister(),
- needs_number_check() ? LocationSummary::kCall
- : LocationSummary::kNoCall) {
- ASSERT((kind() == Token::kEQ_STRICT) || (kind() == Token::kNE_STRICT));
-
+void ComparisonInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Label is_true, is_false;
BranchLabels labels = {&is_true, &is_false, &is_false};
- 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 {
+ 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;
__ 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();
+ bool next_is_true = true_condition == NEXT_IS_TRUE;
+ __ LoadConstant(result, Bool::Get(!next_is_true));
+ Condition actual_condition = EmitComparisonCode(compiler, labels);
+ ASSERT(actual_condition == true_condition);
+ // Although we have a condition to branch on, the comparison code may also
+ // have contained a direct branch to one of the labels, so they may need to
+ // be bound.
+ if (next_is_true && is_true.IsLinked()) {
+ __ Bind(&is_true);
+ } else if (!next_is_true && is_false.IsLinked()) {
+ __ Bind(&is_false);
+ }
+ // This instruction is conditionally skipped by EmitComparisonCode.
+ __ LoadConstant(result, Bool::Get(next_is_true));
+ // If the other label is linked we need to bind it and emit code that loads
+ // the correct boolean.
+ if ((next_is_true && is_false.IsLinked()) ||
+ (!next_is_true && is_true.IsLinked())) {
+ Label done;
+ __ Jump(&done);
+ __ Bind(next_is_true ? &is_false : &is_true);
+ __ LoadConstant(result, Bool::Get(!next_is_true));
+ __ Bind(&done);
+ }
}
}
@@ -601,6 +634,13 @@ 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));
@@ -611,21 +651,10 @@ Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
}
-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();
-}
+DEFINE_MAKE_LOCATION_SUMMARY(TestSmi,
+ 2,
+ Location::RequiresRegister(),
+ LocationSummary::kNoCall)
Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
@@ -662,30 +691,17 @@ Condition TestCidsInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
}
-void TestCidsInstr::EmitBranchCode(FlowGraphCompiler* compiler,
- BranchInstr* branch) {
- BranchLabels labels = compiler->CreateBranchLabels(branch);
- Condition true_condition = EmitComparisonCode(compiler, labels);
- EmitBranchOnCondition(compiler, true_condition, labels);
+Condition TestCidsInstr::GetNextInstructionCondition(
+ FlowGraphCompiler* compiler,
+ BranchLabels labels) {
+ return NEXT_IS_TRUE;
}
-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);
-}
+DEFINE_MAKE_LOCATION_SUMMARY(TestCids,
+ 1,
+ Location::RequiresRegister(),
+ LocationSummary::kNoCall)
EMIT_NATIVE_CODE(CreateArray,
@@ -1753,15 +1769,7 @@ 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:
@@ -1774,31 +1782,21 @@ void DoubleTestOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
UNREACHABLE();
}
const bool is_negated = kind() != Token::kEQ;
- EmitBranchOnCondition(compiler, is_negated ? NEXT_IS_FALSE : NEXT_IS_TRUE,
- labels);
+ return is_negated ? NEXT_IS_FALSE : NEXT_IS_TRUE;
}
-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();
+Condition DoubleTestOpInstr::GetNextInstructionCondition(
+ FlowGraphCompiler* compiler,
+ BranchLabels labels) {
const bool is_negated = kind() != Token::kEQ;
- __ 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());
+ return is_negated ? NEXT_IS_FALSE : NEXT_IS_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();
@@ -1973,7 +1971,8 @@ 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.
+ // 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.
condition = NEXT_IS_FALSE;
comparison = FlipCondition(kind);
}
@@ -2010,29 +2009,20 @@ Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
}
-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());
+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;
+ }
}
-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);
-}
+DEFINE_MAKE_LOCATION_SUMMARY(EqualityCompare, 2, Location::RequiresRegister());
Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
@@ -2046,24 +2036,20 @@ Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
}
-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());
+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;
+ }
}
-void RelationalOpInstr::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(RelationalOp, 2, Location::RequiresRegister())
EMIT_NATIVE_CODE(CheckArrayBound, 2) {
« no previous file with comments | « runtime/vm/intermediate_language_arm64.cc ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698