NVPTXPrologEpilogPass.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. //===-- NVPTXPrologEpilogPass.cpp - NVPTX prolog/epilog inserter ----------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file is a copy of the generic LLVM PrologEpilogInserter pass, modified
  10. // to remove unneeded functionality and to handle virtual registers. Most code
  11. // here is a copy of PrologEpilogInserter.cpp.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "NVPTX.h"
  15. #include "llvm/CodeGen/MachineFrameInfo.h"
  16. #include "llvm/CodeGen/MachineFunction.h"
  17. #include "llvm/CodeGen/MachineFunctionPass.h"
  18. #include "llvm/CodeGen/TargetFrameLowering.h"
  19. #include "llvm/CodeGen/TargetRegisterInfo.h"
  20. #include "llvm/CodeGen/TargetSubtargetInfo.h"
  21. #include "llvm/IR/DebugInfoMetadata.h"
  22. #include "llvm/Pass.h"
  23. #include "llvm/Support/Debug.h"
  24. #include "llvm/Support/raw_ostream.h"
  25. using namespace llvm;
  26. #define DEBUG_TYPE "nvptx-prolog-epilog"
  27. namespace {
  28. class NVPTXPrologEpilogPass : public MachineFunctionPass {
  29. public:
  30. static char ID;
  31. NVPTXPrologEpilogPass() : MachineFunctionPass(ID) {}
  32. bool runOnMachineFunction(MachineFunction &MF) override;
  33. private:
  34. void calculateFrameObjectOffsets(MachineFunction &Fn);
  35. };
  36. }
  37. MachineFunctionPass *llvm::createNVPTXPrologEpilogPass() {
  38. return new NVPTXPrologEpilogPass();
  39. }
  40. char NVPTXPrologEpilogPass::ID = 0;
  41. bool NVPTXPrologEpilogPass::runOnMachineFunction(MachineFunction &MF) {
  42. const TargetSubtargetInfo &STI = MF.getSubtarget();
  43. const TargetFrameLowering &TFI = *STI.getFrameLowering();
  44. const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
  45. bool Modified = false;
  46. calculateFrameObjectOffsets(MF);
  47. for (MachineBasicBlock &MBB : MF) {
  48. for (MachineInstr &MI : MBB) {
  49. for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
  50. if (!MI.getOperand(i).isFI())
  51. continue;
  52. // Frame indices in debug values are encoded in a target independent
  53. // way with simply the frame index and offset rather than any
  54. // target-specific addressing mode.
  55. if (MI.isDebugValue()) {
  56. MachineOperand &Op = MI.getOperand(i);
  57. assert(
  58. MI.isDebugOperand(&Op) &&
  59. "Frame indices can only appear as a debug operand in a DBG_VALUE*"
  60. " machine instruction");
  61. Register Reg;
  62. auto Offset =
  63. TFI.getFrameIndexReference(MF, Op.getIndex(), Reg);
  64. Op.ChangeToRegister(Reg, /*isDef=*/false);
  65. const DIExpression *DIExpr = MI.getDebugExpression();
  66. if (MI.isNonListDebugValue()) {
  67. DIExpr = TRI.prependOffsetExpression(MI.getDebugExpression(), DIExpression::ApplyOffset, Offset);
  68. } else {
  69. SmallVector<uint64_t, 3> Ops;
  70. TRI.getOffsetOpcodes(Offset, Ops);
  71. unsigned OpIdx = MI.getDebugOperandIndex(&Op);
  72. DIExpr = DIExpression::appendOpsToArg(DIExpr, Ops, OpIdx);
  73. }
  74. MI.getDebugExpressionOp().setMetadata(DIExpr);
  75. continue;
  76. }
  77. TRI.eliminateFrameIndex(MI, 0, i, nullptr);
  78. Modified = true;
  79. }
  80. }
  81. }
  82. // Add function prolog/epilog
  83. TFI.emitPrologue(MF, MF.front());
  84. for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
  85. // If last instruction is a return instruction, add an epilogue
  86. if (I->isReturnBlock())
  87. TFI.emitEpilogue(MF, *I);
  88. }
  89. return Modified;
  90. }
  91. /// AdjustStackOffset - Helper function used to adjust the stack frame offset.
  92. static inline void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx,
  93. bool StackGrowsDown, int64_t &Offset,
  94. Align &MaxAlign) {
  95. // If the stack grows down, add the object size to find the lowest address.
  96. if (StackGrowsDown)
  97. Offset += MFI.getObjectSize(FrameIdx);
  98. Align Alignment = MFI.getObjectAlign(FrameIdx);
  99. // If the alignment of this object is greater than that of the stack, then
  100. // increase the stack alignment to match.
  101. MaxAlign = std::max(MaxAlign, Alignment);
  102. // Adjust to alignment boundary.
  103. Offset = alignTo(Offset, Alignment);
  104. if (StackGrowsDown) {
  105. LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset
  106. << "]\n");
  107. MFI.setObjectOffset(FrameIdx, -Offset); // Set the computed offset
  108. } else {
  109. LLVM_DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset
  110. << "]\n");
  111. MFI.setObjectOffset(FrameIdx, Offset);
  112. Offset += MFI.getObjectSize(FrameIdx);
  113. }
  114. }
  115. void
  116. NVPTXPrologEpilogPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
  117. const TargetFrameLowering &TFI = *Fn.getSubtarget().getFrameLowering();
  118. const TargetRegisterInfo *RegInfo = Fn.getSubtarget().getRegisterInfo();
  119. bool StackGrowsDown =
  120. TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
  121. // Loop over all of the stack objects, assigning sequential addresses...
  122. MachineFrameInfo &MFI = Fn.getFrameInfo();
  123. // Start at the beginning of the local area.
  124. // The Offset is the distance from the stack top in the direction
  125. // of stack growth -- so it's always nonnegative.
  126. int LocalAreaOffset = TFI.getOffsetOfLocalArea();
  127. if (StackGrowsDown)
  128. LocalAreaOffset = -LocalAreaOffset;
  129. assert(LocalAreaOffset >= 0
  130. && "Local area offset should be in direction of stack growth");
  131. int64_t Offset = LocalAreaOffset;
  132. // If there are fixed sized objects that are preallocated in the local area,
  133. // non-fixed objects can't be allocated right at the start of local area.
  134. // We currently don't support filling in holes in between fixed sized
  135. // objects, so we adjust 'Offset' to point to the end of last fixed sized
  136. // preallocated object.
  137. for (int i = MFI.getObjectIndexBegin(); i != 0; ++i) {
  138. int64_t FixedOff;
  139. if (StackGrowsDown) {
  140. // The maximum distance from the stack pointer is at lower address of
  141. // the object -- which is given by offset. For down growing stack
  142. // the offset is negative, so we negate the offset to get the distance.
  143. FixedOff = -MFI.getObjectOffset(i);
  144. } else {
  145. // The maximum distance from the start pointer is at the upper
  146. // address of the object.
  147. FixedOff = MFI.getObjectOffset(i) + MFI.getObjectSize(i);
  148. }
  149. if (FixedOff > Offset) Offset = FixedOff;
  150. }
  151. // NOTE: We do not have a call stack
  152. Align MaxAlign = MFI.getMaxAlign();
  153. // No scavenger
  154. // FIXME: Once this is working, then enable flag will change to a target
  155. // check for whether the frame is large enough to want to use virtual
  156. // frame index registers. Functions which don't want/need this optimization
  157. // will continue to use the existing code path.
  158. if (MFI.getUseLocalStackAllocationBlock()) {
  159. Align Alignment = MFI.getLocalFrameMaxAlign();
  160. // Adjust to alignment boundary.
  161. Offset = alignTo(Offset, Alignment);
  162. LLVM_DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
  163. // Resolve offsets for objects in the local block.
  164. for (unsigned i = 0, e = MFI.getLocalFrameObjectCount(); i != e; ++i) {
  165. std::pair<int, int64_t> Entry = MFI.getLocalFrameObjectMap(i);
  166. int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
  167. LLVM_DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" << FIOffset
  168. << "]\n");
  169. MFI.setObjectOffset(Entry.first, FIOffset);
  170. }
  171. // Allocate the local block
  172. Offset += MFI.getLocalFrameSize();
  173. MaxAlign = std::max(Alignment, MaxAlign);
  174. }
  175. // No stack protector
  176. // Then assign frame offsets to stack objects that are not used to spill
  177. // callee saved registers.
  178. for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
  179. if (MFI.isObjectPreAllocated(i) &&
  180. MFI.getUseLocalStackAllocationBlock())
  181. continue;
  182. if (MFI.isDeadObjectIndex(i))
  183. continue;
  184. AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
  185. }
  186. // No scavenger
  187. if (!TFI.targetHandlesStackFrameRounding()) {
  188. // If we have reserved argument space for call sites in the function
  189. // immediately on entry to the current function, count it as part of the
  190. // overall stack size.
  191. if (MFI.adjustsStack() && TFI.hasReservedCallFrame(Fn))
  192. Offset += MFI.getMaxCallFrameSize();
  193. // Round up the size to a multiple of the alignment. If the function has
  194. // any calls or alloca's, align to the target's StackAlignment value to
  195. // ensure that the callee's frame or the alloca data is suitably aligned;
  196. // otherwise, for leaf functions, align to the TransientStackAlignment
  197. // value.
  198. Align StackAlign;
  199. if (MFI.adjustsStack() || MFI.hasVarSizedObjects() ||
  200. (RegInfo->hasStackRealignment(Fn) && MFI.getObjectIndexEnd() != 0))
  201. StackAlign = TFI.getStackAlign();
  202. else
  203. StackAlign = TFI.getTransientStackAlign();
  204. // If the frame pointer is eliminated, all frame offsets will be relative to
  205. // SP not FP. Align to MaxAlign so this works.
  206. Offset = alignTo(Offset, std::max(StackAlign, MaxAlign));
  207. }
  208. // Update frame info to pretend that this is part of the stack...
  209. int64_t StackSize = Offset - LocalAreaOffset;
  210. MFI.setStackSize(StackSize);
  211. }