Index: llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ llvm/trunk/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 @@ 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"); } }; Index: llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp +++ llvm/trunk/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -150,6 +150,12 @@ 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 @@ 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 @@ 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; Index: llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ llvm/trunk/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1160,7 +1160,7 @@ 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, Index: llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp +++ llvm/trunk/lib/Target/AArch64/AArch64CallLowering.cpp @@ -203,11 +203,12 @@ 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 @@ 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 @@ } } } - 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 @@ 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 @@ // 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 @@ return false; if (!RegOffsets.empty()) - MIRBuilder.buildSequence(OrigRet.Reg, SplitRegs, RegOffsets); + MIRBuilder.buildSequence(OrigRet.Regs[0], SplitRegs, RegOffsets); } if (SwiftErrorVReg) { Index: llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp +++ llvm/trunk/lib/Target/ARM/ARMCallLowering.cpp @@ -137,6 +137,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); } } Index: llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp +++ llvm/trunk/lib/Target/Mips/MipsCallLowering.cpp @@ -66,6 +66,8 @@ 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 @@ 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 @@ 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 @@ *STI.getRegBankInfo()); } - if (OrigRet.Reg) { - + if (OrigRet.Regs[0]) { ArgInfos.clear(); SmallVector OrigRetIndices; Index: llvm/trunk/lib/Target/X86/X86CallLowering.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86CallLowering.cpp +++ llvm/trunk/lib/Target/X86/X86CallLowering.cpp @@ -61,6 +61,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ return false; if (!NewRegs.empty()) - MIRBuilder.buildMerge(OrigRet.Reg, NewRegs); + MIRBuilder.buildMerge(OrigRet.Regs[0], NewRegs); } CallSeqStart.addImm(Handler.getStackSize())