mirror of
https://github.com/dart-lang/sdk
synced 2024-09-20 03:41:29 +00:00
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:
parent
314555d49c
commit
6d2277f70f
|
@ -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)) {
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue