diff options
author | Igor Breger <igor.breger@intel.com> | 2017-02-06 08:37:41 +0000 |
---|---|---|
committer | Igor Breger <igor.breger@intel.com> | 2017-02-06 08:37:41 +0000 |
commit | 5c31a4c9a3e86d952d1487b32d55ac526e4c8ee3 (patch) | |
tree | 9d71a316690998c634fa1d3baa94536600b03b35 /llvm/lib/Target/X86/X86CallLowering.cpp | |
parent | d53f34618ba06c19d9a2965c7a5c67296867e3d8 (diff) | |
download | bcm5719-llvm-5c31a4c9a3e86d952d1487b32d55ac526e4c8ee3.tar.gz bcm5719-llvm-5c31a4c9a3e86d952d1487b32d55ac526e4c8ee3.zip |
[X86][GlobalISel] Add limited ret lowering support to the IRTranslator.
Summary:
Support return lowering for i8/i16/i32/i64/float/double, vector type supported for 64bit platform only.
Support argument lowering for float/double types.
Reviewers: t.p.northover, zvi, ab, rovka
Reviewed By: zvi
Subscribers: dberris, kristof.beyls, delena, llvm-commits
Differential Revision: https://reviews.llvm.org/D29261
llvm-svn: 294173
Diffstat (limited to 'llvm/lib/Target/X86/X86CallLowering.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86CallLowering.cpp | 119 |
1 files changed, 105 insertions, 14 deletions
diff --git a/llvm/lib/Target/X86/X86CallLowering.cpp b/llvm/lib/Target/X86/X86CallLowering.cpp index b648b90666e..39c7e514791 100644 --- a/llvm/lib/Target/X86/X86CallLowering.cpp +++ b/llvm/lib/Target/X86/X86CallLowering.cpp @@ -35,17 +35,94 @@ using namespace llvm; X86CallLowering::X86CallLowering(const X86TargetLowering &TLI) : CallLowering(&TLI) {} +void X86CallLowering::splitToValueTypes(const ArgInfo &OrigArg, + SmallVectorImpl<ArgInfo> &SplitArgs, + const DataLayout &DL, + MachineRegisterInfo &MRI, + SplitArgTy PerformArgSplit) const { + + const X86TargetLowering &TLI = *getTLI<X86TargetLowering>(); + LLVMContext &Context = OrigArg.Ty->getContext(); + EVT VT = TLI.getValueType(DL, OrigArg.Ty); + unsigned NumParts = TLI.getNumRegisters(Context, VT); + + if (NumParts == 1) { + SplitArgs.push_back(OrigArg); + return; + } + + SmallVector<uint64_t, 4> BitOffsets; + SmallVector<unsigned, 8> SplitRegs; + + EVT PartVT = TLI.getRegisterType(Context, VT); + Type *PartTy = PartVT.getTypeForEVT(Context); + + for (unsigned i = 0; i < NumParts; ++i) { + ArgInfo Info = ArgInfo{MRI.createGenericVirtualRegister(LLT{*PartTy, DL}), + PartTy, OrigArg.Flags}; + SplitArgs.push_back(Info); + BitOffsets.push_back(PartVT.getSizeInBits() * i); + SplitRegs.push_back(Info.Reg); + } + + PerformArgSplit(SplitRegs, BitOffsets); +} + +namespace { +struct FuncReturnHandler : public CallLowering::ValueHandler { + FuncReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, + MachineInstrBuilder &MIB, CCAssignFn *AssignFn) + : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {} + + unsigned getStackAddress(uint64_t Size, int64_t Offset, + MachinePointerInfo &MPO) override { + llvm_unreachable("Don't know how to get a stack address yet"); + } + + void assignValueToReg(unsigned ValVReg, unsigned PhysReg, + CCValAssign &VA) override { + MIB.addUse(PhysReg, RegState::Implicit); + unsigned ExtReg = extendRegister(ValVReg, VA); + MIRBuilder.buildCopy(PhysReg, ExtReg); + } + + void assignValueToAddress(unsigned ValVReg, unsigned Addr, uint64_t Size, + MachinePointerInfo &MPO, CCValAssign &VA) override { + llvm_unreachable("Don't know how to assign a value to an address yet"); + } + + MachineInstrBuilder &MIB; +}; +} // End anonymous namespace. + bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, unsigned VReg) const { - // TODO: handle functions returning non-void values. - if (Val) - return false; - // silence unused-function warning, remove after the function implementation. - (void)RetCC_X86; + assert(((Val && VReg) || (!Val && !VReg)) && "Return value without a vreg"); + + auto MIB = MIRBuilder.buildInstrNoInsert(X86::RET).addImm(0); + + if (VReg) { + MachineFunction &MF = MIRBuilder.getMF(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + auto &DL = MF.getDataLayout(); + const Function &F = *MF.getFunction(); - MIRBuilder.buildInstr(X86::RET).addImm(0); + ArgInfo OrigArg{VReg, Val->getType()}; + setArgFlags(OrigArg, AttributeSet::ReturnIndex, DL, F); + SmallVector<ArgInfo, 8> SplitArgs; + splitToValueTypes(OrigArg, SplitArgs, DL, MRI, + [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) { + MIRBuilder.buildExtract(Regs, Offsets, VReg); + }); + + FuncReturnHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86); + if(!handleAssignments(MIRBuilder, SplitArgs, Handler)) + return false; + } + + MIRBuilder.insertInstr(MIB); return true; } @@ -98,18 +175,32 @@ bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, if (F.isVarArg()) return false; - auto DL = MIRBuilder.getMF().getDataLayout(); + MachineFunction &MF = MIRBuilder.getMF(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + auto DL = MF.getDataLayout(); - SmallVector<ArgInfo, 8> ArgInfos; + SmallVector<ArgInfo, 8> SplitArgs; unsigned Idx = 0; for (auto &Arg : F.getArgumentList()) { - ArgInfo AInfo(VRegs[Idx], Arg.getType()); - setArgFlags(AInfo, Idx + 1, DL, F); - ArgInfos.push_back(AInfo); + ArgInfo OrigArg(VRegs[Idx], Arg.getType()); + setArgFlags(OrigArg, Idx + 1, DL, F); + splitToValueTypes(OrigArg, SplitArgs, DL, MRI, + [&](ArrayRef<unsigned> Regs, ArrayRef<uint64_t> Offsets) { + MIRBuilder.buildSequence(VRegs[Idx], Regs, Offsets); + }); Idx++; } - FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.getMF().getRegInfo(), - CC_X86, DL); - return handleAssignments(MIRBuilder, ArgInfos, ArgHandler); + MachineBasicBlock &MBB = MIRBuilder.getMBB(); + if (!MBB.empty()) + MIRBuilder.setInstr(*MBB.begin()); + + FormalArgHandler Handler(MIRBuilder, MRI, CC_X86, DL); + if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) + return false; + + // Move back to the end of the basic block. + MIRBuilder.setMBB(MBB); + + return true; } |