diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64CallLowering.cpp | 47 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64CallLowering.h | 4 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h | 4 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMCallLowering.cpp | 35 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMCallLowering.h | 7 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsCallLowering.cpp | 24 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsCallLowering.h | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86CallLowering.cpp | 41 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86CallLowering.h | 4 |
10 files changed, 107 insertions, 66 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp index 26d532555e7..ad751ab0682 100644 --- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp @@ -227,32 +227,45 @@ void AArch64CallLowering::splitToValueTypes( } bool AArch64CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, - const Value *Val, unsigned VReg) const { - MachineFunction &MF = MIRBuilder.getMF(); - const Function &F = MF.getFunction(); - + const Value *Val, + ArrayRef<unsigned> VRegs) const { auto MIB = MIRBuilder.buildInstrNoInsert(AArch64::RET_ReallyLR); - assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg"); - bool Success = true; - if (VReg) { - MachineRegisterInfo &MRI = MF.getRegInfo(); + assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) && + "Return value without a vreg"); - // We zero-extend i1s to i8. - if (MRI.getType(VReg).getSizeInBits() == 1) - VReg = MIRBuilder.buildZExt(LLT::scalar(8), VReg)->getOperand(0).getReg(); + bool Success = true; + if (!VRegs.empty()) { + MachineFunction &MF = MIRBuilder.getMF(); + const Function &F = MF.getFunction(); + MachineRegisterInfo &MRI = MF.getRegInfo(); const AArch64TargetLowering &TLI = *getTLI<AArch64TargetLowering>(); CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv()); auto &DL = F.getParent()->getDataLayout(); + LLVMContext &Ctx = Val->getType()->getContext(); - ArgInfo OrigArg{VReg, Val->getType()}; - setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F); + SmallVector<EVT, 4> SplitEVTs; + ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs); + assert(VRegs.size() == SplitEVTs.size() && + "For each split Type there should be exactly one VReg."); SmallVector<ArgInfo, 8> SplitArgs; - splitToValueTypes(OrigArg, SplitArgs, DL, MRI, F.getCallingConv(), - [&](unsigned Reg, uint64_t Offset) { - MIRBuilder.buildExtract(Reg, VReg, Offset); - }); + for (unsigned i = 0; i < SplitEVTs.size(); ++i) { + // We zero-extend i1s to i8. + unsigned CurVReg = VRegs[i]; + if (MRI.getType(VRegs[i]).getSizeInBits() == 1) { + CurVReg = MIRBuilder.buildZExt(LLT::scalar(8), CurVReg) + ->getOperand(0) + .getReg(); + } + + ArgInfo CurArgInfo = ArgInfo{CurVReg, SplitEVTs[i].getTypeForEVT(Ctx)}; + setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F); + splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI, F.getCallingConv(), + [&](unsigned Reg, uint64_t Offset) { + MIRBuilder.buildExtract(Reg, CurVReg, Offset); + }); + } OutgoingArgHandler Handler(MIRBuilder, MRI, MIB, AssignFn, AssignFn); Success = handleAssignments(MIRBuilder, SplitArgs, Handler); diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.h b/llvm/lib/Target/AArch64/AArch64CallLowering.h index 68c127fc42e..1c2bd6a4de5 100644 --- a/llvm/lib/Target/AArch64/AArch64CallLowering.h +++ b/llvm/lib/Target/AArch64/AArch64CallLowering.h @@ -34,8 +34,8 @@ class AArch64CallLowering: public CallLowering { public: AArch64CallLowering(const AArch64TargetLowering &TLI); - bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, - unsigned VReg) const override; + bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, + ArrayRef<unsigned> VRegs) const override; bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef<unsigned> VRegs) const override; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp index 18c7df0d94f..b6baadef6e4 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.cpp @@ -32,7 +32,8 @@ AMDGPUCallLowering::AMDGPUCallLowering(const AMDGPUTargetLowering &TLI) } bool AMDGPUCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, - const Value *Val, unsigned VReg) const { + const Value *Val, + ArrayRef<unsigned> VRegs) const { // FIXME: Add support for non-void returns. if (Val) return false; diff --git a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h index f51cb6abbf6..00c91a0933c 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUCallLowering.h @@ -35,8 +35,8 @@ class AMDGPUCallLowering: public CallLowering { public: AMDGPUCallLowering(const AMDGPUTargetLowering &TLI); - bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, - unsigned VReg) const override; + bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, + ArrayRef<unsigned> VRegs) const override; bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef<unsigned> VRegs) const override; static CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg); diff --git a/llvm/lib/Target/ARM/ARMCallLowering.cpp b/llvm/lib/Target/ARM/ARMCallLowering.cpp index 47f998b696f..deab039772c 100644 --- a/llvm/lib/Target/ARM/ARMCallLowering.cpp +++ b/llvm/lib/Target/ARM/ARMCallLowering.cpp @@ -237,7 +237,7 @@ void ARMCallLowering::splitToValueTypes( /// 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, - const Value *Val, unsigned VReg, + const Value *Val, ArrayRef<unsigned> VRegs, MachineInstrBuilder &Ret) const { if (!Val) // Nothing to do here. @@ -251,16 +251,24 @@ bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder, if (!isSupportedType(DL, TLI, Val->getType())) return false; - SmallVector<ArgInfo, 4> SplitVTs; - SmallVector<unsigned, 4> Regs; - ArgInfo RetInfo(VReg, Val->getType()); - setArgFlags(RetInfo, AttributeList::ReturnIndex, DL, F); - splitToValueTypes(RetInfo, SplitVTs, MF, [&](unsigned Reg, uint64_t Offset) { - Regs.push_back(Reg); - }); + SmallVector<EVT, 4> SplitEVTs; + ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs); + assert(VRegs.size() == SplitEVTs.size() && + "For each split Type there should be exactly one VReg."); - if (Regs.size() > 1) - MIRBuilder.buildUnmerge(Regs, VReg); + SmallVector<ArgInfo, 4> SplitVTs; + LLVMContext &Ctx = Val->getType()->getContext(); + for (unsigned i = 0; i < SplitEVTs.size(); ++i) { + ArgInfo CurArgInfo(VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx)); + setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F); + + SmallVector<unsigned, 4> Regs; + splitToValueTypes( + CurArgInfo, SplitVTs, MF, + [&](unsigned Reg, uint64_t Offset) { Regs.push_back(Reg); }); + if (Regs.size() > 1) + MIRBuilder.buildUnmerge(Regs, VRegs[i]); + } CCAssignFn *AssignFn = TLI.CCAssignFnForReturn(F.getCallingConv(), F.isVarArg()); @@ -270,14 +278,15 @@ bool ARMCallLowering::lowerReturnVal(MachineIRBuilder &MIRBuilder, } bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, - const Value *Val, unsigned VReg) const { - assert(!Val == !VReg && "Return value without a vreg"); + const Value *Val, + ArrayRef<unsigned> VRegs) const { + assert(!Val == VRegs.empty() && "Return value without a vreg"); auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>(); unsigned Opcode = ST.getReturnOpcode(); auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL)); - if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret)) + if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret)) return false; MIRBuilder.insertInstr(Ret); diff --git a/llvm/lib/Target/ARM/ARMCallLowering.h b/llvm/lib/Target/ARM/ARMCallLowering.h index 86854c53f17..45a988a2f00 100644 --- a/llvm/lib/Target/ARM/ARMCallLowering.h +++ b/llvm/lib/Target/ARM/ARMCallLowering.h @@ -33,8 +33,8 @@ class ARMCallLowering : public CallLowering { public: ARMCallLowering(const ARMTargetLowering &TLI); - bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, - unsigned VReg) const override; + bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, + ArrayRef<unsigned> VRegs) const override; bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef<unsigned> VRegs) const override; @@ -45,7 +45,8 @@ public: private: bool lowerReturnVal(MachineIRBuilder &MIRBuilder, const Value *Val, - unsigned VReg, MachineInstrBuilder &Ret) const; + ArrayRef<unsigned> VRegs, + MachineInstrBuilder &Ret) const; using SplitArgTy = std::function<void(unsigned Reg, uint64_t Offset)>; diff --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp index a705ebb6b19..47b9617af90 100644 --- a/llvm/lib/Target/Mips/MipsCallLowering.cpp +++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp @@ -16,6 +16,7 @@ #include "MipsCallLowering.h" #include "MipsCCState.h" #include "MipsTargetMachine.h" +#include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" using namespace llvm; @@ -192,25 +193,34 @@ static bool isSupportedType(Type *T) { } bool MipsCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, - const Value *Val, unsigned VReg) const { + const Value *Val, + ArrayRef<unsigned> VRegs) const { MachineInstrBuilder Ret = MIRBuilder.buildInstrNoInsert(Mips::RetRA); - if (Val != nullptr) { - if (!isSupportedType(Val->getType())) - return false; + if (Val != nullptr && !isSupportedType(Val->getType())) + return false; + if (!VRegs.empty()) { MachineFunction &MF = MIRBuilder.getMF(); const Function &F = MF.getFunction(); const DataLayout &DL = MF.getDataLayout(); const MipsTargetLowering &TLI = *getTLI<MipsTargetLowering>(); + LLVMContext &Ctx = Val->getType()->getContext(); + + SmallVector<EVT, 4> SplitEVTs; + ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs); + assert(VRegs.size() == SplitEVTs.size() && + "For each split Type there should be exactly one VReg."); SmallVector<ArgInfo, 8> RetInfos; SmallVector<unsigned, 8> OrigArgIndices; - ArgInfo ArgRetInfo(VReg, Val->getType()); - setArgFlags(ArgRetInfo, AttributeList::ReturnIndex, DL, F); - splitToValueTypes(ArgRetInfo, 0, RetInfos, OrigArgIndices); + for (unsigned i = 0; i < SplitEVTs.size(); ++i) { + ArgInfo CurArgInfo = ArgInfo{VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx)}; + setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F); + splitToValueTypes(CurArgInfo, 0, RetInfos, OrigArgIndices); + } SmallVector<ISD::OutputArg, 8> Outs; subTargetRegTypeForCallingConv( diff --git a/llvm/lib/Target/Mips/MipsCallLowering.h b/llvm/lib/Target/Mips/MipsCallLowering.h index e23c10cec56..5f696b0e056 100644 --- a/llvm/lib/Target/Mips/MipsCallLowering.h +++ b/llvm/lib/Target/Mips/MipsCallLowering.h @@ -50,8 +50,8 @@ public: MipsCallLowering(const MipsTargetLowering &TLI); - bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, - unsigned VReg) const override; + bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, + ArrayRef<unsigned> VRegs) const; bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef<unsigned> VRegs) const override; diff --git a/llvm/lib/Target/X86/X86CallLowering.cpp b/llvm/lib/Target/X86/X86CallLowering.cpp index 96ea64dc8c4..1dc83b76595 100644 --- a/llvm/lib/Target/X86/X86CallLowering.cpp +++ b/llvm/lib/Target/X86/X86CallLowering.cpp @@ -65,10 +65,8 @@ bool X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg, SmallVector<uint64_t, 4> Offsets; ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); - if (SplitVTs.size() != 1) { - // TODO: support struct/array split - return false; - } + if (OrigArg.Ty->isVoidTy()) + return true; EVT VT = SplitVTs[0]; unsigned NumParts = TLI.getNumRegisters(Context, VT); @@ -185,27 +183,36 @@ protected: } // end anonymous namespace -bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, - const Value *Val, unsigned VReg) const { - assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg"); - +bool X86CallLowering::lowerReturn( + MachineIRBuilder &MIRBuilder, const Value *Val, + ArrayRef<unsigned> VRegs) const { + assert(((Val && !VRegs.empty()) || (!Val && VRegs.empty())) && + "Return value without a vreg"); auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0); - if (VReg) { + if (!VRegs.empty()) { MachineFunction &MF = MIRBuilder.getMF(); + const Function &F = MF.getFunction(); MachineRegisterInfo &MRI = MF.getRegInfo(); auto &DL = MF.getDataLayout(); - const Function &F = MF.getFunction(); + LLVMContext &Ctx = Val->getType()->getContext(); + const X86TargetLowering &TLI = *getTLI<X86TargetLowering>(); - ArgInfo OrigArg{VReg, Val->getType()}; - setArgFlags(OrigArg, AttributeList::ReturnIndex, DL, F); + SmallVector<EVT, 4> SplitEVTs; + ComputeValueVTs(TLI, DL, Val->getType(), SplitEVTs); + assert(VRegs.size() == SplitEVTs.size() && + "For each split Type there should be exactly one VReg."); SmallVector<ArgInfo, 8> SplitArgs; - if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI, - [&](ArrayRef<unsigned> Regs) { - MIRBuilder.buildUnmerge(Regs, VReg); - })) - return false; + for (unsigned i = 0; i < SplitEVTs.size(); ++i) { + ArgInfo CurArgInfo = ArgInfo{VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx)}; + setArgFlags(CurArgInfo, AttributeList::ReturnIndex, DL, F); + if (!splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI, + [&](ArrayRef<unsigned> Regs) { + MIRBuilder.buildUnmerge(Regs, VRegs[i]); + })) + return false; + } OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86); if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) diff --git a/llvm/lib/Target/X86/X86CallLowering.h b/llvm/lib/Target/X86/X86CallLowering.h index 6c9dc1565da..f5f8f9a3ef6 100644 --- a/llvm/lib/Target/X86/X86CallLowering.h +++ b/llvm/lib/Target/X86/X86CallLowering.h @@ -29,8 +29,8 @@ class X86CallLowering : public CallLowering { public: X86CallLowering(const X86TargetLowering &TLI); - bool lowerReturn(MachineIRBuilder &MIRBuiler, const Value *Val, - unsigned VReg) const override; + bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, + ArrayRef<unsigned> VRegs) const override; bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef<unsigned> VRegs) const override; |