diff options
| author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-07-19 14:29:30 +0000 |
|---|---|---|
| committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-07-19 14:29:30 +0000 |
| commit | b60a2ae40e73bce69f8dbf120f14e3491b70c17f (patch) | |
| tree | d8031d5c08c5ddcb126b7aeb94aa05c2675110c0 /llvm/lib | |
| parent | fecf43eba3630aeb55c56e5d308f99a7bd05bfbe (diff) | |
| download | bcm5719-llvm-b60a2ae40e73bce69f8dbf120f14e3491b70c17f.tar.gz bcm5719-llvm-b60a2ae40e73bce69f8dbf120f14e3491b70c17f.zip | |
AMDGPU/GlobalISel: Support arguments with multiple registers
Handles structs used directly in argument lists.
llvm-svn: 366584
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp | 75 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h | 2 |
2 files changed, 47 insertions, 30 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp index a118743f4d8..8fc55cba494 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp @@ -152,33 +152,45 @@ void AMDGPUCallLowering::splitToValueTypes( SmallVector<EVT, 4> SplitVTs; ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs); - EVT VT = SplitVTs[0]; - unsigned NumParts = TLI.getNumRegistersForCallingConv(Ctx, CallConv, VT); - - if (NumParts == 1) { - // No splitting to do, but we want to replace the original type (e.g. [1 x - // double] -> double). - SplitArgs.emplace_back(OrigArg.Regs[0], VT.getTypeForEVT(Ctx), - OrigArg.Flags, OrigArg.IsFixed); - return; - } + assert(OrigArg.Regs.size() == SplitVTs.size()); - LLT LLTy = getLLTForType(*OrigArg.Ty, DL); - SmallVector<Register, 8> SplitRegs; + int SplitIdx = 0; + for (EVT VT : SplitVTs) { + unsigned NumParts = TLI.getNumRegistersForCallingConv(Ctx, CallConv, VT); + Type *Ty = VT.getTypeForEVT(Ctx); - EVT PartVT = TLI.getRegisterTypeForCallingConv(Ctx, CallConv, VT); - Type *PartTy = PartVT.getTypeForEVT(Ctx); - LLT PartLLT = getLLTForType(*PartTy, DL); - // FIXME: Should we be reporting all of the part registers for a single - // argument, and let handleAssignments take care of the repacking? - for (unsigned i = 0; i < NumParts; ++i) { - Register PartReg = MRI.createGenericVirtualRegister(PartLLT); - SplitRegs.push_back(PartReg); - SplitArgs.emplace_back(ArrayRef<Register>(PartReg), PartTy, OrigArg.Flags); - } - PerformArgSplit(SplitRegs, LLTy, PartLLT); + if (NumParts == 1) { + // No splitting to do, but we want to replace the original type (e.g. [1 x + // double] -> double). + SplitArgs.emplace_back(OrigArg.Regs[SplitIdx], Ty, + OrigArg.Flags, OrigArg.IsFixed); + + ++SplitIdx; + continue; + } + + LLT LLTy = getLLTForType(*Ty, DL); + + SmallVector<Register, 8> SplitRegs; + + EVT PartVT = TLI.getRegisterTypeForCallingConv(Ctx, CallConv, VT); + Type *PartTy = PartVT.getTypeForEVT(Ctx); + LLT PartLLT = getLLTForType(*PartTy, DL); + + // FIXME: Should we be reporting all of the part registers for a single + // argument, and let handleAssignments take care of the repacking? + for (unsigned i = 0; i < NumParts; ++i) { + Register PartReg = MRI.createGenericVirtualRegister(PartLLT); + SplitRegs.push_back(PartReg); + SplitArgs.emplace_back(ArrayRef<Register>(PartReg), PartTy, OrigArg.Flags); + } + + PerformArgSplit(SplitRegs, LLTy, PartLLT, SplitIdx); + + ++SplitIdx; + } } bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, @@ -485,11 +497,11 @@ bool AMDGPUCallLowering::lowerFormalArguments( if (!IsShader && InReg) return false; - // TODO: Handle multiple registers and sret. + // TODO: Handle sret. if (Arg.hasAttribute(Attribute::StructRet) || Arg.hasAttribute(Attribute::SwiftSelf) || Arg.hasAttribute(Attribute::SwiftError) || - Arg.hasAttribute(Attribute::Nest) || VRegs[Idx].size() > 1) + Arg.hasAttribute(Attribute::Nest)) return false; if (CC == CallingConv::AMDGPU_PS && !InReg && PSInputNum <= 15) { @@ -505,7 +517,9 @@ bool AMDGPUCallLowering::lowerFormalArguments( ++PSInputNum; if (SkipArg) { - MIRBuilder.buildUndef(VRegs[Idx][0]); + for (int I = 0, E = VRegs[Idx].size(); I != E; ++I) + MIRBuilder.buildUndef(VRegs[Idx][I]); + ++Idx; continue; } @@ -513,11 +527,14 @@ bool AMDGPUCallLowering::lowerFormalArguments( ArgInfo OrigArg(VRegs[Idx], Arg.getType()); setArgFlags(OrigArg, Idx + AttributeList::FirstArgIndex, DL, F); - splitToValueTypes(OrigArg, SplitArgs, DL, MRI, CC, + + splitToValueTypes( + OrigArg, SplitArgs, DL, MRI, CC, // FIXME: We should probably be passing multiple registers to // handleAssignments to do this - [&](ArrayRef<Register> Regs, LLT LLTy, LLT PartLLT) { - packSplitRegsToOrigType(MIRBuilder, VRegs[Idx], Regs, LLTy, PartLLT); + [&](ArrayRef<Register> Regs, LLT LLTy, LLT PartLLT, int VTSplitIdx) { + packSplitRegsToOrigType(MIRBuilder, VRegs[Idx][VTSplitIdx], Regs, + LLTy, PartLLT); }); ++Idx; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h index 97f8c85b9e7..bc345b6c659 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h @@ -30,7 +30,7 @@ class AMDGPUCallLowering: public CallLowering { Register DstReg) const; /// A function of this type is used to perform value split action. - using SplitArgTy = std::function<void(ArrayRef<Register>, LLT, LLT)>; + using SplitArgTy = std::function<void(ArrayRef<Register>, LLT, LLT, int)>; void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl<ArgInfo> &SplitArgs, |

