1//===-- AMDGPUMachineFunctionInfo.h -------------------------------*- C++ -*-=//
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#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEFUNCTION_H
10#define LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEFUNCTION_H
11
12#include "Utils/AMDGPUBaseInfo.h"
13#include "llvm/ADT/DenseMap.h"
14#include "llvm/CodeGen/MachineFunction.h"
15#include "llvm/IR/DataLayout.h"
16#include "llvm/IR/Function.h"
17#include "llvm/IR/GlobalValue.h"
18#include "llvm/IR/GlobalVariable.h"
19
20namespace llvm {
21
22class AMDGPUSubtarget;
23
24class AMDGPUMachineFunction : public MachineFunctionInfo {
25 /// A map to keep track of local memory objects and their offsets within the
26 /// local memory space.
27 SmallDenseMap<const GlobalValue *, unsigned, 4> LocalMemoryObjects;
28
29protected:
30 uint64_t ExplicitKernArgSize = 0; // Cache for this.
31 Align MaxKernArgAlign; // Cache for this.
32
33 /// Number of bytes in the LDS that are being used.
34 uint32_t LDSSize = 0;
35 uint32_t GDSSize = 0;
36
37 /// Number of bytes in the LDS allocated statically. This field is only used
38 /// in the instruction selector and not part of the machine function info.
39 uint32_t StaticLDSSize = 0;
40 uint32_t StaticGDSSize = 0;
41
42 /// Align for dynamic shared memory if any. Dynamic shared memory is
43 /// allocated directly after the static one, i.e., LDSSize. Need to pad
44 /// LDSSize to ensure that dynamic one is aligned accordingly.
45 /// The maximal alignment is updated during IR translation or lowering
46 /// stages.
47 Align DynLDSAlign;
48
49 // Flag to check dynamic LDS usage by kernel.
50 bool UsesDynamicLDS = false;
51
52 uint32_t NumNamedBarriers = 0;
53
54 // Kernels + shaders. i.e. functions called by the hardware and not called
55 // by other functions.
56 bool IsEntryFunction = false;
57
58 // Entry points called by other functions instead of directly by the hardware.
59 bool IsModuleEntryFunction = false;
60
61 // Functions with the amdgpu_cs_chain or amdgpu_cs_chain_preserve CC.
62 bool IsChainFunction = false;
63
64 // Function may be memory bound.
65 bool MemoryBound = false;
66
67 // Kernel may need limited waves per EU for better performance.
68 bool WaveLimiter = false;
69
70 bool HasInitWholeWave = false;
71
72public:
73 AMDGPUMachineFunction(const Function &F, const AMDGPUSubtarget &ST);
74
75 uint64_t getExplicitKernArgSize() const {
76 return ExplicitKernArgSize;
77 }
78
79 Align getMaxKernArgAlign() const { return MaxKernArgAlign; }
80
81 uint32_t getLDSSize() const {
82 return LDSSize;
83 }
84
85 uint32_t getGDSSize() const {
86 return GDSSize;
87 }
88
89 void recordNumNamedBarriers(uint32_t GVAddr, unsigned BarCnt) {
90 NumNamedBarriers =
91 std::max(a: NumNamedBarriers, b: ((GVAddr & 0x1ff) >> 4) + BarCnt - 1);
92 }
93 uint32_t getNumNamedBarriers() const { return NumNamedBarriers; }
94
95 bool isEntryFunction() const {
96 return IsEntryFunction;
97 }
98
99 bool isModuleEntryFunction() const { return IsModuleEntryFunction; }
100
101 bool isChainFunction() const { return IsChainFunction; }
102
103 // The stack is empty upon entry to this function.
104 bool isBottomOfStack() const {
105 return isEntryFunction() || isChainFunction();
106 }
107
108 bool isMemoryBound() const {
109 return MemoryBound;
110 }
111
112 bool needsWaveLimiter() const {
113 return WaveLimiter;
114 }
115
116 bool hasInitWholeWave() const { return HasInitWholeWave; }
117 void setInitWholeWave() { HasInitWholeWave = true; }
118
119 unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV) {
120 return allocateLDSGlobal(DL, GV, Trailing: DynLDSAlign);
121 }
122
123 unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV,
124 Align Trailing);
125
126 static std::optional<uint32_t> getLDSKernelIdMetadata(const Function &F);
127 static std::optional<uint32_t> getLDSAbsoluteAddress(const GlobalValue &GV);
128
129 Align getDynLDSAlign() const { return DynLDSAlign; }
130
131 void setDynLDSAlign(const Function &F, const GlobalVariable &GV);
132
133 void setUsesDynamicLDS(bool DynLDS);
134
135 bool isDynamicLDSUsed() const;
136};
137
138}
139#endif
140