diff --git a/include/llvm/CodeGen/GlobalISel/CallLowering.h b/include/llvm/CodeGen/GlobalISel/CallLowering.h index 1141bddbc1a..5e5530508a4 100644 --- a/include/llvm/CodeGen/GlobalISel/CallLowering.h +++ b/include/llvm/CodeGen/GlobalISel/CallLowering.h @@ -244,6 +244,13 @@ protected: void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const; + /// Break \p OrigArgInfo into one or more pieces the calling convention can + /// process, returned in \p SplitArgs. For example, this should break structs + /// down into individual fields. + void splitToValueTypes(const ArgInfo &OrigArgInfo, + SmallVectorImpl &SplitArgs, + const DataLayout &DL, CallingConv::ID CallConv) const; + /// Generate instructions for packing \p SrcRegs into one big register /// corresponding to the aggregate type \p PackedTy. /// diff --git a/lib/CodeGen/GlobalISel/CallLowering.cpp b/lib/CodeGen/GlobalISel/CallLowering.cpp index c6bfa245193..d0e8188cf55 100644 --- a/lib/CodeGen/GlobalISel/CallLowering.cpp +++ b/lib/CodeGen/GlobalISel/CallLowering.cpp @@ -187,6 +187,43 @@ CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const CallBase &FuncInfo) const; +void CallLowering::splitToValueTypes(const ArgInfo &OrigArg, + SmallVectorImpl &SplitArgs, + const DataLayout &DL, + CallingConv::ID CallConv) const { + LLVMContext &Ctx = OrigArg.Ty->getContext(); + + SmallVector SplitVTs; + SmallVector Offsets; + ComputeValueVTs(*TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); + + if (SplitVTs.size() == 0) + return; + + 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.Regs[0], SplitVTs[0].getTypeForEVT(Ctx), + OrigArg.Flags[0], OrigArg.IsFixed); + return; + } + + // Create one ArgInfo for each virtual register in the original ArgInfo. + assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch"); + + bool NeedsRegBlock = TLI->functionArgumentNeedsConsecutiveRegisters( + OrigArg.Ty, CallConv, false); + for (unsigned i = 0, e = SplitVTs.size(); i < e; ++i) { + Type *SplitTy = SplitVTs[i].getTypeForEVT(Ctx); + SplitArgs.emplace_back(OrigArg.Regs[i], SplitTy, OrigArg.Flags[0], + OrigArg.IsFixed); + if (NeedsRegBlock) + SplitArgs.back().Flags[0].setInConsecutiveRegs(); + } + + SplitArgs.back().Flags[0].setInConsecutiveRegsLast(); +} + Register CallLowering::packRegs(ArrayRef SrcRegs, Type *PackedTy, MachineIRBuilder &MIRBuilder) const { assert(SrcRegs.size() > 1 && "Nothing to pack"); diff --git a/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/lib/Target/AArch64/GISel/AArch64CallLowering.cpp index ed6b231e5ad..c128e50236e 100644 --- a/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -285,43 +285,6 @@ static bool doesCalleeRestoreStack(CallingConv::ID CallConv, bool TailCallOpt) { return CallConv == CallingConv::Fast && TailCallOpt; } -void AArch64CallLowering::splitToValueTypes( - const ArgInfo &OrigArg, SmallVectorImpl &SplitArgs, - const DataLayout &DL, MachineRegisterInfo &MRI, CallingConv::ID CallConv) const { - const AArch64TargetLowering &TLI = *getTLI(); - LLVMContext &Ctx = OrigArg.Ty->getContext(); - - SmallVector SplitVTs; - SmallVector Offsets; - ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); - - if (SplitVTs.size() == 0) - return; - - 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.Regs[0], SplitVTs[0].getTypeForEVT(Ctx), - OrigArg.Flags[0], OrigArg.IsFixed); - return; - } - - // Create one ArgInfo for each virtual register in the original ArgInfo. - assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch"); - - bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters( - OrigArg.Ty, CallConv, false); - for (unsigned i = 0, e = SplitVTs.size(); i < e; ++i) { - Type *SplitTy = SplitVTs[i].getTypeForEVT(Ctx); - SplitArgs.emplace_back(OrigArg.Regs[i], SplitTy, OrigArg.Flags[0], - OrigArg.IsFixed); - if (NeedsRegBlock) - SplitArgs.back().Flags[0].setInConsecutiveRegs(); - } - - SplitArgs.back().Flags[0].setInConsecutiveRegsLast(); -} - bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef VRegs, @@ -423,7 +386,7 @@ bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, // Reset the arg flags after modifying CurVReg. setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F); } - splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI, CC); + splitToValueTypes(CurArgInfo, SplitArgs, DL, CC); } OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFn, AssignFn); @@ -508,7 +471,7 @@ bool AArch64CallLowering::lowerFormalArguments( ArgInfo OrigArg{VRegs[i], Arg.getType()}; setArgFlags(OrigArg, i + AttributeList::FirstArgIndex, DL, F); - splitToValueTypes(OrigArg, SplitArgs, DL, MRI, F.getCallingConv()); + splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); ++i; } @@ -986,7 +949,7 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, SmallVector OutArgs; for (auto &OrigArg : Info.OrigArgs) { - splitToValueTypes(OrigArg, OutArgs, DL, MRI, Info.CallConv); + splitToValueTypes(OrigArg, OutArgs, DL, Info.CallConv); // AAPCS requires that we zero-extend i1 to 8 bits by the caller. if (OrigArg.Ty->isIntegerTy(1)) OutArgs.back().Flags[0].setZExt(); @@ -994,7 +957,7 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, SmallVector InArgs; if (!Info.OrigRet.Ty->isVoidTy()) - splitToValueTypes(Info.OrigRet, InArgs, DL, MRI, Info.CallConv); + splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv); // If we can lower as a tail call, do that instead. bool CanTailCallOpt = diff --git a/lib/Target/AArch64/GISel/AArch64CallLowering.h b/lib/Target/AArch64/GISel/AArch64CallLowering.h index 786dfc88e29..1b9de9f93a3 100644 --- a/lib/Target/AArch64/GISel/AArch64CallLowering.h +++ b/lib/Target/AArch64/GISel/AArch64CallLowering.h @@ -64,11 +64,6 @@ private: using MemHandler = std::function; - void splitToValueTypes(const ArgInfo &OrigArgInfo, - SmallVectorImpl &SplitArgs, - const DataLayout &DL, MachineRegisterInfo &MRI, - CallingConv::ID CallConv) const; - bool lowerTailCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info, SmallVectorImpl &OutArgs) const; diff --git a/lib/Target/AMDGPU/AMDGPUCallLowering.cpp b/lib/Target/AMDGPU/AMDGPUCallLowering.cpp index 6d0df5ce53c..7ad62fe6da6 100644 --- a/lib/Target/AMDGPU/AMDGPUCallLowering.cpp +++ b/lib/Target/AMDGPU/AMDGPUCallLowering.cpp @@ -278,47 +278,6 @@ static ISD::NodeType extOpcodeToISDExtOpcode(unsigned MIOpc) { } } -// FIXME: This should move to generic code. -void AMDGPUCallLowering::splitToValueTypes(MachineIRBuilder &B, - const ArgInfo &OrigArg, - SmallVectorImpl &SplitArgs, - const DataLayout &DL, - CallingConv::ID CallConv) const { - const SITargetLowering &TLI = *getTLI(); - LLVMContext &Ctx = OrigArg.Ty->getContext(); - - SmallVector SplitVTs; - ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs); - - assert(OrigArg.Regs.size() == SplitVTs.size()); - - if (SplitVTs.size() == 0) - return; - - 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.Regs[0], SplitVTs[0].getTypeForEVT(Ctx), - OrigArg.Flags[0], OrigArg.IsFixed); - return; - } - - // Create one ArgInfo for each virtual register in the original ArgInfo. - assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch"); - - bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters( - OrigArg.Ty, CallConv, false); - for (unsigned i = 0, e = SplitVTs.size(); i < e; ++i) { - Type *SplitTy = SplitVTs[i].getTypeForEVT(Ctx); - SplitArgs.emplace_back(OrigArg.Regs[i], SplitTy, OrigArg.Flags[0], - OrigArg.IsFixed); - if (NeedsRegBlock) - SplitArgs.back().Flags[0].setInConsecutiveRegs(); - } - - SplitArgs.back().Flags[0].setInConsecutiveRegsLast(); -} - void AMDGPUCallLowering::processSplitArgs( MachineIRBuilder &B, const ArgInfo &OrigArg, const SmallVectorImpl &SplitArg, @@ -498,7 +457,7 @@ bool AMDGPUCallLowering::lowerReturnVal(MachineIRBuilder &B, setArgFlags(RetInfo, AttributeList::ReturnIndex, DL, F); } - splitToValueTypes(B, RetInfo, PreSplitRetInfos, DL, CC); + splitToValueTypes(RetInfo, PreSplitRetInfos, DL, CC); // FIXME: This splitting should mostly be done by handleAssignments processSplitArgs(B, RetInfo, @@ -824,7 +783,7 @@ bool AMDGPUCallLowering::lowerFormalArguments( const unsigned OrigArgIdx = Idx + AttributeList::FirstArgIndex; setArgFlags(OrigArg, OrigArgIdx, DL, F); - splitToValueTypes(B, OrigArg, SplitArgs, DL, CC); + splitToValueTypes(OrigArg, SplitArgs, DL, CC); ++Idx; } @@ -1117,7 +1076,7 @@ bool AMDGPUCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, SmallVector SplitArg; for (auto &OrigArg : Info.OrigArgs) { - splitToValueTypes(MIRBuilder, OrigArg, SplitArg, DL, Info.CallConv); + splitToValueTypes(OrigArg, SplitArg, DL, Info.CallConv); processSplitArgs( MIRBuilder, OrigArg, SplitArg, OutArgs, DL, Info.CallConv, true, @@ -1232,7 +1191,7 @@ bool AMDGPUCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, insertSRetLoads(MIRBuilder, Info.OrigRet.Ty, Info.OrigRet.Regs, Info.DemoteRegister, Info.DemoteStackIndex); } else if (!Info.OrigRet.Ty->isVoidTy()) { - splitToValueTypes(MIRBuilder, Info.OrigRet, InArgs, DL, Info.CallConv); + splitToValueTypes(Info.OrigRet, InArgs, DL, Info.CallConv); } // Make sure the raw argument copies are inserted before the marshalling to diff --git a/lib/Target/AMDGPU/AMDGPUCallLowering.h b/lib/Target/AMDGPU/AMDGPUCallLowering.h index 1312388e4a3..8a3280cfcc4 100644 --- a/lib/Target/AMDGPU/AMDGPUCallLowering.h +++ b/lib/Target/AMDGPU/AMDGPUCallLowering.h @@ -31,10 +31,6 @@ class AMDGPUCallLowering final : public CallLowering { /// A function of this type is used to perform value split action. using SplitArgTy = std::function, Register, LLT, LLT, int)>; - void splitToValueTypes(MachineIRBuilder &B, const ArgInfo &OrigArgInfo, - SmallVectorImpl &SplitArgs, - const DataLayout &DL, CallingConv::ID CallConv) const; - void processSplitArgs(MachineIRBuilder &B, const ArgInfo &OrigArgInfo, const SmallVectorImpl &SplitArg, SmallVectorImpl &SplitArgs, diff --git a/lib/Target/ARM/ARMCallLowering.cpp b/lib/Target/ARM/ARMCallLowering.cpp index ea789e2e33c..d4b920a43e8 100644 --- a/lib/Target/ARM/ARMCallLowering.cpp +++ b/lib/Target/ARM/ARMCallLowering.cpp @@ -186,51 +186,6 @@ struct ARMOutgoingValueHandler : public CallLowering::OutgoingValueHandler { } // end anonymous namespace -void ARMCallLowering::splitToValueTypes(const ArgInfo &OrigArg, - SmallVectorImpl &SplitArgs, - MachineFunction &MF) const { - const ARMTargetLowering &TLI = *getTLI(); - LLVMContext &Ctx = OrigArg.Ty->getContext(); - const DataLayout &DL = MF.getDataLayout(); - const Function &F = MF.getFunction(); - - SmallVector SplitVTs; - ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, nullptr, nullptr, 0); - assert(OrigArg.Regs.size() == SplitVTs.size() && "Regs / types mismatch"); - - if (SplitVTs.size() == 1) { - // Even if there is no splitting to do, we still want to replace the - // original type (e.g. pointer type -> integer). - auto Flags = OrigArg.Flags[0]; - Flags.setOrigAlign(DL.getABITypeAlign(OrigArg.Ty)); - SplitArgs.emplace_back(OrigArg.Regs[0], SplitVTs[0].getTypeForEVT(Ctx), - Flags, OrigArg.IsFixed); - return; - } - - // Create one ArgInfo for each virtual register. - for (unsigned i = 0, e = SplitVTs.size(); i != e; ++i) { - EVT SplitVT = SplitVTs[i]; - Type *SplitTy = SplitVT.getTypeForEVT(Ctx); - auto Flags = OrigArg.Flags[0]; - - Flags.setOrigAlign(DL.getABITypeAlign(SplitTy)); - - bool NeedsConsecutiveRegisters = - TLI.functionArgumentNeedsConsecutiveRegisters( - SplitTy, F.getCallingConv(), F.isVarArg()); - if (NeedsConsecutiveRegisters) { - Flags.setInConsecutiveRegs(); - if (i == e - 1) - Flags.setInConsecutiveRegsLast(); - } - - // FIXME: We also want to split SplitTy further. - Register PartReg = OrigArg.Regs[i]; - SplitArgs.emplace_back(PartReg, SplitTy, Flags, OrigArg.IsFixed); - } -} - /// Lower the return value for the already existing \p Ret. This assumes that /// \p MIRBuilder's insertion point is correct. bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder, @@ -243,7 +198,7 @@ bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder, auto &MF = MIRBuilder.getMF(); const auto &F = MF.getFunction(); - auto DL = MF.getDataLayout(); + const auto &DL = MF.getDataLayout(); auto &TLI = *getTLI(); if (!isSupportedType(DL, TLI, Val->getType())) return false; @@ -252,7 +207,7 @@ bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder, setArgFlags(OrigRetInfo, AttributeList::ReturnIndex, DL, F); SmallVector SplitRetInfos; - splitToValueTypes(OrigRetInfo, SplitRetInfos, MF); + splitToValueTypes(OrigRetInfo, SplitRetInfos, DL, F.getCallingConv()); CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg()); @@ -430,7 +385,7 @@ bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, auto &MF = MIRBuilder.getMF(); auto &MBB = MIRBuilder.getMBB(); - auto DL = MF.getDataLayout(); + const auto &DL = MF.getDataLayout(); for (auto &Arg : F.args()) { if (!isSupportedType(DL, TLI, Arg.getType())) @@ -451,7 +406,7 @@ bool ARMCallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, ArgInfo OrigArgInfo(VRegs[Idx], Arg.getType()); setArgFlags(OrigArgInfo, Idx + AttributeList::FirstArgIndex, DL, F); - splitToValueTypes(OrigArgInfo, SplitArgInfos, MF); + splitToValueTypes(OrigArgInfo, SplitArgInfos, DL, F.getCallingConv()); Idx++; } @@ -548,7 +503,7 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo & if (Arg.Flags[0].isByVal()) return false; - splitToValueTypes(Arg, ArgInfos, MF); + splitToValueTypes(Arg, ArgInfos, DL, Info.CallConv); } auto ArgAssignFn = TLI.CCAssignFnForCall(Info.CallConv, Info.IsVarArg); @@ -565,7 +520,7 @@ bool ARMCallLowering::lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo & return false; ArgInfos.clear(); - splitToValueTypes(Info.OrigRet, ArgInfos, MF); + splitToValueTypes(Info.OrigRet, ArgInfos, DL, Info.CallConv); auto RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv, Info.IsVarArg); CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn); if (!handleAssignments(MIRBuilder, ArgInfos, RetHandler, Info.CallConv, diff --git a/lib/Target/ARM/ARMCallLowering.h b/lib/Target/ARM/ARMCallLowering.h index 3be73d497d0..87b18f81174 100644 --- a/lib/Target/ARM/ARMCallLowering.h +++ b/lib/Target/ARM/ARMCallLowering.h @@ -47,12 +47,6 @@ private: bool lowerReturnVal(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef VRegs, MachineInstrBuilder &Ret) const; - - /// Split an argument into one or more arguments that the CC lowering can cope - /// with. - void splitToValueTypes(const ArgInfo &OrigArg, - SmallVectorImpl &SplitArgs, - MachineFunction &MF) const; }; } // end namespace llvm diff --git a/lib/Target/Mips/MipsCallLowering.cpp b/lib/Target/Mips/MipsCallLowering.cpp index 377aa4825b4..d5251ce10bd 100644 --- a/lib/Target/Mips/MipsCallLowering.cpp +++ b/lib/Target/Mips/MipsCallLowering.cpp @@ -664,6 +664,7 @@ void MipsCallLowering::subTargetRegTypeForCallingConv( } } +// FIXME: This should be removed and the generic version used void MipsCallLowering::splitToValueTypes( const DataLayout &DL, const ArgInfo &OrigArg, unsigned OriginalIndex, SmallVectorImpl &SplitArgs, diff --git a/lib/Target/X86/X86CallLowering.cpp b/lib/Target/X86/X86CallLowering.cpp index 8c6a44671c7..28bba84c744 100644 --- a/lib/Target/X86/X86CallLowering.cpp +++ b/lib/Target/X86/X86CallLowering.cpp @@ -50,6 +50,7 @@ using namespace llvm; X86CallLowering::X86CallLowering(const X86TargetLowering &TLI) : CallLowering(&TLI) {} +// FIXME: This should be removed and the generic version used bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg, SmallVectorImpl &SplitArgs, const DataLayout &DL,