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