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

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 78733002: Generalize if-conversion to arbitrary smi comparisons. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: 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
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_ia32.cc
===================================================================
--- runtime/vm/intermediate_language_ia32.cc (revision 30464)
+++ runtime/vm/intermediate_language_ia32.cc (working copy)
@@ -345,10 +345,10 @@
}
-static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
- const LocationSummary& locs,
- Token::Kind kind,
- BranchLabels labels) {
+static Condition EmitSmiComparisonOp(FlowGraphCompiler* compiler,
+ const LocationSummary& locs,
+ Token::Kind kind,
+ BranchLabels labels) {
Location left = locs.in(0);
Location right = locs.in(1);
ASSERT(!left.IsConstant() || !right.IsConstant());
@@ -365,7 +365,7 @@
} else {
__ cmpl(left.reg(), right.reg());
}
- EmitBranchOnCondition(compiler, true_condition, labels);
+ return true_condition;
}
@@ -410,10 +410,10 @@
}
-static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
- const LocationSummary& locs,
- Token::Kind kind,
- BranchLabels labels) {
+static Condition EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
+ const LocationSummary& locs,
+ Token::Kind kind,
+ BranchLabels labels) {
ASSERT(Token::IsEqualityOperator(kind));
XmmRegister left = locs.in(0).fpu_reg();
XmmRegister right = locs.in(1).fpu_reg();
@@ -424,14 +424,14 @@
Condition true_condition = TokenKindToMintCondition(kind);
__ cmpl(temp, Immediate(-1));
- EmitBranchOnCondition(compiler, true_condition, labels);
+ return true_condition;
}
-static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
- const LocationSummary& locs,
- Token::Kind kind,
- BranchLabels labels) {
+static Condition EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
+ const LocationSummary& locs,
+ Token::Kind kind,
+ BranchLabels labels) {
XmmRegister left = locs.in(0).fpu_reg();
XmmRegister right = locs.in(1).fpu_reg();
Register left_tmp = locs.temp(0).reg();
@@ -471,7 +471,7 @@
__ pextrd(left_tmp, left, Immediate(0));
__ pextrd(right_tmp, right, Immediate(0));
__ cmpl(left_tmp, right_tmp);
- EmitBranchOnCondition(compiler, lo_cond, labels);
+ return lo_cond;
}
@@ -490,10 +490,10 @@
}
-static void EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
- const LocationSummary& locs,
- Token::Kind kind,
- BranchLabels labels) {
+static Condition EmitDoubleComparisonOp(FlowGraphCompiler* compiler,
+ const LocationSummary& locs,
+ Token::Kind kind,
+ BranchLabels labels) {
XmmRegister left = locs.in(0).fpu_reg();
XmmRegister right = locs.in(1).fpu_reg();
@@ -503,24 +503,31 @@
Label* nan_result = (true_condition == NOT_EQUAL)
? labels.true_label : labels.false_label;
__ j(PARITY_EVEN, nan_result);
- EmitBranchOnCondition(compiler, true_condition, labels);
+ return true_condition;
}
+Condition EqualityCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+ BranchLabels labels) {
+ if (operation_cid() == kSmiCid) {
+ return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+ } else if (operation_cid() == kMintCid) {
+ return EmitUnboxedMintEqualityOp(compiler, *locs(), kind(), labels);
+ } else {
+ ASSERT(operation_cid() == kDoubleCid);
+ return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
+ }
+}
+
+
void EqualityCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
Label is_true, is_false;
BranchLabels labels = { &is_true, &is_false, &is_false };
+ Condition true_condition = EmitComparisonCode(compiler, labels);
+ EmitBranchOnCondition(compiler, true_condition, labels);
- if (operation_cid() == kSmiCid) {
- 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);
- }
Register result = locs()->out().reg();
Label done;
__ Bind(&is_false);
@@ -537,15 +544,8 @@
ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
BranchLabels labels = compiler->CreateBranchLabels(branch);
-
- if (operation_cid() == kSmiCid) {
- 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);
- }
+ Condition true_condition = EmitComparisonCode(compiler, labels);
+ EmitBranchOnCondition(compiler, true_condition, labels);
}
@@ -562,17 +562,8 @@
}
-void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- // Never emitted outside of the BranchInstr.
- UNREACHABLE();
-}
-
-
-void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
- BranchInstr* branch) {
- BranchLabels labels = compiler->CreateBranchLabels(branch);
-
- Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
+Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+ BranchLabels labels) {
Register left = locs()->in(0).reg();
Location right = locs()->in(1);
if (right.IsConstant()) {
@@ -583,6 +574,21 @@
} else {
__ testl(left, right.reg());
}
+ Condition true_condition = (kind() == Token::kNE) ? NOT_ZERO : ZERO;
+ return true_condition;
+}
+
+
+void TestSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ // Never emitted outside of the BranchInstr.
+ UNREACHABLE();
+}
+
+
+void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
+ BranchInstr* branch) {
+ BranchLabels labels = compiler->CreateBranchLabels(branch);
+ Condition true_condition = EmitComparisonCode(compiler, labels);
EmitBranchOnCondition(compiler, true_condition, labels);
}
@@ -623,18 +629,25 @@
}
-void RelationalOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- Label is_true, is_false;
- BranchLabels labels = { &is_true, &is_false, &is_false };
-
+Condition RelationalOpInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+ BranchLabels labels) {
if (operation_cid() == kSmiCid) {
- EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
+ return EmitSmiComparisonOp(compiler, *locs(), kind(), labels);
} else if (operation_cid() == kMintCid) {
- EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
+ return EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), labels);
} else {
ASSERT(operation_cid() == kDoubleCid);
- EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
+ return EmitDoubleComparisonOp(compiler, *locs(), kind(), labels);
}
+}
+
+
+void RelationalOpInstr::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);
+
Register result = locs()->out().reg();
Label done;
__ Bind(&is_false);
@@ -649,15 +662,8 @@
void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
BranchLabels labels = compiler->CreateBranchLabels(branch);
-
- if (operation_cid() == kSmiCid) {
- 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);
- }
+ Condition true_condition = EmitComparisonCode(compiler, labels);
+ EmitBranchOnCondition(compiler, true_condition, labels);
}
@@ -4618,46 +4624,40 @@
}
-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);
+Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
+ BranchLabels labels) {
+ 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);
+ needs_number_check(),
+ token_pos());
}
- Condition true_condition = (kind == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
- EmitBranchOnCondition(compiler, true_condition, labels);
+ Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
+ return true_condition;
}
-// 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 };
+ Condition true_condition = EmitComparisonCode(compiler, labels);
+ EmitBranchOnCondition(compiler, true_condition, labels);
- EmitStrictComparison(compiler, this, labels);
-
Register result = locs()->out().reg();
Label done;
__ Bind(&is_false);
@@ -4674,8 +4674,8 @@
ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
BranchLabels labels = compiler->CreateBranchLabels(branch);
-
- EmitStrictComparison(compiler, this, labels);
+ Condition true_condition = EmitComparisonCode(compiler, labels);
+ EmitBranchOnCondition(compiler, true_condition, labels);
}
@@ -4687,16 +4687,7 @@
LocationSummary* IfThenElseInstr::MakeLocationSummary() const {
- const intptr_t kNumInputs = 2;
- const intptr_t kNumTemps = 0;
- LocationSummary* locs =
- new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
- locs->set_in(0, Location::RegisterOrConstant(left()));
- // Only one of the inputs can be a constant. Choose register if the first one
- // is a constant.
- locs->set_in(1, locs->in(0).IsConstant()
- ? Location::RequiresRegister()
- : Location::RegisterOrConstant(right()));
+ LocationSummary* locs = comparison()->MakeLocationSummary();
// TODO(vegorov): support byte register constraints in the register allocator.
locs->set_out(Location::RegisterLocation(EDX));
return locs;
@@ -4705,31 +4696,15 @@
void IfThenElseInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(locs()->out().reg() == EDX);
- ASSERT(Token::IsEqualityOperator(kind()));
- Location left = locs()->in(0);
- Location right = locs()->in(1);
- ASSERT(!left.IsConstant() || !right.IsConstant());
-
// Clear upper part of the out register. We are going to use setcc on it
// which is a byte move.
__ xorl(EDX, EDX);
- // Compare left and right. For now only equality comparison is supported.
- // TODO(vegorov): reuse code from the other comparison instructions instead of
- // generating it inline here.
- if (left.IsConstant()) {
- __ CompareObject(right.reg(), left.constant());
- } else if (right.IsConstant()) {
- __ CompareObject(left.reg(), right.constant());
- } else {
- __ cmpl(left.reg(), right.reg());
- }
+ // Emit comparison code. This must not overwrite the result register.
+ BranchLabels labels = { NULL, NULL, NULL };
+ Condition true_condition = comparison()->EmitComparisonCode(compiler, labels);
- Condition true_condition =
- ((kind_ == Token::kEQ_STRICT) || (kind_ == Token::kEQ)) ? EQUAL
- : NOT_EQUAL;
-
const bool is_power_of_two_kind = IsPowerOfTwoKind(if_true_, if_false_);
intptr_t true_value = if_true_;
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698