diff options
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 73 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h | 8 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/LLVMBuild.txt | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 19 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp | 39 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h | 54 |
6 files changed, 188 insertions, 7 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index dd763903397..23ba6ce9334 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -24,11 +24,13 @@ #include "GCNIterativeScheduler.h" #include "GCNSchedStrategy.h" #include "R600MachineScheduler.h" +#include "SIMachineFunctionInfo.h" #include "SIMachineScheduler.h" #include "llvm/CodeGen/GlobalISel/IRTranslator.h" #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" #include "llvm/CodeGen/GlobalISel/Legalizer.h" #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" +#include "llvm/CodeGen/MIRParser/MIParser.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetPassConfig.h" #include "llvm/IR/Attributes.h" @@ -930,3 +932,74 @@ void GCNPassConfig::addPreEmitPass() { TargetPassConfig *GCNTargetMachine::createPassConfig(PassManagerBase &PM) { return new GCNPassConfig(*this, PM); } + +yaml::MachineFunctionInfo *GCNTargetMachine::createDefaultFuncInfoYAML() const { + return new yaml::SIMachineFunctionInfo(); +} + +yaml::MachineFunctionInfo * +GCNTargetMachine::convertFuncInfoToYAML(const MachineFunction &MF) const { + const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); + return new yaml::SIMachineFunctionInfo(*MFI, + *MF.getSubtarget().getRegisterInfo()); +} + +bool GCNTargetMachine::parseMachineFunctionInfo( + const yaml::MachineFunctionInfo &MFI_, PerFunctionMIParsingState &PFS, + SMDiagnostic &Error, SMRange &SourceRange) const { + const yaml::SIMachineFunctionInfo &YamlMFI = + reinterpret_cast<const yaml::SIMachineFunctionInfo &>(MFI_); + MachineFunction &MF = PFS.MF; + SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); + + MFI->initializeBaseYamlFields(YamlMFI); + + auto parseRegister = [&](const yaml::StringValue &RegName, unsigned &RegVal) { + if (parseNamedRegisterReference(PFS, RegVal, RegName.Value, Error)) { + SourceRange = RegName.SourceRange; + return true; + } + + return false; + }; + + auto diagnoseRegisterClass = [&](const yaml::StringValue &RegName) { + // Create a diagnostic for a the register string literal. + const MemoryBuffer &Buffer = + *PFS.SM->getMemoryBuffer(PFS.SM->getMainFileID()); + Error = SMDiagnostic(*PFS.SM, SMLoc(), Buffer.getBufferIdentifier(), 1, + RegName.Value.size(), SourceMgr::DK_Error, + "incorrect register class for field", RegName.Value, + None, None); + SourceRange = RegName.SourceRange; + return true; + }; + + if (parseRegister(YamlMFI.ScratchRSrcReg, MFI->ScratchRSrcReg) || + parseRegister(YamlMFI.ScratchWaveOffsetReg, MFI->ScratchWaveOffsetReg) || + parseRegister(YamlMFI.FrameOffsetReg, MFI->FrameOffsetReg) || + parseRegister(YamlMFI.StackPtrOffsetReg, MFI->StackPtrOffsetReg)) + return true; + + if (MFI->ScratchRSrcReg != AMDGPU::PRIVATE_RSRC_REG && + !AMDGPU::SReg_128RegClass.contains(MFI->ScratchRSrcReg)) { + return diagnoseRegisterClass(YamlMFI.ScratchRSrcReg); + } + + if (MFI->ScratchWaveOffsetReg != AMDGPU::SCRATCH_WAVE_OFFSET_REG && + !AMDGPU::SGPR_32RegClass.contains(MFI->ScratchWaveOffsetReg)) { + return diagnoseRegisterClass(YamlMFI.ScratchWaveOffsetReg); + } + + if (MFI->FrameOffsetReg != AMDGPU::FP_REG && + !AMDGPU::SGPR_32RegClass.contains(MFI->FrameOffsetReg)) { + return diagnoseRegisterClass(YamlMFI.FrameOffsetReg); + } + + if (MFI->StackPtrOffsetReg != AMDGPU::SP_REG && + !AMDGPU::SGPR_32RegClass.contains(MFI->StackPtrOffsetReg)) { + return diagnoseRegisterClass(YamlMFI.StackPtrOffsetReg); + } + + return false; +} diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h index b8805f08bc0..70fa3961236 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.h @@ -110,6 +110,14 @@ public: bool useIPRA() const override { return true; } + + yaml::MachineFunctionInfo *createDefaultFuncInfoYAML() const override; + yaml::MachineFunctionInfo * + convertFuncInfoToYAML(const MachineFunction &MF) const override; + bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &, + PerFunctionMIParsingState &PFS, + SMDiagnostic &Error, + SMRange &SourceRange) const override; }; } // end namespace llvm diff --git a/llvm/lib/Target/AMDGPU/LLVMBuild.txt b/llvm/lib/Target/AMDGPU/LLVMBuild.txt index 2f661af14f9..e18085d0ae5 100644 --- a/llvm/lib/Target/AMDGPU/LLVMBuild.txt +++ b/llvm/lib/Target/AMDGPU/LLVMBuild.txt @@ -29,5 +29,5 @@ has_disassembler = 1 type = Library name = AMDGPUCodeGen parent = AMDGPU -required_libraries = Analysis AsmPrinter CodeGen Core IPO MC AMDGPUAsmPrinter AMDGPUDesc AMDGPUInfo AMDGPUUtils Scalar SelectionDAG Support Target TransformUtils Vectorize GlobalISel BinaryFormat +required_libraries = Analysis AsmPrinter CodeGen Core IPO MC AMDGPUAsmPrinter AMDGPUDesc AMDGPUInfo AMDGPUUtils Scalar SelectionDAG Support Target TransformUtils Vectorize GlobalISel BinaryFormat MIRParser add_to_library_groups = AMDGPU diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 9205c20cefc..f6253317073 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -9607,13 +9607,22 @@ void SITargetLowering::finalizeLowering(MachineFunction &MF) const { assert(Info->getStackPtrOffsetReg() != Info->getFrameOffsetReg()); assert(!TRI->isSubRegister(Info->getScratchRSrcReg(), Info->getStackPtrOffsetReg())); - MRI.replaceRegWith(AMDGPU::SP_REG, Info->getStackPtrOffsetReg()); + if (Info->getStackPtrOffsetReg() != AMDGPU::SP_REG) + MRI.replaceRegWith(AMDGPU::SP_REG, Info->getStackPtrOffsetReg()); } - MRI.replaceRegWith(AMDGPU::PRIVATE_RSRC_REG, Info->getScratchRSrcReg()); - MRI.replaceRegWith(AMDGPU::FP_REG, Info->getFrameOffsetReg()); - MRI.replaceRegWith(AMDGPU::SCRATCH_WAVE_OFFSET_REG, - Info->getScratchWaveOffsetReg()); + // We need to worry about replacing the default register with itself in case + // of MIR testcases missing the MFI. + if (Info->getScratchRSrcReg() != AMDGPU::PRIVATE_RSRC_REG) + MRI.replaceRegWith(AMDGPU::PRIVATE_RSRC_REG, Info->getScratchRSrcReg()); + + if (Info->getFrameOffsetReg() != AMDGPU::FP_REG) + MRI.replaceRegWith(AMDGPU::FP_REG, Info->getFrameOffsetReg()); + + if (Info->getScratchWaveOffsetReg() != AMDGPU::SCRATCH_WAVE_OFFSET_REG) { + MRI.replaceRegWith(AMDGPU::SCRATCH_WAVE_OFFSET_REG, + Info->getScratchWaveOffsetReg()); + } Info->limitOccupancy(MF); diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp index 78e88abda68..834f651c42d 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp @@ -319,3 +319,42 @@ MCPhysReg SIMachineFunctionInfo::getNextUserSGPR() const { MCPhysReg SIMachineFunctionInfo::getNextSystemSGPR() const { return AMDGPU::SGPR0 + NumUserSGPRs + NumSystemSGPRs; } + +static yaml::StringValue regToString(unsigned Reg, + const TargetRegisterInfo &TRI) { + yaml::StringValue Dest; + raw_string_ostream OS(Dest.Value); + OS << printReg(Reg, &TRI); + return Dest; +} + +yaml::SIMachineFunctionInfo::SIMachineFunctionInfo( + const llvm::SIMachineFunctionInfo& MFI, + const TargetRegisterInfo &TRI) + : ExplicitKernArgSize(MFI.getExplicitKernArgSize()), + MaxKernArgAlign(MFI.getMaxKernArgAlign()), + LDSSize(MFI.getLDSSize()), + IsEntryFunction(MFI.isEntryFunction()), + NoSignedZerosFPMath(MFI.hasNoSignedZerosFPMath()), + MemoryBound(MFI.isMemoryBound()), + WaveLimiter(MFI.needsWaveLimiter()), + ScratchRSrcReg(regToString(MFI.getScratchRSrcReg(), TRI)), + ScratchWaveOffsetReg(regToString(MFI.getScratchWaveOffsetReg(), TRI)), + FrameOffsetReg(regToString(MFI.getFrameOffsetReg(), TRI)), + StackPtrOffsetReg(regToString(MFI.getStackPtrOffsetReg(), TRI)) {} + +void yaml::SIMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) { + MappingTraits<SIMachineFunctionInfo>::mapping(YamlIO, *this); +} + +bool SIMachineFunctionInfo::initializeBaseYamlFields( + const yaml::SIMachineFunctionInfo &YamlMFI) { + ExplicitKernArgSize = YamlMFI.ExplicitKernArgSize; + MaxKernArgAlign = YamlMFI.MaxKernArgAlign; + LDSSize = YamlMFI.LDSSize; + IsEntryFunction = YamlMFI.IsEntryFunction; + NoSignedZerosFPMath = YamlMFI.NoSignedZerosFPMath; + MemoryBound = YamlMFI.MemoryBound; + WaveLimiter = YamlMFI.WaveLimiter; + return false; +} diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h index de84fbbd776..ce103dcc31b 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h @@ -15,13 +15,14 @@ #include "AMDGPUArgumentUsageInfo.h" #include "AMDGPUMachineFunction.h" +#include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "SIInstrInfo.h" #include "SIRegisterInfo.h" -#include "MCTargetDesc/AMDGPUMCTargetDesc.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/MIRYamlMapping.h" #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/CodeGen/TargetInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" @@ -78,9 +79,58 @@ public: } }; +namespace yaml { + +struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo { + uint64_t ExplicitKernArgSize = 0; + unsigned MaxKernArgAlign = 0; + unsigned LDSSize = 0; + bool IsEntryFunction = false; + bool NoSignedZerosFPMath = false; + bool MemoryBound = false; + bool WaveLimiter = false; + + StringValue ScratchRSrcReg = "$private_rsrc_reg"; + StringValue ScratchWaveOffsetReg = "$scratch_wave_offset_reg"; + StringValue FrameOffsetReg = "$fp_reg"; + StringValue StackPtrOffsetReg = "$sp_reg"; + + SIMachineFunctionInfo() = default; + SIMachineFunctionInfo(const llvm::SIMachineFunctionInfo &, + const TargetRegisterInfo &TRI); + + void mappingImpl(yaml::IO &YamlIO) override; + ~SIMachineFunctionInfo() = default; +}; + +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("ldsSize", MFI.LDSSize, 0u); + YamlIO.mapOptional("isEntryFunction", MFI.IsEntryFunction, false); + YamlIO.mapOptional("noSignedZerosFPMath", MFI.NoSignedZerosFPMath, false); + YamlIO.mapOptional("memoryBound", MFI.MemoryBound, false); + YamlIO.mapOptional("waveLimiter", MFI.WaveLimiter, false); + YamlIO.mapOptional("scratchRSrcReg", MFI.ScratchRSrcReg, + StringValue("$private_rsrc_reg")); + YamlIO.mapOptional("scratchWaveOffsetReg", MFI.ScratchWaveOffsetReg, + StringValue("$scratch_wave_offset_reg")); + YamlIO.mapOptional("frameOffsetReg", MFI.FrameOffsetReg, + StringValue("$fp_reg")); + YamlIO.mapOptional("stackPtrOffsetReg", MFI.StackPtrOffsetReg, + StringValue("$sp_reg")); + } +}; + +} // end namespace yaml + /// This class keeps track of the SPI_SP_INPUT_ADDR config register, which /// tells the hardware which interpolation parameters to load. class SIMachineFunctionInfo final : public AMDGPUMachineFunction { + friend class GCNTargetMachine; + unsigned TIDReg = AMDGPU::NoRegister; // Registers that may be reserved for spilling purposes. These may be the same @@ -219,6 +269,8 @@ private: public: SIMachineFunctionInfo(const MachineFunction &MF); + bool initializeBaseYamlFields(const yaml::SIMachineFunctionInfo &YamlMFI); + ArrayRef<SpilledReg> getSGPRToVGPRSpills(int FrameIndex) const { auto I = SGPRToVGPRSpills.find(FrameIndex); return (I == SGPRToVGPRSpills.end()) ? |

