26
26
27
27
#include " RISCV.h"
28
28
#include " RISCVSubtarget.h"
29
+ #include " llvm/ADT/SetVector.h"
29
30
#include " llvm/ADT/Statistic.h"
30
31
#include " llvm/CodeGen/LiveDebugVariables.h"
31
32
#include " llvm/CodeGen/LiveIntervals.h"
@@ -895,7 +896,8 @@ class RISCVInsertVSETVLI : public MachineFunctionPass {
895
896
896
897
bool canMutatePriorConfig (const MachineInstr &PrevMI, const MachineInstr &MI,
897
898
const DemandedFields &Used) const ;
898
- void coalesceVSETVLIs (MachineBasicBlock &MBB) const ;
899
+ void coalesceVSETVLIs (SetVector<MachineBasicBlock *> &Worklist,
900
+ MachineBasicBlock &MBB) const ;
899
901
900
902
VSETVLIInfo getInfoForVSETVLI (const MachineInstr &MI) const ;
901
903
VSETVLIInfo computeInfoForInstr (const MachineInstr &MI) const ;
@@ -1642,7 +1644,8 @@ bool RISCVInsertVSETVLI::canMutatePriorConfig(
1642
1644
return areCompatibleVTYPEs (PriorVType, VType, Used);
1643
1645
}
1644
1646
1645
- void RISCVInsertVSETVLI::coalesceVSETVLIs (MachineBasicBlock &MBB) const {
1647
+ void RISCVInsertVSETVLI::coalesceVSETVLIs (
1648
+ SetVector<MachineBasicBlock *> &Worklist, MachineBasicBlock &MBB) const {
1646
1649
MachineInstr *NextMI = nullptr ;
1647
1650
// We can have arbitrary code in successors, so VL and VTYPE
1648
1651
// must be considered demanded.
@@ -1661,9 +1664,18 @@ void RISCVInsertVSETVLI::coalesceVSETVLIs(MachineBasicBlock &MBB) const {
1661
1664
LIS->shrinkToUses (&LIS->getInterval (OldVLReg));
1662
1665
1663
1666
MachineInstr *VLOpDef = MRI->getUniqueVRegDef (OldVLReg);
1664
- if (VLOpDef && TII->isAddImmediate (*VLOpDef, OldVLReg) &&
1665
- MRI->use_nodbg_empty (OldVLReg))
1666
- ToDelete.push_back (VLOpDef);
1667
+ if (VLOpDef && MRI->use_nodbg_empty (OldVLReg)) {
1668
+ if (TII->isAddImmediate (*VLOpDef, OldVLReg))
1669
+ ToDelete.push_back (VLOpDef);
1670
+ // If the destination register of a vset* instruction becomes dead because
1671
+ // of this, there might be a chance to eliminate it. Put into the worklist
1672
+ // so that we can revisit it.
1673
+ // Note that since this is a virtual register, the definition instruction
1674
+ // is always placed earlier in the program order. Thus, we avoid
1675
+ // enqueuing blocks in cycle and therefore guarantee to terminate.
1676
+ if (RISCVInstrInfo::isVectorConfigInstr (*VLOpDef))
1677
+ Worklist.insert (VLOpDef->getParent ());
1678
+ }
1667
1679
};
1668
1680
1669
1681
for (MachineInstr &MI : make_early_inc_range (reverse (MBB))) {
@@ -1840,8 +1852,14 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
1840
1852
// any cross block analysis within the dataflow. We can't have both
1841
1853
// demanded fields based mutation and non-local analysis in the
1842
1854
// dataflow at the same time without introducing inconsistencies.
1843
- for (MachineBasicBlock &MBB : MF)
1844
- coalesceVSETVLIs (MBB);
1855
+ using BBPtrIterator = pointer_iterator<MachineFunction::iterator>;
1856
+ SetVector<MachineBasicBlock *> Worklist (BBPtrIterator (MF.begin ()),
1857
+ BBPtrIterator (MF.end ()));
1858
+ while (!Worklist.empty ()) {
1859
+ MachineBasicBlock *MBB = Worklist.front ();
1860
+ Worklist.erase (Worklist.begin ());
1861
+ coalesceVSETVLIs (Worklist, *MBB);
1862
+ }
1845
1863
1846
1864
// Insert PseudoReadVL after VLEFF/VLSEGFF and replace it with the vl output
1847
1865
// of VLEFF/VLSEGFF.
0 commit comments