Skip to content

Commit cbbe613

Browse files
epilkslinder1RamNalamothu
committed
[AMDGPU] Emit entry function Dwarf CFI
Entry functions represent the end of unwinding, as they are the outer-most frame. This implies they can only have a meaningful definition for the CFA, which AMDGPU defines using a memory location description with a literal private address space address. The return address is set to undefined as a sentinel value to signal the end of unwinding. Co-authored-by: Scott Linder <scott.linder@amd.com> Co-authored-by: Venkata Ramanaiah Nalamothu <VenkataRamanaiah.Nalamothu@amd.com>
1 parent b3d52d3 commit cbbe613

26 files changed

+2547
-39
lines changed

llvm/lib/Target/AMDGPU/SIFrameLowering.cpp

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
#include "GCNSubtarget.h"
1313
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
1414
#include "SIMachineFunctionInfo.h"
15+
#include "llvm/BinaryFormat/Dwarf.h"
1516
#include "llvm/CodeGen/LiveRegUnits.h"
1617
#include "llvm/CodeGen/MachineFrameInfo.h"
18+
#include "llvm/CodeGen/MachineModuleInfo.h"
1719
#include "llvm/CodeGen/RegisterScavenging.h"
1820
#include "llvm/Target/TargetMachine.h"
1921

@@ -43,6 +45,15 @@ static MCRegister findUnusedRegister(MachineRegisterInfo &MRI,
4345
return MCRegister();
4446
}
4547

48+
static bool needsFrameMoves(const MachineFunction &MF) {
49+
// FIXME: There are some places in the compiler which are sensitive to the CFI
50+
// pseudos and so using MachineFunction::needsFrameMoves has the unintended
51+
// effect of making enabling debug info affect codegen. Once we have
52+
// identified and fixed those cases this should be replaced with
53+
// MF.needsFrameMoves()
54+
return true;
55+
}
56+
4657
// Find a scratch register that we can use in the prologue. We avoid using
4758
// callee-save registers since they may appear to be free when this is called
4859
// from canUseAsPrologue (during shrink wrapping), but then no longer be free
@@ -615,10 +626,39 @@ void SIFrameLowering::emitEntryFunctionPrologue(MachineFunction &MF,
615626
const SIRegisterInfo *TRI = &TII->getRegisterInfo();
616627
MachineRegisterInfo &MRI = MF.getRegInfo();
617628
const Function &F = MF.getFunction();
629+
const MCRegisterInfo *MCRI = MF.getContext().getRegisterInfo();
618630
MachineFrameInfo &FrameInfo = MF.getFrameInfo();
619631

620632
assert(MFI->isEntryFunction());
621633

634+
// Debug location must be unknown since the first debug location is used to
635+
// determine the end of the prologue.
636+
DebugLoc DL;
637+
MachineBasicBlock::iterator I = MBB.begin();
638+
639+
if (needsFrameMoves(MF)) {
640+
// On entry the SP/FP are not set up, so we need to define the CFA in terms
641+
// of a literal location expression.
642+
static const char CFAEncodedInstUserOpsArr[] = {
643+
dwarf::DW_CFA_def_cfa_expression,
644+
4, // length
645+
static_cast<char>(dwarf::DW_OP_lit0),
646+
static_cast<char>(dwarf::DW_OP_lit0 +
647+
dwarf::DW_ASPACE_LLVM_AMDGPU_private_wave),
648+
static_cast<char>(dwarf::DW_OP_LLVM_user),
649+
static_cast<char>(dwarf::DW_OP_LLVM_form_aspace_address)};
650+
static StringRef CFAEncodedInstUserOps =
651+
StringRef(CFAEncodedInstUserOpsArr, sizeof(CFAEncodedInstUserOpsArr));
652+
buildCFI(MBB, I, DL,
653+
MCCFIInstruction::createEscape(nullptr, CFAEncodedInstUserOps,
654+
SMLoc(),
655+
"CFA is 0 in private_wave aspace"));
656+
// Unwinding halts when the return address (PC) is undefined.
657+
buildCFI(MBB, I, DL,
658+
MCCFIInstruction::createUndefined(
659+
nullptr, MCRI->getDwarfRegNum(AMDGPU::PC_REG, false)));
660+
}
661+
622662
Register PreloadedScratchWaveOffsetReg = MFI->getPreloadedReg(
623663
AMDGPUFunctionArgInfo::PRIVATE_SEGMENT_WAVE_BYTE_OFFSET);
624664

@@ -655,11 +695,6 @@ void SIFrameLowering::emitEntryFunctionPrologue(MachineFunction &MF,
655695
}
656696
}
657697

658-
// Debug location must be unknown since the first debug location is used to
659-
// determine the end of the prologue.
660-
DebugLoc DL;
661-
MachineBasicBlock::iterator I = MBB.begin();
662-
663698
// We found the SRSRC first because it needs four registers and has an
664699
// alignment requirement. If the SRSRC that we found is clobbering with
665700
// the scratch wave offset, which may be in a fixed SGPR or a free SGPR
@@ -2210,3 +2245,15 @@ bool SIFrameLowering::requiresStackPointerReference(
22102245
// references the SP, like variable sized stack objects.
22112246
return frameTriviallyRequiresSP(MFI);
22122247
}
2248+
2249+
MachineInstr *SIFrameLowering::buildCFI(MachineBasicBlock &MBB,
2250+
MachineBasicBlock::iterator MBBI,
2251+
const DebugLoc &DL,
2252+
const MCCFIInstruction &CFIInst,
2253+
MachineInstr::MIFlag flag) const {
2254+
MachineFunction &MF = *MBB.getParent();
2255+
const SIInstrInfo *TII = MF.getSubtarget<GCNSubtarget>().getInstrInfo();
2256+
return BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
2257+
.addCFIIndex(MF.addFrameInst(CFIInst))
2258+
.setMIFlag(flag);
2259+
}

llvm/lib/Target/AMDGPU/SIFrameLowering.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ class SIFrameLowering final : public AMDGPUFrameLowering {
104104
public:
105105
bool requiresStackPointerReference(const MachineFunction &MF) const;
106106

107+
/// Create a CFI index for CFIInst and build a MachineInstr around it.
108+
MachineInstr *
109+
buildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
110+
const DebugLoc &DL, const MCCFIInstruction &CFIInst,
111+
MachineInstr::MIFlag flag = MachineInstr::FrameSetup) const;
112+
107113
// Returns true if the function may need to reserve space on the stack for the
108114
// CWSR trap handler.
109115
bool mayReserveScratchForCWSR(const MachineFunction &MF) const;

0 commit comments

Comments
 (0)