[llvm] Rebased save csr in ra (PR #131845)

Michael Maitland via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 18 10:26:56 PDT 2025


================
@@ -786,6 +788,153 @@ void RISCVFrameLowering::allocateStack(MachineBasicBlock &MBB,
   }
 }
 
+struct CFIBuildInfo {
+  MachineBasicBlock *MBB;
+  MachineInstr *InsertAfterMI; // nullptr means insert at MBB.begin()
+  DebugLoc DL;
+  unsigned CFIIndex;
+};
+
+static void trackRegisterAndEmitCFIs(
+    MachineFunction &MF, MachineInstr &MI, MCRegister Reg, int DwarfEHRegNum,
+    const ReachingDefAnalysis &RDA, const TargetInstrInfo &TII,
+    const MachineFrameInfo &MFI, const RISCVRegisterInfo &TRI,
+    std::vector<CFIBuildInfo> &CFIBuildInfos,
+    std::unordered_set<MachineInstr *> &VisitedRestorePoints,
+    std::unordered_set<MachineInstr *> &VisitedDefs) {
+
+  if (VisitedRestorePoints.find(&MI) != VisitedRestorePoints.end()) {
+    return;
+  }
+  VisitedRestorePoints.insert(&MI);
+  SmallPtrSet<MachineInstr *, 2> Defs;
+  RDA.getGlobalReachingDefs(&MI, Reg, Defs);
+  MachineBasicBlock &EntryMBB = MF.front();
+  if (Defs.empty()) {
+    // it's a live-in register at the entry block.
+    // unsigned CFIIndex =
+    // MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr,
+    // DwarfEHRegNum)); CFIBuildInfos.push_back({&EntryMBB, nullptr, DebugLoc(),
+    // CFIIndex});
+    return;
+  }
+
+  int FrameIndex = std::numeric_limits<int>::min();
+  for (MachineInstr *Def : Defs) {
+    if (VisitedDefs.find(Def) != VisitedDefs.end())
+      continue;
+    VisitedDefs.insert(Def);
+
+    MachineBasicBlock &MBB = *Def->getParent();
+    const DebugLoc &DL = Def->getDebugLoc();
+
+    if (Register StoredReg = TII.isStoreToStackSlot(*Def, FrameIndex)) {
+      assert(FrameIndex == Register::stackSlot2Index(Reg));
+
+      Register FrameReg;
+      StackOffset Offset =
+          MF.getSubtarget().getFrameLowering()->getFrameIndexReference(
+              MF, FrameIndex, FrameReg);
+      int64_t FixedOffset = Offset.getFixed();
+      // TODO:
+      assert(Offset.getScalable() == 0);
+
+      std::string CommentBuffer;
+      llvm::raw_string_ostream Comment(CommentBuffer);
+      int DwarfEHFrameReg = TRI.getDwarfRegNum(FrameReg, true);
+      Register LLVMReg = *TRI.getLLVMRegNum(DwarfEHRegNum, true);
+      Comment << printReg(LLVMReg, &TRI) << " = *(";
+      Comment << printReg(FrameReg, &TRI) << " + ";
+      Comment << FixedOffset << ")";
+      unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createLLVMRegOffset(
+          nullptr, DwarfEHRegNum, DwarfEHFrameReg, FixedOffset, SMLoc(), Comment.str()));
+
+      CFIBuildInfos.push_back({&MBB, Def, DL, CFIIndex});
+      trackRegisterAndEmitCFIs(MF, *Def, StoredReg, DwarfEHRegNum, RDA, TII,
+                               MFI, TRI, CFIBuildInfos, VisitedRestorePoints,
+                               VisitedDefs);
+    } else if (Register LoadedReg = TII.isLoadFromStackSlot(*Def, FrameIndex)) {
+      assert(LoadedReg == Reg);
+
+      unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRegister(
+          nullptr, DwarfEHRegNum, TRI.getDwarfRegNum(LoadedReg, true)));
+      CFIBuildInfos.push_back({&MBB, Def, DL, CFIIndex});
+      trackRegisterAndEmitCFIs(MF, *Def, Register::index2StackSlot(FrameIndex),
+                               DwarfEHRegNum, RDA, TII, MFI, TRI, CFIBuildInfos,
+                               VisitedRestorePoints, VisitedDefs);
+    } else if (auto DstSrc = TII.isCopyInstr(*Def)) {
+      Register DstReg = DstSrc->Destination->getReg();
+      Register SrcReg = DstSrc->Source->getReg();
+      assert(DstReg == Reg);
+
+      unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRegister(
+          nullptr, DwarfEHRegNum, TRI.getDwarfRegNum(DstReg, true)));
+      CFIBuildInfos.push_back({&MBB, Def, DL, CFIIndex});
+      trackRegisterAndEmitCFIs(MF, *Def, SrcReg, DwarfEHRegNum, RDA, TII, MFI,
+                               TRI, CFIBuildInfos, VisitedRestorePoints,
+                               VisitedDefs);
+    } else {
+      llvm_unreachable("Unexpected instruction");
+    }
+  }
+  return;
+}
+
+int RISCVFrameLowering::getInitialCFAOffset(const MachineFunction &MF) const {
----------------
michaelmaitland wrote:

Is this used? I assume its used somewhere in the CFIInserter already. I'm trying to understand why we didn't need to implement these before wanting to do SaveCSRInRA.

https://github.com/llvm/llvm-project/pull/131845


More information about the llvm-commits mailing list