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