2727#include " RISCV.h"
2828#include " RISCVSubtarget.h"
2929#include " llvm/ADT/Statistic.h"
30- #include " llvm/CodeGen/LiveDebugVariables.h"
3130#include " llvm/CodeGen/LiveIntervals.h"
32- #include " llvm/CodeGen/LiveStacks.h"
3331#include " llvm/CodeGen/MachineFunctionPass.h"
3432#include < queue>
3533using namespace llvm ;
3634
3735#define DEBUG_TYPE " riscv-insert-vsetvli"
3836#define RISCV_INSERT_VSETVLI_NAME " RISC-V Insert VSETVLI pass"
39- #define RISCV_COALESCE_VSETVLI_NAME " RISC-V Coalesce VSETVLI pass"
4037
4138STATISTIC (NumInsertedVSETVL, " Number of VSETVL inst inserted" );
42- STATISTIC (NumCoalescedVSETVL , " Number of VSETVL inst coalesced " );
39+ STATISTIC (NumRemovedVSETVL , " Number of VSETVL inst removed " );
4340
4441static cl::opt<bool > DisableInsertVSETVLPHIOpt (
4542 " riscv-disable-insert-vsetvl-phi-opt" , cl::init(false ), cl::Hidden,
@@ -193,11 +190,6 @@ static bool hasUndefinedMergeOp(const MachineInstr &MI,
193190 if (UseMO.getReg () == RISCV::NoRegister)
194191 return true ;
195192
196- if (UseMO.isUndef ())
197- return true ;
198- if (UseMO.getReg ().isPhysical ())
199- return false ;
200-
201193 if (MachineInstr *UseMI = MRI.getVRegDef (UseMO.getReg ())) {
202194 if (UseMI->isImplicitDef ())
203195 return true ;
@@ -788,52 +780,18 @@ class RISCVInsertVSETVLI : public MachineFunctionPass {
788780 VSETVLIInfo &Info) const ;
789781 void computeIncomingVLVTYPE (const MachineBasicBlock &MBB);
790782 void emitVSETVLIs (MachineBasicBlock &MBB);
783+ void doLocalPostpass (MachineBasicBlock &MBB);
791784 void doPRE (MachineBasicBlock &MBB);
792785 void insertReadVL (MachineBasicBlock &MBB);
793786};
794787
795- class RISCVCoalesceVSETVLI : public MachineFunctionPass {
796- public:
797- static char ID;
798- const RISCVSubtarget *ST;
799- const TargetInstrInfo *TII;
800- MachineRegisterInfo *MRI;
801- LiveIntervals *LIS;
802-
803- RISCVCoalesceVSETVLI () : MachineFunctionPass(ID) {}
804- bool runOnMachineFunction (MachineFunction &MF) override ;
805-
806- void getAnalysisUsage (AnalysisUsage &AU) const override {
807- AU.setPreservesCFG ();
808-
809- AU.addRequired <LiveIntervals>();
810- AU.addPreserved <LiveIntervals>();
811- AU.addRequired <SlotIndexes>();
812- AU.addPreserved <SlotIndexes>();
813- AU.addPreserved <LiveDebugVariables>();
814- AU.addPreserved <LiveStacks>();
815-
816- MachineFunctionPass::getAnalysisUsage (AU);
817- }
818-
819- StringRef getPassName () const override { return RISCV_COALESCE_VSETVLI_NAME; }
820-
821- private:
822- bool coalesceVSETVLIs (MachineBasicBlock &MBB);
823- };
824-
825788} // end anonymous namespace
826789
827790char RISCVInsertVSETVLI::ID = 0 ;
828791
829792INITIALIZE_PASS (RISCVInsertVSETVLI, DEBUG_TYPE, RISCV_INSERT_VSETVLI_NAME,
830793 false , false )
831794
832- char RISCVCoalesceVSETVLI::ID = 0;
833-
834- INITIALIZE_PASS (RISCVCoalesceVSETVLI, " riscv-coalesce-vsetvli" ,
835- RISCV_COALESCE_VSETVLI_NAME, false , false )
836-
837795// Return a VSETVLIInfo representing the changes made by this VSETVLI or
838796// VSETIVLI instruction.
839797static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) {
@@ -1557,12 +1515,12 @@ static bool canMutatePriorConfig(const MachineInstr &PrevMI,
15571515
15581516 auto &AVL = MI.getOperand (1 );
15591517 auto &PrevAVL = PrevMI.getOperand (1 );
1518+ assert (MRI.isSSA ());
15601519
15611520 // If the AVL is a register, we need to make sure MI's AVL dominates PrevMI.
15621521 // For now just check that PrevMI uses the same virtual register.
15631522 if (AVL.isReg () && AVL.getReg () != RISCV::X0 &&
1564- (!MRI.hasOneDef (AVL.getReg ()) || !PrevAVL.isReg () ||
1565- PrevAVL.getReg () != AVL.getReg ()))
1523+ (!PrevAVL.isReg () || PrevAVL.getReg () != AVL.getReg ()))
15661524 return false ;
15671525 }
15681526
@@ -1572,7 +1530,7 @@ static bool canMutatePriorConfig(const MachineInstr &PrevMI,
15721530 return areCompatibleVTYPEs (PriorVType, VType, Used);
15731531}
15741532
1575- bool RISCVCoalesceVSETVLI::coalesceVSETVLIs (MachineBasicBlock &MBB) {
1533+ void RISCVInsertVSETVLI::doLocalPostpass (MachineBasicBlock &MBB) {
15761534 MachineInstr *NextMI = nullptr ;
15771535 // We can have arbitrary code in successors, so VL and VTYPE
15781536 // must be considered demanded.
@@ -1605,49 +1563,20 @@ bool RISCVCoalesceVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) {
16051563
16061564 if (canMutatePriorConfig (MI, *NextMI, Used, *MRI)) {
16071565 if (!isVLPreservingConfig (*NextMI)) {
1608- Register DefReg = NextMI->getOperand (0 ).getReg ();
1609-
1610- MI.getOperand (0 ).setReg (DefReg);
1566+ MI.getOperand (0 ).setReg (NextMI->getOperand (0 ).getReg ());
16111567 MI.getOperand (0 ).setIsDead (false );
1612-
1613- // The def of DefReg moved to MI, so extend the LiveInterval up to
1614- // it.
1615- if (DefReg.isVirtual ()) {
1616- LiveInterval &DefLI = LIS->getInterval (DefReg);
1617- SlotIndex MISlot = LIS->getInstructionIndex (MI).getRegSlot ();
1618- VNInfo *DefVNI = DefLI.getVNInfoAt (DefLI.beginIndex ());
1619- LiveInterval::Segment S (MISlot, DefLI.beginIndex (), DefVNI);
1620- DefLI.addSegment (S);
1621- DefVNI->def = MISlot;
1622- // Mark DefLI as spillable if it was previously unspillable
1623- DefLI.setWeight (0 );
1624-
1625- // DefReg may have had no uses, in which case we need to shrink
1626- // the LiveInterval up to MI.
1627- LIS->shrinkToUses (&DefLI);
1628- }
1629-
16301568 Register OldVLReg;
16311569 if (MI.getOperand (1 ).isReg ())
16321570 OldVLReg = MI.getOperand (1 ).getReg ();
16331571 if (NextMI->getOperand (1 ).isImm ())
16341572 MI.getOperand (1 ).ChangeToImmediate (NextMI->getOperand (1 ).getImm ());
16351573 else
16361574 MI.getOperand (1 ).ChangeToRegister (NextMI->getOperand (1 ).getReg (), false );
1637-
1638- // Clear NextMI's AVL early so we're not counting it as a use.
1639- if (NextMI->getOperand (1 ).isReg ())
1640- NextMI->getOperand (1 ).setReg (RISCV::NoRegister);
1641-
16421575 if (OldVLReg) {
16431576 MachineInstr *VLOpDef = MRI->getUniqueVRegDef (OldVLReg);
16441577 if (VLOpDef && TII->isAddImmediate (*VLOpDef, OldVLReg) &&
16451578 MRI->use_nodbg_empty (OldVLReg))
16461579 VLOpDef->eraseFromParent ();
1647-
1648- // NextMI no longer uses OldVLReg so shrink its LiveInterval.
1649- if (OldVLReg.isVirtual ())
1650- LIS->shrinkToUses (&LIS->getInterval (OldVLReg));
16511580 }
16521581 MI.setDesc (NextMI->getDesc ());
16531582 }
@@ -1660,13 +1589,9 @@ bool RISCVCoalesceVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) {
16601589 Used = getDemanded (MI, MRI, ST);
16611590 }
16621591
1663- NumCoalescedVSETVL += ToDelete.size ();
1664- for (auto *MI : ToDelete) {
1665- LIS->RemoveMachineInstrFromMaps (*MI);
1592+ NumRemovedVSETVL += ToDelete.size ();
1593+ for (auto *MI : ToDelete)
16661594 MI->eraseFromParent ();
1667- }
1668-
1669- return !ToDelete.empty ();
16701595}
16711596
16721597void RISCVInsertVSETVLI::insertReadVL (MachineBasicBlock &MBB) {
@@ -1741,6 +1666,15 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
17411666 for (MachineBasicBlock &MBB : MF)
17421667 emitVSETVLIs (MBB);
17431668
1669+ // Now that all vsetvlis are explicit, go through and do block local
1670+ // DSE and peephole based demanded fields based transforms. Note that
1671+ // this *must* be done outside the main dataflow so long as we allow
1672+ // any cross block analysis within the dataflow. We can't have both
1673+ // demanded fields based mutation and non-local analysis in the
1674+ // dataflow at the same time without introducing inconsistencies.
1675+ for (MachineBasicBlock &MBB : MF)
1676+ doLocalPostpass (MBB);
1677+
17441678 // Insert PseudoReadVL after VLEFF/VLSEGFF and replace it with the vl output
17451679 // of VLEFF/VLSEGFF.
17461680 for (MachineBasicBlock &MBB : MF)
@@ -1754,29 +1688,3 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
17541688FunctionPass *llvm::createRISCVInsertVSETVLIPass () {
17551689 return new RISCVInsertVSETVLI ();
17561690}
1757-
1758- // Now that all vsetvlis are explicit, go through and do block local
1759- // DSE and peephole based demanded fields based transforms. Note that
1760- // this *must* be done outside the main dataflow so long as we allow
1761- // any cross block analysis within the dataflow. We can't have both
1762- // demanded fields based mutation and non-local analysis in the
1763- // dataflow at the same time without introducing inconsistencies.
1764- bool RISCVCoalesceVSETVLI::runOnMachineFunction (MachineFunction &MF) {
1765- // Skip if the vector extension is not enabled.
1766- ST = &MF.getSubtarget <RISCVSubtarget>();
1767- if (!ST->hasVInstructions ())
1768- return false ;
1769- TII = ST->getInstrInfo ();
1770- MRI = &MF.getRegInfo ();
1771- LIS = &getAnalysis<LiveIntervals>();
1772-
1773- bool Changed = false ;
1774- for (MachineBasicBlock &MBB : MF)
1775- Changed |= coalesceVSETVLIs (MBB);
1776-
1777- return Changed;
1778- }
1779-
1780- FunctionPass *llvm::createRISCVCoalesceVSETVLIPass () {
1781- return new RISCVCoalesceVSETVLI ();
1782- }
0 commit comments