51 #include "X86GenCallingConv.inc" 56 bool X86CallLowering::splitToValueTypes(
const ArgInfo &OrigArg,
60 SplitArgTy PerformArgSplit)
const {
86 for (
unsigned i = 0; i < NumParts; ++i) {
89 PartTy, OrigArg.
Flags};
94 PerformArgSplit(SplitRegs);
107 unsigned getStackAddress(uint64_t
Size, int64_t
Offset,
112 MIRBuilder.
buildCopy(SPReg, STI.getRegisterInfo()->getStackRegister());
118 MIRBuilder.
buildGEP(AddrReg, SPReg, OffsetReg);
124 void assignValueToReg(
unsigned ValVReg,
unsigned PhysReg,
135 unsigned PhysRegSize =
139 if (PhysRegSize > ValSize && LocSize == ValSize) {
140 assert((PhysRegSize == 128 || PhysRegSize == 80) &&
"We expect that to be 128 bit");
144 ExtReg = extendRegister(ValVReg, VA);
149 void assignValueToAddress(
unsigned ValVReg,
unsigned Addr, uint64_t Size,
151 unsigned ExtReg = extendRegister(ValVReg, VA);
158 bool assignArg(
unsigned ValNo,
MVT ValVT,
MVT LocVT,
161 bool Res = AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.
Flags, State);
164 static const MCPhysReg XMMArgRegs[] = {X86::XMM0, X86::XMM1, X86::XMM2,
165 X86::XMM3, X86::XMM4, X86::XMM5,
166 X86::XMM6, X86::XMM7};
173 uint64_t getStackSize() {
return StackSize; }
174 uint64_t getNumXmmRegs() {
return NumXMMRegs; }
178 uint64_t StackSize = 0;
181 unsigned NumXMMRegs = 0;
190 "Return value without a vreg");
193 if (!VRegs.
empty()) {
204 "For each split Type there should be exactly one VReg.");
207 for (
unsigned i = 0; i < SplitEVTs.size(); ++i) {
208 ArgInfo CurArgInfo =
ArgInfo{VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx)};
210 if (!splitToValueTypes(CurArgInfo, SplitArgs, DL, MRI,
217 OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, RetCC_X86);
234 unsigned getStackAddress(uint64_t
Size, int64_t
Offset,
246 void assignValueToAddress(
unsigned ValVReg,
unsigned Addr, uint64_t Size,
251 MIRBuilder.
buildLoad(ValVReg, Addr, *MMO);
254 void assignValueToReg(
unsigned ValVReg,
unsigned PhysReg,
256 markPhysRegUsed(PhysReg);
266 unsigned PhysRegSize =
270 if (PhysRegSize > ValSize && LocSize == ValSize) {
279 case CCValAssign::LocInfo::SExt:
280 case CCValAssign::LocInfo::ZExt:
281 case CCValAssign::LocInfo::AExt: {
292 virtual void markPhysRegUsed(
unsigned PhysReg) = 0;
298 struct FormalArgHandler :
public IncomingValueHandler {
301 : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
303 void markPhysRegUsed(
unsigned PhysReg)
override {
308 struct CallReturnHandler :
public IncomingValueHandler {
311 : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
313 void markPhysRegUsed(
unsigned PhysReg)
override {
352 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
364 FormalArgHandler Handler(MIRBuilder, MRI, CC_X86);
392 unsigned AdjStackDown = TII.getCallFrameSetupOpcode();
393 auto CallSeqStart = MIRBuilder.
buildInstr(AdjStackDown);
398 unsigned CallOpc = Callee.
isReg()
399 ? (Is64Bit ? X86::CALL64r : X86::CALL32r)
400 : (Is64Bit ? X86::CALL64pcrel32 : X86::CALLpcrel32);
403 TRI->getCallPreservedMask(MF, CallConv));
406 for (
const auto &OrigArg : OrigArgs) {
412 if (!splitToValueTypes(OrigArg, SplitArgs, DL, MRI,
419 OutgoingValueHandler Handler(MIRBuilder, MRI, MIB, CC_X86);
423 bool IsFixed = OrigArgs.empty() ?
true : OrigArgs.back().IsFixed;
435 .
addImm(Handler.getNumXmmRegs());
458 if (!splitToValueTypes(OrigRet, SplitArgs, DL, MRI,
464 CallReturnHandler Handler(MIRBuilder, MRI, RetCC_X86, MIB);
468 if (!NewRegs.
empty())
472 CallSeqStart.
addImm(Handler.getStackSize())
476 unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
478 .
addImm(Handler.getStackSize())
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set, or Regs.size() if they are all allocated.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
bool is64Bit() const
Is this x86_64? (disregarding specific ABI / programming model)
const MachineInstrBuilder & add(const MachineOperand &MO) const
A parsed version of the target data layout string in and methods for querying it. ...
C - The default llvm calling convention, compatible with C.
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ...
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res = G_GEP Op0, Op1.
This class represents lattice values for constants.
const X86InstrInfo * getInstrInfo() const override
void push_back(const T &Elt)
unsigned getReg() const
getReg - Returns the register number.
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change...
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< unsigned > VRegs) const override
This hook must be implemented to lower the incoming (formal) arguments, described by Args...
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
virtual const RegisterBankInfo * getRegBankInfo() const
If the information for the register banks is available, return it.
unsigned const TargetRegisterInfo * TRI
block Block Frequency true
bool lowerCall(MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, const MachineOperand &Callee, const ArgInfo &OrigRet, ArrayRef< ArgInfo > OrigArgs) const override
This hook must be implemented to lower the given call instruction, including argument and return valu...
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
MVT getRegisterType(MVT VT) const
Return the type of registers that this ValueType will eventually require.
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
bool handleAssignments(MachineIRBuilder &MIRBuilder, ArrayRef< ArgInfo > Args, ValueHandler &Handler) const
Invoke Handler::assignArg on each of the given Args and then use Callback to move them to the assigne...
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
const HexagonInstrInfo * TII
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This file contains the simple types necessary to represent the attributes associated with functions a...
unsigned getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
LocInfo getLocInfo() const
unsigned getSizeInBits() const
void assign(size_type NumElts, const T &Elt)
unsigned getNextStackOffset() const
getNextStackOffset - Return the next stack offset such that all stack slots satisfy their alignment r...
Type * getType() const
All values are typed, get the type of this value.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
virtual const TargetInstrInfo * getInstrInfo() const
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
void ComputeValueVTs(const TargetLowering &TLI, const DataLayout &DL, Type *Ty, SmallVectorImpl< EVT > &ValueVTs, SmallVectorImpl< uint64_t > *Offsets=nullptr, uint64_t StartingOffset=0)
ComputeValueVTs - Given an LLVM IR type, compute a sequence of EVTs that represent all the individual...
Analysis containing CSE Info
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
TargetInstrInfo - Interface to description of machine instruction set.
bool isVoidTy() const
Return true if this is 'void'.
void addLiveIn(MCPhysReg PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const TargetRegisterInfo * getTargetRegisterInfo() const
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
size_t size() const
size - Get the array size.
Helper class to build MachineInstr.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
const MachineInstrBuilder & addRegMask(const uint32_t *Mask) const
The C convention as specified in the x86-64 supplement to the System V ABI, used on most non-Windows ...
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
Argument handling is mostly uniform between the four places that make these decisions: function forma...
This class contains a discriminated union of information about pointers in memory operands...
MachineInstrBuilder buildFrameIndex(unsigned Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
The memory access writes data.
const X86RegisterInfo * getRegisterInfo() const override
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef< unsigned > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ...
CCState - This class holds information needed while lowering arguments and return values...
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
CCValAssign - Represent assignment of one arg/retval to a location.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
This file declares the MachineIRBuilder class.
This file describes how to lower LLVM calls to machine code calls.
amdgpu Simplify well known AMD library false Value Value * Arg
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
void emplace_back(ArgTypes &&... Args)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
LLVM_NODISCARD bool empty() const
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
The memory access always returns the same value (or traps).
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef< unsigned > VRegs) const override
This hook must be implemented to lower outgoing return values, described by Val, into the specified v...
unsigned getNumRegisters(LLVMContext &Context, EVT VT) const
Return the number of registers that this ValueType will eventually require.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space (defaulting to 0).
bool isTargetLinux() const
bool isCallingConvWin64(CallingConv::ID CC) const
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
X86CallLowering(const X86TargetLowering &TLI)
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
unsigned constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const MCInstrDesc &II, const MachineOperand &RegMO, unsigned OpIdx)
Try to constrain Reg so that it is usable by argument OpIdx of the provided MCInstrDesc II...
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineOperand & getOperand(unsigned i) const
iterator_range< arg_iterator > args()
bool empty() const
empty - Check if the array is empty.