In strict comarison use constants instead of registers if possible.

Review URL: https://codereview.chromium.org//10977020

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@12879 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
srdjan@google.com 2012-09-25 20:34:15 +00:00
parent 428258ff2d
commit 8415b6e37c
2 changed files with 118 additions and 11 deletions

View file

@ -1560,19 +1560,36 @@ void StoreContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
LocationSummary* StrictCompareInstr::MakeLocationSummary() const {
return LocationSummary::Make(2,
Location::SameAsFirstInput(),
LocationSummary::kNoCall);
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()));
locs->set_in(1, Location::RegisterOrConstant(right()));
locs->set_out(Location::RequiresRegister());
return locs;
}
void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register left = locs()->in(0).reg();
Register right = locs()->in(1).reg();
ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
__ CompareRegisters(left, right);
Location left = locs()->in(0);
Location right = locs()->in(1);
if (left.IsConstant() && right.IsConstant()) {
// TODO(vegorov): should be eliminated earlier by constant propagation.
const bool result = left.constant().raw() == right.constant().raw();
__ LoadObject(locs()->out().reg(), result ? compiler->bool_true() :
compiler->bool_false());
return;
}
if (left.IsConstant()) {
__ CompareObject(right.reg(), left.constant());
} else if (right.IsConstant()) {
__ CompareObject(left.reg(), right.constant());
} else {
__ CompareRegisters(left.reg(), right.reg());
}
Register result = locs()->out().reg();
Label load_true, done;
@ -1587,11 +1604,24 @@ void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
BranchInstr* branch) {
Register left = locs()->in(0).reg();
Register right = locs()->in(1).reg();
ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
__ CompareRegisters(left, right);
Location left = locs()->in(0);
Location right = locs()->in(1);
if (left.IsConstant() && right.IsConstant()) {
// TODO(vegorov): should be eliminated earlier by constant propagation.
const bool result = left.constant().raw() == right.constant().raw();
branch->EmitBranchOnValue(compiler, result);
return;
}
if (left.IsConstant()) {
__ CompareObject(right.reg(), left.constant());
} else if (right.IsConstant()) {
__ CompareObject(left.reg(), right.constant());
} else {
__ CompareRegisters(left.reg(), right.reg());
}
branch->EmitBranchOnCondition(compiler, true_condition);
}

View file

@ -0,0 +1,77 @@
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
main() {
for (int i = 0; i < 6000; i++) {
Expect.isFalse(test1(5));
Expect.isTrue(test1(3));
Expect.isTrue(test2(5));
Expect.isFalse(test2(3));
Expect.isTrue(test2r(5));
Expect.isFalse(test2r(3));
Expect.isTrue(test3());
Expect.equals(2, test4(5));
Expect.equals(1, test4(3));
Expect.equals(1, test5(5));
Expect.equals(2, test5(3));
Expect.equals(1, test6());
}
}
test1(a) {
return a === 3;
}
test2(a) {
return a !== 3;
}
test2r(a) {
return 3 !== a;
}
test3() {
return get5() === 5;
}
test4(a) {
if (a === 3) {
return 1;
} else {
return 2;
}
}
test5(a) {
if (a !== 3) {
return 1;
} else {
return 2;
}
}
test6() {
if (get5() === 5) {
return 1;
} else {
return 2;
}
}
get5() {
return 5;
}