1 //===-- AMDGPUMachineFunctionInfo.cpp ---------------------------------------=// 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 #include "AMDGPUMachineFunction.h" 10 #include "AMDGPUPerfHintAnalysis.h" 11 #include "AMDGPUSubtarget.h" 12 #include "llvm/CodeGen/MachineModuleInfo.h" 13 #include "llvm/Target/TargetMachine.h" 14 15 using namespace llvm; 16 17 AMDGPUMachineFunction::AMDGPUMachineFunction(const MachineFunction &MF) 18 : Mode(MF.getFunction()), IsEntryFunction(AMDGPU::isEntryFunctionCC( 19 MF.getFunction().getCallingConv())), 20 IsModuleEntryFunction( 21 AMDGPU::isModuleEntryFunctionCC(MF.getFunction().getCallingConv())), 22 NoSignedZerosFPMath(MF.getTarget().Options.NoSignedZerosFPMath) { 23 const AMDGPUSubtarget &ST = AMDGPUSubtarget::get(MF); 24 25 // FIXME: Should initialize KernArgSize based on ExplicitKernelArgOffset, 26 // except reserved size is not correctly aligned. 27 const Function &F = MF.getFunction(); 28 29 Attribute MemBoundAttr = F.getFnAttribute("amdgpu-memory-bound"); 30 MemoryBound = MemBoundAttr.getValueAsBool(); 31 32 Attribute WaveLimitAttr = F.getFnAttribute("amdgpu-wave-limiter"); 33 WaveLimiter = WaveLimitAttr.getValueAsBool(); 34 35 // FIXME: How is this attribute supposed to interact with statically known 36 // global sizes? 37 StringRef S = F.getFnAttribute("amdgpu-gds-size").getValueAsString(); 38 if (!S.empty()) 39 S.consumeInteger(0, GDSSize); 40 41 // Assume the attribute allocates before any known GDS globals. 42 StaticGDSSize = GDSSize; 43 44 CallingConv::ID CC = F.getCallingConv(); 45 if (CC == CallingConv::AMDGPU_KERNEL || CC == CallingConv::SPIR_KERNEL) 46 ExplicitKernArgSize = ST.getExplicitKernArgSize(F, MaxKernArgAlign); 47 } 48 49 unsigned AMDGPUMachineFunction::allocateLDSGlobal(const DataLayout &DL, 50 const GlobalVariable &GV) { 51 auto Entry = LocalMemoryObjects.insert(std::make_pair(&GV, 0)); 52 if (!Entry.second) 53 return Entry.first->second; 54 55 Align Alignment = 56 DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType()); 57 58 unsigned Offset; 59 if (GV.getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS) { 60 /// TODO: We should sort these to minimize wasted space due to alignment 61 /// padding. Currently the padding is decided by the first encountered use 62 /// during lowering. 63 Offset = StaticLDSSize = alignTo(StaticLDSSize, Alignment); 64 65 StaticLDSSize += DL.getTypeAllocSize(GV.getValueType()); 66 67 // Update the LDS size considering the padding to align the dynamic shared 68 // memory. 69 LDSSize = alignTo(StaticLDSSize, DynLDSAlign); 70 } else { 71 Offset = StaticGDSSize = alignTo(StaticGDSSize, Alignment); 72 StaticGDSSize += DL.getTypeAllocSize(GV.getValueType()); 73 74 // FIXME: Apply alignment of dynamic GDS 75 GDSSize = StaticGDSSize; 76 } 77 78 Entry.first->second = Offset; 79 return Offset; 80 } 81 82 void AMDGPUMachineFunction::allocateModuleLDSGlobal(const Module *M) { 83 if (isModuleEntryFunction()) { 84 const GlobalVariable *GV = M->getNamedGlobal("llvm.amdgcn.module.lds"); 85 if (GV) { 86 unsigned Offset = allocateLDSGlobal(M->getDataLayout(), *GV); 87 (void)Offset; 88 assert(Offset == 0 && 89 "Module LDS expected to be allocated before other LDS"); 90 } 91 } 92 } 93 94 void AMDGPUMachineFunction::setDynLDSAlign(const DataLayout &DL, 95 const GlobalVariable &GV) { 96 assert(DL.getTypeAllocSize(GV.getValueType()).isZero()); 97 98 Align Alignment = 99 DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType()); 100 if (Alignment <= DynLDSAlign) 101 return; 102 103 LDSSize = alignTo(StaticLDSSize, Alignment); 104 DynLDSAlign = Alignment; 105 } 106