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

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 10536145: Fuse comparisons that are used by branches together. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address review comments Created 8 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.cc ('k') | runtime/vm/intermediate_language_x64.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
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index a07b68266aa6c77c2e1bfa3ad41cd8b46ed1ddd3..0f7e539d967aad2b69294c044735593cee73b264 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -31,7 +31,13 @@ LocationSummary* Computation::MakeCallSummary() {
void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
computation()->EmitNativeCode(compiler);
- __ pushl(locs()->out().reg());
+ if (locs()->out().kind() == Location::kRegister) {
+ // TODO(vegorov): this should really happen only for comparisons fused
+ // with branches. Currrently IR does not provide an easy way to remove
+ // instructions from the graph so we just leave fused comparison in it
+ // but change its result location to be NoLocation.
+ __ pushl(locs()->out().reg());
+ }
}
@@ -163,9 +169,9 @@ void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) {
// Check that the type of the value is allowed in conditional context.
// Call the runtime if the object is not bool::true or bool::false.
Label done;
- __ CompareObject(obj, Bool::ZoneHandle(Bool::True()));
+ __ CompareObject(obj, compiler->bool_true());
__ j(EQUAL, &done, Assembler::kNearJump);
- __ CompareObject(obj, Bool::ZoneHandle(Bool::False()));
+ __ CompareObject(obj, compiler->bool_false());
__ j(EQUAL, &done, Assembler::kNearJump);
__ pushl(Immediate(Smi::RawValue(token_index()))); // Source location.
@@ -186,7 +192,9 @@ LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
LocationSummary* locs = new LocationSummary(2, 0);
locs->set_in(0, Location::RequiresRegister());
locs->set_in(1, Location::RequiresRegister());
- locs->set_out(Location::RegisterLocation(EAX));
+ if (!is_fused_with_branch()) {
+ locs->set_out(Location::RegisterLocation(EAX));
+ }
return locs;
}
@@ -194,23 +202,25 @@ LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
Register left = locs()->in(0).reg();
Register right = locs()->in(1).reg();
- Register result = locs()->out().reg();
- ASSERT(locs()->out().reg() == EAX);
- const Bool& bool_true = Bool::ZoneHandle(Bool::True());
- const Bool& bool_false = Bool::ZoneHandle(Bool::False());
const Immediate raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
- Label done, load_true, non_null_compare;
+ Label done, non_null_compare;
__ cmpl(left, raw_null);
__ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
// Comparison with NULL is "===".
__ cmpl(left, right);
- __ j(EQUAL, &load_true, Assembler::kNearJump);
- __ LoadObject(result, bool_false);
- __ jmp(&done, Assembler::kNearJump);
- __ Bind(&load_true);
- __ LoadObject(result, bool_true);
+ if (!is_fused_with_branch()) {
+ Register result = locs()->out().reg();
+ Label load_true;
+ __ j(EQUAL, &load_true, Assembler::kNearJump);
+ __ LoadObject(result, compiler->bool_false());
+ __ jmp(&done, Assembler::kNearJump);
+ __ Bind(&load_true);
+ __ LoadObject(result, compiler->bool_true());
+ } else {
+ fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL);
+ }
__ jmp(&done);
__ Bind(&non_null_compare);
@@ -228,6 +238,13 @@ void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
kNumberOfArguments,
kNoArgumentNames,
kNumArgumentsChecked);
+ ASSERT(fused_with_branch() != NULL || locs()->out().reg() == EAX);
+
+ if (fused_with_branch() != NULL) {
+ __ CompareObject(EAX, compiler->bool_true());
+ fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL);
+ }
+
__ Bind(&done);
}
@@ -239,7 +256,9 @@ LocationSummary* RelationalOpComp::MakeLocationSummary() const {
LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
summary->set_in(0, Location::RequiresRegister());
summary->set_in(1, Location::RequiresRegister());
- summary->set_out(Location::RequiresRegister());
+ if (!is_fused_with_branch()) {
+ summary->set_out(Location::RequiresRegister());
+ }
summary->set_temp(0, Location::RequiresRegister());
return summary;
}
@@ -267,7 +286,6 @@ static void EmitSmiRelationalOp(FlowGraphCompiler* compiler,
RelationalOpComp* comp) {
Register left = comp->locs()->in(0).reg();
Register right = comp->locs()->in(1).reg();
- Register result = comp->locs()->out().reg();
Register temp = comp->locs()->temp(0).reg();
Label* deopt = compiler->AddDeoptStub(comp->cid(),
comp->token_index(),
@@ -279,18 +297,23 @@ static void EmitSmiRelationalOp(FlowGraphCompiler* compiler,
__ orl(temp, right);
__ testl(temp, Immediate(kSmiTagMask));
__ j(NOT_ZERO, deopt);
- const Bool& bool_true = Bool::ZoneHandle(Bool::True());
- const Bool& bool_false = Bool::ZoneHandle(Bool::False());
- Condition condition = TokenKindToSmiCondition(comp->kind());
- Label done, is_true;
+ Condition true_condition = TokenKindToSmiCondition(comp->kind());
__ cmpl(left, right);
- __ j(condition, &is_true);
- __ LoadObject(result, bool_false);
- __ jmp(&done);
- __ Bind(&is_true);
- __ LoadObject(result, bool_true);
- __ Bind(&done);
+
+ if (comp->is_fused_with_branch()) {
+ comp->fused_with_branch()->EmitBranchOnCondition(compiler, true_condition);
+ } else {
+ Register result = comp->locs()->out().reg();
+ Label done, is_true;
+
+ __ j(true_condition, &is_true);
+ __ LoadObject(result, compiler->bool_false());
+ __ jmp(&done);
+ __ Bind(&is_true);
+ __ LoadObject(result, compiler->bool_true());
+ __ Bind(&done);
+ }
}
@@ -312,7 +335,6 @@ static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler,
RelationalOpComp* comp) {
Register left = comp->locs()->in(0).reg();
Register right = comp->locs()->in(1).reg();
- Register result = comp->locs()->out().reg();
// TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
Register temp = comp->locs()->temp(0).reg();
Label* deopt = compiler->AddDeoptStub(comp->cid(),
@@ -323,19 +345,26 @@ static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler,
right);
compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
- const Bool& bool_true = Bool::ZoneHandle(Bool::True());
- const Bool& bool_false = Bool::ZoneHandle(Bool::False());
+
Condition true_condition = TokenKindToDoubleCondition(comp->kind());
- Label is_false, is_true, done;
__ comisd(XMM0, XMM1);
- __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
- __ 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);
+
+ if (comp->is_fused_with_branch()) {
+ BranchInstr* branch = comp->fused_with_branch();
+ __ j(PARITY_EVEN, compiler->GetBlockLabel(branch->false_successor()));
+ branch->EmitBranchOnCondition(compiler, true_condition);
+ } else {
+ Register result = comp->locs()->out().reg();
+ Label is_false, is_true, done;
+ __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
+ __ j(true_condition, &is_true, Assembler::kNearJump);
+ __ Bind(&is_false);
+ __ LoadObject(result, compiler->bool_false());
+ __ jmp(&done);
+ __ Bind(&is_true);
+ __ LoadObject(result, compiler->bool_true());
+ __ Bind(&done);
+ }
}
@@ -1426,10 +1455,11 @@ void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
LocationSummary* ToDoubleComp::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
- const intptr_t kNumTemps = 1;
if (from() == kDouble) {
+ const intptr_t kNumTemps = 1;
LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
locs->set_in(0, Location::RequiresRegister());
+ locs->set_temp(0, Location::RequiresRegister());
locs->set_out(Location::SameAsFirstInput());
return locs;
} else {
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698