diff options
author | Michael Liao <michael.hliao@gmail.com> | 2019-07-03 02:00:21 +0000 |
---|---|---|
committer | Michael Liao <michael.hliao@gmail.com> | 2019-07-03 02:00:21 +0000 |
commit | 80177ca5a9b0731b62943e30c7d8f39e7664bb82 (patch) | |
tree | 6a25550f313815ad117b0209b7e21728dc85e1dc /llvm/lib | |
parent | cac1151845e6b55d38ecac014438e64f8feae687 (diff) | |
download | llvm-80177ca5a9b0731b62943e30c7d8f39e7664bb82.zip llvm-80177ca5a9b0731b62943e30c7d8f39e7664bb82.tar.gz llvm-80177ca5a9b0731b62943e30c7d8f39e7664bb82.tar.bz2 |
[AMDGPU] Enable serializing of argument info.
Summary:
- Support serialization of all arguments in machine function info. This
enables fabricating MIR tests depending on argument info.
Reviewers: arsenm, rampitec
Subscribers: kzhuravl, jvesely, wdng, nhaehnle, yaxunl, dstuttard, tpr, t-tye, hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D64096
llvm-svn: 364995
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 79 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp | 54 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h | 121 |
3 files changed, 253 insertions, 1 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index 8e4f35a..667c6f3 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -1059,5 +1059,84 @@ bool GCNTargetMachine::parseMachineFunctionInfo( return diagnoseRegisterClass(YamlMFI.StackPtrOffsetReg); } + auto parseAndCheckArgument = [&](const Optional<yaml::SIArgument> &A, + const TargetRegisterClass &RC, + ArgDescriptor &Arg) { + // Skip parsing if it's not present. + if (!A) + return false; + + if (A->IsRegister) { + unsigned Reg; + if (parseNamedRegisterReference(PFS, Reg, A->RegisterName.Value, + Error)) { + SourceRange = A->RegisterName.SourceRange; + return true; + } + if (!RC.contains(Reg)) + return diagnoseRegisterClass(A->RegisterName); + Arg = ArgDescriptor::createRegister(Reg); + } else + Arg = ArgDescriptor::createStack(A->StackOffset); + // Check and apply the optional mask. + if (A->Mask) + Arg = ArgDescriptor::createArg(Arg, A->Mask.getValue()); + + return false; + }; + + if (YamlMFI.ArgInfo && + (parseAndCheckArgument(YamlMFI.ArgInfo->PrivateSegmentBuffer, + AMDGPU::SReg_128RegClass, + MFI->ArgInfo.PrivateSegmentBuffer) || + parseAndCheckArgument(YamlMFI.ArgInfo->DispatchPtr, + AMDGPU::SReg_64RegClass, + MFI->ArgInfo.DispatchPtr) || + parseAndCheckArgument(YamlMFI.ArgInfo->QueuePtr, AMDGPU::SReg_64RegClass, + MFI->ArgInfo.QueuePtr) || + parseAndCheckArgument(YamlMFI.ArgInfo->KernargSegmentPtr, + AMDGPU::SReg_64RegClass, + MFI->ArgInfo.KernargSegmentPtr) || + parseAndCheckArgument(YamlMFI.ArgInfo->DispatchID, + AMDGPU::SReg_64RegClass, + MFI->ArgInfo.DispatchID) || + parseAndCheckArgument(YamlMFI.ArgInfo->FlatScratchInit, + AMDGPU::SReg_64RegClass, + MFI->ArgInfo.FlatScratchInit) || + parseAndCheckArgument(YamlMFI.ArgInfo->PrivateSegmentSize, + AMDGPU::SGPR_32RegClass, + MFI->ArgInfo.PrivateSegmentSize) || + parseAndCheckArgument(YamlMFI.ArgInfo->WorkGroupIDX, + AMDGPU::SGPR_32RegClass, + MFI->ArgInfo.WorkGroupIDX) || + parseAndCheckArgument(YamlMFI.ArgInfo->WorkGroupIDY, + AMDGPU::SGPR_32RegClass, + MFI->ArgInfo.WorkGroupIDY) || + parseAndCheckArgument(YamlMFI.ArgInfo->WorkGroupIDZ, + AMDGPU::SGPR_32RegClass, + MFI->ArgInfo.WorkGroupIDZ) || + parseAndCheckArgument(YamlMFI.ArgInfo->WorkGroupInfo, + AMDGPU::SGPR_32RegClass, + MFI->ArgInfo.WorkGroupInfo) || + parseAndCheckArgument(YamlMFI.ArgInfo->PrivateSegmentWaveByteOffset, + AMDGPU::SGPR_32RegClass, + MFI->ArgInfo.PrivateSegmentWaveByteOffset) || + parseAndCheckArgument(YamlMFI.ArgInfo->ImplicitArgPtr, + AMDGPU::SReg_64RegClass, + MFI->ArgInfo.ImplicitArgPtr) || + parseAndCheckArgument(YamlMFI.ArgInfo->ImplicitBufferPtr, + AMDGPU::SReg_64RegClass, + MFI->ArgInfo.ImplicitBufferPtr) || + parseAndCheckArgument(YamlMFI.ArgInfo->WorkItemIDX, + AMDGPU::VGPR_32RegClass, + MFI->ArgInfo.WorkItemIDX) || + parseAndCheckArgument(YamlMFI.ArgInfo->WorkItemIDY, + AMDGPU::VGPR_32RegClass, + MFI->ArgInfo.WorkItemIDY) || + parseAndCheckArgument(YamlMFI.ArgInfo->WorkItemIDZ, + AMDGPU::VGPR_32RegClass, + MFI->ArgInfo.WorkItemIDZ))) + return true; + return false; } diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp index 8bb8ea7..f7d6172 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp @@ -324,6 +324,57 @@ static yaml::StringValue regToString(unsigned Reg, return Dest; } +static Optional<yaml::SIArgumentInfo> +convertArgumentInfo(const AMDGPUFunctionArgInfo &ArgInfo, + const TargetRegisterInfo &TRI) { + yaml::SIArgumentInfo AI; + + auto convertArg = [&](Optional<yaml::SIArgument> &A, + const ArgDescriptor &Arg) { + if (!Arg) + return false; + + // Create a register or stack argument. + yaml::SIArgument SA = yaml::SIArgument::createArgument(Arg.isRegister()); + if (Arg.isRegister()) { + raw_string_ostream OS(SA.RegisterName.Value); + OS << printReg(Arg.getRegister(), &TRI); + } else + SA.StackOffset = Arg.getStackOffset(); + // Check and update the optional mask. + if (Arg.isMasked()) + SA.Mask = Arg.getMask(); + + A = SA; + return true; + }; + + bool Any = false; + Any |= convertArg(AI.PrivateSegmentBuffer, ArgInfo.PrivateSegmentBuffer); + Any |= convertArg(AI.DispatchPtr, ArgInfo.DispatchPtr); + Any |= convertArg(AI.QueuePtr, ArgInfo.QueuePtr); + Any |= convertArg(AI.KernargSegmentPtr, ArgInfo.KernargSegmentPtr); + Any |= convertArg(AI.DispatchID, ArgInfo.DispatchID); + Any |= convertArg(AI.FlatScratchInit, ArgInfo.FlatScratchInit); + Any |= convertArg(AI.PrivateSegmentSize, ArgInfo.PrivateSegmentSize); + Any |= convertArg(AI.WorkGroupIDX, ArgInfo.WorkGroupIDX); + Any |= convertArg(AI.WorkGroupIDY, ArgInfo.WorkGroupIDY); + Any |= convertArg(AI.WorkGroupIDZ, ArgInfo.WorkGroupIDZ); + Any |= convertArg(AI.WorkGroupInfo, ArgInfo.WorkGroupInfo); + Any |= convertArg(AI.PrivateSegmentWaveByteOffset, + ArgInfo.PrivateSegmentWaveByteOffset); + Any |= convertArg(AI.ImplicitArgPtr, ArgInfo.ImplicitArgPtr); + Any |= convertArg(AI.ImplicitBufferPtr, ArgInfo.ImplicitBufferPtr); + Any |= convertArg(AI.WorkItemIDX, ArgInfo.WorkItemIDX); + Any |= convertArg(AI.WorkItemIDY, ArgInfo.WorkItemIDY); + Any |= convertArg(AI.WorkItemIDZ, ArgInfo.WorkItemIDZ); + + if (Any) + return AI; + + return None; +} + yaml::SIMachineFunctionInfo::SIMachineFunctionInfo( const llvm::SIMachineFunctionInfo& MFI, const TargetRegisterInfo &TRI) @@ -337,7 +388,8 @@ yaml::SIMachineFunctionInfo::SIMachineFunctionInfo( ScratchRSrcReg(regToString(MFI.getScratchRSrcReg(), TRI)), ScratchWaveOffsetReg(regToString(MFI.getScratchWaveOffsetReg(), TRI)), FrameOffsetReg(regToString(MFI.getFrameOffsetReg(), TRI)), - StackPtrOffsetReg(regToString(MFI.getStackPtrOffsetReg(), TRI)) {} + StackPtrOffsetReg(regToString(MFI.getStackPtrOffsetReg(), TRI)), + ArgInfo(convertArgumentInfo(MFI.getArgInfo(), TRI)) {} void yaml::SIMachineFunctionInfo::mappingImpl(yaml::IO &YamlIO) { MappingTraits<SIMachineFunctionInfo>::mapping(YamlIO, *this); diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h index 329b38c..7339363 100644 --- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h +++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h @@ -21,6 +21,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SparseBitVector.h" #include "llvm/CodeGen/MIRYamlMapping.h" @@ -114,6 +115,123 @@ public: namespace yaml { +struct SIArgument { + bool IsRegister; + union { + StringValue RegisterName; + unsigned StackOffset; + }; + Optional<unsigned> Mask; + + // Default constructor, which creates a stack argument. + SIArgument() : IsRegister(false), StackOffset(0) {} + SIArgument(const SIArgument &Other) { + IsRegister = Other.IsRegister; + if (IsRegister) { + ::new ((void *)std::addressof(RegisterName)) + StringValue(Other.RegisterName); + } else + StackOffset = Other.StackOffset; + Mask = Other.Mask; + } + SIArgument &operator=(const SIArgument &Other) { + IsRegister = Other.IsRegister; + if (IsRegister) { + ::new ((void *)std::addressof(RegisterName)) + StringValue(Other.RegisterName); + } else + StackOffset = Other.StackOffset; + Mask = Other.Mask; + return *this; + } + ~SIArgument() { + if (IsRegister) + RegisterName.~StringValue(); + } + + // Helper to create a register or stack argument. + static inline SIArgument createArgument(bool IsReg) { + if (IsReg) + return SIArgument(IsReg); + return SIArgument(); + } + +private: + // Construct a register argument. + SIArgument(bool) : IsRegister(true), RegisterName() {} +}; + +template <> struct MappingTraits<SIArgument> { + static void mapping(IO &YamlIO, SIArgument &A) { + if (YamlIO.outputting()) { + if (A.IsRegister) + YamlIO.mapRequired("reg", A.RegisterName); + else + YamlIO.mapRequired("offset", A.StackOffset); + } else { + auto Keys = YamlIO.keys(); + if (is_contained(Keys, "reg")) { + A = SIArgument::createArgument(true); + YamlIO.mapRequired("reg", A.RegisterName); + } else if (is_contained(Keys, "offset")) + YamlIO.mapRequired("offset", A.StackOffset); + else + YamlIO.setError("missing required key 'reg' or 'offset'"); + } + YamlIO.mapOptional("mask", A.Mask); + } + static const bool flow = true; +}; + +struct SIArgumentInfo { + Optional<SIArgument> PrivateSegmentBuffer; + Optional<SIArgument> DispatchPtr; + Optional<SIArgument> QueuePtr; + Optional<SIArgument> KernargSegmentPtr; + Optional<SIArgument> DispatchID; + Optional<SIArgument> FlatScratchInit; + Optional<SIArgument> PrivateSegmentSize; + + Optional<SIArgument> WorkGroupIDX; + Optional<SIArgument> WorkGroupIDY; + Optional<SIArgument> WorkGroupIDZ; + Optional<SIArgument> WorkGroupInfo; + Optional<SIArgument> PrivateSegmentWaveByteOffset; + + Optional<SIArgument> ImplicitArgPtr; + Optional<SIArgument> ImplicitBufferPtr; + + Optional<SIArgument> WorkItemIDX; + Optional<SIArgument> WorkItemIDY; + Optional<SIArgument> WorkItemIDZ; +}; + +template <> struct MappingTraits<SIArgumentInfo> { + static void mapping(IO &YamlIO, SIArgumentInfo &AI) { + YamlIO.mapOptional("privateSegmentBuffer", AI.PrivateSegmentBuffer); + YamlIO.mapOptional("dispatchPtr", AI.DispatchPtr); + YamlIO.mapOptional("queuePtr", AI.QueuePtr); + YamlIO.mapOptional("kernargSegmentPtr", AI.KernargSegmentPtr); + YamlIO.mapOptional("dispatchID", AI.DispatchID); + YamlIO.mapOptional("flatScratchInit", AI.FlatScratchInit); + YamlIO.mapOptional("privateSegmentSize", AI.PrivateSegmentSize); + + YamlIO.mapOptional("workGroupIDX", AI.WorkGroupIDX); + YamlIO.mapOptional("workGroupIDY", AI.WorkGroupIDY); + YamlIO.mapOptional("workGroupIDZ", AI.WorkGroupIDZ); + YamlIO.mapOptional("workGroupInfo", AI.WorkGroupInfo); + YamlIO.mapOptional("privateSegmentWaveByteOffset", + AI.PrivateSegmentWaveByteOffset); + + YamlIO.mapOptional("implicitArgPtr", AI.ImplicitArgPtr); + YamlIO.mapOptional("implicitBufferPtr", AI.ImplicitBufferPtr); + + YamlIO.mapOptional("workItemIDX", AI.WorkItemIDX); + YamlIO.mapOptional("workItemIDY", AI.WorkItemIDY); + YamlIO.mapOptional("workItemIDZ", AI.WorkItemIDZ); + } +}; + struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo { uint64_t ExplicitKernArgSize = 0; unsigned MaxKernArgAlign = 0; @@ -128,6 +246,8 @@ struct SIMachineFunctionInfo final : public yaml::MachineFunctionInfo { StringValue FrameOffsetReg = "$fp_reg"; StringValue StackPtrOffsetReg = "$sp_reg"; + Optional<SIArgumentInfo> ArgInfo; + SIMachineFunctionInfo() = default; SIMachineFunctionInfo(const llvm::SIMachineFunctionInfo &, const TargetRegisterInfo &TRI); @@ -154,6 +274,7 @@ template <> struct MappingTraits<SIMachineFunctionInfo> { StringValue("$fp_reg")); YamlIO.mapOptional("stackPtrOffsetReg", MFI.StackPtrOffsetReg, StringValue("$sp_reg")); + YamlIO.mapOptional("argumentInfo", MFI.ArgInfo); } }; |