27
27
#include " RISCV.h"
28
28
#include " RISCVSubtarget.h"
29
29
#include " llvm/ADT/Statistic.h"
30
- #include " llvm/CodeGen/LiveDebugVariables.h"
31
30
#include " llvm/CodeGen/LiveIntervals.h"
32
- #include " llvm/CodeGen/LiveStacks.h"
33
31
#include " llvm/CodeGen/MachineFunctionPass.h"
34
32
#include < queue>
35
33
using namespace llvm ;
36
34
37
35
#define DEBUG_TYPE " riscv-insert-vsetvli"
38
36
#define RISCV_INSERT_VSETVLI_NAME " RISC-V Insert VSETVLI pass"
39
- #define RISCV_COALESCE_VSETVLI_NAME " RISC-V Coalesce VSETVLI pass"
40
37
41
38
STATISTIC (NumInsertedVSETVL, " Number of VSETVL inst inserted" );
42
- STATISTIC (NumCoalescedVSETVL , " Number of VSETVL inst coalesced " );
39
+ STATISTIC (NumRemovedVSETVL , " Number of VSETVL inst removed " );
43
40
44
41
static cl::opt<bool > DisableInsertVSETVLPHIOpt (
45
42
" riscv-disable-insert-vsetvl-phi-opt" , cl::init(false ), cl::Hidden,
@@ -193,11 +190,6 @@ static bool hasUndefinedMergeOp(const MachineInstr &MI,
193
190
if (UseMO.getReg () == RISCV::NoRegister)
194
191
return true ;
195
192
196
- if (UseMO.isUndef ())
197
- return true ;
198
- if (UseMO.getReg ().isPhysical ())
199
- return false ;
200
-
201
193
if (MachineInstr *UseMI = MRI.getVRegDef (UseMO.getReg ())) {
202
194
if (UseMI->isImplicitDef ())
203
195
return true ;
@@ -788,52 +780,18 @@ class RISCVInsertVSETVLI : public MachineFunctionPass {
788
780
VSETVLIInfo &Info) const ;
789
781
void computeIncomingVLVTYPE (const MachineBasicBlock &MBB);
790
782
void emitVSETVLIs (MachineBasicBlock &MBB);
783
+ void doLocalPostpass (MachineBasicBlock &MBB);
791
784
void doPRE (MachineBasicBlock &MBB);
792
785
void insertReadVL (MachineBasicBlock &MBB);
793
786
};
794
787
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
-
825
788
} // end anonymous namespace
826
789
827
790
char RISCVInsertVSETVLI::ID = 0 ;
828
791
829
792
INITIALIZE_PASS (RISCVInsertVSETVLI, DEBUG_TYPE, RISCV_INSERT_VSETVLI_NAME,
830
793
false , false )
831
794
832
- char RISCVCoalesceVSETVLI::ID = 0;
833
-
834
- INITIALIZE_PASS (RISCVCoalesceVSETVLI, " riscv-coalesce-vsetvli" ,
835
- RISCV_COALESCE_VSETVLI_NAME, false , false )
836
-
837
795
// Return a VSETVLIInfo representing the changes made by this VSETVLI or
838
796
// VSETIVLI instruction.
839
797
static VSETVLIInfo getInfoForVSETVLI(const MachineInstr &MI) {
@@ -1557,12 +1515,12 @@ static bool canMutatePriorConfig(const MachineInstr &PrevMI,
1557
1515
1558
1516
auto &AVL = MI.getOperand (1 );
1559
1517
auto &PrevAVL = PrevMI.getOperand (1 );
1518
+ assert (MRI.isSSA ());
1560
1519
1561
1520
// If the AVL is a register, we need to make sure MI's AVL dominates PrevMI.
1562
1521
// For now just check that PrevMI uses the same virtual register.
1563
1522
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 ()))
1566
1524
return false ;
1567
1525
}
1568
1526
@@ -1572,7 +1530,7 @@ static bool canMutatePriorConfig(const MachineInstr &PrevMI,
1572
1530
return areCompatibleVTYPEs (PriorVType, VType, Used);
1573
1531
}
1574
1532
1575
- bool RISCVCoalesceVSETVLI::coalesceVSETVLIs (MachineBasicBlock &MBB) {
1533
+ void RISCVInsertVSETVLI::doLocalPostpass (MachineBasicBlock &MBB) {
1576
1534
MachineInstr *NextMI = nullptr ;
1577
1535
// We can have arbitrary code in successors, so VL and VTYPE
1578
1536
// must be considered demanded.
@@ -1605,49 +1563,20 @@ bool RISCVCoalesceVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) {
1605
1563
1606
1564
if (canMutatePriorConfig (MI, *NextMI, Used, *MRI)) {
1607
1565
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 ());
1611
1567
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
-
1630
1568
Register OldVLReg;
1631
1569
if (MI.getOperand (1 ).isReg ())
1632
1570
OldVLReg = MI.getOperand (1 ).getReg ();
1633
1571
if (NextMI->getOperand (1 ).isImm ())
1634
1572
MI.getOperand (1 ).ChangeToImmediate (NextMI->getOperand (1 ).getImm ());
1635
1573
else
1636
1574
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
-
1642
1575
if (OldVLReg) {
1643
1576
MachineInstr *VLOpDef = MRI->getUniqueVRegDef (OldVLReg);
1644
1577
if (VLOpDef && TII->isAddImmediate (*VLOpDef, OldVLReg) &&
1645
1578
MRI->use_nodbg_empty (OldVLReg))
1646
1579
VLOpDef->eraseFromParent ();
1647
-
1648
- // NextMI no longer uses OldVLReg so shrink its LiveInterval.
1649
- if (OldVLReg.isVirtual ())
1650
- LIS->shrinkToUses (&LIS->getInterval (OldVLReg));
1651
1580
}
1652
1581
MI.setDesc (NextMI->getDesc ());
1653
1582
}
@@ -1660,13 +1589,9 @@ bool RISCVCoalesceVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) {
1660
1589
Used = getDemanded (MI, MRI, ST);
1661
1590
}
1662
1591
1663
- NumCoalescedVSETVL += ToDelete.size ();
1664
- for (auto *MI : ToDelete) {
1665
- LIS->RemoveMachineInstrFromMaps (*MI);
1592
+ NumRemovedVSETVL += ToDelete.size ();
1593
+ for (auto *MI : ToDelete)
1666
1594
MI->eraseFromParent ();
1667
- }
1668
-
1669
- return !ToDelete.empty ();
1670
1595
}
1671
1596
1672
1597
void RISCVInsertVSETVLI::insertReadVL (MachineBasicBlock &MBB) {
@@ -1741,6 +1666,15 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
1741
1666
for (MachineBasicBlock &MBB : MF)
1742
1667
emitVSETVLIs (MBB);
1743
1668
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
+
1744
1678
// Insert PseudoReadVL after VLEFF/VLSEGFF and replace it with the vl output
1745
1679
// of VLEFF/VLSEGFF.
1746
1680
for (MachineBasicBlock &MBB : MF)
@@ -1754,29 +1688,3 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
1754
1688
FunctionPass *llvm::createRISCVInsertVSETVLIPass () {
1755
1689
return new RISCVInsertVSETVLI ();
1756
1690
}
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