summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2019-07-19 14:29:30 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2019-07-19 14:29:30 +0000
commitb60a2ae40e73bce69f8dbf120f14e3491b70c17f (patch)
treed8031d5c08c5ddcb126b7aeb94aa05c2675110c0 /llvm/lib
parentfecf43eba3630aeb55c56e5d308f99a7bd05bfbe (diff)
downloadbcm5719-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.cpp75
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h2
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,
OpenPOWER on IntegriCloud