[llvm] [PHIElimination] Handle subranges in LiveInterval updates (PR #69429)
Carl Ritson via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 31 01:13:25 PDT 2023
================
@@ -400,24 +400,50 @@ void PHIElimination::LowerPHINode(MachineBasicBlock &MBB,
}
LiveInterval &DestLI = LIS->getInterval(DestReg);
- assert(!DestLI.empty() && "PHIs should have nonempty LiveIntervals.");
- if (DestLI.endIndex().isDead()) {
- // A dead PHI's live range begins and ends at the start of the MBB, but
- // the lowered copy, which will still be dead, needs to begin and end at
- // the copy instruction.
- VNInfo *OrigDestVNI = DestLI.getVNInfoAt(MBBStartIndex);
- assert(OrigDestVNI && "PHI destination should be live at block entry.");
- DestLI.removeSegment(MBBStartIndex, MBBStartIndex.getDeadSlot());
- DestLI.createDeadDef(DestCopyIndex.getRegSlot(),
- LIS->getVNInfoAllocator());
- DestLI.removeValNo(OrigDestVNI);
- } else {
- // Otherwise, remove the region from the beginning of MBB to the copy
- // instruction from DestReg's live interval.
- DestLI.removeSegment(MBBStartIndex, DestCopyIndex.getRegSlot());
- VNInfo *DestVNI = DestLI.getVNInfoAt(DestCopyIndex.getRegSlot());
+ assert(!DestLI.empty() && "PHIs should have non-empty LiveIntervals.");
+
+ SlotIndex NewStart = DestCopyIndex.getRegSlot();
+
+ SmallVector<LiveRange *> ToUpdate;
+ ToUpdate.push_back(&DestLI);
+ for (auto &SR : DestLI.subranges())
+ ToUpdate.push_back(&SR);
+
+ for (auto LR : ToUpdate) {
+ auto DestSegment = LR->find(MBBStartIndex);
+ assert(DestSegment != LR->end() &&
+ "PHI destination must be live in block");
+
+ if (LR->endIndex().isDead()) {
+ // A dead PHI's live range begins and ends at the start of the MBB, but
+ // the lowered copy, which will still be dead, needs to begin and end at
+ // the copy instruction.
+ VNInfo *OrigDestVNI = LR->getVNInfoAt(DestSegment->start);
+ assert(OrigDestVNI && "PHI destination should be live at block entry.");
+ LR->removeSegment(DestSegment->start, DestSegment->start.getDeadSlot());
+ LR->createDeadDef(NewStart, LIS->getVNInfoAllocator());
+ LR->removeValNo(OrigDestVNI);
+ continue;
+ }
+
+ if (DestSegment->start > NewStart) {
+ // With a single PHI removed from block the index of the copy may be
+ // lower than the original PHI. Extend live range backward to cover
+ // the copy.
----------------
perlfu wrote:
I have moved and reworded this comment for clarity.
There are two details here that matter to understanding this:
* LiveIntervals of PHIs destinations start at the PHI slot index, not the block start.
* Destination copies are not inserted in the order of the PHIs they replace.
Taking the example of the attached test.
Original PHIs look like this:
```
320B %phi0:vgpr_32 = PHI %s0a:vgpr_32, %bb.0, %s0c:vgpr_32, %bb.1
336B %phi1:vgpr_32 = PHI %s0b:vgpr_32, %bb.0, %s0d:vgpr_32, %bb.1
```
With intervals as follows:
```
%6 [112r,208r:0) 0 at 112r weight:0.000000e+00 -- s0a
%7 [128r,224r:0) 0 at 128r weight:0.000000e+00 -- s0b
%8 [208r,256B:0) 0 at 208r weight:0.000000e+00 -- s0c
%9 [224r,256B:0) 0 at 224r weight:0.000000e+00 -- s0d
%10 [320r,384r:0) 0 at 320r weight:0.000000e+00 -- phi0
%11 [336r,384r:0) 0 at 336r weight:0.000000e+00 -- phi1
```
phi0 is lowered, giving the following IR:
```
336B %phi1:vgpr_32 = PHI %s0b:vgpr_32, %bb.0, %s0d:vgpr_32, %bb.1
344B %phi0:vgpr_32 = COPY %12:vgpr_32
```
phi1 is lowered, giving:
```
312B %phi1:vgpr_32 = COPY %13:vgpr_32
344B %phi0:vgpr_32 = COPY %12:vgpr_32
```
Hence COPY for phi0 has index after original PHI, but phi1 has index before original PHI.
https://github.com/llvm/llvm-project/pull/69429
More information about the llvm-commits
mailing list