@@ -41,14 +41,52 @@ class NVPTXPrologEpilogPass : public MachineFunctionPass {
4141private:
4242 void calculateFrameObjectOffsets (MachineFunction &Fn);
4343};
44- }
44+ } // end anonymous namespace
4545
4646MachineFunctionPass *llvm::createNVPTXPrologEpilogPass () {
4747 return new NVPTXPrologEpilogPass ();
4848}
4949
5050char NVPTXPrologEpilogPass::ID = 0 ;
5151
52+ INITIALIZE_PASS (NVPTXPrologEpilogPass, DEBUG_TYPE,
53+ " NVPTX Prologue/Epilogue Insertion" , false , false )
54+
55+ static bool replaceFrameIndexDebugInstr(MachineFunction &MF, MachineInstr &MI,
56+ unsigned OpIdx) {
57+ const TargetFrameLowering *TFI = MF.getSubtarget ().getFrameLowering ();
58+ const TargetRegisterInfo &TRI = *MF.getSubtarget ().getRegisterInfo ();
59+ if (MI.isDebugValue ()) {
60+
61+ MachineOperand &Op = MI.getOperand (OpIdx);
62+ assert (MI.isDebugOperand (&Op) &&
63+ " Frame indices can only appear as a debug operand in a DBG_VALUE*"
64+ " machine instruction" );
65+ Register Reg;
66+ unsigned FrameIdx = Op.getIndex ();
67+
68+ StackOffset Offset = TFI->getFrameIndexReference (MF, FrameIdx, Reg);
69+ Op.ChangeToRegister (Reg, false /* isDef*/ );
70+
71+ const DIExpression *DIExpr = MI.getDebugExpression ();
72+ if (MI.isNonListDebugValue ()) {
73+ DIExpr = TRI.prependOffsetExpression (MI.getDebugExpression (),
74+ DIExpression::ApplyOffset, Offset);
75+ } else {
76+ // The debug operand at DebugOpIndex was a frame index at offset
77+ // `Offset`; now the operand has been replaced with the frame
78+ // register, we must add Offset with `register x, plus Offset`.
79+ unsigned DebugOpIndex = MI.getDebugOperandIndex (&Op);
80+ SmallVector<uint64_t , 3 > Ops;
81+ TRI.getOffsetOpcodes (Offset, Ops);
82+ DIExpr = DIExpression::appendOpsToArg (DIExpr, Ops, DebugOpIndex);
83+ }
84+ MI.getDebugExpressionOp ().setMetadata (DIExpr);
85+ return true ;
86+ }
87+ return false ;
88+ }
89+
5290bool NVPTXPrologEpilogPass::runOnMachineFunction (MachineFunction &MF) {
5391 const TargetSubtargetInfo &STI = MF.getSubtarget ();
5492 const TargetFrameLowering &TFI = *STI.getFrameLowering ();
@@ -57,41 +95,27 @@ bool NVPTXPrologEpilogPass::runOnMachineFunction(MachineFunction &MF) {
5795
5896 calculateFrameObjectOffsets (MF);
5997
60- for (MachineBasicBlock &MBB : MF) {
61- for (MachineInstr &MI : MBB) {
62- for (unsigned i = 0 , e = MI.getNumOperands (); i != e; ++i) {
63- if (!MI.getOperand (i).isFI ())
98+ for (MachineBasicBlock &BB : MF) {
99+ for (MachineBasicBlock::iterator I = BB.end (); I != BB.begin ();) {
100+ MachineInstr &MI = *std::prev (I);
101+
102+ bool RemovedMI = false ;
103+ for (const auto &[Idx, Op] : enumerate(MI.operands ())) {
104+ if (!Op.isFI ())
64105 continue ;
65106
66- // Frame indices in debug values are encoded in a target independent
67- // way with simply the frame index and offset rather than any
68- // target-specific addressing mode.
69- if (MI.isDebugValue ()) {
70- MachineOperand &Op = MI.getOperand (i);
71- assert (
72- MI.isDebugOperand (&Op) &&
73- " Frame indices can only appear as a debug operand in a DBG_VALUE*"
74- " machine instruction" );
75- Register Reg;
76- auto Offset =
77- TFI.getFrameIndexReference (MF, Op.getIndex (), Reg);
78- Op.ChangeToRegister (Reg, /* isDef=*/ false );
79- const DIExpression *DIExpr = MI.getDebugExpression ();
80- if (MI.isNonListDebugValue ()) {
81- DIExpr = TRI.prependOffsetExpression (MI.getDebugExpression (), DIExpression::ApplyOffset, Offset);
82- } else {
83- SmallVector<uint64_t , 3 > Ops;
84- TRI.getOffsetOpcodes (Offset, Ops);
85- unsigned OpIdx = MI.getDebugOperandIndex (&Op);
86- DIExpr = DIExpression::appendOpsToArg (DIExpr, Ops, OpIdx);
87- }
88- MI.getDebugExpressionOp ().setMetadata (DIExpr);
107+ if (replaceFrameIndexDebugInstr (MF, MI, Idx))
89108 continue ;
90- }
91109
92- TRI.eliminateFrameIndex (MI, 0 , i, nullptr );
110+ // Eliminate this FrameIndex operand.
111+ TRI.eliminateFrameIndex (MI, 0 , Idx, nullptr );
93112 Modified = true ;
113+ if (RemovedMI)
114+ break ;
94115 }
116+
117+ if (!RemovedMI)
118+ --I;
95119 }
96120 }
97121
0 commit comments