SIMachineFunctionInfo.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. //===- SIMachineFunctionInfo.cpp - SI Machine Function Info ---------------===//
  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. #include "SIMachineFunctionInfo.h"
  9. #include "AMDGPUArgumentUsageInfo.h"
  10. #include "AMDGPUSubtarget.h"
  11. #include "SIRegisterInfo.h"
  12. #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
  13. #include "Utils/AMDGPUBaseInfo.h"
  14. #include "llvm/ADT/Optional.h"
  15. #include "llvm/CodeGen/MachineBasicBlock.h"
  16. #include "llvm/CodeGen/MachineFrameInfo.h"
  17. #include "llvm/CodeGen/MachineFunction.h"
  18. #include "llvm/CodeGen/MachineRegisterInfo.h"
  19. #include "llvm/IR/CallingConv.h"
  20. #include "llvm/IR/Function.h"
  21. #include <cassert>
  22. #include <vector>
  23. #define MAX_LANES 64
  24. using namespace llvm;
  25. SIMachineFunctionInfo::SIMachineFunctionInfo(const MachineFunction &MF)
  26. : AMDGPUMachineFunction(MF),
  27. Mode(MF.getFunction()),
  28. PrivateSegmentBuffer(false),
  29. DispatchPtr(false),
  30. QueuePtr(false),
  31. KernargSegmentPtr(false),
  32. DispatchID(false),
  33. FlatScratchInit(false),
  34. WorkGroupIDX(false),
  35. WorkGroupIDY(false),
  36. WorkGroupIDZ(false),
  37. WorkGroupInfo(false),
  38. PrivateSegmentWaveByteOffset(false),
  39. WorkItemIDX(false),
  40. WorkItemIDY(false),
  41. WorkItemIDZ(false),
  42. ImplicitBufferPtr(false),
  43. ImplicitArgPtr(false),
  44. GITPtrHigh(0xffffffff),
  45. HighBitsOf32BitAddress(0),
  46. GDSSize(0) {
  47. const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
  48. const Function &F = MF.getFunction();
  49. FlatWorkGroupSizes = ST.getFlatWorkGroupSizes(F);
  50. WavesPerEU = ST.getWavesPerEU(F);
  51. Occupancy = ST.computeOccupancy(MF, getLDSSize());
  52. CallingConv::ID CC = F.getCallingConv();
  53. if (CC == CallingConv::AMDGPU_KERNEL || CC == CallingConv::SPIR_KERNEL) {
  54. if (!F.arg_empty())
  55. KernargSegmentPtr = true;
  56. WorkGroupIDX = true;
  57. WorkItemIDX = true;
  58. } else if (CC == CallingConv::AMDGPU_PS) {
  59. PSInputAddr = AMDGPU::getInitialPSInputAddr(F);
  60. }
  61. if (!isEntryFunction()) {
  62. // Non-entry functions have no special inputs for now, other registers
  63. // required for scratch access.
  64. ScratchRSrcReg = AMDGPU::SGPR0_SGPR1_SGPR2_SGPR3;
  65. ScratchWaveOffsetReg = AMDGPU::SGPR33;
  66. // TODO: Pick a high register, and shift down, similar to a kernel.
  67. FrameOffsetReg = AMDGPU::SGPR34;
  68. StackPtrOffsetReg = AMDGPU::SGPR32;
  69. ArgInfo.PrivateSegmentBuffer =
  70. ArgDescriptor::createRegister(ScratchRSrcReg);
  71. ArgInfo.PrivateSegmentWaveByteOffset =
  72. ArgDescriptor::createRegister(ScratchWaveOffsetReg);
  73. if (F.hasFnAttribute("amdgpu-implicitarg-ptr"))
  74. ImplicitArgPtr = true;
  75. } else {
  76. if (F.hasFnAttribute("amdgpu-implicitarg-ptr")) {
  77. KernargSegmentPtr = true;
  78. MaxKernArgAlign = std::max(ST.getAlignmentForImplicitArgPtr(),
  79. MaxKernArgAlign);
  80. }
  81. }
  82. if (F.hasFnAttribute("amdgpu-work-group-id-x"))
  83. WorkGroupIDX = true;
  84. if (F.hasFnAttribute("amdgpu-work-group-id-y"))
  85. WorkGroupIDY = true;
  86. if (F.hasFnAttribute("amdgpu-work-group-id-z"))
  87. WorkGroupIDZ = true;
  88. if (F.hasFnAttribute("amdgpu-work-item-id-x"))
  89. WorkItemIDX = true;
  90. if (F.hasFnAttribute("amdgpu-work-item-id-y"))
  91. WorkItemIDY = true;
  92. if (F.hasFnAttribute("amdgpu-work-item-id-z"))
  93. WorkItemIDZ = true;
  94. const MachineFrameInfo &FrameInfo = MF.getFrameInfo();
  95. bool HasStackObjects = FrameInfo.hasStackObjects();
  96. if (isEntryFunction()) {
  97. // X, XY, and XYZ are the only supported combinations, so make sure Y is
  98. // enabled if Z is.
  99. if (WorkItemIDZ)
  100. WorkItemIDY = true;
  101. PrivateSegmentWaveByteOffset = true;
  102. // HS and GS always have the scratch wave offset in SGPR5 on GFX9.
  103. if (ST.getGeneration() >= AMDGPUSubtarget::GFX9 &&
  104. (CC == CallingConv::AMDGPU_HS || CC == CallingConv::AMDGPU_GS))
  105. ArgInfo.PrivateSegmentWaveByteOffset =
  106. ArgDescriptor::createRegister(AMDGPU::SGPR5);
  107. }
  108. bool isAmdHsaOrMesa = ST.isAmdHsaOrMesa(F);
  109. if (isAmdHsaOrMesa) {
  110. PrivateSegmentBuffer = true;
  111. if (F.hasFnAttribute("amdgpu-dispatch-ptr"))
  112. DispatchPtr = true;
  113. if (F.hasFnAttribute("amdgpu-queue-ptr"))
  114. QueuePtr = true;
  115. if (F.hasFnAttribute("amdgpu-dispatch-id"))
  116. DispatchID = true;
  117. } else if (ST.isMesaGfxShader(F)) {
  118. ImplicitBufferPtr = true;
  119. }
  120. if (F.hasFnAttribute("amdgpu-kernarg-segment-ptr"))
  121. KernargSegmentPtr = true;
  122. if (ST.hasFlatAddressSpace() && isEntryFunction() && isAmdHsaOrMesa) {
  123. auto hasNonSpillStackObjects = [&]() {
  124. // Avoid expensive checking if there's no stack objects.
  125. if (!HasStackObjects)
  126. return false;
  127. for (auto OI = FrameInfo.getObjectIndexBegin(),
  128. OE = FrameInfo.getObjectIndexEnd(); OI != OE; ++OI)
  129. if (!FrameInfo.isSpillSlotObjectIndex(OI))
  130. return true;
  131. // All stack objects are spill slots.
  132. return false;
  133. };
  134. // TODO: This could be refined a lot. The attribute is a poor way of
  135. // detecting calls that may require it before argument lowering.
  136. if (hasNonSpillStackObjects() || F.hasFnAttribute("amdgpu-flat-scratch"))
  137. FlatScratchInit = true;
  138. }
  139. Attribute A = F.getFnAttribute("amdgpu-git-ptr-high");
  140. StringRef S = A.getValueAsString();
  141. if (!S.empty())
  142. S.consumeInteger(0, GITPtrHigh);
  143. A = F.getFnAttribute("amdgpu-32bit-address-high-bits");
  144. S = A.getValueAsString();
  145. if (!S.empty())
  146. S.consumeInteger(0, HighBitsOf32BitAddress);
  147. S = F.getFnAttribute("amdgpu-gds-size").getValueAsString();
  148. if (!S.empty())
  149. S.consumeInteger(0, GDSSize);
  150. }
  151. void SIMachineFunctionInfo::limitOccupancy(const MachineFunction &MF) {
  152. limitOccupancy(getMaxWavesPerEU());
  153. const GCNSubtarget& ST = MF.getSubtarget<GCNSubtarget>();
  154. limitOccupancy(ST.getOccupancyWithLocalMemSize(getLDSSize(),
  155. MF.getFunction()));
  156. }
  157. unsigned SIMachineFunctionInfo::addPrivateSegmentBuffer(
  158. const SIRegisterInfo &TRI) {
  159. ArgInfo.PrivateSegmentBuffer =
  160. ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
  161. getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SGPR_128RegClass));
  162. NumUserSGPRs += 4;
  163. return ArgInfo.PrivateSegmentBuffer.getRegister();
  164. }
  165. unsigned SIMachineFunctionInfo::addDispatchPtr(const SIRegisterInfo &TRI) {
  166. ArgInfo.DispatchPtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
  167. getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
  168. NumUserSGPRs += 2;
  169. return ArgInfo.DispatchPtr.getRegister();
  170. }
  171. unsigned SIMachineFunctionInfo::addQueuePtr(const SIRegisterInfo &TRI) {
  172. ArgInfo.QueuePtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
  173. getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
  174. NumUserSGPRs += 2;
  175. return ArgInfo.QueuePtr.getRegister();
  176. }
  177. unsigned SIMachineFunctionInfo::addKernargSegmentPtr(const SIRegisterInfo &TRI) {
  178. ArgInfo.KernargSegmentPtr
  179. = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
  180. getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
  181. NumUserSGPRs += 2;
  182. return ArgInfo.KernargSegmentPtr.getRegister();
  183. }
  184. unsigned SIMachineFunctionInfo::addDispatchID(const SIRegisterInfo &TRI) {
  185. ArgInfo.DispatchID = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
  186. getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
  187. NumUserSGPRs += 2;
  188. return ArgInfo.DispatchID.getRegister();
  189. }
  190. unsigned SIMachineFunctionInfo::addFlatScratchInit(const SIRegisterInfo &TRI) {
  191. ArgInfo.FlatScratchInit = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
  192. getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
  193. NumUserSGPRs += 2;
  194. return ArgInfo.FlatScratchInit.getRegister();
  195. }
  196. unsigned SIMachineFunctionInfo::addImplicitBufferPtr(const SIRegisterInfo &TRI) {
  197. ArgInfo.ImplicitBufferPtr = ArgDescriptor::createRegister(TRI.getMatchingSuperReg(
  198. getNextUserSGPR(), AMDGPU::sub0, &AMDGPU::SReg_64RegClass));
  199. NumUserSGPRs += 2;
  200. return ArgInfo.ImplicitBufferPtr.getRegister();
  201. }
  202. static bool isCalleeSavedReg(const MCPhysReg *CSRegs, MCPhysReg Reg) {
  203. for (unsigned I = 0; CSRegs[I]; ++I) {
  204. if (CSRegs[I] == Reg)
  205. return true;
  206. }
  207. return false;
  208. }
  209. /// \p returns true if \p NumLanes slots are available in VGPRs already used for
  210. /// SGPR spilling.
  211. //
  212. // FIXME: This only works after processFunctionBeforeFrameFinalized
  213. bool SIMachineFunctionInfo::haveFreeLanesForSGPRSpill(const MachineFunction &MF,
  214. unsigned NumNeed) const {
  215. const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
  216. unsigned WaveSize = ST.getWavefrontSize();
  217. return NumVGPRSpillLanes + NumNeed <= WaveSize * SpillVGPRs.size();
  218. }
  219. /// Reserve a slice of a VGPR to support spilling for FrameIndex \p FI.
  220. bool SIMachineFunctionInfo::allocateSGPRSpillToVGPR(MachineFunction &MF,
  221. int FI) {
  222. std::vector<SpilledReg> &SpillLanes = SGPRToVGPRSpills[FI];
  223. // This has already been allocated.
  224. if (!SpillLanes.empty())
  225. return true;
  226. const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
  227. const SIRegisterInfo *TRI = ST.getRegisterInfo();
  228. MachineFrameInfo &FrameInfo = MF.getFrameInfo();
  229. MachineRegisterInfo &MRI = MF.getRegInfo();
  230. unsigned WaveSize = ST.getWavefrontSize();
  231. unsigned Size = FrameInfo.getObjectSize(FI);
  232. assert(Size >= 4 && Size <= 64 && "invalid sgpr spill size");
  233. assert(TRI->spillSGPRToVGPR() && "not spilling SGPRs to VGPRs");
  234. int NumLanes = Size / 4;
  235. const MCPhysReg *CSRegs = MRI.getCalleeSavedRegs();
  236. // Make sure to handle the case where a wide SGPR spill may span between two
  237. // VGPRs.
  238. for (int I = 0; I < NumLanes; ++I, ++NumVGPRSpillLanes) {
  239. unsigned LaneVGPR;
  240. unsigned VGPRIndex = (NumVGPRSpillLanes % WaveSize);
  241. if (VGPRIndex == 0) {
  242. LaneVGPR = TRI->findUnusedRegister(MRI, &AMDGPU::VGPR_32RegClass, MF);
  243. if (LaneVGPR == AMDGPU::NoRegister) {
  244. // We have no VGPRs left for spilling SGPRs. Reset because we will not
  245. // partially spill the SGPR to VGPRs.
  246. SGPRToVGPRSpills.erase(FI);
  247. NumVGPRSpillLanes -= I;
  248. return false;
  249. }
  250. Optional<int> CSRSpillFI;
  251. if ((FrameInfo.hasCalls() || !isEntryFunction()) && CSRegs &&
  252. isCalleeSavedReg(CSRegs, LaneVGPR)) {
  253. CSRSpillFI = FrameInfo.CreateSpillStackObject(4, 4);
  254. }
  255. SpillVGPRs.push_back(SGPRSpillVGPRCSR(LaneVGPR, CSRSpillFI));
  256. // Add this register as live-in to all blocks to avoid machine verifer
  257. // complaining about use of an undefined physical register.
  258. for (MachineBasicBlock &BB : MF)
  259. BB.addLiveIn(LaneVGPR);
  260. } else {
  261. LaneVGPR = SpillVGPRs.back().VGPR;
  262. }
  263. SpillLanes.push_back(SpilledReg(LaneVGPR, VGPRIndex));
  264. }
  265. return true;
  266. }
  267. /// Reserve AGPRs or VGPRs to support spilling for FrameIndex \p FI.
  268. /// Either AGPR is spilled to VGPR to vice versa.
  269. /// Returns true if a \p FI can be eliminated completely.
  270. bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
  271. int FI,
  272. bool isAGPRtoVGPR) {
  273. MachineRegisterInfo &MRI = MF.getRegInfo();
  274. MachineFrameInfo &FrameInfo = MF.getFrameInfo();
  275. const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
  276. assert(ST.hasMAIInsts() && FrameInfo.isSpillSlotObjectIndex(FI));
  277. auto &Spill = VGPRToAGPRSpills[FI];
  278. // This has already been allocated.
  279. if (!Spill.Lanes.empty())
  280. return Spill.FullyAllocated;
  281. unsigned Size = FrameInfo.getObjectSize(FI);
  282. unsigned NumLanes = Size / 4;
  283. Spill.Lanes.resize(NumLanes, AMDGPU::NoRegister);
  284. const TargetRegisterClass &RC =
  285. isAGPRtoVGPR ? AMDGPU::VGPR_32RegClass : AMDGPU::AGPR_32RegClass;
  286. auto Regs = RC.getRegisters();
  287. auto &SpillRegs = isAGPRtoVGPR ? SpillAGPR : SpillVGPR;
  288. const SIRegisterInfo *TRI = ST.getRegisterInfo();
  289. Spill.FullyAllocated = true;
  290. // FIXME: Move allocation logic out of MachineFunctionInfo and initialize
  291. // once.
  292. BitVector OtherUsedRegs;
  293. OtherUsedRegs.resize(TRI->getNumRegs());
  294. const uint32_t *CSRMask =
  295. TRI->getCallPreservedMask(MF, MF.getFunction().getCallingConv());
  296. if (CSRMask)
  297. OtherUsedRegs.setBitsInMask(CSRMask);
  298. // TODO: Should include register tuples, but doesn't matter with current
  299. // usage.
  300. for (MCPhysReg Reg : SpillAGPR)
  301. OtherUsedRegs.set(Reg);
  302. for (MCPhysReg Reg : SpillVGPR)
  303. OtherUsedRegs.set(Reg);
  304. SmallVectorImpl<MCPhysReg>::const_iterator NextSpillReg = Regs.begin();
  305. for (unsigned I = 0; I < NumLanes; ++I) {
  306. NextSpillReg = std::find_if(
  307. NextSpillReg, Regs.end(), [&MRI, &OtherUsedRegs](MCPhysReg Reg) {
  308. return MRI.isAllocatable(Reg) && !MRI.isPhysRegUsed(Reg) &&
  309. !OtherUsedRegs[Reg];
  310. });
  311. if (NextSpillReg == Regs.end()) { // Registers exhausted
  312. Spill.FullyAllocated = false;
  313. break;
  314. }
  315. OtherUsedRegs.set(*NextSpillReg);
  316. SpillRegs.push_back(*NextSpillReg);
  317. Spill.Lanes[I] = *NextSpillReg++;
  318. }
  319. return Spill.FullyAllocated;
  320. }
  321. void SIMachineFunctionInfo::removeDeadFrameIndices(MachineFrameInfo &MFI) {
  322. // The FP spill hasn't been inserted yet, so keep it around.
  323. for (auto &R : SGPRToVGPRSpills) {
  324. if (R.first != FramePointerSaveIndex)
  325. MFI.RemoveStackObject(R.first);
  326. }
  327. // All other SPGRs must be allocated on the default stack, so reset the stack
  328. // ID.
  329. for (int i = MFI.getObjectIndexBegin(), e = MFI.getObjectIndexEnd(); i != e;
  330. ++i)
  331. if (i != FramePointerSaveIndex)
  332. MFI.setStackID(i, TargetStackID::Default);
  333. for (auto &R : VGPRToAGPRSpills) {
  334. if (R.second.FullyAllocated)
  335. MFI.RemoveStackObject(R.first);
  336. }
  337. }
  338. MCPhysReg SIMachineFunctionInfo::getNextUserSGPR() const {
  339. assert(NumSystemSGPRs == 0 && "System SGPRs must be added after user SGPRs");
  340. return AMDGPU::SGPR0 + NumUserSGPRs;
  341. }
  342. MCPhysReg SIMachineFunctionInfo::getNextSystemSGPR() const {
  343. return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs;
  344. }
  345. static yaml::StringValue regToString(unsigned Reg,
  346. const TargetRegisterInfo &TRI) {
  347. yaml::StringValue Dest;
  348. {
  349. raw_string_ostream OS(Dest.Value);
  350. OS << printReg(Reg, &TRI);
  351. }
  352. return Dest;
  353. }
  354. static Optional<yaml::SIArgumentInfo>
  355. convertArgumentInfo(const AMDGPUFunctionArgInfo &ArgInfo,
  356. const TargetRegisterInfo &TRI) {
  357. yaml::SIArgumentInfo AI;
  358. auto convertArg = [&](Optional<yaml::SIArgument> &A,
  359. const ArgDescriptor &Arg) {
  360. if (!Arg)
  361. return false;
  362. // Create a register or stack argument.
  363. yaml::SIArgument SA = yaml::SIArgument::createArgument(Arg.isRegister());
  364. if (Arg.isRegister()) {
  365. raw_string_ostream OS(SA.RegisterName.Value);
  366. OS << printReg(Arg.getRegister(), &TRI);
  367. } else
  368. SA.StackOffset = Arg.getStackOffset();
  369. // Check and update the optional mask.
  370. if (Arg.isMasked())
  371. SA.Mask = Arg.getMask();
  372. A = SA;
  373. return true;
  374. };
  375. bool Any = false;
  376. Any |= convertArg(AI.PrivateSegmentBuffer, ArgInfo.PrivateSegmentBuffer);
  377. Any |= convertArg(AI.DispatchPtr, ArgInfo.DispatchPtr);
  378. Any |= convertArg(AI.QueuePtr, ArgInfo.QueuePtr);
  379. Any |= convertArg(AI.KernargSegmentPtr, ArgInfo.KernargSegmentPtr);
  380. Any |= convertArg(AI.DispatchID, ArgInfo.DispatchID);
  381. Any |= convertArg(AI.FlatScratchInit, ArgInfo.FlatScratchInit);
  382. Any |= convertArg(AI.PrivateSegmentSize, ArgInfo.PrivateSegmentSize);
  383. Any |= convertArg(AI.WorkGroupIDX, ArgInfo.WorkGroupIDX);
  384. Any |= convertArg(AI.WorkGroupIDY, ArgInfo.WorkGroupIDY);
  385. Any |= convertArg(AI.WorkGroupIDZ, ArgInfo.WorkGroupIDZ);
  386. Any |= convertArg(AI.WorkGroupInfo, ArgInfo.WorkGroupInfo);
  387. Any |= convertArg(AI.PrivateSegmentWaveByteOffset,
  388. ArgInfo.PrivateSegmentWaveByteOffset);
  389. Any |= convertArg(AI.ImplicitArgPtr, ArgInfo.ImplicitArgPtr);
  390. Any |= convertArg(AI.ImplicitBufferPtr, ArgInfo.ImplicitBufferPtr);
  391. Any |= convertArg(AI.WorkItemIDX, ArgInfo.WorkItemIDX);
  392. Any |= convertArg(AI.WorkItemIDY, ArgInfo.WorkItemIDY);
  393. Any |= convertArg(AI.WorkItemIDZ, ArgInfo.WorkItemIDZ);
  394. if (Any)
  395. return AI;
  396. return None;
  397. }
  398. yaml::SIMachineFunctionInfo::SIMachineFunctionInfo(
  399. const llvm::SIMachineFunctionInfo& MFI,
  400. const TargetRegisterInfo &TRI)
  401. : ExplicitKernArgSize(MFI.getExplicitKernArgSize()),
  402. MaxKernArgAlign(MFI.getMaxKernArgAlign()),
  403. LDSSize(MFI.getLDSSize()),
  404. IsEntryFunction(MFI.isEntryFunction()),
  405. NoSignedZerosFPMath(MFI.hasNoSignedZerosFPMath()),
  406. MemoryBound(MFI.isMemoryBound()),
  407. WaveLimiter(MFI.needsWaveLimiter()),
  408. HighBitsOf32BitAddress(MFI.get32BitAddressHighBits()),
  409. ScratchRSrcReg(regToString(MFI.getScratchRSrcReg(), TRI)),
  410. ScratchWaveOffsetReg(regToString(MFI.getScratchWaveOffsetReg(), TRI)),
  411. FrameOffsetReg(regToString(MFI.getFrameOffsetReg(), TRI)),
  412. StackPtrOffsetReg(regToString(MFI.getStackPtrOffsetReg(), TRI)),
  413. ArgInfo(convertArgumentInfo(MFI.getArgInfo(), TRI)),
  414. Mode(MFI.getMode()) {}
  415. void yaml::SIMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) {
  416. MappingTraits<SIMachineFunctionInfo>::mapping(YamlIO, *this);
  417. }
  418. bool SIMachineFunctionInfo::initializeBaseYamlFields(
  419. const yaml::SIMachineFunctionInfo &YamlMFI) {
  420. ExplicitKernArgSize = YamlMFI.ExplicitKernArgSize;
  421. MaxKernArgAlign = YamlMFI.MaxKernArgAlign;
  422. LDSSize = YamlMFI.LDSSize;
  423. HighBitsOf32BitAddress = YamlMFI.HighBitsOf32BitAddress;
  424. IsEntryFunction = YamlMFI.IsEntryFunction;
  425. NoSignedZerosFPMath = YamlMFI.NoSignedZerosFPMath;
  426. MemoryBound = YamlMFI.MemoryBound;
  427. WaveLimiter = YamlMFI.WaveLimiter;
  428. return false;
  429. }