[GlobalISel] Accept multiple vregs for lowerCall's args
Change the interface of CallLowering::lowerCall to accept several
virtual registers for each argument, instead of just one. This is a
follow-up to D46018.
CallLowering::lowerReturn was similarly refactored in D49660 and
lowerFormalArguments in D63549.
With this change, we no longer pack the virtual registers generated for
aggregates into one big lump before delegating to the target. Therefore,
the target can decide itself whether it wants to handle them as separate
pieces or use one big register.
ARM and AArch64 have been updated to use the passed in virtual registers
directly, which means we no longer need to generate so many
merge/extract instructions.
NFCI for AMDGPU, Mips and X86.
Differential Revision: https://reviews.llvm.org/D63551
llvm-svn: 364512
diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index 0772021..d257bbc 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -29,7 +29,7 @@
bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, ImmutableCallSite CS,
ArrayRef<Register> ResRegs,
- ArrayRef<Register> ArgRegs,
+ ArrayRef<ArrayRef<Register>> ArgRegs,
Register SwiftErrorVReg,
std::function<unsigned()> GetCalleeReg) const {
auto &DL = CS.getParent()->getParent()->getParent()->getDataLayout();
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 2f07659..48b3a52 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -1587,8 +1587,8 @@
if (!F || !F->isIntrinsic() || ID == Intrinsic::not_intrinsic) {
ArrayRef<Register> Res = getOrCreateVRegs(CI);
- SmallVector<Register, 8> Args;
- Register SwiftErrorVReg;
+ SmallVector<ArrayRef<Register>, 8> Args;
+ Register SwiftErrorVReg = 0;
for (auto &Arg: CI.arg_operands()) {
if (CLI->supportSwiftError() && isSwiftError(Arg)) {
LLT Ty = getLLTForType(*Arg->getType(), *DL);
@@ -1600,7 +1600,7 @@
SwiftError.getOrCreateVRegDefAt(&CI, &MIRBuilder.getMBB(), Arg);
continue;
}
- Args.push_back(packRegs(*Arg, MIRBuilder));
+ Args.push_back(getOrCreateVRegs(*Arg));
}
MF->getFrameInfo().setHasCalls(true);
@@ -1684,7 +1684,7 @@
ArrayRef<Register> Res;
if (!I.getType()->isVoidTy())
Res = getOrCreateVRegs(I);
- SmallVector<Register, 8> Args;
+ SmallVector<ArrayRef<Register>, 8> Args;
Register SwiftErrorVReg = 0;
for (auto &Arg : I.arg_operands()) {
if (CLI->supportSwiftError() && isSwiftError(Arg)) {
@@ -1698,7 +1698,7 @@
continue;
}
- Args.push_back(packRegs(*Arg, MIRBuilder));
+ Args.push_back(getOrCreateVRegs(*Arg));
}
if (!CLI->lowerCall(MIRBuilder, &I, Res, Args, SwiftErrorVReg,
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
index 1fa12b0..76a858c 100644
--- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
@@ -441,10 +441,9 @@
SmallVector<ArgInfo, 8> SplitArgs;
for (auto &OrigArg : OrigArgs) {
- assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet");
splitToValueTypes(OrigArg, SplitArgs, DL, MRI, CallConv,
[&](Register Reg, uint64_t Offset) {
- MIRBuilder.buildExtract(Reg, OrigArg.Regs[0], Offset);
+ llvm_unreachable("Call params should already be split");
});
// AAPCS requires that we zero-extend i1 to 8 bits by the caller.
if (OrigArg.Ty->isIntegerTy(1))
diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp
index 71b9251..fdd94ab 100644
--- a/llvm/lib/Target/ARM/ARMCallLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp
@@ -596,14 +596,9 @@
if (Arg.Flags.isByVal())
return false;
- assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet");
-
- SmallVector<Register, 8> Regs;
- splitToValueTypes(Arg, ArgInfos, MF,
- [&](unsigned Reg) { Regs.push_back(Reg); });
-
- if (Regs.size() > 1)
- MIRBuilder.buildUnmerge(Regs, Arg.Regs[0]);
+ splitToValueTypes(Arg, ArgInfos, MF, [&](Register Reg) {
+ llvm_unreachable("Function args should already be split");
+ });
}
auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, IsVarArg);
diff --git a/llvm/lib/Target/X86/X86CallLowering.cpp b/llvm/lib/Target/X86/X86CallLowering.cpp
index 3a980f4..b16b383 100644
--- a/llvm/lib/Target/X86/X86CallLowering.cpp
+++ b/llvm/lib/Target/X86/X86CallLowering.cpp
@@ -409,7 +409,9 @@
if (OrigArg.Flags.isByVal())
return false;
- assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet");
+ if (OrigArg.Regs.size() > 1)
+ return false;
+
if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
[&](ArrayRef<Register> Regs) {
MIRBuilder.buildUnmerge(Regs, OrigArg.Regs[0]);