NVPTXPrologEpilogPass.cpp 9.3 KB

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