[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