xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.h (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
10b57cec5SDimitry Andric //===-- AMDGPUMachineFunctionInfo.h -------------------------------*- C++ -*-=//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEFUNCTION_H
100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEFUNCTION_H
110b57cec5SDimitry Andric 
12e8d8bef9SDimitry Andric #include "Utils/AMDGPUBaseInfo.h"
130b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
140b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
1581ad6265SDimitry Andric #include "llvm/IR/DataLayout.h"
16fcaf7f86SDimitry Andric #include "llvm/IR/Function.h"
1781ad6265SDimitry Andric #include "llvm/IR/GlobalValue.h"
1881ad6265SDimitry Andric #include "llvm/IR/GlobalVariable.h"
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric namespace llvm {
210b57cec5SDimitry Andric 
22bdd1243dSDimitry Andric class AMDGPUSubtarget;
23bdd1243dSDimitry Andric 
240b57cec5SDimitry Andric class AMDGPUMachineFunction : public MachineFunctionInfo {
250b57cec5SDimitry Andric   /// A map to keep track of local memory objects and their offsets within the
260b57cec5SDimitry Andric   /// local memory space.
270b57cec5SDimitry Andric   SmallDenseMap<const GlobalValue *, unsigned, 4> LocalMemoryObjects;
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric protected:
305ffd83dbSDimitry Andric   uint64_t ExplicitKernArgSize = 0; // Cache for this.
318bcb0991SDimitry Andric   Align MaxKernArgAlign;        // Cache for this.
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric   /// Number of bytes in the LDS that are being used.
3481ad6265SDimitry Andric   uint32_t LDSSize = 0;
3581ad6265SDimitry Andric   uint32_t GDSSize = 0;
360b57cec5SDimitry Andric 
37e8d8bef9SDimitry Andric   /// Number of bytes in the LDS allocated statically. This field is only used
38e8d8bef9SDimitry Andric   /// in the instruction selector and not part of the machine function info.
3981ad6265SDimitry Andric   uint32_t StaticLDSSize = 0;
4081ad6265SDimitry Andric   uint32_t StaticGDSSize = 0;
41e8d8bef9SDimitry Andric 
42e8d8bef9SDimitry Andric   /// Align for dynamic shared memory if any. Dynamic shared memory is
43e8d8bef9SDimitry Andric   /// allocated directly after the static one, i.e., LDSSize. Need to pad
44e8d8bef9SDimitry Andric   /// LDSSize to ensure that dynamic one is aligned accordingly.
45e8d8bef9SDimitry Andric   /// The maximal alignment is updated during IR translation or lowering
46e8d8bef9SDimitry Andric   /// stages.
47e8d8bef9SDimitry Andric   Align DynLDSAlign;
48e8d8bef9SDimitry Andric 
49*1db9f3b2SDimitry Andric   // Flag to check dynamic LDS usage by kernel.
50*1db9f3b2SDimitry Andric   bool UsesDynamicLDS = false;
51*1db9f3b2SDimitry Andric 
52e8d8bef9SDimitry Andric   // Kernels + shaders. i.e. functions called by the hardware and not called
530b57cec5SDimitry Andric   // by other functions.
545ffd83dbSDimitry Andric   bool IsEntryFunction = false;
550b57cec5SDimitry Andric 
56e8d8bef9SDimitry Andric   // Entry points called by other functions instead of directly by the hardware.
57e8d8bef9SDimitry Andric   bool IsModuleEntryFunction = false;
58e8d8bef9SDimitry Andric 
595f757f3fSDimitry Andric   // Functions with the amdgpu_cs_chain or amdgpu_cs_chain_preserve CC.
605f757f3fSDimitry Andric   bool IsChainFunction = false;
615f757f3fSDimitry Andric 
625ffd83dbSDimitry Andric   bool NoSignedZerosFPMath = false;
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   // Function may be memory bound.
655ffd83dbSDimitry Andric   bool MemoryBound = false;
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   // Kernel may need limited waves per EU for better performance.
685ffd83dbSDimitry Andric   bool WaveLimiter = false;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric public:
71bdd1243dSDimitry Andric   AMDGPUMachineFunction(const Function &F, const AMDGPUSubtarget &ST);
720b57cec5SDimitry Andric 
getExplicitKernArgSize()730b57cec5SDimitry Andric   uint64_t getExplicitKernArgSize() const {
740b57cec5SDimitry Andric     return ExplicitKernArgSize;
750b57cec5SDimitry Andric   }
760b57cec5SDimitry Andric 
getMaxKernArgAlign()7781ad6265SDimitry Andric   Align getMaxKernArgAlign() const { return MaxKernArgAlign; }
780b57cec5SDimitry Andric 
getLDSSize()7981ad6265SDimitry Andric   uint32_t getLDSSize() const {
800b57cec5SDimitry Andric     return LDSSize;
810b57cec5SDimitry Andric   }
820b57cec5SDimitry Andric 
getGDSSize()8381ad6265SDimitry Andric   uint32_t getGDSSize() const {
8481ad6265SDimitry Andric     return GDSSize;
8581ad6265SDimitry Andric   }
8681ad6265SDimitry Andric 
isEntryFunction()870b57cec5SDimitry Andric   bool isEntryFunction() const {
880b57cec5SDimitry Andric     return IsEntryFunction;
890b57cec5SDimitry Andric   }
900b57cec5SDimitry Andric 
isModuleEntryFunction()91e8d8bef9SDimitry Andric   bool isModuleEntryFunction() const { return IsModuleEntryFunction; }
92e8d8bef9SDimitry Andric 
isChainFunction()935f757f3fSDimitry Andric   bool isChainFunction() const { return IsChainFunction; }
945f757f3fSDimitry Andric 
955f757f3fSDimitry Andric   // The stack is empty upon entry to this function.
isBottomOfStack()965f757f3fSDimitry Andric   bool isBottomOfStack() const {
975f757f3fSDimitry Andric     return isEntryFunction() || isChainFunction();
985f757f3fSDimitry Andric   }
995f757f3fSDimitry Andric 
hasNoSignedZerosFPMath()1000b57cec5SDimitry Andric   bool hasNoSignedZerosFPMath() const {
1010b57cec5SDimitry Andric     return NoSignedZerosFPMath;
1020b57cec5SDimitry Andric   }
1030b57cec5SDimitry Andric 
isMemoryBound()1040b57cec5SDimitry Andric   bool isMemoryBound() const {
1050b57cec5SDimitry Andric     return MemoryBound;
1060b57cec5SDimitry Andric   }
1070b57cec5SDimitry Andric 
needsWaveLimiter()1080b57cec5SDimitry Andric   bool needsWaveLimiter() const {
1090b57cec5SDimitry Andric     return WaveLimiter;
1100b57cec5SDimitry Andric   }
1110b57cec5SDimitry Andric 
allocateLDSGlobal(const DataLayout & DL,const GlobalVariable & GV)112bdd1243dSDimitry Andric   unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV) {
113bdd1243dSDimitry Andric     return allocateLDSGlobal(DL, GV, DynLDSAlign);
114bdd1243dSDimitry Andric   }
115e8d8bef9SDimitry Andric 
116bdd1243dSDimitry Andric   unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV,
117bdd1243dSDimitry Andric                              Align Trailing);
118bdd1243dSDimitry Andric 
119bdd1243dSDimitry Andric   static std::optional<uint32_t> getLDSKernelIdMetadata(const Function &F);
12006c3fb27SDimitry Andric   static std::optional<uint32_t> getLDSAbsoluteAddress(const GlobalValue &GV);
121fcaf7f86SDimitry Andric 
getDynLDSAlign()122e8d8bef9SDimitry Andric   Align getDynLDSAlign() const { return DynLDSAlign; }
123e8d8bef9SDimitry Andric 
12406c3fb27SDimitry Andric   void setDynLDSAlign(const Function &F, const GlobalVariable &GV);
125*1db9f3b2SDimitry Andric 
126*1db9f3b2SDimitry Andric   void setUsesDynamicLDS(bool DynLDS);
127*1db9f3b2SDimitry Andric 
128*1db9f3b2SDimitry Andric   bool isDynamicLDSUsed() const;
1290b57cec5SDimitry Andric };
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric }
1320b57cec5SDimitry Andric #endif
133