1*0b57cec5SDimitry Andric //===-- AMDGPUMachineFunctionInfo.cpp ---------------------------------------=//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #include "AMDGPUMachineFunction.h"
10*0b57cec5SDimitry Andric #include "AMDGPUPerfHintAnalysis.h"
11e8d8bef9SDimitry Andric #include "AMDGPUSubtarget.h"
12*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
13e8d8bef9SDimitry Andric #include "llvm/Target/TargetMachine.h"
14*0b57cec5SDimitry Andric 
15*0b57cec5SDimitry Andric using namespace llvm;
16*0b57cec5SDimitry Andric 
17e8d8bef9SDimitry Andric AMDGPUMachineFunction::AMDGPUMachineFunction(const MachineFunction &MF)
18e8d8bef9SDimitry Andric     : MachineFunctionInfo(), Mode(MF.getFunction()),
19e8d8bef9SDimitry Andric       IsEntryFunction(
20e8d8bef9SDimitry Andric           AMDGPU::isEntryFunctionCC(MF.getFunction().getCallingConv())),
21e8d8bef9SDimitry Andric       IsModuleEntryFunction(
22e8d8bef9SDimitry Andric           AMDGPU::isModuleEntryFunctionCC(MF.getFunction().getCallingConv())),
235ffd83dbSDimitry Andric       NoSignedZerosFPMath(MF.getTarget().Options.NoSignedZerosFPMath) {
24*0b57cec5SDimitry Andric   const AMDGPUSubtarget &ST = AMDGPUSubtarget::get(MF);
25*0b57cec5SDimitry Andric 
26*0b57cec5SDimitry Andric   // FIXME: Should initialize KernArgSize based on ExplicitKernelArgOffset,
27*0b57cec5SDimitry Andric   // except reserved size is not correctly aligned.
28*0b57cec5SDimitry Andric   const Function &F = MF.getFunction();
29*0b57cec5SDimitry Andric 
30*0b57cec5SDimitry Andric   Attribute MemBoundAttr = F.getFnAttribute("amdgpu-memory-bound");
31*0b57cec5SDimitry Andric   MemoryBound = MemBoundAttr.isStringAttribute() &&
32*0b57cec5SDimitry Andric                 MemBoundAttr.getValueAsString() == "true";
33*0b57cec5SDimitry Andric 
34*0b57cec5SDimitry Andric   Attribute WaveLimitAttr = F.getFnAttribute("amdgpu-wave-limiter");
35*0b57cec5SDimitry Andric   WaveLimiter = WaveLimitAttr.isStringAttribute() &&
36*0b57cec5SDimitry Andric                 WaveLimitAttr.getValueAsString() == "true";
37*0b57cec5SDimitry Andric 
38*0b57cec5SDimitry Andric   CallingConv::ID CC = F.getCallingConv();
39*0b57cec5SDimitry Andric   if (CC == CallingConv::AMDGPU_KERNEL || CC == CallingConv::SPIR_KERNEL)
40*0b57cec5SDimitry Andric     ExplicitKernArgSize = ST.getExplicitKernArgSize(F, MaxKernArgAlign);
41*0b57cec5SDimitry Andric }
42*0b57cec5SDimitry Andric 
43*0b57cec5SDimitry Andric unsigned AMDGPUMachineFunction::allocateLDSGlobal(const DataLayout &DL,
445ffd83dbSDimitry Andric                                                   const GlobalVariable &GV) {
45*0b57cec5SDimitry Andric   auto Entry = LocalMemoryObjects.insert(std::make_pair(&GV, 0));
46*0b57cec5SDimitry Andric   if (!Entry.second)
47*0b57cec5SDimitry Andric     return Entry.first->second;
48*0b57cec5SDimitry Andric 
495ffd83dbSDimitry Andric   Align Alignment =
505ffd83dbSDimitry Andric       DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType());
51*0b57cec5SDimitry Andric 
52*0b57cec5SDimitry Andric   /// TODO: We should sort these to minimize wasted space due to alignment
53*0b57cec5SDimitry Andric   /// padding. Currently the padding is decided by the first encountered use
54*0b57cec5SDimitry Andric   /// during lowering.
55e8d8bef9SDimitry Andric   unsigned Offset = StaticLDSSize = alignTo(StaticLDSSize, Alignment);
56*0b57cec5SDimitry Andric 
57*0b57cec5SDimitry Andric   Entry.first->second = Offset;
58e8d8bef9SDimitry Andric   StaticLDSSize += DL.getTypeAllocSize(GV.getValueType());
59e8d8bef9SDimitry Andric 
60e8d8bef9SDimitry Andric   // Update the LDS size considering the padding to align the dynamic shared
61e8d8bef9SDimitry Andric   // memory.
62e8d8bef9SDimitry Andric   LDSSize = alignTo(StaticLDSSize, DynLDSAlign);
63*0b57cec5SDimitry Andric 
64*0b57cec5SDimitry Andric   return Offset;
65*0b57cec5SDimitry Andric }
66e8d8bef9SDimitry Andric 
67e8d8bef9SDimitry Andric void AMDGPUMachineFunction::setDynLDSAlign(const DataLayout &DL,
68e8d8bef9SDimitry Andric                                            const GlobalVariable &GV) {
69e8d8bef9SDimitry Andric   assert(DL.getTypeAllocSize(GV.getValueType()).isZero());
70e8d8bef9SDimitry Andric 
71e8d8bef9SDimitry Andric   Align Alignment =
72e8d8bef9SDimitry Andric       DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType());
73e8d8bef9SDimitry Andric   if (Alignment <= DynLDSAlign)
74e8d8bef9SDimitry Andric     return;
75e8d8bef9SDimitry Andric 
76e8d8bef9SDimitry Andric   LDSSize = alignTo(StaticLDSSize, Alignment);
77e8d8bef9SDimitry Andric   DynLDSAlign = Alignment;
78e8d8bef9SDimitry Andric }
79