diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86CallLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86CallLowering.cpp | 244 |
1 files changed, 75 insertions, 169 deletions
diff --git a/llvm/lib/Target/X86/X86CallLowering.cpp b/llvm/lib/Target/X86/X86CallLowering.cpp index 53f57565d56e..c8bffb4d4d37 100644 --- a/llvm/lib/Target/X86/X86CallLowering.cpp +++ b/llvm/lib/Target/X86/X86CallLowering.cpp @@ -50,61 +50,47 @@ using namespace llvm; X86CallLowering::X86CallLowering(const X86TargetLowering &TLI) : CallLowering(&TLI) {} -bool 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(); - - SmallVector<EVT, 4> SplitVTs; - SmallVector<uint64_t, 4> Offsets; - ComputeValueVTs(TLI, DL, OrigArg.Ty, SplitVTs, &Offsets, 0); - assert(OrigArg.Regs.size() == 1 && "Can't handle multple regs yet"); +namespace { - if (OrigArg.Ty->isVoidTy()) - return true; +struct X86OutgoingValueAssigner : public CallLowering::OutgoingValueAssigner { +private: + uint64_t StackSize = 0; + unsigned NumXMMRegs = 0; - EVT VT = SplitVTs[0]; - unsigned NumParts = TLI.getNumRegisters(Context, VT); +public: + uint64_t getStackSize() { return StackSize; } + unsigned getNumXmmRegs() { return NumXMMRegs; } - if (NumParts == 1) { - // replace the original type ( pointer -> GPR ). - SplitArgs.emplace_back(OrigArg.Regs[0], VT.getTypeForEVT(Context), - OrigArg.Flags, OrigArg.IsFixed); - return true; - } + X86OutgoingValueAssigner(CCAssignFn *AssignFn_) + : CallLowering::OutgoingValueAssigner(AssignFn_) {} - SmallVector<Register, 8> SplitRegs; + bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, + CCValAssign::LocInfo LocInfo, + const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags, + CCState &State) override { + bool Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State); + StackSize = State.getNextStackOffset(); - EVT PartVT = TLI.getRegisterType(Context, VT); - Type *PartTy = PartVT.getTypeForEVT(Context); + static const MCPhysReg XMMArgRegs[] = {X86::XMM0, X86::XMM1, X86::XMM2, + X86::XMM3, X86::XMM4, X86::XMM5, + X86::XMM6, X86::XMM7}; + if (!Info.IsFixed) + NumXMMRegs = State.getFirstUnallocated(XMMArgRegs); - for (unsigned i = 0; i < NumParts; ++i) { - ArgInfo Info = - ArgInfo{MRI.createGenericVirtualRegister(getLLTForType(*PartTy, DL)), - PartTy, OrigArg.Flags}; - SplitArgs.push_back(Info); - SplitRegs.push_back(Info.Regs[0]); + return Res; } - - PerformArgSplit(SplitRegs); - return true; -} - -namespace { +}; struct X86OutgoingValueHandler : public CallLowering::OutgoingValueHandler { X86OutgoingValueHandler(MachineIRBuilder &MIRBuilder, - MachineRegisterInfo &MRI, MachineInstrBuilder &MIB, - CCAssignFn *AssignFn) - : OutgoingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB), + MachineRegisterInfo &MRI, MachineInstrBuilder &MIB) + : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB), DL(MIRBuilder.getMF().getDataLayout()), STI(MIRBuilder.getMF().getSubtarget<X86Subtarget>()) {} Register getStackAddress(uint64_t Size, int64_t Offset, - MachinePointerInfo &MPO) override { + MachinePointerInfo &MPO, + ISD::ArgFlagsTy Flags) override { LLT p0 = LLT::pointer(0, DL.getPointerSizeInBits(0)); LLT SType = LLT::scalar(DL.getPointerSizeInBits(0)); auto SPReg = @@ -121,65 +107,24 @@ struct X86OutgoingValueHandler : public CallLowering::OutgoingValueHandler { void assignValueToReg(Register ValVReg, Register PhysReg, CCValAssign &VA) override { MIB.addUse(PhysReg, RegState::Implicit); - - Register ExtReg; - // If we are copying the value to a physical register with the - // size larger than the size of the value itself - build AnyExt - // to the size of the register first and only then do the copy. - // The example of that would be copying from s32 to xmm0, for which - // case ValVT == LocVT == MVT::f32. If LocSize and ValSize are not equal - // we expect normal extendRegister mechanism to work. - unsigned PhysRegSize = - MRI.getTargetRegisterInfo()->getRegSizeInBits(PhysReg, MRI); - unsigned ValSize = VA.getValVT().getSizeInBits(); - unsigned LocSize = VA.getLocVT().getSizeInBits(); - if (PhysRegSize > ValSize && LocSize == ValSize) { - assert((PhysRegSize == 128 || PhysRegSize == 80) && - "We expect that to be 128 bit"); - ExtReg = - MIRBuilder.buildAnyExt(LLT::scalar(PhysRegSize), ValVReg).getReg(0); - } else - ExtReg = extendRegister(ValVReg, VA); - + Register ExtReg = extendRegister(ValVReg, VA); MIRBuilder.buildCopy(PhysReg, ExtReg); } - void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size, + void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, MachinePointerInfo &MPO, CCValAssign &VA) override { MachineFunction &MF = MIRBuilder.getMF(); Register ExtReg = extendRegister(ValVReg, VA); - auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, - VA.getLocVT().getStoreSize(), + auto *MMO = MF.getMachineMemOperand(MPO, MachineMemOperand::MOStore, MemTy, inferAlignFromPtrInfo(MF, MPO)); MIRBuilder.buildStore(ExtReg, Addr, *MMO); } - bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT, - CCValAssign::LocInfo LocInfo, - const CallLowering::ArgInfo &Info, ISD::ArgFlagsTy Flags, - CCState &State) override { - bool Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Flags, State); - StackSize = State.getNextStackOffset(); - - static const MCPhysReg XMMArgRegs[] = {X86::XMM0, X86::XMM1, X86::XMM2, - X86::XMM3, X86::XMM4, X86::XMM5, - X86::XMM6, X86::XMM7}; - if (!Info.IsFixed) - NumXMMRegs = State.getFirstUnallocated(XMMArgRegs); - - return Res; - } - - uint64_t getStackSize() { return StackSize; } - uint64_t getNumXmmRegs() { return NumXMMRegs; } - protected: MachineInstrBuilder &MIB; - uint64_t StackSize = 0; const DataLayout &DL; const X86Subtarget &STI; - unsigned NumXMMRegs = 0; }; } // end anonymous namespace @@ -196,27 +141,18 @@ bool X86CallLowering::lowerReturn(MachineIRBuilder &MIRBuilder, const Function &F = MF.getFunction(); MachineRegisterInfo &MRI = MF.getRegInfo(); const DataLayout &DL = MF.getDataLayout(); - LLVMContext &Ctx = Val->getType()->getContext(); - const X86TargetLowering &TLI = *getTLI<X86TargetLowering>(); - 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."); + ArgInfo OrigRetInfo(VRegs, Val->getType(), 0); + setArgFlags(OrigRetInfo, AttributeList::ReturnIndex, DL, F); - SmallVector<ArgInfo, 8> SplitArgs; - 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<Register> Regs) { - MIRBuilder.buildUnmerge(Regs, VRegs[i]); - })) - return false; - } + SmallVector<ArgInfo, 4> SplitRetInfos; + splitToValueTypes(OrigRetInfo, SplitRetInfos, DL, F.getCallingConv()); - X86OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86); - if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) + X86OutgoingValueAssigner Assigner(RetCC_X86); + X86OutgoingValueHandler Handler(MIRBuilder, MRI, MIB); + if (!determineAndHandleAssignments(Handler, Assigner, SplitRetInfos, + MIRBuilder, F.getCallingConv(), + F.isVarArg())) return false; } @@ -228,14 +164,20 @@ namespace { struct X86IncomingValueHandler : public CallLowering::IncomingValueHandler { X86IncomingValueHandler(MachineIRBuilder &MIRBuilder, - MachineRegisterInfo &MRI, CCAssignFn *AssignFn) - : IncomingValueHandler(MIRBuilder, MRI, AssignFn), + MachineRegisterInfo &MRI) + : IncomingValueHandler(MIRBuilder, MRI), DL(MIRBuilder.getMF().getDataLayout()) {} Register getStackAddress(uint64_t Size, int64_t Offset, - MachinePointerInfo &MPO) override { + MachinePointerInfo &MPO, + ISD::ArgFlagsTy Flags) override { auto &MFI = MIRBuilder.getMF().getFrameInfo(); - int FI = MFI.CreateFixedObject(Size, Offset, true); + + // Byval is assumed to be writable memory, but other stack passed arguments + // are not. + const bool IsImmutable = !Flags.isByVal(); + + int FI = MFI.CreateFixedObject(Size, Offset, IsImmutable); MPO = MachinePointerInfo::getFixedStack(MIRBuilder.getMF(), FI); return MIRBuilder @@ -243,11 +185,11 @@ struct X86IncomingValueHandler : public CallLowering::IncomingValueHandler { .getReg(0); } - void assignValueToAddress(Register ValVReg, Register Addr, uint64_t Size, + void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, MachinePointerInfo &MPO, CCValAssign &VA) override { MachineFunction &MF = MIRBuilder.getMF(); auto *MMO = MF.getMachineMemOperand( - MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, Size, + MPO, MachineMemOperand::MOLoad | MachineMemOperand::MOInvariant, MemTy, inferAlignFromPtrInfo(MF, MPO)); MIRBuilder.buildLoad(ValVReg, Addr, *MMO); } @@ -255,36 +197,7 @@ struct X86IncomingValueHandler : public CallLowering::IncomingValueHandler { void assignValueToReg(Register ValVReg, Register PhysReg, CCValAssign &VA) override { markPhysRegUsed(PhysReg); - - switch (VA.getLocInfo()) { - default: { - // If we are copying the value from a physical register with the - // size larger than the size of the value itself - build the copy - // of the phys reg first and then build the truncation of that copy. - // The example of that would be copying from xmm0 to s32, for which - // case ValVT == LocVT == MVT::f32. If LocSize and ValSize are not equal - // we expect this to be handled in SExt/ZExt/AExt case. - unsigned PhysRegSize = - MRI.getTargetRegisterInfo()->getRegSizeInBits(PhysReg, MRI); - unsigned ValSize = VA.getValVT().getSizeInBits(); - unsigned LocSize = VA.getLocVT().getSizeInBits(); - if (PhysRegSize > ValSize && LocSize == ValSize) { - auto Copy = MIRBuilder.buildCopy(LLT::scalar(PhysRegSize), PhysReg); - MIRBuilder.buildTrunc(ValVReg, Copy); - return; - } - - MIRBuilder.buildCopy(ValVReg, PhysReg); - break; - } - case CCValAssign::LocInfo::SExt: - case CCValAssign::LocInfo::ZExt: - case CCValAssign::LocInfo::AExt: { - auto Copy = MIRBuilder.buildCopy(LLT{VA.getLocVT()}, PhysReg); - MIRBuilder.buildTrunc(ValVReg, Copy); - break; - } - } + IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA); } /// How the physical register gets marked varies between formal @@ -297,9 +210,8 @@ protected: }; struct FormalArgHandler : public X86IncomingValueHandler { - FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, - CCAssignFn *AssignFn) - : X86IncomingValueHandler(MIRBuilder, MRI, AssignFn) {} + FormalArgHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI) + : X86IncomingValueHandler(MIRBuilder, MRI) {} void markPhysRegUsed(unsigned PhysReg) override { MIRBuilder.getMRI()->addLiveIn(PhysReg); @@ -309,8 +221,8 @@ struct FormalArgHandler : public X86IncomingValueHandler { struct CallReturnHandler : public X86IncomingValueHandler { CallReturnHandler(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, - CCAssignFn *AssignFn, MachineInstrBuilder &MIB) - : X86IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {} + MachineInstrBuilder &MIB) + : X86IncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {} void markPhysRegUsed(unsigned PhysReg) override { MIB.addDef(PhysReg, RegState::Implicit); @@ -349,13 +261,9 @@ bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, Arg.hasAttribute(Attribute::Nest) || VRegs[Idx].size() > 1) return false; - ArgInfo OrigArg(VRegs[Idx], Arg.getType()); + ArgInfo OrigArg(VRegs[Idx], Arg.getType(), Idx); setArgFlags(OrigArg, Idx + AttributeList::FirstArgIndex, DL, F); - if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI, - [&](ArrayRef<Register> Regs) { - MIRBuilder.buildMerge(VRegs[Idx][0], Regs); - })) - return false; + splitToValueTypes(OrigArg, SplitArgs, DL, F.getCallingConv()); Idx++; } @@ -363,8 +271,10 @@ bool X86CallLowering::lowerFormalArguments(MachineIRBuilder &MIRBuilder, if (!MBB.empty()) MIRBuilder.setInstr(*MBB.begin()); - FormalArgHandler Handler(MIRBuilder, MRI, CC_X86); - if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) + X86OutgoingValueAssigner Assigner(CC_X86); + FormalArgHandler Handler(MIRBuilder, MRI); + if (!determineAndHandleAssignments(Handler, Assigner, SplitArgs, MIRBuilder, + F.getCallingConv(), F.isVarArg())) return false; // Move back to the end of the basic block. @@ -412,15 +322,13 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, if (OrigArg.Regs.size() > 1) return false; - if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI, - [&](ArrayRef<Register> Regs) { - MIRBuilder.buildUnmerge(Regs, OrigArg.Regs[0]); - })) - return false; + splitToValueTypes(OrigArg, SplitArgs, DL, Info.CallConv); } // Do the actual argument marshalling. - X86OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, CC_X86); - if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) + X86OutgoingValueAssigner Assigner(CC_X86); + X86OutgoingValueHandler Handler(MIRBuilder, MRI, MIB); + if (!determineAndHandleAssignments(Handler, Assigner, SplitArgs, MIRBuilder, + Info.CallConv, Info.IsVarArg)) return false; bool IsFixed = Info.OrigArgs.empty() ? true : Info.OrigArgs.back().IsFixed; @@ -435,7 +343,7 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, MIRBuilder.buildInstr(X86::MOV8ri) .addDef(X86::AL) - .addImm(Handler.getNumXmmRegs()); + .addImm(Assigner.getNumXmmRegs()); MIB.addUse(X86::AL, RegState::Implicit); } @@ -462,27 +370,25 @@ bool X86CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, SplitArgs.clear(); SmallVector<Register, 8> NewRegs; - if (!splitToValueTypes(Info.OrigRet, SplitArgs, DL, MRI, - [&](ArrayRef<Register> Regs) { - NewRegs.assign(Regs.begin(), Regs.end()); - })) - return false; + splitToValueTypes(Info.OrigRet, SplitArgs, DL, Info.CallConv); - CallReturnHandler Handler(MIRBuilder, MRI, RetCC_X86, MIB); - if (!handleAssignments(MIRBuilder, SplitArgs, Handler)) + X86OutgoingValueAssigner Assigner(RetCC_X86); + CallReturnHandler Handler(MIRBuilder, MRI, MIB); + if (!determineAndHandleAssignments(Handler, Assigner, SplitArgs, MIRBuilder, + Info.CallConv, Info.IsVarArg)) return false; if (!NewRegs.empty()) MIRBuilder.buildMerge(Info.OrigRet.Regs[0], NewRegs); } - CallSeqStart.addImm(Handler.getStackSize()) + CallSeqStart.addImm(Assigner.getStackSize()) .addImm(0 /* see getFrameTotalSize */) .addImm(0 /* see getFrameAdjustment */); unsigned AdjStackUp = TII.getCallFrameDestroyOpcode(); MIRBuilder.buildInstr(AdjStackUp) - .addImm(Handler.getStackSize()) + .addImm(Assigner.getStackSize()) .addImm(0 /* NumBytesForCalleeToPop */); return true; |
