@@ -48,10 +48,13 @@ static cl::opt<bool> DisableInsertVSETVLPHIOpt(
4848namespace {
4949
5050// / 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.
5253static VNInfo *getVNInfoFromReg (Register Reg, const MachineInstr &MI,
5354 const LiveIntervals *LIS) {
5455 assert (Reg.isVirtual ());
56+ if (!LIS)
57+ return nullptr ;
5558 auto &LI = LIS->getInterval (Reg);
5659 SlotIndex SI = LIS->getSlotIndexes ()->getInstructionIndex (MI);
5760 return LI.getVNInfoBefore (SI);
@@ -512,7 +515,8 @@ DemandedFields getDemanded(const MachineInstr &MI, const RISCVSubtarget *ST) {
512515// / values of the VL and VTYPE registers after insertion.
513516class VSETVLIInfo {
514517 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.
516520 const VNInfo *ValNo;
517521 Register DefReg;
518522 };
@@ -526,7 +530,7 @@ class VSETVLIInfo {
526530 AVLIsReg,
527531 AVLIsImm,
528532 AVLIsVLMAX,
529- Unknown,
533+ Unknown, // AVL and VTYPE are fully unknown
530534 } State = Uninitialized;
531535
532536 // Fields from VTYPE.
@@ -552,7 +556,7 @@ class VSETVLIInfo {
552556 bool isUnknown () const { return State == Unknown; }
553557
554558 void setAVLRegDef (const VNInfo *VNInfo, Register AVLReg) {
555- assert (VNInfo && AVLReg.isVirtual ());
559+ assert (AVLReg.isVirtual ());
556560 AVLRegDef.ValNo = VNInfo;
557561 AVLRegDef.DefReg = AVLReg;
558562 State = AVLIsReg;
@@ -582,9 +586,11 @@ class VSETVLIInfo {
582586 }
583587 // Most AVLIsReg infos will have a single defining MachineInstr, unless it was
584588 // 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.
586590 const MachineInstr *getAVLDefMI (const LiveIntervals *LIS) const {
587591 assert (hasAVLReg ());
592+ if (!LIS)
593+ return nullptr ;
588594 auto *MI = LIS->getInstructionFromIndex (getAVLVNInfo ()->def );
589595 assert (!(getAVLVNInfo ()->isPHIDef () && MI));
590596 return MI;
@@ -628,10 +634,15 @@ class VSETVLIInfo {
628634 return (hasNonZeroAVL (LIS) && Other.hasNonZeroAVL (LIS));
629635 }
630636
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 ();
633643 return getAVLVNInfo ()->id == Other.getAVLVNInfo ()->id &&
634644 getAVLReg () == Other.getAVLReg ();
645+ }
635646
636647 if (hasAVLImm () && Other.hasAVLImm ())
637648 return getAVLImm () == Other.getAVLImm ();
@@ -642,6 +653,21 @@ class VSETVLIInfo {
642653 return false ;
643654 }
644655
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+
645671 void setVTYPE (unsigned VType) {
646672 assert (isValid () && !isUnknown () &&
647673 " Can't set VTYPE for uninitialized or unknown" );
@@ -741,7 +767,7 @@ class VSETVLIInfo {
741767 if (Other.isUnknown ())
742768 return isUnknown ();
743769
744- if (!hasSameAVL (Other))
770+ if (!hasSameAVLLatticeValue (Other))
745771 return false ;
746772
747773 // If the SEWLMULRatioOnly bits are different, then they aren't equal.
@@ -849,6 +875,7 @@ class RISCVInsertVSETVLI : public MachineFunctionPass {
849875 const RISCVSubtarget *ST;
850876 const TargetInstrInfo *TII;
851877 MachineRegisterInfo *MRI;
878+ // Possibly null!
852879 LiveIntervals *LIS;
853880
854881 std::vector<BlockData> BlockInfo;
@@ -863,9 +890,9 @@ class RISCVInsertVSETVLI : public MachineFunctionPass {
863890 void getAnalysisUsage (AnalysisUsage &AU) const override {
864891 AU.setPreservesCFG ();
865892
866- AU.addRequired <LiveIntervals>();
893+ AU.addUsedIfAvailable <LiveIntervals>();
867894 AU.addPreserved <LiveIntervals>();
868- AU.addRequired <SlotIndexes>();
895+ AU.addUsedIfAvailable <SlotIndexes>();
869896 AU.addPreserved <SlotIndexes>();
870897 AU.addPreserved <LiveDebugVariables>();
871898 AU.addPreserved <LiveStacks>();
@@ -1061,7 +1088,8 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
10611088 .addReg (RISCV::X0, RegState::Kill)
10621089 .addImm (Info.encodeVTYPE ())
10631090 .addReg (RISCV::VL, RegState::Implicit);
1064- LIS->InsertMachineInstrInMaps (*MI);
1091+ if (LIS)
1092+ LIS->InsertMachineInstrInMaps (*MI);
10651093 return ;
10661094 }
10671095
@@ -1078,7 +1106,8 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
10781106 .addReg (RISCV::X0, RegState::Kill)
10791107 .addImm (Info.encodeVTYPE ())
10801108 .addReg (RISCV::VL, RegState::Implicit);
1081- LIS->InsertMachineInstrInMaps (*MI);
1109+ if (LIS)
1110+ LIS->InsertMachineInstrInMaps (*MI);
10821111 return ;
10831112 }
10841113 }
@@ -1090,7 +1119,8 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
10901119 .addReg (RISCV::X0, RegState::Define | RegState::Dead)
10911120 .addImm (Info.getAVLImm ())
10921121 .addImm (Info.encodeVTYPE ());
1093- LIS->InsertMachineInstrInMaps (*MI);
1122+ if (LIS)
1123+ LIS->InsertMachineInstrInMaps (*MI);
10941124 return ;
10951125 }
10961126
@@ -1100,8 +1130,10 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
11001130 .addReg (DestReg, RegState::Define | RegState::Dead)
11011131 .addReg (RISCV::X0, RegState::Kill)
11021132 .addImm (Info.encodeVTYPE ());
1103- LIS->InsertMachineInstrInMaps (*MI);
1104- LIS->createAndComputeVirtRegInterval (DestReg);
1133+ if (LIS) {
1134+ LIS->InsertMachineInstrInMaps (*MI);
1135+ LIS->createAndComputeVirtRegInterval (DestReg);
1136+ }
11051137 return ;
11061138 }
11071139
@@ -1111,12 +1143,14 @@ void RISCVInsertVSETVLI::insertVSETVLI(MachineBasicBlock &MBB,
11111143 .addReg (RISCV::X0, RegState::Define | RegState::Dead)
11121144 .addReg (AVLReg)
11131145 .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+ }
11201154}
11211155
11221156// / Return true if a VSETVLI is required to transition from CurInfo to Require
@@ -1230,10 +1264,14 @@ void RISCVInsertVSETVLI::transferAfter(VSETVLIInfo &Info,
12301264 if (RISCV::isFaultFirstLoad (MI)) {
12311265 // Update AVL to vl-output of the fault first load.
12321266 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 ());
12371275 return ;
12381276 }
12391277
@@ -1327,6 +1365,9 @@ bool RISCVInsertVSETVLI::needVSETVLIPHI(const VSETVLIInfo &Require,
13271365 if (!Require.hasAVLReg ())
13281366 return true ;
13291367
1368+ if (!LIS)
1369+ return true ;
1370+
13301371 // We need the AVL to have been produced by a PHI node in this basic block.
13311372 const VNInfo *Valno = Require.getAVLVNInfo ();
13321373 if (!Valno->isPHIDef () || LIS->getMBBFromIndex (Valno->def ) != &MBB)
@@ -1402,27 +1443,29 @@ void RISCVInsertVSETVLI::emitVSETVLIs(MachineBasicBlock &MBB) {
14021443 MachineOperand &VLOp = MI.getOperand (getVLOpNum (MI));
14031444 if (VLOp.isReg ()) {
14041445 Register Reg = VLOp.getReg ();
1405- LiveInterval &LI = LIS->getInterval (Reg);
14061446
14071447 // Erase the AVL operand from the instruction.
14081448 VLOp.setReg (RISCV::NoRegister);
14091449 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+ }
14261469 }
14271470 }
14281471 MI.addOperand (MachineOperand::CreateReg (RISCV::VL, /* isDef*/ false ,
@@ -1479,6 +1522,9 @@ void RISCVInsertVSETVLI::doPRE(MachineBasicBlock &MBB) {
14791522 if (!UnavailablePred || !AvailableInfo.isValid ())
14801523 return ;
14811524
1525+ if (!LIS)
1526+ return ;
1527+
14821528 // If we don't know the exact VTYPE, we can't copy the vsetvli to the exit of
14831529 // the unavailable pred.
14841530 if (AvailableInfo.hasSEWLMULRatioOnly ())
@@ -1625,7 +1671,7 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
16251671
16261672 // The def of DefReg moved to MI, so extend the LiveInterval up to
16271673 // it.
1628- if (DefReg.isVirtual ()) {
1674+ if (DefReg.isVirtual () && LIS ) {
16291675 LiveInterval &DefLI = LIS->getInterval (DefReg);
16301676 SlotIndex MISlot = LIS->getInstructionIndex (MI).getRegSlot ();
16311677 VNInfo *DefVNI = DefLI.getVNInfoAt (DefLI.beginIndex ());
@@ -1654,13 +1700,15 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
16541700
16551701 if (OldVLReg && OldVLReg.isVirtual ()) {
16561702 // NextMI no longer uses OldVLReg so shrink its LiveInterval.
1657- LIS->shrinkToUses (&LIS->getInterval (OldVLReg));
1703+ if (LIS)
1704+ LIS->shrinkToUses (&LIS->getInterval (OldVLReg));
16581705
16591706 MachineInstr *VLOpDef = MRI->getUniqueVRegDef (OldVLReg);
16601707 if (VLOpDef && TII->isAddImmediate (*VLOpDef, OldVLReg) &&
16611708 MRI->use_nodbg_empty (OldVLReg)) {
16621709 VLOpDef->eraseFromParent ();
1663- LIS->removeInterval (OldVLReg);
1710+ if (LIS)
1711+ LIS->removeInterval (OldVLReg);
16641712 }
16651713 }
16661714 MI.setDesc (NextMI->getDesc ());
@@ -1676,7 +1724,8 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
16761724
16771725 NumCoalescedVSETVL += ToDelete.size ();
16781726 for (auto *MI : ToDelete) {
1679- LIS->RemoveMachineInstrFromMaps (*MI);
1727+ if (LIS)
1728+ LIS->RemoveMachineInstrFromMaps (*MI);
16801729 MI->eraseFromParent ();
16811730 }
16821731}
@@ -1691,12 +1740,14 @@ void RISCVInsertVSETVLI::insertReadVL(MachineBasicBlock &MBB) {
16911740 auto ReadVLMI = BuildMI (MBB, I, MI.getDebugLoc (),
16921741 TII->get (RISCV::PseudoReadVL), VLOutput);
16931742 // 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+ }
17001751 }
17011752 // We don't use the vl output of the VLEFF/VLSEGFF anymore.
17021753 MI.getOperand (1 ).setReg (RISCV::X0);
@@ -1714,7 +1765,7 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
17141765
17151766 TII = ST->getInstrInfo ();
17161767 MRI = &MF.getRegInfo ();
1717- LIS = &getAnalysis <LiveIntervals>();
1768+ LIS = getAnalysisIfAvailable <LiveIntervals>();
17181769
17191770 assert (BlockInfo.empty () && " Expect empty block infos" );
17201771 BlockInfo.resize (MF.getNumBlockIDs ());
0 commit comments