| Index: runtime/vm/intermediate_language.cc
|
| diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
|
| index bc136fb6040e660e7e2b7eb0e01c48f03be1e435..8385f1ae5775a3a38f264fac42db5f9ac30db8e0 100644
|
| --- a/runtime/vm/intermediate_language.cc
|
| +++ b/runtime/vm/intermediate_language.cc
|
| @@ -343,6 +343,45 @@ bool Value::BindsToConstant() const {
|
| }
|
|
|
|
|
| +bool Value::BindsTo32BitMint() const {
|
| + if (!definition()->IsMintDefinition()) {
|
| + return false;
|
| + }
|
| + if (definition()->IsBinaryMintOp()) {
|
| + BinaryMintOpInstr* instr = definition()->AsBinaryMintOp();
|
| + return instr->is_32_bit();
|
| + } else if (definition()->IsShiftMintOp()) {
|
| + ShiftMintOpInstr* instr = definition()->AsShiftMintOp();
|
| + return instr->is_32_bit();
|
| + } else if (definition()->IsUnboxInteger()) {
|
| + UnboxIntegerInstr* instr = definition()->AsUnboxInteger();
|
| + return instr->is_32_bit();
|
| + } else if (definition()->IsUnaryMintOp()) {
|
| + UnaryMintOpInstr* instr = definition()->AsUnaryMintOp();
|
| + return instr->is_32_bit();
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +
|
| +bool Value::BindsTo32BitMaskConstant() const {
|
| + if (!definition()->IsUnboxInteger()) {
|
| + return false;
|
| + }
|
| + UnboxIntegerInstr* instr = definition()->AsUnboxInteger();
|
| + if (!instr->value()->BindsToConstant()) {
|
| + return false;
|
| + }
|
| + const Object& obj = instr->value()->BoundConstant();
|
| + if (!obj.IsMint()) {
|
| + return false;
|
| + }
|
| + Mint& mint = Mint::Handle();
|
| + mint ^= obj.raw();
|
| + return mint.value() == kMaxUint32;
|
| +}
|
| +
|
| +
|
| // Returns true if the value represents constant null.
|
| bool Value::BindsToConstantNull() const {
|
| ConstantInstr* constant = definition()->AsConstant();
|
| @@ -3217,6 +3256,13 @@ void BinarySmiOpInstr::InferRange() {
|
| }
|
|
|
|
|
| +Representation BinaryMintOpInstr::RequiredInputRepresentation(
|
| + intptr_t idx) const {
|
| + ASSERT((idx == 0) || (idx == 1));
|
| + return InputAt(idx)->BindsTo32BitMint() ? kUnboxedMint32 : kUnboxedMint;
|
| +}
|
| +
|
| +
|
| void BinaryMintOpInstr::InferRange() {
|
| // TODO(vegorov): canonicalize BinaryMintOpInstr to always have constant on
|
| // the right and a non-constant on the left.
|
| @@ -3410,12 +3456,25 @@ bool Range::And(const Range* left_range,
|
| ASSERT(result_min != NULL);
|
| ASSERT(result_max != NULL);
|
|
|
| + // Both ranges are >= 0.
|
| + if ((Range::ConstantMin(left_range).ConstantValue() >= 0) &&
|
| + (Range::ConstantMin(right_range).ConstantValue() >= 0)) {
|
| + *result_min = RangeBoundary::FromConstant(0);
|
| + // Take minimum value as new range.
|
| + *result_max = RangeBoundary::Min(Range::ConstantMax(left_range),
|
| + Range::ConstantMax(right_range),
|
| + RangeBoundary::kRangeBoundaryInt64);
|
| + return true;
|
| + }
|
| +
|
| + // Right range is >= 0.
|
| if (Range::ConstantMin(right_range).ConstantValue() >= 0) {
|
| *result_min = RangeBoundary::FromConstant(0);
|
| *result_max = Range::ConstantMax(right_range);
|
| return true;
|
| }
|
|
|
| + // Left range is >= 0.
|
| if (Range::ConstantMin(left_range).ConstantValue() >= 0) {
|
| *result_min = RangeBoundary::FromConstant(0);
|
| *result_max = Range::ConstantMax(left_range);
|
|
|