summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/X86CallLowering.cpp
diff options
context:
space:
mode:
authorIgor Breger <igor.breger@intel.com>2017-02-06 08:37:41 +0000
committerIgor Breger <igor.breger@intel.com>2017-02-06 08:37:41 +0000
commit5c31a4c9a3e86d952d1487b32d55ac526e4c8ee3 (patch)
tree9d71a316690998c634fa1d3baa94536600b03b35 /llvm/lib/Target/X86/X86CallLowering.cpp
parentd53f34618ba06c19d9a2965c7a5c67296867e3d8 (diff)
downloadbcm5719-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.cpp119
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;
}
OpenPOWER on IntegriCloud