|
12 | 12 | #include "GCNSubtarget.h" |
13 | 13 | #include "MCTargetDesc/AMDGPUMCTargetDesc.h" |
14 | 14 | #include "SIMachineFunctionInfo.h" |
| 15 | +#include "llvm/BinaryFormat/Dwarf.h" |
15 | 16 | #include "llvm/CodeGen/LiveRegUnits.h" |
16 | 17 | #include "llvm/CodeGen/MachineFrameInfo.h" |
| 18 | +#include "llvm/CodeGen/MachineModuleInfo.h" |
17 | 19 | #include "llvm/CodeGen/RegisterScavenging.h" |
18 | 20 | #include "llvm/Target/TargetMachine.h" |
19 | 21 |
|
@@ -43,6 +45,15 @@ static MCRegister findUnusedRegister(MachineRegisterInfo &MRI, |
43 | 45 | return MCRegister(); |
44 | 46 | } |
45 | 47 |
|
| 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 | + |
46 | 57 | // Find a scratch register that we can use in the prologue. We avoid using |
47 | 58 | // callee-save registers since they may appear to be free when this is called |
48 | 59 | // from canUseAsPrologue (during shrink wrapping), but then no longer be free |
@@ -615,10 +626,39 @@ void SIFrameLowering::emitEntryFunctionPrologue(MachineFunction &MF, |
615 | 626 | const SIRegisterInfo *TRI = &TII->getRegisterInfo(); |
616 | 627 | MachineRegisterInfo &MRI = MF.getRegInfo(); |
617 | 628 | const Function &F = MF.getFunction(); |
| 629 | + const MCRegisterInfo *MCRI = MF.getContext().getRegisterInfo(); |
618 | 630 | MachineFrameInfo &FrameInfo = MF.getFrameInfo(); |
619 | 631 |
|
620 | 632 | assert(MFI->isEntryFunction()); |
621 | 633 |
|
| 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 | + |
622 | 662 | Register PreloadedScratchWaveOffsetReg = MFI->getPreloadedReg( |
623 | 663 | AMDGPUFunctionArgInfo::PRIVATE_SEGMENT_WAVE_BYTE_OFFSET); |
624 | 664 |
|
@@ -655,11 +695,6 @@ void SIFrameLowering::emitEntryFunctionPrologue(MachineFunction &MF, |
655 | 695 | } |
656 | 696 | } |
657 | 697 |
|
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 | | - |
663 | 698 | // We found the SRSRC first because it needs four registers and has an |
664 | 699 | // alignment requirement. If the SRSRC that we found is clobbering with |
665 | 700 | // the scratch wave offset, which may be in a fixed SGPR or a free SGPR |
@@ -2210,3 +2245,15 @@ bool SIFrameLowering::requiresStackPointerReference( |
2210 | 2245 | // references the SP, like variable sized stack objects. |
2211 | 2246 | return frameTriviallyRequiresSP(MFI); |
2212 | 2247 | } |
| 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 | +} |
0 commit comments