423 {
424 GrowableArray<Definition*>
worklist(calls_->length());
425 BitVector processed(graph->zone(), graph->current_ssa_temp_index());
426
427 auto add_to_worklist = [&](Definition* defn) {
428 ASSERT(defn->HasSSATemp());
429 const auto ssa_index = defn->ssa_temp_index();
430 if (ssa_index < processed.length() && !processed.Contains(ssa_index)) {
431 processed.Add(ssa_index);
433 return true;
434 }
435 return false;
436 };
437
438 auto add_transitive_dependencies_to_worklist = [&](intptr_t from_index) {
439
440
441
442
443 for (intptr_t
i = from_index;
i <
worklist.length();
i++) {
445 for (auto input : defn->inputs()) {
446 add_to_worklist(input);
447 }
448
449
450 ASSERT(defn->ArgumentCount() == 0 || !defn->HasMoveArguments());
451 }
452 };
453
454
455
456
457 for (auto& call_info : *calls_) {
458
459
460
461 if (call_info.call->HasSSATemp()) {
462 add_to_worklist(call_info.call);
463 } else {
465 }
466 }
468 add_transitive_dependencies_to_worklist(0);
469
470
471
472
473
474
475 bool changed = false;
476 intptr_t last_unhandled_call_index = calls_->length() - 1;
479
480
481
482 CallInfo<InstanceCallInstr>* call_info = nullptr;
483 if (
worklist.length() == last_unhandled_call_index) {
484 call_info = &(*calls_)[last_unhandled_call_index];
486 last_unhandled_call_index--;
487 }
488
489
490 if (defn->HasUnmatchedInputRepresentations() &&
492 continue;
493 }
494
495 auto replacement = defn->Canonicalize(graph);
496 if (replacement != defn) {
497 changed = true;
498 if (replacement != nullptr) {
499 defn->ReplaceUsesWith(replacement);
500 if (replacement->ssa_temp_index() == -1) {
501 graph->EnsureSSATempIndex(defn, replacement);
502 }
503
504
505 if (add_to_worklist(replacement)) {
506 add_transitive_dependencies_to_worklist(
worklist.length() - 1);
507 }
508
509
510
511
512
513
514
515
516
517
518 const bool newly_inserted =
519 replacement->ssa_temp_index() >= processed.length();
520 if (call_info != nullptr && replacement->IsStaticCall() &&
521 newly_inserted) {
522 HandleDevirtualization(call_info,
523 replacement->Cast<StaticCallInstr>());
524 }
525 }
526 if (auto phi = defn->AsPhi()) {
527 phi->UnuseAllInputs();
528 phi->block()->RemovePhi(phi);
529 } else {
530 defn->RemoveFromGraph();
531 }
532 }
533 }
534
535 if (changed) {
540 }
541 }
#define RELEASE_ASSERT(cond)
static void PruneRemovedCallsIn(GrowableArray< CallInfo< CallType > > *arr)