@@ -48,10 +48,13 @@ static cl::opt<bool> DisableInsertVSETVLPHIOpt(
48
48
namespace {
49
49
50
50
// / Given a virtual register \p Reg, return the corresponding VNInfo for it.
51
- // / This will return nullptr if the virtual register is an implicit_def.
51
+ // / This will return nullptr if the virtual register is an implicit_def or
52
+ // / if LiveIntervals is not available.
52
53
static VNInfo *getVNInfoFromReg (Register Reg, const MachineInstr &MI,
53
54
const LiveIntervals *LIS) {
54
55
assert (Reg.isVirtual ());
56
+ if (!LIS)
57
+ return nullptr ;
55
58
auto &LI = LIS->getInterval (Reg);
56
59
SlotIndex SI = LIS->getSlotIndexes ()->getInstructionIndex (MI);
57
60
return LI.getVNInfoBefore (SI);
@@ -512,7 +515,8 @@ DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) {
512
515
// / values of the VL and VTYPE registers after insertion.
513
516
class VSETVLIInfo {
514
517
struct AVLDef {
515
- // Every AVLDef should have a VNInfo.
518
+ // Every AVLDef should have a VNInfo, unless we're running without
519
+ // LiveIntervals in which case this will be nullptr.
516
520
const VNInfo *ValNo;
517
521
Register DefReg;
518
522
};
@@ -526,7 +530,7 @@ class VSETVLIInfo {
526
530
AVLIsReg,
527
531
AVLIsImm,
528
532
AVLIsVLMAX,
529
- Unknown,
533
+ Unknown, // AVL and VTYPE are fully unknown
530
534
} State = Uninitialized;
531
535
532
536
// Fields from VTYPE.
@@ -552,7 +556,7 @@ class VSETVLIInfo {
552
556
bool isUnknown () const { return State == Unknown; }
553
557
554
558
void setAVLRegDef (const VNInfo *VNInfo, Register AVLReg) {
555
- assert (VNInfo && AVLReg.isVirtual ());
559
+ assert (AVLReg.isVirtual ());
556
560
AVLRegDef.ValNo = VNInfo;
557
561
AVLRegDef.DefReg = AVLReg;
558
562
State = AVLIsReg;
@@ -582,9 +586,11 @@ class VSETVLIInfo {
582
586
}
583
587
// Most AVLIsReg infos will have a single defining MachineInstr, unless it was
584
588
// a PHI node. In that case getAVLVNInfo()->def will point to the block
585
- // boundary slot.
589
+ // boundary slot. If LiveIntervals isn't available, then nullptr is returned.
586
590
const MachineInstr *getAVLDefMI (const LiveIntervals *LIS) const {
587
591
assert (hasAVLReg ());
592
+ if (!LIS)
593
+ return nullptr ;
588
594
auto *MI = LIS->getInstructionFromIndex (getAVLVNInfo ()->def );
589
595
assert (!(getAVLVNInfo ()->isPHIDef () && MI));
590
596
return MI;
@@ -628,10 +634,15 @@ class VSETVLIInfo {
628
634
return (hasNonZeroAVL (LIS) && Other.hasNonZeroAVL (LIS));
629
635
}
630
636
631
- bool hasSameAVL (const VSETVLIInfo &Other) const {
632
- if (hasAVLReg () && Other.hasAVLReg ())
637
+ bool hasSameAVLLatticeValue (const VSETVLIInfo &Other) const {
638
+ if (hasAVLReg () && Other.hasAVLReg ()) {
639
+ assert (!getAVLVNInfo () == !Other.getAVLVNInfo () &&
640
+ " we either have intervals or we don't" );
641
+ if (!getAVLVNInfo ())
642
+ return getAVLReg () == Other.getAVLReg ();
633
643
return getAVLVNInfo ()->id == Other.getAVLVNInfo ()->id &&
634
644
getAVLReg () == Other.getAVLReg ();
645
+ }
635
646
636
647
if (hasAVLImm () && Other.hasAVLImm ())
637
648
return getAVLImm () == Other.getAVLImm ();
@@ -642,6 +653,21 @@ class VSETVLIInfo {
642
653
return false ;
643
654
}
644
655
656
+ // Return true if the two lattice values are guaranteed to have
657
+ // the same AVL value at runtime.
658
+ bool hasSameAVL (const VSETVLIInfo &Other) const {
659
+ // Without LiveIntervals, we don't know which instruction defines a
660
+ // register. Since a register may be redefined, this means all AVLIsReg
661
+ // states must be treated as possibly distinct.
662
+ if (hasAVLReg () && Other.hasAVLReg ()) {
663
+ assert (!getAVLVNInfo () == !Other.getAVLVNInfo () &&
664
+ " we either have intervals or we don't" );
665
+ if (!getAVLVNInfo ())
666
+ return false ;
667
+ }
668
+ return hasSameAVLLatticeValue (Other);
669
+ }
670
+
645
671
void setVTYPE (unsigned VType) {
646
672
assert (isValid () && !isUnknown () &&
647
673
" Can't set VTYPE for uninitialized or unknown" );
@@ -741,7 +767,7 @@ class VSETVLIInfo {
741
767
if (Other.isUnknown ())
742
768
return isUnknown ();
743
769
744
- if (!hasSameAVL (Other))
770
+ if (!hasSameAVLLatticeValue (Other))
745
771
return false ;
746
772
747
773
// If the SEWLMULRatioOnly bits are different, then they aren't equal.
@@ -849,6 +875,7 @@ class RISCVInsertVSETVLI : public MachineFunctionPass {
849
875
const RISCVSubtarget *ST;
850
876
const TargetInstrInfo *TII;
851
877
MachineRegisterInfo *MRI;
878
+ // Possibly null!
852
879
LiveIntervals *LIS;
853
880
854
881
std::vector<BlockData> BlockInfo;
@@ -863,9 +890,9 @@ class RISCVInsertVSETVLI : public MachineFunctionPass {
863
890
void getAnalysisUsage (AnalysisUsage &AU) const override {
864
891
AU.setPreservesCFG ();
865
892
866
- AU.addRequired <LiveIntervals>();
893
+ AU.addUsedIfAvailable <LiveIntervals>();
867
894
AU.addPreserved <LiveIntervals>();
868
- AU.addRequired <SlotIndexes>();
895
+ AU.addUsedIfAvailable <SlotIndexes>();
869
896
AU.addPreserved <SlotIndexes>();
870
897
AU.addPreserved <LiveDebugVariables>();
871
898
AU.addPreserved <LiveStacks>();
@@ -1061,7 +1088,8 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
1061
1088
.addReg (RISCV::X0, RegState::Kill)
1062
1089
.addImm (Info.encodeVTYPE ())
1063
1090
.addReg (RISCV::VL, RegState::Implicit);
1064
- LIS->InsertMachineInstrInMaps (*MI);
1091
+ if (LIS)
1092
+ LIS->InsertMachineInstrInMaps (*MI);
1065
1093
return ;
1066
1094
}
1067
1095
@@ -1078,7 +1106,8 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
1078
1106
.addReg (RISCV::X0, RegState::Kill)
1079
1107
.addImm (Info.encodeVTYPE ())
1080
1108
.addReg (RISCV::VL, RegState::Implicit);
1081
- LIS->InsertMachineInstrInMaps (*MI);
1109
+ if (LIS)
1110
+ LIS->InsertMachineInstrInMaps (*MI);
1082
1111
return ;
1083
1112
}
1084
1113
}
@@ -1090,7 +1119,8 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
1090
1119
.addReg (RISCV::X0, RegState::Define | RegState::Dead)
1091
1120
.addImm (Info.getAVLImm ())
1092
1121
.addImm (Info.encodeVTYPE ());
1093
- LIS->InsertMachineInstrInMaps (*MI);
1122
+ if (LIS)
1123
+ LIS->InsertMachineInstrInMaps (*MI);
1094
1124
return ;
1095
1125
}
1096
1126
@@ -1100,8 +1130,10 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
1100
1130
.addReg (DestReg, RegState::Define | RegState::Dead)
1101
1131
.addReg (RISCV::X0, RegState::Kill)
1102
1132
.addImm (Info.encodeVTYPE ());
1103
- LIS->InsertMachineInstrInMaps (*MI);
1104
- LIS->createAndComputeVirtRegInterval (DestReg);
1133
+ if (LIS) {
1134
+ LIS->InsertMachineInstrInMaps (*MI);
1135
+ LIS->createAndComputeVirtRegInterval (DestReg);
1136
+ }
1105
1137
return ;
1106
1138
}
1107
1139
@@ -1111,12 +1143,14 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
1111
1143
.addReg (RISCV::X0, RegState::Define | RegState::Dead)
1112
1144
.addReg (AVLReg)
1113
1145
.addImm (Info.encodeVTYPE ());
1114
- LIS->InsertMachineInstrInMaps (*MI);
1115
- // Normally the AVL's live range will already extend past the inserted vsetvli
1116
- // because the pseudos below will already use the AVL. But this isn't always
1117
- // the case, e.g. PseudoVMV_X_S doesn't have an AVL operand.
1118
- LIS->getInterval (AVLReg).extendInBlock (
1119
- LIS->getMBBStartIdx (&MBB), LIS->getInstructionIndex (*MI).getRegSlot ());
1146
+ if (LIS) {
1147
+ LIS->InsertMachineInstrInMaps (*MI);
1148
+ // Normally the AVL's live range will already extend past the inserted
1149
+ // vsetvli because the pseudos below will already use the AVL. But this
1150
+ // isn't always the case, e.g. PseudoVMV_X_S doesn't have an AVL operand.
1151
+ LIS->getInterval (AVLReg).extendInBlock (
1152
+ LIS->getMBBStartIdx (&MBB), LIS->getInstructionIndex (*MI).getRegSlot ());
1153
+ }
1120
1154
}
1121
1155
1122
1156
// / Return true if a VSETVLI is required to transition from CurInfo to Require
@@ -1230,10 +1264,14 @@ void RISCVInsertVSETVLI::transferAfter(VSETVLIInfo &Info,
1230
1264
if (RISCV::isFaultFirstLoad (MI)) {
1231
1265
// Update AVL to vl-output of the fault first load.
1232
1266
assert (MI.getOperand (1 ).getReg ().isVirtual ());
1233
- auto &LI = LIS->getInterval (MI.getOperand (1 ).getReg ());
1234
- SlotIndex SI = LIS->getSlotIndexes ()->getInstructionIndex (MI).getRegSlot ();
1235
- VNInfo *VNI = LI.getVNInfoAt (SI);
1236
- Info.setAVLRegDef (VNI, MI.getOperand (1 ).getReg ());
1267
+ if (LIS) {
1268
+ auto &LI = LIS->getInterval (MI.getOperand (1 ).getReg ());
1269
+ SlotIndex SI =
1270
+ LIS->getSlotIndexes ()->getInstructionIndex (MI).getRegSlot ();
1271
+ VNInfo *VNI = LI.getVNInfoAt (SI);
1272
+ Info.setAVLRegDef (VNI, MI.getOperand (1 ).getReg ());
1273
+ } else
1274
+ Info.setAVLRegDef (nullptr , MI.getOperand (1 ).getReg ());
1237
1275
return ;
1238
1276
}
1239
1277
@@ -1327,6 +1365,9 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
1327
1365
if (!Require.hasAVLReg ())
1328
1366
return true ;
1329
1367
1368
+ if (!LIS)
1369
+ return true ;
1370
+
1330
1371
// We need the AVL to have been produced by a PHI node in this basic block.
1331
1372
const VNInfo *Valno = Require.getAVLVNInfo ();
1332
1373
if (!Valno->isPHIDef () || LIS->getMBBFromIndex (Valno->def ) != &MBB)
@@ -1402,27 +1443,29 @@ void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) {
1402
1443
MachineOperand &VLOp = MI.getOperand (getVLOpNum (MI));
1403
1444
if (VLOp.isReg ()) {
1404
1445
Register Reg = VLOp.getReg ();
1405
- LiveInterval &LI = LIS->getInterval (Reg);
1406
1446
1407
1447
// Erase the AVL operand from the instruction.
1408
1448
VLOp.setReg (RISCV::NoRegister);
1409
1449
VLOp.setIsKill (false );
1410
- SmallVector<MachineInstr *> DeadMIs;
1411
- LIS->shrinkToUses (&LI, &DeadMIs);
1412
- // We might have separate components that need split due to
1413
- // needVSETVLIPHI causing us to skip inserting a new VL def.
1414
- SmallVector<LiveInterval *> SplitLIs;
1415
- LIS->splitSeparateComponents (LI, SplitLIs);
1416
-
1417
- // If the AVL was an immediate > 31, then it would have been emitted
1418
- // as an ADDI. However, the ADDI might not have been used in the
1419
- // vsetvli, or a vsetvli might not have been emitted, so it may be
1420
- // dead now.
1421
- for (MachineInstr *DeadMI : DeadMIs) {
1422
- if (!TII->isAddImmediate (*DeadMI, Reg))
1423
- continue ;
1424
- LIS->RemoveMachineInstrFromMaps (*DeadMI);
1425
- DeadMI->eraseFromParent ();
1450
+ if (LIS) {
1451
+ LiveInterval &LI = LIS->getInterval (Reg);
1452
+ SmallVector<MachineInstr *> DeadMIs;
1453
+ LIS->shrinkToUses (&LI, &DeadMIs);
1454
+ // We might have separate components that need split due to
1455
+ // needVSETVLIPHI causing us to skip inserting a new VL def.
1456
+ SmallVector<LiveInterval *> SplitLIs;
1457
+ LIS->splitSeparateComponents (LI, SplitLIs);
1458
+
1459
+ // If the AVL was an immediate > 31, then it would have been emitted
1460
+ // as an ADDI. However, the ADDI might not have been used in the
1461
+ // vsetvli, or a vsetvli might not have been emitted, so it may be
1462
+ // dead now.
1463
+ for (MachineInstr *DeadMI : DeadMIs) {
1464
+ if (!TII->isAddImmediate (*DeadMI, Reg))
1465
+ continue ;
1466
+ LIS->RemoveMachineInstrFromMaps (*DeadMI);
1467
+ DeadMI->eraseFromParent ();
1468
+ }
1426
1469
}
1427
1470
}
1428
1471
MI.addOperand (MachineOperand::CreateReg (RISCV::VL, /* isDef*/ false ,
@@ -1479,6 +1522,9 @@ void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) {
1479
1522
if (!UnavailablePred || !AvailableInfo.isValid ())
1480
1523
return ;
1481
1524
1525
+ if (!LIS)
1526
+ return ;
1527
+
1482
1528
// If we don't know the exact VTYPE, we can't copy the vsetvli to the exit of
1483
1529
// the unavailable pred.
1484
1530
if (AvailableInfo.hasSEWLMULRatioOnly ())
@@ -1625,7 +1671,7 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
1625
1671
1626
1672
// The def of DefReg moved to MI, so extend the LiveInterval up to
1627
1673
// it.
1628
- if (DefReg.isVirtual ()) {
1674
+ if (DefReg.isVirtual () && LIS ) {
1629
1675
LiveInterval &DefLI = LIS->getInterval (DefReg);
1630
1676
SlotIndex MISlot = LIS->getInstructionIndex (MI).getRegSlot ();
1631
1677
VNInfo *DefVNI = DefLI.getVNInfoAt (DefLI.beginIndex ());
@@ -1654,13 +1700,15 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
1654
1700
1655
1701
if (OldVLReg && OldVLReg.isVirtual ()) {
1656
1702
// NextMI no longer uses OldVLReg so shrink its LiveInterval.
1657
- LIS->shrinkToUses (&LIS->getInterval (OldVLReg));
1703
+ if (LIS)
1704
+ LIS->shrinkToUses (&LIS->getInterval (OldVLReg));
1658
1705
1659
1706
MachineInstr *VLOpDef = MRI->getUniqueVRegDef (OldVLReg);
1660
1707
if (VLOpDef && TII->isAddImmediate (*VLOpDef, OldVLReg) &&
1661
1708
MRI->use_nodbg_empty (OldVLReg)) {
1662
1709
VLOpDef->eraseFromParent ();
1663
- LIS->removeInterval (OldVLReg);
1710
+ if (LIS)
1711
+ LIS->removeInterval (OldVLReg);
1664
1712
}
1665
1713
}
1666
1714
MI.setDesc (NextMI->getDesc ());
@@ -1676,7 +1724,8 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
1676
1724
1677
1725
NumCoalescedVSETVL += ToDelete.size ();
1678
1726
for (auto *MI : ToDelete) {
1679
- LIS->RemoveMachineInstrFromMaps (*MI);
1727
+ if (LIS)
1728
+ LIS->RemoveMachineInstrFromMaps (*MI);
1680
1729
MI->eraseFromParent ();
1681
1730
}
1682
1731
}
@@ -1691,12 +1740,14 @@ void RISCVInsertVSETVLI::insertReadVL(MachineBasicBlock &MBB) {
1691
1740
auto ReadVLMI = BuildMI (MBB, I, MI.getDebugLoc (),
1692
1741
TII->get (RISCV::PseudoReadVL), VLOutput);
1693
1742
// Move the LiveInterval's definition down to PseudoReadVL.
1694
- SlotIndex NewDefSI =
1695
- LIS->InsertMachineInstrInMaps (*ReadVLMI).getRegSlot ();
1696
- LiveInterval &DefLI = LIS->getInterval (VLOutput);
1697
- VNInfo *DefVNI = DefLI.getVNInfoAt (DefLI.beginIndex ());
1698
- DefLI.removeSegment (DefLI.beginIndex (), NewDefSI);
1699
- DefVNI->def = NewDefSI;
1743
+ if (LIS) {
1744
+ SlotIndex NewDefSI =
1745
+ LIS->InsertMachineInstrInMaps (*ReadVLMI).getRegSlot ();
1746
+ LiveInterval &DefLI = LIS->getInterval (VLOutput);
1747
+ VNInfo *DefVNI = DefLI.getVNInfoAt (DefLI.beginIndex ());
1748
+ DefLI.removeSegment (DefLI.beginIndex (), NewDefSI);
1749
+ DefVNI->def = NewDefSI;
1750
+ }
1700
1751
}
1701
1752
// We don't use the vl output of the VLEFF/VLSEGFF anymore.
1702
1753
MI.getOperand (1 ).setReg (RISCV::X0);
@@ -1714,7 +1765,7 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
1714
1765
1715
1766
TII = ST->getInstrInfo ();
1716
1767
MRI = &MF.getRegInfo ();
1717
- LIS = &getAnalysis <LiveIntervals>();
1768
+ LIS = getAnalysisIfAvailable <LiveIntervals>();
1718
1769
1719
1770
assert (BlockInfo.empty () && " Expect empty block infos" );
1720
1771
BlockInfo.resize (MF.getNumBlockIDs ());
0 commit comments