Skip to content

[ARM] Use helper class for emitting CFI instructions into MIR #135994

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 1 commit into from
Apr 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions llvm/include/llvm/CodeGen/CFIInstBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class CFIInstBuilder {
setInsertPoint(InsertPt);
}

CFIInstBuilder(MachineBasicBlock *MBB, MachineInstr::MIFlag MIFlag,
bool IsEH = true)
: CFIInstBuilder(*MBB, MBB->end(), MIFlag, IsEH) {}

void setInsertPoint(MachineBasicBlock::iterator IP) { InsertPt = IP; }

void insertCFIInst(const MCCFIInstruction &CFIInst) const {
Expand Down Expand Up @@ -72,11 +76,27 @@ class CFIInstBuilder {
nullptr, TRI.getDwarfRegNum(Reg, IsEH), Offset));
}

void buildRegister(MCRegister Reg1, MCRegister Reg2) const {
insertCFIInst(MCCFIInstruction::createRegister(
nullptr, TRI.getDwarfRegNum(Reg1, IsEH),
TRI.getDwarfRegNum(Reg2, IsEH)));
}

void buildRestore(MCRegister Reg) const {
insertCFIInst(MCCFIInstruction::createRestore(
nullptr, TRI.getDwarfRegNum(Reg, IsEH)));
}

void buildUndefined(MCRegister Reg) const {
insertCFIInst(MCCFIInstruction::createUndefined(
nullptr, TRI.getDwarfRegNum(Reg, IsEH)));
}

void buildSameValue(MCRegister Reg) const {
insertCFIInst(MCCFIInstruction::createSameValue(
nullptr, TRI.getDwarfRegNum(Reg, IsEH)));
}

void buildEscape(StringRef Bytes, StringRef Comment = "") const {
insertCFIInst(
MCCFIInstruction::createEscape(nullptr, Bytes, SMLoc(), Comment));
Expand Down
89 changes: 14 additions & 75 deletions llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/CFIInstBuilder.h"
#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
Expand Down Expand Up @@ -6485,51 +6486,20 @@ void ARMBaseInstrInfo::saveLROnStack(MachineBasicBlock &MBB,
if (!CFI)
return;

MachineFunction &MF = *MBB.getParent();

// Add a CFI, saying CFA is offset by Align bytes from SP.
int64_t StackPosEntry =
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Align));
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
.addCFIIndex(StackPosEntry)
.setMIFlags(MachineInstr::FrameSetup);
CFIInstBuilder CFIBuilder(MBB, It, MachineInstr::FrameSetup);
CFIBuilder.buildDefCFAOffset(Align);

// Add a CFI saying that the LR that we want to find is now higher than
// before.
int LROffset = Auth ? Align - 4 : Align;
const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
int64_t LRPosEntry = MF.addFrameInst(
MCCFIInstruction::createOffset(nullptr, DwarfLR, -LROffset));
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
.addCFIIndex(LRPosEntry)
.setMIFlags(MachineInstr::FrameSetup);
CFIBuilder.buildOffset(ARM::LR, -LROffset);
if (Auth) {
// Add a CFI for the location of the return adddress PAC.
unsigned DwarfRAC = MRI->getDwarfRegNum(ARM::RA_AUTH_CODE, true);
int64_t RACPosEntry = MF.addFrameInst(
MCCFIInstruction::createOffset(nullptr, DwarfRAC, -Align));
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
.addCFIIndex(RACPosEntry)
.setMIFlags(MachineInstr::FrameSetup);
CFIBuilder.buildOffset(ARM::RA_AUTH_CODE, -Align);
}
}

void ARMBaseInstrInfo::emitCFIForLRSaveToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator It,
Register Reg) const {
MachineFunction &MF = *MBB.getParent();
const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true);

int64_t LRPosEntry = MF.addFrameInst(
MCCFIInstruction::createRegister(nullptr, DwarfLR, DwarfReg));
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
.addCFIIndex(LRPosEntry)
.setMIFlags(MachineInstr::FrameSetup);
}

void ARMBaseInstrInfo::restoreLRFromStack(MachineBasicBlock &MBB,
MachineBasicBlock::iterator It,
bool CFI, bool Auth) const {
Expand Down Expand Up @@ -6560,50 +6530,18 @@ void ARMBaseInstrInfo::restoreLRFromStack(MachineBasicBlock &MBB,
}

if (CFI) {
// Now stack has moved back up...
MachineFunction &MF = *MBB.getParent();
const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);
int64_t StackPosEntry =
MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 0));
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
.addCFIIndex(StackPosEntry)
.setMIFlags(MachineInstr::FrameDestroy);

// ... and we have restored LR.
int64_t LRPosEntry =
MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, DwarfLR));
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
.addCFIIndex(LRPosEntry)
.setMIFlags(MachineInstr::FrameDestroy);

if (Auth) {
unsigned DwarfRAC = MRI->getDwarfRegNum(ARM::RA_AUTH_CODE, true);
int64_t Entry =
MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, DwarfRAC));
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
.addCFIIndex(Entry)
.setMIFlags(MachineInstr::FrameDestroy);
}
// Now stack has moved back up and we have restored LR.
CFIInstBuilder CFIBuilder(MBB, It, MachineInstr::FrameDestroy);
CFIBuilder.buildDefCFAOffset(0);
CFIBuilder.buildRestore(ARM::LR);
if (Auth)
CFIBuilder.buildUndefined(ARM::RA_AUTH_CODE);
}

if (Auth)
BuildMI(MBB, It, DebugLoc(), get(ARM::t2AUT));
}

void ARMBaseInstrInfo::emitCFIForLRRestoreFromReg(
MachineBasicBlock &MBB, MachineBasicBlock::iterator It) const {
MachineFunction &MF = *MBB.getParent();
const MCRegisterInfo *MRI = Subtarget.getRegisterInfo();
unsigned DwarfLR = MRI->getDwarfRegNum(ARM::LR, true);

int64_t LRPosEntry =
MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, DwarfLR));
BuildMI(MBB, It, DebugLoc(), get(ARM::CFI_INSTRUCTION))
.addCFIIndex(LRPosEntry)
.setMIFlags(MachineInstr::FrameDestroy);
}

void ARMBaseInstrInfo::buildOutlinedFrame(
MachineBasicBlock &MBB, MachineFunction &MF,
const outliner::OutlinedFunction &OF) const {
Expand Down Expand Up @@ -6722,11 +6660,12 @@ MachineBasicBlock::iterator ARMBaseInstrInfo::insertOutlinedCall(
// Save and restore LR from that register.
copyPhysReg(MBB, It, DebugLoc(), Reg, ARM::LR, true);
if (!AFI.isLRSpilled())
emitCFIForLRSaveToReg(MBB, It, Reg);
CFIInstBuilder(MBB, It, MachineInstr::FrameSetup)
.buildRegister(ARM::LR, Reg);
CallPt = MBB.insert(It, CallMIB);
copyPhysReg(MBB, It, DebugLoc(), ARM::LR, Reg, true);
if (!AFI.isLRSpilled())
emitCFIForLRRestoreFromReg(MBB, It);
CFIInstBuilder(MBB, It, MachineInstr::FrameDestroy).buildRestore(ARM::LR);
Comment on lines +6663 to +6668
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These probably don't need FrameSetup/FrameDestroy, but that's what the original code does, and I wanted to keep this PR NFC-ish.

It--;
return CallPt;
}
Expand Down
10 changes: 0 additions & 10 deletions llvm/lib/Target/ARM/ARMBaseInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,16 +409,6 @@ class ARMBaseInstrInfo : public ARMGenInstrInfo {
MachineBasicBlock::iterator It, bool CFI,
bool Auth) const;

/// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It,
/// for the case when the LR is saved in the register \p Reg.
void emitCFIForLRSaveToReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator It,
Register Reg) const;

/// Emit CFI instructions into the MachineBasicBlock \p MBB at position \p It,
/// after the LR is was restored from a register.
void emitCFIForLRRestoreFromReg(MachineBasicBlock &MBB,
MachineBasicBlock::iterator It) const;
/// \brief Sets the offsets on outlined instructions in \p MBB which use SP
/// so that they will be valid post-outlining.
///
Expand Down
Loading
Loading