summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h')
-rw-r--r--llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h179
1 files changed, 103 insertions, 76 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
index 8e821274bb77..bebb13cbf09f 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
@@ -15,9 +15,10 @@
#include "AMDGPUArgumentUsageInfo.h"
#include "AMDGPUMachineFunction.h"
+#include "AMDGPUTargetMachine.h"
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
#include "SIInstrInfo.h"
-#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/CodeGen/MIRYamlMapping.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Support/raw_ostream.h"
@@ -39,8 +40,8 @@ public:
};
protected:
- AMDGPUPseudoSourceValue(unsigned Kind, const TargetInstrInfo &TII)
- : PseudoSourceValue(Kind, TII) {}
+ AMDGPUPseudoSourceValue(unsigned Kind, const AMDGPUTargetMachine &TM)
+ : PseudoSourceValue(Kind, TM) {}
public:
bool isConstant(const MachineFrameInfo *) const override {
@@ -60,8 +61,8 @@ public:
class AMDGPUBufferPseudoSourceValue final : public AMDGPUPseudoSourceValue {
public:
- explicit AMDGPUBufferPseudoSourceValue(const TargetInstrInfo &TII)
- : AMDGPUPseudoSourceValue(PSVBuffer, TII) {}
+ explicit AMDGPUBufferPseudoSourceValue(const AMDGPUTargetMachine &TM)
+ : AMDGPUPseudoSourceValue(PSVBuffer, TM) {}
static bool classof(const PseudoSourceValue *V) {
return V->kind() == PSVBuffer;
@@ -73,8 +74,8 @@ public:
class AMDGPUImagePseudoSourceValue final : public AMDGPUPseudoSourceValue {
public:
// TODO: Is the img rsrc useful?
- explicit AMDGPUImagePseudoSourceValue(const TargetInstrInfo &TII)
- : AMDGPUPseudoSourceValue(PSVImage, TII) {}
+ explicit AMDGPUImagePseudoSourceValue(const AMDGPUTargetMachine &TM)
+ : AMDGPUPseudoSourceValue(PSVImage, TM) {}
static bool classof(const PseudoSourceValue *V) {
return V->kind() == PSVImage;
@@ -85,8 +86,8 @@ public:
class AMDGPUGWSResourcePseudoSourceValue final : public AMDGPUPseudoSourceValue {
public:
- explicit AMDGPUGWSResourcePseudoSourceValue(const TargetInstrInfo &TII)
- : AMDGPUPseudoSourceValue(GWSResource, TII) {}
+ explicit AMDGPUGWSResourcePseudoSourceValue(const AMDGPUTargetMachine &TM)
+ : AMDGPUPseudoSourceValue(GWSResource, TM) {}
static bool classof(const PseudoSourceValue *V) {
return V->kind() == GWSResource;
@@ -269,8 +270,9 @@ template <> struct MappingTraits<SIMode> {
struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo {
uint64_t ExplicitKernArgSize = 0;
- unsigned MaxKernArgAlign = 0;
- unsigned LDSSize = 0;
+ Align MaxKernArgAlign;
+ uint32_t LDSSize = 0;
+ uint32_t GDSSize = 0;
Align DynLDSAlign;
bool IsEntryFunction = false;
bool NoSignedZerosFPMath = false;
@@ -283,13 +285,19 @@ struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo {
// TODO: 10 may be a better default since it's the maximum.
unsigned Occupancy = 0;
+ SmallVector<StringValue> WWMReservedRegs;
+
StringValue ScratchRSrcReg = "$private_rsrc_reg";
StringValue FrameOffsetReg = "$fp_reg";
StringValue StackPtrOffsetReg = "$sp_reg";
+ unsigned BytesInStackArgArea = 0;
+ bool ReturnsVoid = true;
+
Optional<SIArgumentInfo> ArgInfo;
SIMode Mode;
Optional<FrameIndex> ScavengeFI;
+ StringValue VGPRForAGPRCopy;
SIMachineFunctionInfo() = default;
SIMachineFunctionInfo(const llvm::SIMachineFunctionInfo &,
@@ -304,8 +312,9 @@ template <> struct MappingTraits<SIMachineFunctionInfo> {
static void mapping(IO &YamlIO, SIMachineFunctionInfo &MFI) {
YamlIO.mapOptional("explicitKernArgSize", MFI.ExplicitKernArgSize,
UINT64_C(0));
- YamlIO.mapOptional("maxKernArgAlign", MFI.MaxKernArgAlign, 0u);
+ YamlIO.mapOptional("maxKernArgAlign", MFI.MaxKernArgAlign);
YamlIO.mapOptional("ldsSize", MFI.LDSSize, 0u);
+ YamlIO.mapOptional("gdsSize", MFI.GDSSize, 0u);
YamlIO.mapOptional("dynLDSAlign", MFI.DynLDSAlign, Align());
YamlIO.mapOptional("isEntryFunction", MFI.IsEntryFunction, false);
YamlIO.mapOptional("noSignedZerosFPMath", MFI.NoSignedZerosFPMath, false);
@@ -319,12 +328,17 @@ template <> struct MappingTraits<SIMachineFunctionInfo> {
StringValue("$fp_reg"));
YamlIO.mapOptional("stackPtrOffsetReg", MFI.StackPtrOffsetReg,
StringValue("$sp_reg"));
+ YamlIO.mapOptional("bytesInStackArgArea", MFI.BytesInStackArgArea, 0u);
+ YamlIO.mapOptional("returnsVoid", MFI.ReturnsVoid, true);
YamlIO.mapOptional("argumentInfo", MFI.ArgInfo);
YamlIO.mapOptional("mode", MFI.Mode, SIMode());
YamlIO.mapOptional("highBitsOf32BitAddress",
MFI.HighBitsOf32BitAddress, 0u);
YamlIO.mapOptional("occupancy", MFI.Occupancy, 0);
+ YamlIO.mapOptional("wwmReservedRegs", MFI.WWMReservedRegs);
YamlIO.mapOptional("scavengeFI", MFI.ScavengeFI);
+ YamlIO.mapOptional("vgprForAGPRCopy", MFI.VGPRForAGPRCopy,
+ StringValue()); // Don't print out when it's empty.
}
};
@@ -335,8 +349,6 @@ template <> struct MappingTraits<SIMachineFunctionInfo> {
class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
friend class GCNTargetMachine;
- Register TIDReg = AMDGPU::NoRegister;
-
// Registers that may be reserved for spilling purposes. These may be the same
// as the input registers.
Register ScratchRSrcReg = AMDGPU::PRIVATE_RSRC_REG;
@@ -377,12 +389,11 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunction {
// unit. Minimum - first, maximum - second.
std::pair<unsigned, unsigned> WavesPerEU = {0, 0};
- std::unique_ptr<const AMDGPUBufferPseudoSourceValue> BufferPSV;
- std::unique_ptr<const AMDGPUImagePseudoSourceValue> ImagePSV;
- std::unique_ptr<const AMDGPUGWSResourcePseudoSourceValue> GWSResourcePSV;
+ const AMDGPUBufferPseudoSourceValue BufferPSV;
+ const AMDGPUImagePseudoSourceValue ImagePSV;
+ const AMDGPUGWSResourcePseudoSourceValue GWSResourcePSV;
private:
- unsigned LDSWaveSpillSize = 0;
unsigned NumUserSGPRs = 0;
unsigned NumSystemSGPRs = 0;
@@ -422,13 +433,14 @@ private:
// user arguments. This is an offset from the KernargSegmentPtr.
bool ImplicitArgPtr : 1;
+ bool MayNeedAGPRs : 1;
+
// The hard-wired high half of the address of the global information table
// for AMDPAL OS type. 0xffffffff represents no hard-wired high half, since
// current hardware only allows a 16 bit value.
unsigned GITPtrHigh;
unsigned HighBitsOf32BitAddress;
- unsigned GDSSize;
// Current recorded maximum possible occupancy.
unsigned Occupancy;
@@ -440,17 +452,6 @@ private:
MCPhysReg getNextSystemSGPR() const;
public:
- struct SpilledReg {
- Register VGPR;
- int Lane = -1;
-
- SpilledReg() = default;
- SpilledReg(Register R, int L) : VGPR (R), Lane (L) {}
-
- bool hasLane() { return Lane != -1;}
- bool hasReg() { return VGPR != 0;}
- };
-
struct SGPRSpillVGPR {
// VGPR used for SGPR spills
Register VGPR;
@@ -468,14 +469,28 @@ public:
bool IsDead = false;
};
- // Map WWM VGPR to a stack slot that is used to save/restore it in the
- // prolog/epilog.
- MapVector<Register, Optional<int>> WWMReservedRegs;
+ // Track VGPRs reserved for WWM.
+ SmallSetVector<Register, 8> WWMReservedRegs;
+
+ /// Track stack slots used for save/restore of reserved WWM VGPRs in the
+ /// prolog/epilog.
+
+ /// FIXME: This is temporary state only needed in PrologEpilogInserter, and
+ /// doesn't really belong here. It does not require serialization
+ SmallVector<int, 8> WWMReservedFrameIndexes;
+
+ void allocateWWMReservedSpillSlots(MachineFrameInfo &MFI,
+ const SIRegisterInfo &TRI);
+
+ auto wwmAllocation() const {
+ assert(WWMReservedRegs.size() == WWMReservedFrameIndexes.size());
+ return zip(WWMReservedRegs, WWMReservedFrameIndexes);
+ }
private:
// Track VGPR + wave index for each subregister of the SGPR spilled to
// frameindex key.
- DenseMap<int, std::vector<SpilledReg>> SGPRToVGPRSpills;
+ DenseMap<int, std::vector<SIRegisterInfo::SpilledReg>> SGPRToVGPRSpills;
unsigned NumVGPRSpillLanes = 0;
SmallVector<SGPRSpillVGPR, 2> SpillVGPRs;
@@ -491,6 +506,18 @@ private:
// frame, so save it here and add it to the RegScavenger later.
Optional<int> ScavengeFI;
+private:
+ Register VGPRForAGPRCopy;
+
+public:
+ Register getVGPRForAGPRCopy() const {
+ return VGPRForAGPRCopy;
+ }
+
+ void setVGPRForAGPRCopy(Register NewVGPRForAGPRCopy) {
+ VGPRForAGPRCopy = NewVGPRForAGPRCopy;
+ }
+
public: // FIXME
/// If this is set, an SGPR used for save/restore of the register used for the
/// frame pointer.
@@ -506,31 +533,32 @@ public: // FIXME
public:
SIMachineFunctionInfo(const MachineFunction &MF);
+ SIMachineFunctionInfo(const SIMachineFunctionInfo &MFI) = default;
+
+ MachineFunctionInfo *
+ clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
+ const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
+ const override;
bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI,
const MachineFunction &MF,
PerFunctionMIParsingState &PFS,
SMDiagnostic &Error, SMRange &SourceRange);
- void reserveWWMRegister(Register Reg, Optional<int> FI) {
- WWMReservedRegs.insert(std::make_pair(Reg, FI));
+ void reserveWWMRegister(Register Reg) {
+ WWMReservedRegs.insert(Reg);
}
- ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const {
+ ArrayRef<SIRegisterInfo::SpilledReg>
+ getSGPRToVGPRSpills(int FrameIndex) const {
auto I = SGPRToVGPRSpills.find(FrameIndex);
- return (I == SGPRToVGPRSpills.end()) ?
- ArrayRef<SpilledReg>() : makeArrayRef(I->second);
+ return (I == SGPRToVGPRSpills.end())
+ ? ArrayRef<SIRegisterInfo::SpilledReg>()
+ : makeArrayRef(I->second);
}
ArrayRef<SGPRSpillVGPR> getSGPRSpillVGPRs() const { return SpillVGPRs; }
- void setSGPRSpillVGPRs(Register NewVGPR, Optional<int> newFI, int Index) {
- SpillVGPRs[Index].VGPR = NewVGPR;
- SpillVGPRs[Index].FI = newFI;
- }
-
- bool removeVGPRForSGPRSpill(Register ReservedVGPR, MachineFunction &MF);
-
ArrayRef<MCPhysReg> getAGPRSpillVGPRs() const {
return SpillAGPR;
}
@@ -555,15 +583,15 @@ public:
unsigned NumLane) const;
bool allocateSGPRSpillToVGPR(MachineFunction &MF, int FI);
bool allocateVGPRSpillToAGPR(MachineFunction &MF, int FI, bool isAGPRtoVGPR);
- void removeDeadFrameIndices(MachineFrameInfo &MFI);
+
+ /// If \p ResetSGPRSpillStackIDs is true, reset the stack ID from sgpr-spill
+ /// to the default stack.
+ bool removeDeadFrameIndices(MachineFrameInfo &MFI,
+ bool ResetSGPRSpillStackIDs);
int getScavengeFI(MachineFrameInfo &MFI, const SIRegisterInfo &TRI);
Optional<int> getOptionalScavengeFI() const { return ScavengeFI; }
- bool hasCalculatedTID() const { return TIDReg != 0; };
- Register getTIDReg() const { return TIDReg; };
- void setTIDReg(Register Reg) { TIDReg = Reg; }
-
unsigned getBytesInStackArgArea() const {
return BytesInStackArgArea;
}
@@ -581,6 +609,13 @@ public:
Register addFlatScratchInit(const SIRegisterInfo &TRI);
Register addImplicitBufferPtr(const SIRegisterInfo &TRI);
+ /// Increment user SGPRs used for padding the argument list only.
+ Register addReservedUserSGPR() {
+ Register Next = getNextUserSGPR();
+ ++NumUserSGPRs;
+ return Next;
+ }
+
// Add system SGPRs.
Register addWorkGroupIDX() {
ArgInfo.WorkGroupIDX = ArgDescriptor::createRegister(getNextSystemSGPR());
@@ -722,10 +757,6 @@ public:
return HighBitsOf32BitAddress;
}
- unsigned getGDSSize() const {
- return GDSSize;
- }
-
unsigned getNumUserSGPRs() const {
return NumUserSGPRs;
}
@@ -903,31 +934,19 @@ public:
llvm_unreachable("unexpected dimension");
}
- unsigned getLDSWaveSpillSize() const {
- return LDSWaveSpillSize;
+ const AMDGPUBufferPseudoSourceValue *
+ getBufferPSV(const AMDGPUTargetMachine &TM) {
+ return &BufferPSV;
}
- const AMDGPUBufferPseudoSourceValue *getBufferPSV(const SIInstrInfo &TII) {
- if (!BufferPSV)
- BufferPSV = std::make_unique<AMDGPUBufferPseudoSourceValue>(TII);
-
- return BufferPSV.get();
- }
-
- const AMDGPUImagePseudoSourceValue *getImagePSV(const SIInstrInfo &TII) {
- if (!ImagePSV)
- ImagePSV = std::make_unique<AMDGPUImagePseudoSourceValue>(TII);
-
- return ImagePSV.get();
+ const AMDGPUImagePseudoSourceValue *
+ getImagePSV(const AMDGPUTargetMachine &TM) {
+ return &ImagePSV;
}
- const AMDGPUGWSResourcePseudoSourceValue *getGWSPSV(const SIInstrInfo &TII) {
- if (!GWSResourcePSV) {
- GWSResourcePSV =
- std::make_unique<AMDGPUGWSResourcePseudoSourceValue>(TII);
- }
-
- return GWSResourcePSV.get();
+ const AMDGPUGWSResourcePseudoSourceValue *
+ getGWSPSV(const AMDGPUTargetMachine &TM) {
+ return &GWSResourcePSV;
}
unsigned getOccupancy() const {
@@ -953,6 +972,14 @@ public:
limitOccupancy(MF);
}
+ bool mayNeedAGPRs() const {
+ return MayNeedAGPRs;
+ }
+
+ // \returns true if a function has a use of AGPRs via inline asm or
+ // has a call which may use it.
+ bool mayUseAGPRs(const MachineFunction &MF) const;
+
// \returns true if a function needs or may need AGPRs.
bool usesAGPRs(const MachineFunction &MF) const;
};