Files
clang-p2996/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.h
Jon Chesterfield 74e928a081 [amdgpu][lds] Remove recalculation of LDS frame from backend
Do the LDS frame calculation once, in the IR pass, instead of repeating the work in the backend.

Prior to this patch:
The IR lowering pass sets up a per-kernel LDS frame and annotates the variables with absolute_symbol
metadata so that the assembler can build lookup tables out of it. There is a fragile association between
kernel functions and named structs which is used to recompute the frame layout in the backend, with
fatal_errors catching inconsistencies in the second calculation.

After this patch:
The IR lowering pass additionally sets a frame size attribute on kernels. The backend uses the same
absolute_symbol metadata that the assembler uses to place objects within that frame size.

Deleted the now dead allocation code from the backend. Left for a later cleanup:
- enabling lowering for anonymous functions
- removing the elide-module-lds attribute (test churn, it's not used by llc any more)
- adjusting the dynamic alignment check to not use symbol names

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D155190
2023-07-13 23:54:38 +01:00

117 lines
3.4 KiB
C++

//===-- AMDGPUMachineFunctionInfo.h -------------------------------*- C++ -*-=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEFUNCTION_H
#define LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEFUNCTION_H
#include "Utils/AMDGPUBaseInfo.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
namespace llvm {
class AMDGPUSubtarget;
class GCNSubtarget;
class AMDGPUMachineFunction : public MachineFunctionInfo {
/// A map to keep track of local memory objects and their offsets within the
/// local memory space.
SmallDenseMap<const GlobalValue *, unsigned, 4> LocalMemoryObjects;
protected:
uint64_t ExplicitKernArgSize = 0; // Cache for this.
Align MaxKernArgAlign; // Cache for this.
/// Number of bytes in the LDS that are being used.
uint32_t LDSSize = 0;
uint32_t GDSSize = 0;
/// Number of bytes in the LDS allocated statically. This field is only used
/// in the instruction selector and not part of the machine function info.
uint32_t StaticLDSSize = 0;
uint32_t StaticGDSSize = 0;
/// Align for dynamic shared memory if any. Dynamic shared memory is
/// allocated directly after the static one, i.e., LDSSize. Need to pad
/// LDSSize to ensure that dynamic one is aligned accordingly.
/// The maximal alignment is updated during IR translation or lowering
/// stages.
Align DynLDSAlign;
// Kernels + shaders. i.e. functions called by the hardware and not called
// by other functions.
bool IsEntryFunction = false;
// Entry points called by other functions instead of directly by the hardware.
bool IsModuleEntryFunction = false;
bool NoSignedZerosFPMath = false;
// Function may be memory bound.
bool MemoryBound = false;
// Kernel may need limited waves per EU for better performance.
bool WaveLimiter = false;
public:
AMDGPUMachineFunction(const Function &F, const AMDGPUSubtarget &ST);
uint64_t getExplicitKernArgSize() const {
return ExplicitKernArgSize;
}
Align getMaxKernArgAlign() const { return MaxKernArgAlign; }
uint32_t getLDSSize() const {
return LDSSize;
}
uint32_t getGDSSize() const {
return GDSSize;
}
bool isEntryFunction() const {
return IsEntryFunction;
}
bool isModuleEntryFunction() const { return IsModuleEntryFunction; }
bool hasNoSignedZerosFPMath() const {
return NoSignedZerosFPMath;
}
bool isMemoryBound() const {
return MemoryBound;
}
bool needsWaveLimiter() const {
return WaveLimiter;
}
unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV) {
return allocateLDSGlobal(DL, GV, DynLDSAlign);
}
unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV,
Align Trailing);
static std::optional<uint32_t> getLDSKernelIdMetadata(const Function &F);
static std::optional<uint32_t> getLDSAbsoluteAddress(const GlobalValue &GV);
Align getDynLDSAlign() const { return DynLDSAlign; }
void setDynLDSAlign(const Function &F, const GlobalVariable &GV);
};
}
#endif