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() ||
429 (
type->IsNeverType() &&
type->IsLegacy()))
432 EnsureMoreAccurateRedefinition(
433 true_successor,
left,
436 }
437 } else if (comparison->InputAt(0)->BindsToConstant() &&
438 comparison->InputAt(0)->BoundConstant().IsNull()) {
439
440 BlockEntryInstr* true_successor =
441 negated ? instr->true_successor() : instr->false_successor();
442 EnsureMoreAccurateRedefinition(
443 true_successor, comparison->InputAt(1)->definition(),
444 comparison->InputAt(1)->Type()->CopyNonNullable());
445
446 } else if (comparison->InputAt(1)->BindsToConstant() &&
447 comparison->InputAt(1)->BoundConstant().IsNull()) {
448
449 BlockEntryInstr* true_successor =
450 negated ? instr->true_successor() : instr->false_successor();
451 EnsureMoreAccurateRedefinition(
452 true_successor, comparison->InputAt(0)->definition(),
453 comparison->InputAt(0)->Type()->CopyNonNullable());
454 } else if (comparison->InputAt(0)->BindsToConstant() &&
455 comparison->InputAt(0)->BoundConstant().ptr() ==
456 Object::sentinel().ptr()) {
457
458 BlockEntryInstr* true_successor =
459 negated ? instr->true_successor() : instr->false_successor();
460 EnsureMoreAccurateRedefinition(
461 true_successor, comparison->InputAt(1)->definition(),
462 comparison->InputAt(1)->Type()->CopyNonSentinel());
463
464 } else if (comparison->InputAt(1)->BindsToConstant() &&
465 comparison->InputAt(1)->BoundConstant().ptr() ==
466 Object::sentinel().ptr()) {
467
468 BlockEntryInstr* true_successor =
469 negated ? instr->true_successor() : instr->false_successor();
470 EnsureMoreAccurateRedefinition(
471 true_successor, comparison->InputAt(0)->definition(),
472 comparison->InputAt(0)->Type()->CopyNonSentinel());
473 }
474
475}
static bool left(const SkPoint &p0, const SkPoint &p1)
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)