Add range to kBIT_AND with positive constants. Use that range to eliminate compares in left shifts.

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

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@14304 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
srdjan@google.com 2012-10-30 19:59:58 +00:00
parent 314555d49c
commit 6d2277f70f
4 changed files with 45 additions and 7 deletions

View file

@ -2513,6 +2513,23 @@ void BinarySmiOpInstr::InferRange() {
}
break;
case Token::kBIT_AND:
if (Range::ConstantMin(right_range).value() >= 0) {
min = RangeBoundary::FromConstant(0);
max = Range::ConstantMax(right_range);
break;
}
if (Range::ConstantMin(left_range).value() >= 0) {
min = RangeBoundary::FromConstant(0);
max = Range::ConstantMax(left_range);
break;
}
if (range_ == NULL) {
range_ = Range::Unknown();
}
return;
default:
if (range_ == NULL) {
range_ = Range::Unknown();
@ -2530,6 +2547,14 @@ void BinarySmiOpInstr::InferRange() {
}
// Inclusive.
bool Range::IsWithin(intptr_t min_int, intptr_t max_int) const {
if (min().LowerBound().value() < min_int) return false;
if (max().UpperBound().value() > max_int) return false;
return true;
}
bool CheckArrayBoundInstr::IsRedundant(RangeBoundary length) {
// Check that array has an immutable length.
if ((array_type() != kArrayCid) && (array_type() != kImmutableArrayCid)) {

View file

@ -1691,8 +1691,8 @@ class Range : public ZoneAllocated {
void PrintTo(BufferFormatter* f) const;
static const char* ToCString(Range* range);
const RangeBoundary& min() { return min_; }
const RangeBoundary& max() { return max_; }
const RangeBoundary& min() const { return min_; }
const RangeBoundary& max() const { return max_; }
bool Equals(Range* other) {
return min_.Equals(other->min_) && max_.Equals(other->max_);
@ -1708,6 +1708,9 @@ class Range : public ZoneAllocated {
return range->max().UpperBound();
}
// Inclusive.
bool IsWithin(intptr_t min_int, intptr_t max_int) const;
private:
RangeBoundary min_;
RangeBoundary max_;

View file

@ -1757,9 +1757,14 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Label call_method, done;
// Check if count too large for handling it inlined.
__ movl(temp, left);
__ cmpl(right,
Range* right_range = this->right()->definition()->range();
const bool right_needs_check =
(right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1));
if (right_needs_check) {
__ cmpl(right,
Immediate(reinterpret_cast<int32_t>(Smi::New(Smi::kBits))));
__ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
__ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
}
Register right_temp = locs()->temp(1).reg();
ASSERT(right_temp == ECX); // Count must be in ECX
__ movl(right_temp, right);

View file

@ -1719,9 +1719,14 @@ void BinarySmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Label call_method, done;
// Check if count too large for handling it inlined.
__ movq(temp, left);
__ cmpq(right,
Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
__ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
Range* right_range = this->right()->definition()->range();
const bool right_needs_check =
(right_range == NULL) || !right_range->IsWithin(0, (Smi::kBits - 1));
if (right_needs_check) {
__ cmpq(right,
Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
__ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
}
Register right_temp = locs()->temp(1).reg();
ASSERT(right_temp == RCX); // Count must be in RCX
__ movq(right_temp, right);