diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h | 179 |
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; }; |
