2409 {
2410
2411
2415 auto* const replacement =
2416 flow_graph->TryCreateConstantReplacementFor(
this,
value);
2417 if (replacement != this) {
2418 return replacement;
2419 }
2420 }
2421
2422
2423
2424
2425
2426 if (
left()->BindsToConstant() &&
right()->BindsToConstant()) {
2430
2432 return flow_graph->TryCreateConstantReplacementFor(
this,
result);
2433 }
2434 }
2435
2436 if (
left()->BindsToConstant() && !
right()->BindsToConstant() &&
2442 }
2443
2444 int64_t rhs;
2446 return this;
2447 }
2448
2451 case Token::kMUL:
2452 case Token::kSUB:
2453 case Token::kADD:
2454 case Token::kBIT_AND:
2455 case Token::kBIT_OR:
2456 case Token::kBIT_XOR:
2458 break;
2459 default:
2460 break;
2461 }
2462 }
2463
2465
2466
2467
2468 return this;
2469 }
2470
2472 case Token::kMUL:
2473 if (rhs == 1) {
2475 } else if (rhs == 0) {
2481 : kTagged;
2482 ConstantInstr* constant_shift_amount = flow_graph->GetConstant(
2488 if (shift != nullptr) {
2489
2490
2491 if (auto shift_with_range = shift->AsShiftIntegerOp()) {
2492 shift_with_range->set_shift_range(
2495 }
2497 ASSERT(!shift->MayThrow());
2498 }
2500 ASSERT(!shift->CanDeoptimize());
2501 }
2503 return shift;
2504 }
2505 }
2506
2507 break;
2508 case Token::kADD:
2509 if (rhs == 0) {
2511 }
2512 break;
2513 case Token::kBIT_AND:
2514 if (rhs == 0) {
2518 }
2519 break;
2520 case Token::kBIT_OR:
2521 if (rhs == 0) {
2525 }
2526 break;
2527 case Token::kBIT_XOR:
2528 if (rhs == 0) {
2534 if (bit_not != nullptr) {
2536 return bit_not;
2537 }
2538 }
2539 break;
2540
2541 case Token::kSUB:
2542 if (rhs == 0) {
2544 }
2545 break;
2546
2547 case Token::kTRUNCDIV:
2548 if (rhs == 1) {
2550 } else if (rhs == -1) {
2554 if (negation != nullptr) {
2556 return negation;
2557 }
2558 }
2559 break;
2560
2561 case Token::kMOD:
2562 if ((rhs == -1) || (rhs == 1)) {
2563 return flow_graph->TryCreateConstantReplacementFor(this,
2564 Object::smi_zero());
2565 }
2566 break;
2567
2568 case Token::kUSHR:
2570 return flow_graph->TryCreateConstantReplacementFor(this,
2571 Object::smi_zero());
2572 }
2574 case Token::kSHR:
2575 if (rhs == 0) {
2577 } else if (rhs < 0) {
2578
2580
2581
2582 break;
2583 }
2585 DeoptimizeInstr* deopt =
2586 new DeoptimizeInstr(ICData::kDeoptBinarySmiOp,
GetDeoptId());
2588
2589 return flow_graph->TryCreateConstantReplacementFor(this,
2590 Object::smi_zero());
2591 }
2592 break;
2593
2594 case Token::kSHL: {
2596 if (rhs == 0) {
2600 return flow_graph->TryCreateConstantReplacementFor(this,
2601 Object::smi_zero());
2602 }
else if ((rhs < 0) || ((rhs >= result_bits) && !
is_truncating())) {
2603
2604
2606
2607
2608 break;
2609 }
2611 DeoptimizeInstr* deopt =
2612 new DeoptimizeInstr(ICData::kDeoptBinarySmiOp,
GetDeoptId());
2614
2615 return flow_graph->TryCreateConstantReplacementFor(this,
2616 Object::smi_zero());
2617 }
2618 break;
2619 }
2620
2621 default:
2622 break;
2623 }
2624
2625 return this;
2626}
static BinaryIntegerOpInstr * Make(Representation representation, Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
BinaryIntegerOpInstr(Token::Kind op_kind, Value *left, Value *right, intptr_t deopt_id)
virtual bool CanReplaceWithConstant() const
static constexpr intptr_t kNone
static int64_t TruncateTo(int64_t v, Representation r)
static IntegerPtr BinaryIntegerEvaluate(const Object &left, const Object &right, Token::Kind token_kind, bool is_truncating, Representation representation, Thread *thread)
static bool ToIntegerConstant(Value *value, int64_t *result)
intptr_t GetDeoptId() const
Environment * env() const
bool HasUnmatchedInputRepresentations() const
virtual Representation representation() const
bool CanDeoptimize() const
SpeculativeMode SpeculativeModeOfInputs() const
static IntegerPtr NewCanonical(const String &str)
static RangeBoundary FromConstant(int64_t val)
static bool IsSingleton(Range *range)
static SmiPtr New(intptr_t value)
virtual bool MayThrow() const
static Thread * Current()
static UnaryIntegerOpInstr * Make(Representation representation, Token::Kind op_kind, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode, Range *range)
static constexpr int ShiftForPowerOfTwo(T x)
static constexpr bool IsPowerOfTwo(T x)
Definition * definition() const
static int64_t RepresentationMask(Representation r)
static intptr_t RepresentationBits(Representation r)
static bool IsCommutative(Token::Kind op)
constexpr intptr_t kBitsPerInt64