386 {
387 StrictCompareInstr* comparison = instr->comparison()->AsStrictCompare();
388 if (comparison == nullptr) return;
389 bool negated = comparison->kind() == Token::kNE_STRICT;
390 LoadClassIdInstr* load_cid =
391 comparison->InputAt(0)->definition()->AsLoadClassId();
392 InstanceCallInstr*
call =
393 comparison->InputAt(0)->definition()->AsInstanceCall();
394 InstanceOfInstr* instance_of =
395 comparison->InputAt(0)->definition()->AsInstanceOf();
396 bool is_simple_instance_of =
397 (
call !=
nullptr) &&
call->MatchesCoreName(Symbols::_simpleInstanceOf());
398 if (load_cid != nullptr && comparison->InputAt(1)->BindsToConstant()) {
399 intptr_t
cid = Smi::Cast(comparison->InputAt(1)->BoundConstant()).Value();
400 BlockEntryInstr* true_successor =
401 negated ? instr->false_successor() : instr->true_successor();
402 EnsureMoreAccurateRedefinition(true_successor,
403 load_cid->object()->definition(),
405 } else if ((is_simple_instance_of || (instance_of != nullptr)) &&
406 comparison->InputAt(1)->BindsToConstant() &&
407 comparison->InputAt(1)->BoundConstant().IsBool()) {
408 if (comparison->InputAt(1)->BoundConstant().ptr() ==
Bool::False().
ptr()) {
409 negated = !negated;
410 }
411 BlockEntryInstr* true_successor =
412 negated ? instr->false_successor() : instr->true_successor();
413 const AbstractType*
type =
nullptr;
414 Definition*
left =
nullptr;
415 if (is_simple_instance_of) {
417 const Object& type_obj =
call->ArgumentAt(1)->AsConstant()->value();
418 if (!type_obj.IsType()) {
419 return;
420 }
421 type = &Type::Cast(type_obj);
423 } else {
424 type = &(instance_of->type());
425 left = instance_of->value()->definition();
426 }
427 if (!
type->IsTopTypeForInstanceOf()) {
428 const bool is_nullable = (
type->IsNullable() ||
type->IsTypeParameter())
431 EnsureMoreAccurateRedefinition(
432 true_successor, left,
435 }
436 } else if (comparison->InputAt(0)->BindsToConstant() &&
437 comparison->InputAt(0)->BoundConstant().IsNull()) {
438
439 BlockEntryInstr* true_successor =
440 negated ? instr->true_successor() : instr->false_successor();
441 EnsureMoreAccurateRedefinition(
442 true_successor, comparison->InputAt(1)->definition(),
443 comparison->InputAt(1)->Type()->CopyNonNullable());
444
445 } else if (comparison->InputAt(1)->BindsToConstant() &&
446 comparison->InputAt(1)->BoundConstant().IsNull()) {
447
448 BlockEntryInstr* true_successor =
449 negated ? instr->true_successor() : instr->false_successor();
450 EnsureMoreAccurateRedefinition(
451 true_successor, comparison->InputAt(0)->definition(),
452 comparison->InputAt(0)->Type()->CopyNonNullable());
453 } else if (comparison->InputAt(0)->BindsToConstant() &&
454 comparison->InputAt(0)->BoundConstant().ptr() ==
455 Object::sentinel().ptr()) {
456
457 BlockEntryInstr* true_successor =
458 negated ? instr->true_successor() : instr->false_successor();
459 EnsureMoreAccurateRedefinition(
460 true_successor, comparison->InputAt(1)->definition(),
461 comparison->InputAt(1)->Type()->CopyNonSentinel());
462
463 } else if (comparison->InputAt(1)->BindsToConstant() &&
464 comparison->InputAt(1)->BoundConstant().ptr() ==
465 Object::sentinel().ptr()) {
466
467 BlockEntryInstr* true_successor =
468 negated ? instr->true_successor() : instr->false_successor();
469 EnsureMoreAccurateRedefinition(
470 true_successor, comparison->InputAt(0)->definition(),
471 comparison->InputAt(0)->Type()->CopyNonSentinel());
472 }
473
474}
static const Bool & False()
static CompileType FromCid(intptr_t cid)
static constexpr bool kCannotBeSentinel
static constexpr bool kCannotBeNull
static constexpr bool kCanBeNull
static CompileType FromAbstractType(const AbstractType &type, bool can_be_null, bool can_be_sentinel)