xref: /src/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.h (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
101095a5dSDimitry Andric //===-- AMDGPUMachineFunctionInfo.h -------------------------------*- C++ -*-=//
23a0822f0SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63a0822f0SDimitry Andric //
73a0822f0SDimitry Andric //===----------------------------------------------------------------------===//
83a0822f0SDimitry Andric 
901095a5dSDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEFUNCTION_H
1001095a5dSDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEFUNCTION_H
113a0822f0SDimitry Andric 
12b60736ecSDimitry Andric #include "Utils/AMDGPUBaseInfo.h"
13b915e9e0SDimitry Andric #include "llvm/ADT/DenseMap.h"
147ab83427SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
15145449b1SDimitry Andric #include "llvm/IR/DataLayout.h"
164b4fe385SDimitry Andric #include "llvm/IR/Function.h"
17145449b1SDimitry Andric #include "llvm/IR/GlobalValue.h"
18145449b1SDimitry Andric #include "llvm/IR/GlobalVariable.h"
193a0822f0SDimitry Andric 
203a0822f0SDimitry Andric namespace llvm {
213a0822f0SDimitry Andric 
22e3b55780SDimitry Andric class AMDGPUSubtarget;
23e3b55780SDimitry Andric 
243a0822f0SDimitry Andric class AMDGPUMachineFunction : public MachineFunctionInfo {
25b915e9e0SDimitry Andric   /// A map to keep track of local memory objects and their offsets within the
26b915e9e0SDimitry Andric   /// local memory space.
27b915e9e0SDimitry Andric   SmallDenseMap<const GlobalValue *, unsigned, 4> LocalMemoryObjects;
28b915e9e0SDimitry Andric 
29eb11fae6SDimitry Andric protected:
30cfca06d7SDimitry Andric   uint64_t ExplicitKernArgSize = 0; // Cache for this.
311d5ae102SDimitry Andric   Align MaxKernArgAlign;        // Cache for this.
3201095a5dSDimitry Andric 
33b915e9e0SDimitry Andric   /// Number of bytes in the LDS that are being used.
34145449b1SDimitry Andric   uint32_t LDSSize = 0;
35145449b1SDimitry Andric   uint32_t GDSSize = 0;
36b915e9e0SDimitry Andric 
37b60736ecSDimitry Andric   /// Number of bytes in the LDS allocated statically. This field is only used
38b60736ecSDimitry Andric   /// in the instruction selector and not part of the machine function info.
39145449b1SDimitry Andric   uint32_t StaticLDSSize = 0;
40145449b1SDimitry Andric   uint32_t StaticGDSSize = 0;
41b60736ecSDimitry Andric 
42b60736ecSDimitry Andric   /// Align for dynamic shared memory if any. Dynamic shared memory is
43b60736ecSDimitry Andric   /// allocated directly after the static one, i.e., LDSSize. Need to pad
44b60736ecSDimitry Andric   /// LDSSize to ensure that dynamic one is aligned accordingly.
45b60736ecSDimitry Andric   /// The maximal alignment is updated during IR translation or lowering
46b60736ecSDimitry Andric   /// stages.
47b60736ecSDimitry Andric   Align DynLDSAlign;
48b60736ecSDimitry Andric 
49aca2e42cSDimitry Andric   // Flag to check dynamic LDS usage by kernel.
50aca2e42cSDimitry Andric   bool UsesDynamicLDS = false;
51aca2e42cSDimitry Andric 
52b60736ecSDimitry Andric   // Kernels + shaders. i.e. functions called by the hardware and not called
5371d5a254SDimitry Andric   // by other functions.
54cfca06d7SDimitry Andric   bool IsEntryFunction = false;
5571d5a254SDimitry Andric 
56b60736ecSDimitry Andric   // Entry points called by other functions instead of directly by the hardware.
57b60736ecSDimitry Andric   bool IsModuleEntryFunction = false;
58b60736ecSDimitry Andric 
59b1c73532SDimitry Andric   // Functions with the amdgpu_cs_chain or amdgpu_cs_chain_preserve CC.
60b1c73532SDimitry Andric   bool IsChainFunction = false;
61b1c73532SDimitry Andric 
62cfca06d7SDimitry Andric   bool NoSignedZerosFPMath = false;
633a0822f0SDimitry Andric 
64eb11fae6SDimitry Andric   // Function may be memory bound.
65cfca06d7SDimitry Andric   bool MemoryBound = false;
66eb11fae6SDimitry Andric 
67eb11fae6SDimitry Andric   // Kernel may need limited waves per EU for better performance.
68cfca06d7SDimitry Andric   bool WaveLimiter = false;
69eb11fae6SDimitry Andric 
703a0822f0SDimitry Andric public:
71e3b55780SDimitry Andric   AMDGPUMachineFunction(const Function &F, const AMDGPUSubtarget &ST);
7201095a5dSDimitry Andric 
getExplicitKernArgSize()73eb11fae6SDimitry Andric   uint64_t getExplicitKernArgSize() const {
74eb11fae6SDimitry Andric     return ExplicitKernArgSize;
75b915e9e0SDimitry Andric   }
763a0822f0SDimitry Andric 
getMaxKernArgAlign()77145449b1SDimitry Andric   Align getMaxKernArgAlign() const { return MaxKernArgAlign; }
783a0822f0SDimitry Andric 
getLDSSize()79145449b1SDimitry Andric   uint32_t getLDSSize() const {
80b915e9e0SDimitry Andric     return LDSSize;
81b915e9e0SDimitry Andric   }
82b915e9e0SDimitry Andric 
getGDSSize()83145449b1SDimitry Andric   uint32_t getGDSSize() const {
84145449b1SDimitry Andric     return GDSSize;
85145449b1SDimitry Andric   }
86145449b1SDimitry Andric 
isEntryFunction()8771d5a254SDimitry Andric   bool isEntryFunction() const {
8871d5a254SDimitry Andric     return IsEntryFunction;
8971d5a254SDimitry Andric   }
9071d5a254SDimitry Andric 
isModuleEntryFunction()91b60736ecSDimitry Andric   bool isModuleEntryFunction() const { return IsModuleEntryFunction; }
92b60736ecSDimitry Andric 
isChainFunction()93b1c73532SDimitry Andric   bool isChainFunction() const { return IsChainFunction; }
94b1c73532SDimitry Andric 
95b1c73532SDimitry Andric   // The stack is empty upon entry to this function.
isBottomOfStack()96b1c73532SDimitry Andric   bool isBottomOfStack() const {
97b1c73532SDimitry Andric     return isEntryFunction() || isChainFunction();
98b1c73532SDimitry Andric   }
99b1c73532SDimitry Andric 
hasNoSignedZerosFPMath()10071d5a254SDimitry Andric   bool hasNoSignedZerosFPMath() const {
10171d5a254SDimitry Andric     return NoSignedZerosFPMath;
102b915e9e0SDimitry Andric   }
103b915e9e0SDimitry Andric 
isMemoryBound()104eb11fae6SDimitry Andric   bool isMemoryBound() const {
105eb11fae6SDimitry Andric     return MemoryBound;
106eb11fae6SDimitry Andric   }
107eb11fae6SDimitry Andric 
needsWaveLimiter()108eb11fae6SDimitry Andric   bool needsWaveLimiter() const {
109eb11fae6SDimitry Andric     return WaveLimiter;
110eb11fae6SDimitry Andric   }
111eb11fae6SDimitry Andric 
allocateLDSGlobal(const DataLayout & DL,const GlobalVariable & GV)112e3b55780SDimitry Andric   unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV) {
113e3b55780SDimitry Andric     return allocateLDSGlobal(DL, GV, DynLDSAlign);
114e3b55780SDimitry Andric   }
115b60736ecSDimitry Andric 
116e3b55780SDimitry Andric   unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV,
117e3b55780SDimitry Andric                              Align Trailing);
118e3b55780SDimitry Andric 
119e3b55780SDimitry Andric   static std::optional<uint32_t> getLDSKernelIdMetadata(const Function &F);
1207fa27ce4SDimitry Andric   static std::optional<uint32_t> getLDSAbsoluteAddress(const GlobalValue &GV);
1214b4fe385SDimitry Andric 
getDynLDSAlign()122b60736ecSDimitry Andric   Align getDynLDSAlign() const { return DynLDSAlign; }
123b60736ecSDimitry Andric 
1247fa27ce4SDimitry Andric   void setDynLDSAlign(const Function &F, const GlobalVariable &GV);
125aca2e42cSDimitry Andric 
126aca2e42cSDimitry Andric   void setUsesDynamicLDS(bool DynLDS);
127aca2e42cSDimitry Andric 
128aca2e42cSDimitry Andric   bool isDynamicLDSUsed() const;
1293a0822f0SDimitry Andric };
1303a0822f0SDimitry Andric 
1311a82d4c0SDimitry Andric }
1323a0822f0SDimitry Andric #endif
133