Skip to content

[CodeGen][RISCV] Add helper class for emitting CFI instructions into MIR #135845

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 16, 2025

Conversation

s-barannikov
Copy link
Contributor

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Apr 15, 2025

@llvm/pr-subscribers-backend-risc-v

Author: Sergei Barannikov (s-barannikov)

Changes

Patch is 23.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135845.diff

2 Files Affected:

  • (added) llvm/include/llvm/CodeGen/CFIInstEmitterHelper.h (+88)
  • (modified) llvm/lib/Target/RISCV/RISCVFrameLowering.cpp (+53-203)
diff --git a/llvm/include/llvm/CodeGen/CFIInstEmitterHelper.h b/llvm/include/llvm/CodeGen/CFIInstEmitterHelper.h
new file mode 100644
index 0000000000000..bcc4c2667d081
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/CFIInstEmitterHelper.h
@@ -0,0 +1,88 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_CFIINSTREMITTERHELPER_H
+#define LLVM_CODEGEN_CFIINSTREMITTERHELPER_H
+
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/MC/MCDwarf.h"
+
+namespace llvm {
+
+/// Helper class for emitting CFI instructions into Machine IR.
+class CFIInstEmitterHelper {
+  MachineFunction &MF;
+  MachineBasicBlock &MBB;
+  MachineBasicBlock::iterator InsertPt;
+
+  /// MIflag to set on a MachineInstr. Typically, FrameSetup or FrameDestroy.
+  MachineInstr::MIFlag MIFlag;
+
+  /// Selects DWARF register numbering: debug or exception handling. Should be
+  /// consistent with the choice of the ELF section (.debug_frame or .eh_frame)
+  /// where CFI will be encoded.
+  bool IsEH;
+
+  // Cache frequently used variables.
+  const TargetRegisterInfo &TRI;
+  const MCInstrDesc &CFIID;
+  const MIMetadata MIMD; // Default-initialized, no debug location desired.
+
+  void emitCFIInstr(const MCCFIInstruction &CFIInst) const {
+    BuildMI(MBB, InsertPt, MIMD, CFIID)
+        .addCFIIndex(MF.addFrameInst(CFIInst))
+        .setMIFlag(MIFlag);
+  }
+
+public:
+  CFIInstEmitterHelper(MachineBasicBlock &MBB,
+                       MachineBasicBlock::iterator InsertPt,
+                       MachineInstr::MIFlag MIFlag, bool IsEH = true)
+      : MF(*MBB.getParent()), MBB(MBB), MIFlag(MIFlag), IsEH(IsEH),
+        TRI(*MF.getSubtarget().getRegisterInfo()),
+        CFIID(MF.getSubtarget().getInstrInfo()->get(
+            TargetOpcode::CFI_INSTRUCTION)) {
+    setInsertPoint(InsertPt);
+  }
+
+  void setInsertPoint(MachineBasicBlock::iterator IP) { InsertPt = IP; }
+
+  void emitDefCFA(MCRegister Reg, int64_t Offset) const {
+    emitCFIInstr(MCCFIInstruction::cfiDefCfa(
+        nullptr, TRI.getDwarfRegNum(Reg, IsEH), Offset));
+  }
+
+  void emitDefCFARegister(MCRegister Reg) const {
+    emitCFIInstr(MCCFIInstruction::createDefCfaRegister(
+        nullptr, TRI.getDwarfRegNum(Reg, IsEH)));
+  }
+
+  void emitDefCFAOffset(int64_t Offset) const {
+    emitCFIInstr(MCCFIInstruction::cfiDefCfaOffset(nullptr, Offset));
+  }
+
+  void emitOffset(MCRegister Reg, int64_t Offset) const {
+    emitCFIInstr(MCCFIInstruction::createOffset(
+        nullptr, TRI.getDwarfRegNum(Reg, IsEH), Offset));
+  }
+
+  void emitRestore(MCRegister Reg) const {
+    emitCFIInstr(MCCFIInstruction::createRestore(
+        nullptr, TRI.getDwarfRegNum(Reg, IsEH)));
+  }
+
+  void emitEscape(StringRef Bytes) const {
+    emitCFIInstr(MCCFIInstruction::createEscape(nullptr, Bytes));
+  }
+};
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_CFIINSTREMITTERHELPER_H
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index c7b2b781422d1..c8ddcc2e46633 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -14,6 +14,7 @@
 #include "RISCVMachineFunctionInfo.h"
 #include "RISCVSubtarget.h"
 #include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/CodeGen/CFIInstEmitterHelper.h"
 #include "llvm/CodeGen/LivePhysRegs.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
@@ -28,64 +29,6 @@
 
 using namespace llvm;
 
-namespace {
-
-class CFISaveRegisterEmitter {
-  MachineFunction &MF;
-  MachineFrameInfo &MFI;
-
-public:
-  CFISaveRegisterEmitter(MachineFunction &MF)
-      : MF{MF}, MFI{MF.getFrameInfo()} {};
-
-  void emit(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
-            const RISCVRegisterInfo &RI, const RISCVInstrInfo &TII,
-            const DebugLoc &DL, const CalleeSavedInfo &CS) const {
-    int FrameIdx = CS.getFrameIdx();
-    int64_t Offset = MFI.getObjectOffset(FrameIdx);
-    MCRegister Reg = CS.getReg();
-    unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
-        nullptr, RI.getDwarfRegNum(Reg, true), Offset));
-    BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlag(MachineInstr::FrameSetup);
-  }
-};
-
-class CFIRestoreRegisterEmitter {
-  MachineFunction &MF;
-
-public:
-  CFIRestoreRegisterEmitter(MachineFunction &MF) : MF{MF} {};
-
-  void emit(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
-            const RISCVRegisterInfo &RI, const RISCVInstrInfo &TII,
-            const DebugLoc &DL, const CalleeSavedInfo &CS) const {
-    MCRegister Reg = CS.getReg();
-    unsigned CFIIndex = MF.addFrameInst(
-        MCCFIInstruction::createRestore(nullptr, RI.getDwarfRegNum(Reg, true)));
-    BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlag(MachineInstr::FrameDestroy);
-  }
-};
-
-} // namespace
-
-template <typename Emitter>
-void RISCVFrameLowering::emitCFIForCSI(
-    MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
-    const SmallVector<CalleeSavedInfo, 8> &CSI) const {
-  MachineFunction *MF = MBB.getParent();
-  const RISCVRegisterInfo *RI = STI.getRegisterInfo();
-  const RISCVInstrInfo *TII = STI.getInstrInfo();
-  DebugLoc DL = MBB.findDebugLoc(MBBI);
-
-  Emitter E{*MF};
-  for (const auto &CS : CSI)
-    E.emit(MBB, MBBI, *RI, *TII, DL, CS);
-}
-
 static Align getABIStackAlignment(RISCVABI::ABI ABI) {
   if (ABI == RISCVABI::ABI_ILP32E)
     return Align(4);
@@ -209,11 +152,8 @@ static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB,
       Offset, // addend (sleb128)
   };
 
-  unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(
-      nullptr, StringRef(CFIInst, sizeof(CFIInst))));
-  BuildMI(MBB, MI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-      .addCFIIndex(CFIIndex)
-      .setMIFlag(MachineInstr::FrameSetup);
+  CFIInstEmitterHelper(MBB, MI, MachineInstr::FrameSetup)
+      .emitEscape(StringRef(CFIInst, sizeof(CFIInst)));
 }
 
 static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB,
@@ -257,11 +197,8 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB,
       .addImm(-SlotSize)
       .setMIFlag(MachineInstr::FrameDestroy);
   // Restore the SCS pointer
-  unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
-      nullptr, STI.getRegisterInfo()->getDwarfRegNum(SCSPReg, /*IsEH*/ true)));
-  BuildMI(MBB, MI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-      .addCFIIndex(CFIIndex)
-      .setMIFlags(MachineInstr::FrameDestroy);
+  CFIInstEmitterHelper(MBB, MI, MachineInstr::FrameDestroy)
+      .emitRestore(SCSPReg);
 }
 
 // Get the ID of the libcall used for spilling and restoring callee saved
@@ -531,14 +468,10 @@ void RISCVFrameLowering::allocateAndProbeStackForRVV(
       .setMIFlag(Flag);
   TII->mulImm(MF, MBB, MBBI, DL, TargetReg, NumOfVReg, Flag);
 
+  CFIInstEmitterHelper CFIHelper(MBB, MBBI, MachineInstr::FrameDestroy);
   if (EmitCFI) {
     // Set the CFA register to TargetReg.
-    unsigned Reg = STI.getRegisterInfo()->getDwarfRegNum(TargetReg, true);
-    unsigned CFIIndex =
-        MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, -Amount));
-    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlags(MachineInstr::FrameSetup);
+    CFIHelper.emitDefCFA(TargetReg, -Amount);
   }
 
   // It will be expanded to a probe loop in `inlineStackProbe`.
@@ -548,12 +481,7 @@ void RISCVFrameLowering::allocateAndProbeStackForRVV(
 
   if (EmitCFI) {
     // Set the CFA register back to SP.
-    unsigned Reg = STI.getRegisterInfo()->getDwarfRegNum(SPReg, true);
-    unsigned CFIIndex =
-        MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
-    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlags(MachineInstr::FrameSetup);
+    CFIHelper.emitDefCFARegister(SPReg);
   }
 
   // SUB SP, SP, T1
@@ -665,20 +593,15 @@ void RISCVFrameLowering::allocateStack(MachineBasicBlock &MBB,
   const RISCVRegisterInfo *RI = STI.getRegisterInfo();
   const RISCVInstrInfo *TII = STI.getInstrInfo();
   bool IsRV64 = STI.is64Bit();
+  CFIInstEmitterHelper CFIHelper(MBB, MBBI, MachineInstr::FrameSetup);
 
   // Simply allocate the stack if it's not big enough to require a probe.
   if (!NeedProbe || Offset <= ProbeSize) {
     RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(-Offset),
                   MachineInstr::FrameSetup, getStackAlign());
 
-    if (EmitCFI) {
-      // Emit ".cfi_def_cfa_offset RealStackSize"
-      unsigned CFIIndex = MF.addFrameInst(
-          MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize));
-      BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-          .addCFIIndex(CFIIndex)
-          .setMIFlag(MachineInstr::FrameSetup);
-    }
+    if (EmitCFI)
+      CFIHelper.emitDefCFAOffset(RealStackSize);
 
     if (NeedProbe && DynAllocation) {
       // s[d|w] zero, 0(sp)
@@ -707,14 +630,8 @@ void RISCVFrameLowering::allocateStack(MachineBasicBlock &MBB,
           .setMIFlags(MachineInstr::FrameSetup);
 
       CurrentOffset += ProbeSize;
-      if (EmitCFI) {
-        // Emit ".cfi_def_cfa_offset CurrentOffset"
-        unsigned CFIIndex = MF.addFrameInst(
-            MCCFIInstruction::cfiDefCfaOffset(nullptr, CurrentOffset));
-        BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-            .addCFIIndex(CFIIndex)
-            .setMIFlag(MachineInstr::FrameSetup);
-      }
+      if (EmitCFI)
+        CFIHelper.emitDefCFAOffset(CurrentOffset);
     }
 
     uint64_t Residual = Offset - CurrentOffset;
@@ -722,14 +639,8 @@ void RISCVFrameLowering::allocateStack(MachineBasicBlock &MBB,
       RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg,
                     StackOffset::getFixed(-Residual), MachineInstr::FrameSetup,
                     getStackAlign());
-      if (EmitCFI) {
-        // Emit ".cfi_def_cfa_offset Offset"
-        unsigned CFIIndex =
-            MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Offset));
-        BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-            .addCFIIndex(CFIIndex)
-            .setMIFlag(MachineInstr::FrameSetup);
-      }
+      if (EmitCFI)
+        CFIHelper.emitDefCFAOffset(Offset);
 
       if (DynAllocation) {
         // s[d|w] zero, 0(sp)
@@ -756,12 +667,7 @@ void RISCVFrameLowering::allocateStack(MachineBasicBlock &MBB,
 
   if (EmitCFI) {
     // Set the CFA register to TargetReg.
-    unsigned Reg = STI.getRegisterInfo()->getDwarfRegNum(TargetReg, true);
-    unsigned CFIIndex =
-        MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, RoundedSize));
-    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlags(MachineInstr::FrameSetup);
+    CFIHelper.emitDefCFA(TargetReg, RoundedSize);
   }
 
   // It will be expanded to a probe loop in `inlineStackProbe`.
@@ -771,12 +677,7 @@ void RISCVFrameLowering::allocateStack(MachineBasicBlock &MBB,
 
   if (EmitCFI) {
     // Set the CFA register back to SP.
-    unsigned Reg = STI.getRegisterInfo()->getDwarfRegNum(SPReg, true);
-    unsigned CFIIndex =
-        MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
-    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlags(MachineInstr::FrameSetup);
+    CFIHelper.emitDefCFARegister(SPReg);
   }
 
   if (Residual) {
@@ -792,14 +693,8 @@ void RISCVFrameLowering::allocateStack(MachineBasicBlock &MBB,
     }
   }
 
-  if (EmitCFI) {
-    // Emit ".cfi_def_cfa_offset Offset"
-    unsigned CFIIndex =
-        MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Offset));
-    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlags(MachineInstr::FrameSetup);
-  }
+  if (EmitCFI)
+    CFIHelper.emitDefCFAOffset(Offset);
 }
 
 static bool isPush(unsigned Opcode) {
@@ -888,6 +783,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
   // callee-saved register.
   MBBI = std::prev(MBBI, getRVVCalleeSavedInfo(MF, CSI).size() +
                              getUnmanagedCSI(MF, CSI).size());
+  CFIInstEmitterHelper CFIHelper(MBB, MBBI, MachineInstr::FrameSetup);
 
   // If libcalls are used to spill and restore callee-saved registers, the frame
   // has two sections; the opaque section managed by the libcalls, and the
@@ -915,14 +811,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
         alignTo((STI.getXLen() / 8) * LibCallRegs, getStackAlign());
     RVFI->setLibCallStackSize(LibCallFrameSize);
 
-    unsigned CFIIndex = MF.addFrameInst(
-        MCCFIInstruction::cfiDefCfaOffset(nullptr, LibCallFrameSize));
-    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlag(MachineInstr::FrameSetup);
-
-    emitCFIForCSI<CFISaveRegisterEmitter>(MBB, MBBI,
-                                          getPushOrLibCallsSavedInfo(MF, CSI));
+    CFIHelper.emitDefCFAOffset(LibCallFrameSize);
+    for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI))
+      CFIHelper.emitOffset(CS.getReg(), MFI.getObjectOffset(CS.getFrameIdx()));
   }
 
   // FIXME (note copied from Lanai): This appears to be overallocating.  Needs
@@ -949,13 +840,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
   }
 
   if (RVFI->useQCIInterrupt(MF)) {
-    unsigned CFIIndex = MF.addFrameInst(
-        MCCFIInstruction::cfiDefCfaOffset(nullptr, QCIInterruptPushAmount));
-    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlag(MachineInstr::FrameSetup);
-
-    emitCFIForCSI<CFISaveRegisterEmitter>(MBB, MBBI, getQCISavedInfo(MF, CSI));
+    CFIHelper.emitDefCFAOffset(QCIInterruptPushAmount);
+    for (const CalleeSavedInfo &CS : getQCISavedInfo(MF, CSI))
+      CFIHelper.emitOffset(CS.getReg(), MFI.getObjectOffset(CS.getFrameIdx()));
   } else if (RVFI->isPushable(MF) && FirstFrameSetup != MBB.end() &&
              isPush(FirstFrameSetup->getOpcode())) {
     // Use available stack adjustment in push instruction to allocate additional
@@ -967,14 +854,9 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
     FirstFrameSetup->getOperand(1).setImm(StackAdj);
     StackSize -= StackAdj;
 
-    unsigned CFIIndex = MF.addFrameInst(
-        MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize - StackSize));
-    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlag(MachineInstr::FrameSetup);
-
-    emitCFIForCSI<CFISaveRegisterEmitter>(MBB, MBBI,
-                                          getPushOrLibCallsSavedInfo(MF, CSI));
+    CFIHelper.emitDefCFAOffset(RealStackSize - StackSize);
+    for (const CalleeSavedInfo &CS : getPushOrLibCallsSavedInfo(MF, CSI))
+      CFIHelper.emitOffset(CS.getReg(), MFI.getObjectOffset(CS.getFrameIdx()));
   }
 
   // Allocate space on the stack if necessary.
@@ -995,10 +877,12 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
   // FIXME: assumes exactly one instruction is used to save each callee-saved
   // register.
   std::advance(MBBI, getUnmanagedCSI(MF, CSI).size());
+  CFIHelper.setInsertPoint(MBBI);
 
   // Iterate over list of callee-saved registers and emit .cfi_offset
   // directives.
-  emitCFIForCSI<CFISaveRegisterEmitter>(MBB, MBBI, getUnmanagedCSI(MF, CSI));
+  for (const CalleeSavedInfo &CS : getUnmanagedCSI(MF, CSI))
+    CFIHelper.emitOffset(CS.getReg(), MFI.getObjectOffset(CS.getFrameIdx()));
 
   // Generate new FP.
   if (hasFP(MF)) {
@@ -1017,12 +901,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
           MachineInstr::FrameSetup, getStackAlign());
     }
 
-    // Emit ".cfi_def_cfa $fp, RVFI->getVarArgsSaveSize()"
-    unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
-        nullptr, RI->getDwarfRegNum(FPReg, true), RVFI->getVarArgsSaveSize()));
-    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex)
-        .setMIFlag(MachineInstr::FrameSetup);
+    CFIHelper.emitDefCFA(FPReg, RVFI->getVarArgsSaveSize());
   }
 
   uint64_t SecondSPAdjustAmount = 0;
@@ -1122,17 +1001,13 @@ void RISCVFrameLowering::deallocateStack(MachineFunction &MF,
                                          uint64_t &StackSize,
                                          int64_t CFAOffset) const {
   const RISCVRegisterInfo *RI = STI.getRegisterInfo();
-  const RISCVInstrInfo *TII = STI.getInstrInfo();
 
   RI->adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackOffset::getFixed(StackSize),
                 MachineInstr::FrameDestroy, getStackAlign());
   StackSize = 0;
 
-  unsigned CFIIndex =
-      MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, CFAOffset));
-  BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-      .addCFIIndex(CFIIndex)
-      .setMIFlag(MachineInstr::FrameDestroy);
+  CFIInstEmitterHelper(MBB, MBBI, MachineInstr::FrameDestroy)
+      .emitDefCFAOffset(CFAOffset);
 }
 
 void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
@@ -1140,7 +1015,6 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
   const RISCVRegisterInfo *RI = STI.getRegisterInfo();
   MachineFrameInfo &MFI = MF.getFrameInfo();
   auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
-  const RISCVInstrInfo *TII = STI.getInstrInfo();
 
   // All calls are tail calls in GHC calling conv, and functions have no
   // prologue/epilogue.
@@ -1171,6 +1045,8 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
   // callee-saved register.
   auto FirstScalarCSRRestoreInsn =
       std::next(MBBI, getRVVCalleeSavedInfo(MF, CSI).size());
+  CFIInstEmitterHelper CFIHelper(MBB, FirstScalarCSRRestoreInsn,
+                                 MachineInstr::FrameDestroy);
 
   uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF);
   uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
@@ -1191,14 +1067,8 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
                     StackOffset::getScalable(RVVStackSize),
                     MachineInstr::FrameDestroy, getStackAlign());
 
-    if (!hasFP(MF)) {
-      unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
-          nullptr, RI->getDwarfRegNum(SPReg, true), RealStackSize));
-      BuildMI(MBB, FirstScalarCSRRestoreInsn, DL,
-              TII->get(TargetOpcode::CFI_INSTRUCTION))
-          .addCFIIndex(CFIIndex)
-          .setMIFlag(MachineInstr::FrameDestroy);
-    }
+    if (!hasFP(MF))
+      CFIHelper.emitDefCFA(SPReg, RealStackSize);
 
     emitCalleeSavedRVVEpilogCFI(MBB, FirstScalarCSRRestoreInsn);
   }
@@ -1216,14 +1086,8 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
                     StackOffset::getFixed(SecondSPAdjustAmount),
                     MachineInstr::FrameDestroy, getStackAlign());
 
-    if (!hasFP(MF)) {
-      unsigned CFIIndex = MF.addFrameInst(
-          MCCFIInstruction::cfiDefCfaOffset(nullptr, FirstSPAdjustAmount));
-      BuildMI(MBB, FirstScalarCSRRestoreInsn, DL,
-              TII->get(TargetOpcode::CFI_INSTRUCTION))
-          .addCFIIndex(CFIIndex)
-          .setMIFlag(MachineInstr::FrameDestroy);
-    }
+    if (!hasFP(MF))
+      CFIHelper.emitDefCFAOffset(FirstSPAdjustAmount);
   }
 
   // Restore the stack pointer using the value of the frame pointer. Only
@@ -1243,19 +1107,14 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
                   getStackAlign());
   }
 
-  if (hasFP(MF)) {
-    unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::cfiDefCfa(
-        nullptr, RI->getDwarfRegNum(SPReg, true), RealStackSize));
-    BuildMI(MBB, FirstScalar...
[truncated]

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@s-barannikov s-barannikov merged commit ed9bcb5 into llvm:main Apr 16, 2025
9 of 11 checks passed
@s-barannikov s-barannikov deleted the cfi/riscv branch April 16, 2025 17:05
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request Apr 16, 2025
s-barannikov added a commit to s-barannikov/llvm-project that referenced this pull request Apr 17, 2025
Don't emit CFI instructions when they will be skipped by AsmPrinter.
Also, use a helper class to simplify emission.

As a side effect, this seems to have unblocked delay slot filler
optimization on some tests, though it is not obvious to me whether
the transformations are legitimate.

Similar to llvm#135845 and llvm#136060.
s-barannikov added a commit to s-barannikov/llvm-project that referenced this pull request Apr 17, 2025
Don't emit CFI instructions when they will be skipped by AsmPrinter.
Also, use a helper class to simplify emission.

As a side effect, this seems to have unblocked delay slot filler
optimization on some tests, though it is not obvious to me whether
the transformations are legitimate.

Similar to llvm#135845 and llvm#136060.
s-barannikov added a commit to s-barannikov/llvm-project that referenced this pull request Apr 17, 2025
Don't emit CFI instructions when they will be skipped by AsmPrinter.
Also, use a helper class to simplify emission.

As a side effect, this seems to have unblocked delay slot filler
optimization on some tests, though it is not obvious to me whether
the transformations are legitimate.

Similar to llvm#135845 and llvm#136060.
var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
var-const pushed a commit to ldionne/llvm-project that referenced this pull request Apr 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants