@@ -433,36 +433,45 @@ void Optimizer::insertLifetime(Value *ptr, Constant *sz, Instruction *orig)
433
433
abort ();
434
434
}
435
435
#endif
436
- // Record extra BBs that contain invisible uses.
436
+
437
+ // Record extra BBs that contain invisible uses with gc_preserve_{begin,end}.
438
+ // We traverse the dominator tree starting at each `gc_preserve_begin` and marking blocks
439
+ // as users until a corresponding `gc_preserve_end` is found. Blocks containing
440
+ // the `gc_preserve_end` have already been marked in the previous step.
437
441
SmallSet<BasicBlock*, 8 > extra_use;
438
442
SmallVector<DomTreeNodeBase<BasicBlock>*, 8 > dominated;
439
443
for (auto preserve: use_info.preserves ) {
440
- for (auto RN = DT.getNode (preserve->getParent ()); RN;
441
- RN = dominated.empty () ? nullptr : dominated.pop_back_val ()) {
442
- for (auto N: *RN) {
443
- auto bb = N->getBlock ();
444
- if (extra_use.count (bb))
445
- continue ;
446
- bool ended = false ;
447
- for (auto end: preserve->users ()) {
448
- auto end_bb = cast<Instruction>(end)->getParent ();
449
- auto end_node = DT.getNode (end_bb);
450
- if (end_bb == bb || (end_node && DT.dominates (end_node, N))) {
451
- ended = true ;
452
- break ;
453
- }
444
+ assert (dominated.empty ());
445
+ dominated.push_back (DT.getNode (preserve->getParent ()));
446
+ while (!dominated.empty ()) {
447
+ auto N = dominated.pop_back_val ();
448
+ if (!N) {
449
+ dominated.clear ();
450
+ break ;
451
+ }
452
+ auto bb = N->getBlock ();
453
+ if (extra_use.count (bb))
454
+ continue ;
455
+ bool ended = false ;
456
+ for (auto end: preserve->users ()) {
457
+ auto end_bb = cast<Instruction>(end)->getParent ();
458
+ auto end_node = DT.getNode (end_bb);
459
+ if (end_bb == bb || (end_node && DT.dominates (end_node, N))) {
460
+ ended = true ;
461
+ break ;
454
462
}
455
- if (ended)
456
- continue ;
457
- bbs.insert (bb);
458
- extra_use.insert (bb);
459
- dominated.push_back (N);
460
463
}
464
+ if (ended)
465
+ continue ;
466
+ bbs.insert (bb);
467
+ extra_use.insert (bb);
468
+ dominated.append (N->begin (), N->end ());
461
469
}
462
- assert (dominated.empty ());
463
470
}
471
+
464
472
// For each BB, find the first instruction(s) where the allocation is possibly dead.
465
473
// If all successors are live, then there isn't one.
474
+ // If the BB has "invisible" uses, then there isn't one.
466
475
// If all successors are dead, then it's the first instruction after the last use
467
476
// within the BB.
468
477
// If some successors are live and others are dead, it's the first instruction in
0 commit comments