summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/X86CallLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/X86CallLowering.cpp')
-rw-r--r--llvm/lib/Target/X86/X86CallLowering.cpp244
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;