[llvm] [RISCV] Separate doLocalPostpass into new pass and move to post vector regalloc (PR #88295)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 10 09:51:21 PDT 2024
================
@@ -1682,3 +1651,121 @@ bool RISCVInsertVSETVLI::runOnMachineFunction(MachineFunction &MF) {
FunctionPass *llvm::createRISCVInsertVSETVLIPass() {
return new RISCVInsertVSETVLI();
}
+
+// Now that all vsetvlis are explicit, go through and do block local
+// DSE and peephole based demanded fields based transforms. Note that
+// this *must* be done outside the main dataflow so long as we allow
+// any cross block analysis within the dataflow. We can't have both
+// demanded fields based mutation and non-local analysis in the
+// dataflow at the same time without introducing inconsistencies.
+bool RISCVCoalesceVSETVLI::runOnMachineFunction(MachineFunction &MF) {
+ // Skip if the vector extension is not enabled.
+ auto *ST = &MF.getSubtarget<RISCVSubtarget>();
+ if (!ST->hasVInstructions())
+ return false;
+
+ LiveIntervals &LIS = getAnalysis<LiveIntervals>();
+
+ bool Changed = false;
+
+ const auto *TII = ST->getInstrInfo();
+ auto *MRI = &MF.getRegInfo();
+ for (MachineBasicBlock &MBB : MF) {
+ MachineInstr *NextMI = nullptr;
+ // We can have arbitrary code in successors, so VL and VTYPE
+ // must be considered demanded.
+ DemandedFields Used;
+ Used.demandVL();
+ Used.demandVTYPE();
+ SmallVector<MachineInstr *> ToDelete;
+ for (MachineInstr &MI : make_range(MBB.rbegin(), MBB.rend())) {
+
+ if (!isVectorConfigInstr(MI)) {
+ doUnion(Used, getDemanded(MI, MRI, ST));
+ continue;
+ }
+
+ Register VRegDef = MI.getOperand(0).getReg();
+ if (VRegDef != RISCV::X0 &&
+ !(VRegDef.isVirtual() && MRI->use_nodbg_empty(VRegDef)))
+ Used.demandVL();
+
+ if (NextMI) {
+ if (!Used.usedVL() && !Used.usedVTYPE()) {
+ ToDelete.push_back(&MI);
+ // Leave NextMI unchanged
+ continue;
+ } else if (canMutatePriorConfig(MI, *NextMI, Used, *MRI)) {
+ if (!isVLPreservingConfig(*NextMI)) {
+
+ Register DefReg = NextMI->getOperand(0).getReg();
+
+ MI.getOperand(0).setReg(DefReg);
+ MI.getOperand(0).setIsDead(false);
+
+ // The def of DefReg moved to MI, so extend the LiveInterval up to
+ // it.
+ if (DefReg.isVirtual()) {
+ LiveInterval &DefLI = LIS.getInterval(DefReg);
+ SlotIndex MISlot = LIS.getInstructionIndex(MI).getRegSlot();
+ VNInfo *DefVNI = DefLI.getVNInfoAt(DefLI.beginIndex());
+ LiveInterval::Segment S(MISlot, DefLI.beginIndex(), DefVNI);
+ DefLI.addSegment(S);
+ DefVNI->def = MISlot;
+
+ // DefReg may have had no uses, in which case we need to shrink
+ // the LiveInterval up to MI.
+ LIS.shrinkToUses(&DefLI);
+ }
+
+ Register OldVLReg;
+ if (MI.getOperand(1).isReg())
+ OldVLReg = MI.getOperand(1).getReg();
+ if (NextMI->getOperand(1).isImm())
+ MI.getOperand(1).ChangeToImmediate(
+ NextMI->getOperand(1).getImm());
+ else
+ MI.getOperand(1).ChangeToRegister(NextMI->getOperand(1).getReg(),
+ false);
+
+ // Clear NextMI's AVL early so we're not counting it as a use.
+ if (NextMI->getOperand(1).isReg())
+ NextMI->getOperand(1).setReg(RISCV::NoRegister);
+
+ if (OldVLReg) {
+ MachineInstr *VLOpDef = MRI->getUniqueVRegDef(OldVLReg);
+ if (VLOpDef && TII->isAddImmediate(*VLOpDef, OldVLReg) &&
+ MRI->use_nodbg_empty(OldVLReg)) {
+ VLOpDef->eraseFromParent();
+ }
+
+ // NextMI no longer uses OldVLReg so shrink its LiveInterval.
+ if (OldVLReg.isVirtual())
+ LIS.shrinkToUses(&LIS.getInterval(OldVLReg));
+ }
+
+ MI.setDesc(NextMI->getDesc());
+ }
+ MI.getOperand(2).setImm(NextMI->getOperand(2).getImm());
+ ToDelete.push_back(NextMI);
+ // fallthrough
+ }
+ }
+ NextMI = &MI;
+ Used = getDemanded(MI, MRI, ST);
+ }
+
+ Changed |= !ToDelete.empty();
+ NumCoalescedVSETVL += ToDelete.size();
+ for (auto *MI : ToDelete) {
+ LIS.RemoveMachineInstrFromMaps(*MI);
----------------
lukel97 wrote:
And here
https://github.com/llvm/llvm-project/pull/88295
More information about the llvm-commits
mailing list