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

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 64483002: Streamline code generator for branches and comparisons. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: added other platformd, comments addressed Created 7 years, 1 month 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
Index: runtime/vm/intermediate_language_ia32.cc
===================================================================
--- runtime/vm/intermediate_language_ia32.cc (revision 30153)
+++ runtime/vm/intermediate_language_ia32.cc (working copy)
@@ -327,20 +327,19 @@
static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
- TargetEntryInstr* true_successor,
- TargetEntryInstr* false_successor,
- Condition true_condition) {
- if (compiler->CanFallThroughTo(false_successor)) {
+ Condition true_condition,
+ BranchLabels labels) {
+ if (labels.fall_through == labels.false_label) {
// If the next block is the false successor, fall through to it.
- __ j(true_condition, compiler->GetJumpLabel(true_successor));
+ __ j(true_condition, labels.true_label);
} else {
// If the next block is not the false successor, branch to it.
Condition false_condition = NegateCondition(true_condition);
- __ j(false_condition, compiler->GetJumpLabel(false_successor));
+ __ j(false_condition, labels.false_label);
// Fall through or jump to the true successor.
- if (!compiler->CanFallThroughTo(true_successor)) {
- __ jmp(compiler->GetJumpLabel(true_successor));
+ if (labels.fall_through != labels.true_label) {
+ __ jmp(labels.true_label);
}
}
}
@@ -349,7 +348,7 @@
static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
const LocationSummary& locs,
Token::Kind kind,
- BranchInstr* branch) {
+ BranchLabels labels) {
Location left = locs.in(0);
Location right = locs.in(1);
ASSERT(!left.IsConstant() || !right.IsConstant());
@@ -366,22 +365,7 @@
} else {
__ cmpl(left.reg(), right.reg());
}
-
- if (branch != NULL) {
- EmitBranchOnCondition(compiler,
- branch->true_successor(),
- branch->false_successor(),
- true_condition);
- } else {
- Register result = locs.out().reg();
- Label done, is_true;
- __ j(true_condition, &is_true);
- __ LoadObject(result, Bool::False());
- __ jmp(&done);
- __ Bind(&is_true);
- __ LoadObject(result, Bool::True());
- __ Bind(&done);
- }
+ EmitBranchOnCondition(compiler, true_condition, labels);
}
@@ -429,7 +413,7 @@
static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
const LocationSummary& locs,
Token::Kind kind,
- BranchInstr* branch) {
+ BranchLabels labels) {
ASSERT(Token::IsEqualityOperator(kind));
XmmRegister left = locs.in(0).fpu_reg();
XmmRegister right = locs.in(1).fpu_reg();
@@ -440,34 +424,18 @@
Condition true_condition = TokenKindToMintCondition(kind);
__ cmpl(temp, Immediate(-1));
-
- if (branch != NULL) {
- EmitBranchOnCondition(compiler,
- branch->true_successor(),
- branch->false_successor(),
- true_condition);
- } else {
- Register result = locs.out().reg();
- Label done, is_true;
- __ j(true_condition, &is_true);
- __ LoadObject(result, Bool::False());
- __ jmp(&done);
- __ Bind(&is_true);
- __ LoadObject(result, Bool::True());
- __ Bind(&done);
- }
+ EmitBranchOnCondition(compiler, true_condition, labels);
}
static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
const LocationSummary& locs,
Token::Kind kind,
- BranchInstr* branch) {
+ BranchLabels labels) {
XmmRegister left = locs.in(0).fpu_reg();
XmmRegister right = locs.in(1).fpu_reg();
Register left_tmp = locs.temp(0).reg();
Register right_tmp = locs.temp(1).reg();
- Register result = branch == NULL ? locs.out().reg() : kNoRegister;
Condition hi_cond = OVERFLOW, lo_cond = OVERFLOW;
switch (kind) {
@@ -496,34 +464,14 @@
__ pextrd(left_tmp, left, Immediate(1));
__ pextrd(right_tmp, right, Immediate(1));
__ cmpl(left_tmp, right_tmp);
- if (branch != NULL) {
- __ j(hi_cond, compiler->GetJumpLabel(branch->true_successor()));
- __ j(FlipCondition(hi_cond),
- compiler->GetJumpLabel(branch->false_successor()));
- } else {
- __ j(hi_cond, &is_true);
- __ j(FlipCondition(hi_cond), &is_false);
- }
+ __ j(hi_cond, labels.true_label);
+ __ j(FlipCondition(hi_cond), labels.false_label);
// If upper is equal, compare lower half.
__ pextrd(left_tmp, left, Immediate(0));
__ pextrd(right_tmp, right, Immediate(0));
__ cmpl(left_tmp, right_tmp);
- if (branch != NULL) {
- EmitBranchOnCondition(compiler,
- branch->true_successor(),
- branch->false_successor(),
- lo_cond);
- } else {
- Label done;
- __ j(lo_cond, &is_true);
- __ Bind(&is_false);
- __ LoadObject(result, Bool::False());
- __ jmp(&done);
- __ Bind(&is_true);
- __ LoadObject(result, Bool::True());
- __ Bind(&done);
- }
+ EmitBranchOnCondition(compiler, lo_cond, labels);
}
@@ -542,96 +490,62 @@
}
-static void EmitDoubleCompareBranch(FlowGraphCompiler* compiler,
- Condition true_condition,
- FpuRegister left,
- FpuRegister right,
- BranchInstr* branch) {
- ASSERT(branch != NULL);
- __ comisd(left, right);
- BlockEntryInstr* nan_result = (true_condition == NOT_EQUAL) ?
- branch->true_successor() : branch->false_successor();
- __ j(PARITY_EVEN, compiler->GetJumpLabel(nan_result));
- EmitBranchOnCondition(compiler,
- branch->true_successor(),
- branch->false_successor(),
- true_condition);
-}
-
-
-
-static void EmitDoubleCompareBool(FlowGraphCompiler* compiler,
- Condition true_condition,
- FpuRegister left,
- FpuRegister right,
- Register result) {
- __ comisd(left, right);
- Label is_false, is_true, done;
- // x == NaN -> false, x != NaN -> true.
- Label* nan_label = (true_condition == NOT_EQUAL) ? &is_true : &is_false;
- __ j(PARITY_EVEN, nan_label, Assembler::kNearJump);
- __ j(true_condition, &is_true, Assembler::kNearJump);
- __ Bind(&is_false);
- __ LoadObject(result, Bool::False());
- __ jmp(&done);
- __ Bind(&is_true);
- __ LoadObject(result, Bool::True());
- __ Bind(&done);
-}
-
-
static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
const LocationSummary& locs,
Token::Kind kind,
- BranchInstr* branch) {
+ BranchLabels labels) {
XmmRegister left = locs.in(0).fpu_reg();
XmmRegister right = locs.in(1).fpu_reg();
+ __ comisd(left, right);
+
Condition true_condition = TokenKindToDoubleCondition(kind);
- if (branch != NULL) {
- EmitDoubleCompareBranch(compiler, true_condition, left, right, branch);
- } else {
- EmitDoubleCompareBool(compiler, true_condition,
- left, right, locs.out().reg());
- }
+ Label* nan_result = (true_condition == NOT_EQUAL)
+ ? labels.true_label : labels.false_label;
+ __ j(PARITY_EVEN, nan_result);
+ EmitBranchOnCondition(compiler, true_condition, labels);
}
void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
- BranchInstr* kNoBranch = NULL;
+
+ Label is_true, is_false;
+ BranchLabels labels = { &is_true, &is_false, &is_false };
+
if (operation_cid() == kSmiCid) {
- EmitSmiComparisonOp(compiler, *locs(), kind(), kNoBranch);
- return;
+ EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+ } else if (operation_cid() == kMintCid) {
+ EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels);
+ } else {
+ ASSERT(operation_cid() == kDoubleCid);
+ EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
}
- if (operation_cid() == kMintCid) {
- EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), kNoBranch);
- return;
- }
- if (operation_cid() == kDoubleCid) {
- EmitDoubleComparisonOp(compiler, *locs(), kind(), kNoBranch);
- return;
- }
- UNREACHABLE();
+ Register result = locs()->out().reg();
+ Label done;
+ __ Bind(&is_false);
+ __ LoadObject(result, Bool::False());
+ __ jmp(&done, Assembler::kNearJump);
+ __ Bind(&is_true);
+ __ LoadObject(result, Bool::True());
+ __ Bind(&done);
}
void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
+
+ BranchLabels labels = compiler->CreateBranchLabels(branch);
+
if (operation_cid() == kSmiCid) {
- EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
- return;
+ EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+ } else if (operation_cid() == kMintCid) {
+ EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels);
+ } else {
+ ASSERT(operation_cid() == kDoubleCid);
+ EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
}
- if (operation_cid() == kMintCid) {
- EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), branch);
- return;
- }
- if (operation_cid() == kDoubleCid) {
- EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
- return;
- }
- UNREACHABLE();
}
@@ -656,7 +570,9 @@
void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
- Condition branch_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
+ BranchLabels labels = compiler->CreateBranchLabels(branch);
+
+ Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
Register left = locs()->in(0).reg();
Location right = locs()->in(1);
if (right.IsConstant()) {
@@ -667,10 +583,7 @@
} else {
__ testl(left, right.reg());
}
- EmitBranchOnCondition(compiler,
- branch->true_successor(),
- branch->false_successor(),
- branch_condition);
+ EmitBranchOnCondition(compiler, true_condition, labels);
}
@@ -711,31 +624,40 @@
void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ Label is_true, is_false;
+ BranchLabels labels = { &is_true, &is_false, &is_false };
+
if (operation_cid() == kSmiCid) {
- EmitSmiComparisonOp(compiler, *locs(), kind(), NULL);
- return;
+ EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+ } else if (operation_cid() == kMintCid) {
+ EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
+ } else {
+ ASSERT(operation_cid() == kDoubleCid);
+ EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
}
- if (operation_cid() == kMintCid) {
- EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), NULL);
- return;
- }
- ASSERT(operation_cid() == kDoubleCid);
- EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL);
+ Register result = locs()->out().reg();
+ Label done;
+ __ Bind(&is_false);
+ __ LoadObject(result, Bool::False());
+ __ jmp(&done, Assembler::kNearJump);
+ __ Bind(&is_true);
+ __ LoadObject(result, Bool::True());
+ __ Bind(&done);
}
void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
+ BranchLabels labels = compiler->CreateBranchLabels(branch);
+
if (operation_cid() == kSmiCid) {
- EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
- return;
+ EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+ } else if (operation_cid() == kMintCid) {
+ EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
+ } else {
+ ASSERT(operation_cid() == kDoubleCid);
+ EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
}
- if (operation_cid() == kMintCid) {
- EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
- return;
- }
- ASSERT(operation_cid() == kDoubleCid);
- EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
}
@@ -4696,36 +4618,52 @@
}
-// Special code for numbers (compare values instead of references.)
-void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
- Location left = locs()->in(0);
- Location right = locs()->in(1);
+static void EmitStrictComparison(FlowGraphCompiler* compiler,
+ StrictCompareInstr* compare,
+ BranchLabels labels) {
+ LocationSummary* locs = compare->locs();
+ bool needs_number_check = compare->needs_number_check();
+ intptr_t token_pos = compare->token_pos();
+ Token::Kind kind = compare->kind();
+ Location left = locs->in(0);
+ Location right = locs->in(1);
ASSERT(!left.IsConstant() || !right.IsConstant());
if (left.IsConstant()) {
compiler->EmitEqualityRegConstCompare(right.reg(),
left.constant(),
- needs_number_check(),
- token_pos());
+ needs_number_check,
+ token_pos);
} else if (right.IsConstant()) {
compiler->EmitEqualityRegConstCompare(left.reg(),
right.constant(),
- needs_number_check(),
- token_pos());
+ needs_number_check,
+ token_pos);
} else {
compiler->EmitEqualityRegRegCompare(left.reg(),
- right.reg(),
- needs_number_check(),
- token_pos());
+ right.reg(),
+ needs_number_check,
+ token_pos);
}
+ Condition true_condition = (kind == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
+ EmitBranchOnCondition(compiler, true_condition, labels);
+}
+
+// Special code for numbers (compare values instead of references.)
+void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
+
+ Label is_true, is_false;
+ BranchLabels labels = { &is_true, &is_false, &is_false };
+
+ EmitStrictComparison(compiler, this, labels);
+
Register result = locs()->out().reg();
- Label load_true, done;
- Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
- __ j(true_condition, &load_true, Assembler::kNearJump);
+ Label done;
+ __ Bind(&is_false);
__ LoadObject(result, Bool::False());
__ jmp(&done, Assembler::kNearJump);
- __ Bind(&load_true);
+ __ Bind(&is_true);
__ LoadObject(result, Bool::True());
__ Bind(&done);
}
@@ -4734,31 +4672,10 @@
void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
- Location left = locs()->in(0);
- Location right = locs()->in(1);
- ASSERT(!left.IsConstant() || !right.IsConstant());
- if (left.IsConstant()) {
- compiler->EmitEqualityRegConstCompare(right.reg(),
- left.constant(),
- needs_number_check(),
- token_pos());
- } else if (right.IsConstant()) {
- compiler->EmitEqualityRegConstCompare(left.reg(),
- right.constant(),
- needs_number_check(),
- token_pos());
- } else {
- compiler->EmitEqualityRegRegCompare(left.reg(),
- right.reg(),
- needs_number_check(),
- token_pos());
- }
- Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
- EmitBranchOnCondition(compiler,
- branch->true_successor(),
- branch->false_successor(),
- true_condition);
+ BranchLabels labels = compiler->CreateBranchLabels(branch);
+
+ EmitStrictComparison(compiler, this, labels);
}

Powered by Google App Engine
This is Rietveld 408576698