From 43a431faf58197a3c54dd9d8e4929d88bfd110c0 Mon Sep 17 00:00:00 2001 From: Diana Picus Date: Thu, 27 Jun 2019 08:50:53 +0000 Subject: [PATCH] [GlobalISel] Allow multiple VRegs in ArgInfo. NFC Allow CallLowering::ArgInfo to contain more than one virtual register. This is useful when passes split aggregates into several virtual registers, but need to also provide information about the original type to the call lowering. Used in follow-up patches. Differential Revision: https://reviews.llvm.org/D63548 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364509 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/GlobalISel/CallLowering.h | 13 ++++++++----- lib/CodeGen/GlobalISel/CallLowering.cpp | 14 ++++++++++---- lib/CodeGen/GlobalISel/IRTranslator.cpp | 2 +- lib/Target/AArch64/AArch64CallLowering.cpp | 17 ++++++++++------- lib/Target/ARM/ARMCallLowering.cpp | 22 +++++++++++++++------- lib/Target/Mips/MipsCallLowering.cpp | 14 +++++++++----- lib/Target/X86/X86CallLowering.cpp | 14 +++++++++----- 7 files changed, 62 insertions(+), 34 deletions(-) diff --git a/include/llvm/CodeGen/GlobalISel/CallLowering.h b/include/llvm/CodeGen/GlobalISel/CallLowering.h index 35963b4848f..8734fb455f1 100644 --- a/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -15,6 +15,7 @@ #define LLVM_CODEGEN_GLOBALISEL_CALLLOWERING_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/TargetCallingConv.h" #include "llvm/IR/CallSite.h" @@ -42,15 +43,17 @@ class CallLowering { virtual void anchor(); public: struct ArgInfo { - Register Reg; + SmallVector Regs; Type *Ty; ISD::ArgFlagsTy Flags; bool IsFixed; - ArgInfo(unsigned Reg, Type *Ty, ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{}, - bool IsFixed = true) - : Reg(Reg), Ty(Ty), Flags(Flags), IsFixed(IsFixed) { - assert((Ty->isVoidTy() == (Reg == 0)) && + ArgInfo(ArrayRef Regs, Type *Ty, + ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy{}, bool IsFixed = true) + : Regs(Regs.begin(), Regs.end()), Ty(Ty), Flags(Flags), + IsFixed(IsFixed) { + assert(Regs.size() == 1 && "Can't handle multiple regs yet"); + assert((Ty->isVoidTy() == (Regs[0] == 0)) && "only void types should have no register"); } }; diff --git a/lib/CodeGen/GlobalISel/CallLowering.cpp b/lib/CodeGen/GlobalISel/CallLowering.cpp index 99143a40c64..e8ffd713ddd 100644 --- a/lib/CodeGen/GlobalISel/CallLowering.cpp +++ b/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -150,6 +150,12 @@ bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder, continue; } + assert(Args[i].Regs.size() == 1 && + "Can't handle multiple virtual regs yet"); + + // FIXME: Pack registers if we have more than one. + unsigned ArgReg = Args[i].Regs[0]; + if (VA.isRegLoc()) { MVT OrigVT = MVT::getVT(Args[i].Ty); MVT VAVT = VA.getValVT(); @@ -172,12 +178,12 @@ bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder, return false; } auto Unmerge = MIRBuilder.buildUnmerge({OrigTy, OrigTy}, {NewReg}); - MIRBuilder.buildCopy(Args[i].Reg, Unmerge.getReg(0)); + MIRBuilder.buildCopy(ArgReg, Unmerge.getReg(0)); } else { - MIRBuilder.buildTrunc(Args[i].Reg, {NewReg}).getReg(0); + MIRBuilder.buildTrunc(ArgReg, {NewReg}).getReg(0); } } else { - Handler.assignValueToReg(Args[i].Reg, VA.getLocReg(), VA); + Handler.assignValueToReg(ArgReg, VA.getLocReg(), VA); } } else if (VA.isMemLoc()) { MVT VT = MVT::getVT(Args[i].Ty); @@ -186,7 +192,7 @@ bool CallLowering::handleAssignments(MachineIRBuilder &MIRBuilder, unsigned Offset = VA.getLocMemOffset(); MachinePointerInfo MPO; unsigned StackAddr = Handler.getStackAddress(Size, Offset, MPO); - Handler.assignValueToAddress(Args[i].Reg, StackAddr, Size, MPO, VA); + Handler.assignValueToAddress(ArgReg, StackAddr, Size, MPO, VA); } else { // FIXME: Support byvals and other weirdness return false; diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index 2623b09834e..3a060b29c1b 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1160,7 +1160,7 @@ bool IRTranslator::translateMemfunc(const CallInst &CI, return CLI->lowerCall(MIRBuilder, CI.getCallingConv(), MachineOperand::CreateES(Callee), - CallLowering::ArgInfo(0, CI.getType()), Args); + CallLowering::ArgInfo({0}, CI.getType()), Args); } void IRTranslator::getStackGuard(Register DstReg, diff --git a/lib/Target/AArch64/AArch64CallLowering.cpp b/lib/Target/AArch64/AArch64CallLowering.cpp index a497bd9b339..f596d63ed0b 100644 --- a/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/lib/Target/AArch64/AArch64CallLowering.cpp @@ -203,11 +203,12 @@ void AArch64CallLowering::splitToValueTypes( SmallVector SplitVTs; SmallVector Offsets; ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); + assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet"); if (SplitVTs.size() == 1) { // No splitting to do, but we want to replace the original type (e.g. [1 x // double] -> double). - SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx), + SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx), OrigArg.Flags, OrigArg.IsFixed); return; } @@ -227,7 +228,7 @@ void AArch64CallLowering::splitToValueTypes( SplitArgs.back().Flags.setInConsecutiveRegsLast(); for (unsigned i = 0; i < Offsets.size(); ++i) - PerformArgSplit(SplitArgs[FirstRegIdx + i].Reg, Offsets[i] * 8); + PerformArgSplit(SplitArgs[FirstRegIdx + i].Regs[0], Offsets[i] * 8); } bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, @@ -326,8 +327,8 @@ bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, } } } - if (CurVReg != CurArgInfo.Reg) { - CurArgInfo.Reg = CurVReg; + if (CurVReg != CurArgInfo.Regs[0]) { + CurArgInfo.Regs[0] = CurVReg; // Reset the arg flags after modifying CurVReg. setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F); } @@ -435,9 +436,10 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, SmallVector 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.Reg, Offset); + MIRBuilder.buildExtract(Reg, OrigArg.Regs[0], Offset); }); // AAPCS requires that we zero-extend i1 to 8 bits by the caller. if (OrigArg.Ty->isIntegerTy(1)) @@ -491,7 +493,8 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, // symmetry with the arugments, the physical register must be an // implicit-define of the call instruction. CCAssignFn *RetAssignFn = TLI.CCAssignFnForReturn(F.getCallingConv()); - if (OrigRet.Reg) { + assert(OrigRet.Regs.size() == 1 && "Can't handle multple regs yet"); + if (OrigRet.Regs[0]) { SplitArgs.clear(); SmallVector RegOffsets; @@ -507,7 +510,7 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, return false; if (!RegOffsets.empty()) - MIRBuilder.buildSequence(OrigRet.Reg, SplitRegs, RegOffsets); + MIRBuilder.buildSequence(OrigRet.Regs[0], SplitRegs, RegOffsets); } if (SwiftErrorVReg) { diff --git a/lib/Target/ARM/ARMCallLowering.cpp b/lib/Target/ARM/ARMCallLowering.cpp index fa54a9ea418..9d2c93be90c 100644 --- a/lib/Target/ARM/ARMCallLowering.cpp +++ b/lib/Target/ARM/ARMCallLowering.cpp @@ -137,6 +137,8 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler { unsigned assignCustomValue(const CallLowering::ArgInfo &Arg, ArrayRef VAs) override { + assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet"); + CCValAssign VA = VAs[0]; assert(VA.needsCustom() && "Value doesn't need custom handling"); assert(VA.getValVT() == MVT::f64 && "Unsupported type"); @@ -153,7 +155,7 @@ struct OutgoingValueHandler : public CallLowering::ValueHandler { Register NewRegs[] = {MRI.createGenericVirtualRegister(LLT::scalar(32)), MRI.createGenericVirtualRegister(LLT::scalar(32))}; - MIRBuilder.buildUnmerge(NewRegs, Arg.Reg); + MIRBuilder.buildUnmerge(NewRegs, Arg.Regs[0]); bool IsLittle = MIRBuilder.getMF().getSubtarget().isLittle(); if (!IsLittle) @@ -193,6 +195,7 @@ void ARMCallLowering::splitToValueTypes( SmallVector SplitVTs; ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, nullptr, nullptr, 0); + assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet"); if (SplitVTs.size() == 1) { // Even if there is no splitting to do, we still want to replace the @@ -200,8 +203,8 @@ void ARMCallLowering::splitToValueTypes( auto Flags = OrigArg.Flags; unsigned OriginalAlignment = DL.getABITypeAlignment(OrigArg.Ty); Flags.setOrigAlign(OriginalAlignment); - SplitArgs.emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx), Flags, - OrigArg.IsFixed); + SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx), + Flags, OrigArg.IsFixed); return; } @@ -222,7 +225,7 @@ void ARMCallLowering::splitToValueTypes( Flags.setInConsecutiveRegsLast(); } - unsigned PartReg = + Register PartReg = MRI.createGenericVirtualRegister(getLLTForType(*SplitTy, DL)); SplitArgs.push_back(ArgInfo{PartReg, SplitTy, Flags, OrigArg.IsFixed}); PerformArgSplit(PartReg); @@ -372,6 +375,8 @@ struct IncomingValueHandler : public CallLowering::ValueHandler { unsigned assignCustomValue(const ARMCallLowering::ArgInfo &Arg, ArrayRef VAs) override { + assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet"); + CCValAssign VA = VAs[0]; assert(VA.needsCustom() && "Value doesn't need custom handling"); assert(VA.getValVT() == MVT::f64 && "Unsupported type"); @@ -396,7 +401,7 @@ struct IncomingValueHandler : public CallLowering::ValueHandler { if (!IsLittle) std::swap(NewRegs[0], NewRegs[1]); - MIRBuilder.buildMerge(Arg.Reg, NewRegs); + MIRBuilder.buildMerge(Arg.Regs[0], NewRegs); return 1; } @@ -568,12 +573,14 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, if (Arg.Flags.isByVal()) return false; + assert(Arg.Regs.size() == 1 && "Can't handle multple regs yet"); + SmallVector Regs; splitToValueTypes(Arg, ArgInfos, MF, [&](unsigned Reg) { Regs.push_back(Reg); }); if (Regs.size() > 1) - MIRBuilder.buildUnmerge(Regs, Arg.Reg); + MIRBuilder.buildUnmerge(Regs, Arg.Regs[0]); } auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv, IsVarArg); @@ -601,7 +608,8 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, if (!SplitRegs.empty()) { // We have split the value and allocated each individual piece, now build // it up again. - MIRBuilder.buildMerge(OrigRet.Reg, SplitRegs); + assert(OrigRet.Regs.size() == 1 && "Can't handle multple regs yet"); + MIRBuilder.buildMerge(OrigRet.Regs[0], SplitRegs); } } diff --git a/lib/Target/Mips/MipsCallLowering.cpp b/lib/Target/Mips/MipsCallLowering.cpp index dc4eaf8f1b1..de235d4744c 100644 --- a/lib/Target/Mips/MipsCallLowering.cpp +++ b/lib/Target/Mips/MipsCallLowering.cpp @@ -66,6 +66,8 @@ bool MipsCallLowering::MipsHandler::handle( EVT VT = TLI.getValueType(DL, Args[ArgsIndex].Ty); SplitLength = TLI.getNumRegistersForCallingConv(F.getContext(), F.getCallingConv(), VT); + assert(Args[ArgsIndex].Regs.size() == 1 && "Can't handle multple regs yet"); + if (SplitLength > 1) { VRegs.clear(); MVT RegisterVT = TLI.getRegisterTypeForCallingConv( @@ -73,10 +75,11 @@ bool MipsCallLowering::MipsHandler::handle( for (unsigned i = 0; i < SplitLength; ++i) VRegs.push_back(MRI.createGenericVirtualRegister(LLT{RegisterVT})); - if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Reg, VT)) + if (!handleSplit(VRegs, ArgLocs, ArgLocsIndex, Args[ArgsIndex].Regs[0], + VT)) return false; } else { - if (!assign(Args[ArgsIndex].Reg, ArgLocs[ArgLocsIndex], VT)) + if (!assign(Args[ArgsIndex].Regs[0], ArgLocs[ArgLocsIndex], VT)) return false; } } @@ -510,7 +513,9 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, if (Arg.Flags.isByVal() || Arg.Flags.isSRet()) return false; } - if (OrigRet.Reg && !isSupportedType(OrigRet.Ty)) + + assert(OrigRet.Regs.size() == 1 && "Can't handle multple regs yet"); + if (OrigRet.Regs[0] && !isSupportedType(OrigRet.Ty)) return false; MachineFunction &MF = MIRBuilder.getMF(); @@ -595,8 +600,7 @@ bool MipsCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, *STI.getRegBankInfo()); } - if (OrigRet.Reg) { - + if (OrigRet.Regs[0]) { ArgInfos.clear(); SmallVector OrigRetIndices; diff --git a/lib/Target/X86/X86CallLowering.cpp b/lib/Target/X86/X86CallLowering.cpp index 3f5b007f23e..6403d968941 100644 --- a/lib/Target/X86/X86CallLowering.cpp +++ b/lib/Target/X86/X86CallLowering.cpp @@ -61,6 +61,7 @@ bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg, SmallVector SplitVTs; SmallVector Offsets; ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); + assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet"); if (OrigArg.Ty->isVoidTy()) return true; @@ -70,7 +71,7 @@ bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg, if (NumParts == 1) { // replace the original type ( pointer -> GPR ). - SplitArgs.emplace_back(OrigArg.Reg, VT.getTypeForEVT(Context), + SplitArgs.emplace_back(OrigArg.Regs[0], VT.getTypeForEVT(Context), OrigArg.Flags, OrigArg.IsFixed); return true; } @@ -85,7 +86,7 @@ bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg, ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*PartTy, DL)), PartTy, OrigArg.Flags}; SplitArgs.push_back(Info); - SplitRegs.push_back(Info.Reg); + SplitRegs.push_back(Info.Regs[0]); } PerformArgSplit(SplitRegs); @@ -408,9 +409,10 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, if (OrigArg.Flags.isByVal()) return false; + assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet"); if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI, [&](ArrayRef Regs) { - MIRBuilder.buildUnmerge(Regs, OrigArg.Reg); + MIRBuilder.buildUnmerge(Regs, OrigArg.Regs[0]); })) return false; } @@ -450,7 +452,9 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, // symmetry with the arguments, the physical register must be an // implicit-define of the call instruction. - if (OrigRet.Reg) { + if (!OrigRet.Ty->isVoidTy()) { + assert(OrigRet.Regs.size() == 1 && "Can't handle multple regs yet"); + SplitArgs.clear(); SmallVector NewRegs; @@ -465,7 +469,7 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, return false; if (!NewRegs.empty()) - MIRBuilder.buildMerge(OrigRet.Reg, NewRegs); + MIRBuilder.buildMerge(OrigRet.Regs[0], NewRegs); } CallSeqStart.addImm(Handler.getStackSize()) -- 2.11.0