152ef4019SMatt Arsenault //===-- AMDGPUMachineFunctionInfo.cpp ---------------------------------------=//
252ef4019SMatt Arsenault //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
652ef4019SMatt Arsenault //
752ef4019SMatt Arsenault //===----------------------------------------------------------------------===//
852ef4019SMatt Arsenault 
945bb48eaSTom Stellard #include "AMDGPUMachineFunction.h"
101c538423SStanislav Mekhanoshin #include "AMDGPUPerfHintAnalysis.h"
116a87e9b0Sdfukalov #include "AMDGPUSubtarget.h"
121c538423SStanislav Mekhanoshin #include "llvm/CodeGen/MachineModuleInfo.h"
136a87e9b0Sdfukalov #include "llvm/Target/TargetMachine.h"
14e935f05aSMatt Arsenault 
1545bb48eaSTom Stellard using namespace llvm;
1645bb48eaSTom Stellard 
175733167fSSebastian Neubauer AMDGPUMachineFunction::AMDGPUMachineFunction(const MachineFunction &MF)
185733167fSSebastian Neubauer     : MachineFunctionInfo(), Mode(MF.getFunction()),
195733167fSSebastian Neubauer       IsEntryFunction(
205733167fSSebastian Neubauer           AMDGPU::isEntryFunctionCC(MF.getFunction().getCallingConv())),
215733167fSSebastian Neubauer       IsModuleEntryFunction(
225733167fSSebastian Neubauer           AMDGPU::isModuleEntryFunctionCC(MF.getFunction().getCallingConv())),
2361813b80SMatt Arsenault       NoSignedZerosFPMath(MF.getTarget().Options.NoSignedZerosFPMath) {
244bec7d42SMatt Arsenault   const AMDGPUSubtarget &ST = AMDGPUSubtarget::get(MF);
254bec7d42SMatt Arsenault 
2652ef4019SMatt Arsenault   // FIXME: Should initialize KernArgSize based on ExplicitKernelArgOffset,
2752ef4019SMatt Arsenault   // except reserved size is not correctly aligned.
284bec7d42SMatt Arsenault   const Function &F = MF.getFunction();
291c538423SStanislav Mekhanoshin 
30e7e23e3eSMatt Arsenault   Attribute MemBoundAttr = F.getFnAttribute("amdgpu-memory-bound");
31e7e23e3eSMatt Arsenault   MemoryBound = MemBoundAttr.isStringAttribute() &&
32e7e23e3eSMatt Arsenault                 MemBoundAttr.getValueAsString() == "true";
33e7e23e3eSMatt Arsenault 
34e7e23e3eSMatt Arsenault   Attribute WaveLimitAttr = F.getFnAttribute("amdgpu-wave-limiter");
35e7e23e3eSMatt Arsenault   WaveLimiter = WaveLimitAttr.isStringAttribute() &&
36e7e23e3eSMatt Arsenault                 WaveLimitAttr.getValueAsString() == "true";
374bec7d42SMatt Arsenault 
384bec7d42SMatt Arsenault   CallingConv::ID CC = F.getCallingConv();
394bec7d42SMatt Arsenault   if (CC == CallingConv::AMDGPU_KERNEL || CC == CallingConv::SPIR_KERNEL)
404bec7d42SMatt Arsenault     ExplicitKernArgSize = ST.getExplicitKernArgSize(F, MaxKernArgAlign);
41beb24f5bSNikolay Haustov }
42beb24f5bSNikolay Haustov 
4352ef4019SMatt Arsenault unsigned AMDGPUMachineFunction::allocateLDSGlobal(const DataLayout &DL,
44a2caa3b6SEli Friedman                                                   const GlobalVariable &GV) {
4552ef4019SMatt Arsenault   auto Entry = LocalMemoryObjects.insert(std::make_pair(&GV, 0));
4652ef4019SMatt Arsenault   if (!Entry.second)
4752ef4019SMatt Arsenault     return Entry.first->second;
4852ef4019SMatt Arsenault 
4952911428SGuillaume Chatelet   Align Alignment =
5052911428SGuillaume Chatelet       DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType());
5152ef4019SMatt Arsenault 
5252ef4019SMatt Arsenault   /// TODO: We should sort these to minimize wasted space due to alignment
5352ef4019SMatt Arsenault   /// padding. Currently the padding is decided by the first encountered use
5452ef4019SMatt Arsenault   /// during lowering.
555257a60eSMichael Liao   unsigned Offset = StaticLDSSize = alignTo(StaticLDSSize, Alignment);
5652ef4019SMatt Arsenault 
5752ef4019SMatt Arsenault   Entry.first->second = Offset;
585257a60eSMichael Liao   StaticLDSSize += DL.getTypeAllocSize(GV.getValueType());
595257a60eSMichael Liao 
605257a60eSMichael Liao   // Update the LDS size considering the padding to align the dynamic shared
615257a60eSMichael Liao   // memory.
625257a60eSMichael Liao   LDSSize = alignTo(StaticLDSSize, DynLDSAlign);
6352ef4019SMatt Arsenault 
6452ef4019SMatt Arsenault   return Offset;
65beb24f5bSNikolay Haustov }
665257a60eSMichael Liao 
67*13e49dceSJon Chesterfield void AMDGPUMachineFunction::allocateModuleLDSGlobal(const Module *M) {
68*13e49dceSJon Chesterfield   if (isModuleEntryFunction()) {
69*13e49dceSJon Chesterfield     GlobalVariable *GV = M->getGlobalVariable("llvm.amdgcn.module.lds");
70*13e49dceSJon Chesterfield     if (GV) {
71*13e49dceSJon Chesterfield       unsigned Offset = allocateLDSGlobal(M->getDataLayout(), *GV);
72*13e49dceSJon Chesterfield       (void)Offset;
73*13e49dceSJon Chesterfield       assert(Offset == 0 &&
74*13e49dceSJon Chesterfield              "Module LDS expected to be allocated before other LDS");
75*13e49dceSJon Chesterfield     }
76*13e49dceSJon Chesterfield   }
77*13e49dceSJon Chesterfield }
78*13e49dceSJon Chesterfield 
795257a60eSMichael Liao void AMDGPUMachineFunction::setDynLDSAlign(const DataLayout &DL,
805257a60eSMichael Liao                                            const GlobalVariable &GV) {
815257a60eSMichael Liao   assert(DL.getTypeAllocSize(GV.getValueType()).isZero());
825257a60eSMichael Liao 
835257a60eSMichael Liao   Align Alignment =
845257a60eSMichael Liao       DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType());
855257a60eSMichael Liao   if (Alignment <= DynLDSAlign)
865257a60eSMichael Liao     return;
875257a60eSMichael Liao 
885257a60eSMichael Liao   LDSSize = alignTo(StaticLDSSize, Alignment);
895257a60eSMichael Liao   DynLDSAlign = Alignment;
905257a60eSMichael Liao }
91