| //===-- AMDGPUMachineFunctionInfo.cpp ---------------------------------------=// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "AMDGPUMachineFunction.h" |
| #include "AMDGPUPerfHintAnalysis.h" |
| #include "AMDGPUSubtarget.h" |
| #include "llvm/CodeGen/MachineModuleInfo.h" |
| #include "llvm/Target/TargetMachine.h" |
| |
| using namespace llvm; |
| |
| AMDGPUMachineFunction::AMDGPUMachineFunction(const MachineFunction &MF) |
| : MachineFunctionInfo(), Mode(MF.getFunction()), |
| IsEntryFunction( |
| AMDGPU::isEntryFunctionCC(MF.getFunction().getCallingConv())), |
| IsModuleEntryFunction( |
| AMDGPU::isModuleEntryFunctionCC(MF.getFunction().getCallingConv())), |
| NoSignedZerosFPMath(MF.getTarget().Options.NoSignedZerosFPMath) { |
| const AMDGPUSubtarget &ST = AMDGPUSubtarget::get(MF); |
| |
| // FIXME: Should initialize KernArgSize based on ExplicitKernelArgOffset, |
| // except reserved size is not correctly aligned. |
| const Function &F = MF.getFunction(); |
| |
| Attribute MemBoundAttr = F.getFnAttribute("amdgpu-memory-bound"); |
| MemoryBound = MemBoundAttr.getValueAsBool(); |
| |
| Attribute WaveLimitAttr = F.getFnAttribute("amdgpu-wave-limiter"); |
| WaveLimiter = WaveLimitAttr.getValueAsBool(); |
| |
| CallingConv::ID CC = F.getCallingConv(); |
| if (CC == CallingConv::AMDGPU_KERNEL || CC == CallingConv::SPIR_KERNEL) |
| ExplicitKernArgSize = ST.getExplicitKernArgSize(F, MaxKernArgAlign); |
| } |
| |
| unsigned AMDGPUMachineFunction::allocateLDSGlobal(const DataLayout &DL, |
| const GlobalVariable &GV) { |
| auto Entry = LocalMemoryObjects.insert(std::make_pair(&GV, 0)); |
| if (!Entry.second) |
| return Entry.first->second; |
| |
| Align Alignment = |
| DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType()); |
| |
| /// TODO: We should sort these to minimize wasted space due to alignment |
| /// padding. Currently the padding is decided by the first encountered use |
| /// during lowering. |
| unsigned Offset = StaticLDSSize = alignTo(StaticLDSSize, Alignment); |
| |
| Entry.first->second = Offset; |
| StaticLDSSize += DL.getTypeAllocSize(GV.getValueType()); |
| |
| // Update the LDS size considering the padding to align the dynamic shared |
| // memory. |
| LDSSize = alignTo(StaticLDSSize, DynLDSAlign); |
| |
| return Offset; |
| } |
| |
| void AMDGPUMachineFunction::allocateModuleLDSGlobal(const Module *M) { |
| if (isModuleEntryFunction()) { |
| const GlobalVariable *GV = M->getNamedGlobal("llvm.amdgcn.module.lds"); |
| if (GV) { |
| unsigned Offset = allocateLDSGlobal(M->getDataLayout(), *GV); |
| (void)Offset; |
| assert(Offset == 0 && |
| "Module LDS expected to be allocated before other LDS"); |
| } |
| } |
| } |
| |
| void AMDGPUMachineFunction::setDynLDSAlign(const DataLayout &DL, |
| const GlobalVariable &GV) { |
| assert(DL.getTypeAllocSize(GV.getValueType()).isZero()); |
| |
| Align Alignment = |
| DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType()); |
| if (Alignment <= DynLDSAlign) |
| return; |
| |
| LDSSize = alignTo(StaticLDSSize, Alignment); |
| DynLDSAlign = Alignment; |
| } |