64 auto StructT = cast<StructType>(
T);
65 for (
unsigned i = 1, e = StructT->getNumElements(); i != e; ++i)
66 if (StructT->getElementType(i) != StructT->getElementType(0))
82 return VTSize == 1 || VTSize == 8 || VTSize == 16 || VTSize == 32;
92 : ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
94 unsigned getStackAddress(uint64_t
Size, int64_t
Offset,
96 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
108 MIRBuilder.
buildGEP(AddrReg, SPReg, OffsetReg);
114 void assignValueToReg(
unsigned ValVReg,
unsigned PhysReg,
122 unsigned ExtReg = extendRegister(ValVReg, VA);
127 void assignValueToAddress(
unsigned ValVReg,
unsigned Addr, uint64_t Size,
129 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
132 unsigned ExtReg = extendRegister(ValVReg, VA);
146 assert(NextVA.needsCustom() &&
"Value doesn't need custom handling");
150 "Values belong to different arguments");
153 assert(NextVA.isRegLoc() &&
"Value should be in reg");
163 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
164 assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
169 bool assignArg(
unsigned ValNo,
MVT ValVT,
MVT LocVT,
172 if (AssignFn(ValNo, ValVT, LocVT, LocInfo, Info.
Flags, State))
181 uint64_t StackSize = 0;
186 void ARMCallLowering::splitToValueTypes(
199 if (SplitVTs.
size() == 1) {
202 auto Flags = OrigArg.Flags;
204 Flags.setOrigAlign(OriginalAlignment);
205 SplitArgs.
emplace_back(OrigArg.Reg, SplitVTs[0].getTypeForEVT(Ctx), Flags,
210 unsigned FirstRegIdx = SplitArgs.
size();
211 for (
unsigned i = 0, e = SplitVTs.
size(); i != e; ++i) {
212 EVT SplitVT = SplitVTs[i];
214 auto Flags = OrigArg.Flags;
217 Flags.setOrigAlign(OriginalAlignment);
219 bool NeedsConsecutiveRegisters =
222 if (NeedsConsecutiveRegisters) {
223 Flags.setInConsecutiveRegs();
225 Flags.setInConsecutiveRegsLast();
230 SplitTy, Flags, OrigArg.IsFixed});
233 for (
unsigned i = 0; i < Offsets.
size(); ++i)
234 PerformArgSplit(SplitArgs[FirstRegIdx + i].
Reg, Offsets[i] * 8);
246 auto &MF = MIRBuilder.
getMF();
250 auto &TLI = *getTLI<ARMTargetLowering>();
257 "For each split Type there should be exactly one VReg.");
261 for (
unsigned i = 0; i < SplitEVTs.
size(); ++i) {
262 ArgInfo CurArgInfo(VRegs[i], SplitEVTs[i].getTypeForEVT(Ctx));
267 CurArgInfo, SplitVTs, MF,
274 TLI.CCAssignFnForReturn(
F.getCallingConv(),
F.isVarArg());
276 OutgoingValueHandler RetHandler(MIRBuilder, MF.
getRegInfo(),
Ret, AssignFn);
283 assert(!Val == VRegs.
empty() &&
"Return value without a vreg");
289 if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
305 unsigned getStackAddress(uint64_t
Size, int64_t
Offset,
307 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
322 void assignValueToAddress(
unsigned ValVReg,
unsigned Addr, uint64_t Size,
324 assert((Size == 1 || Size == 2 || Size == 4 || Size == 8) &&
335 buildLoad(LoadVReg, Addr, Size, 0, MPO);
339 buildLoad(ValVReg, Addr, Size, 0, MPO);
343 void buildLoad(
unsigned Val,
unsigned Addr, uint64_t Size,
unsigned Alignment,
350 void assignValueToReg(
unsigned ValVReg,
unsigned PhysReg,
358 assert(ValSize <= 64 &&
"Unsupported value size");
359 assert(LocSize <= 64 &&
"Unsupported location size");
361 markPhysRegUsed(PhysReg);
362 if (ValSize == LocSize) {
365 assert(ValSize < LocSize &&
"Extensions not supported");
372 MIRBuilder.
buildCopy(PhysRegToVReg, PhysReg);
373 MIRBuilder.
buildTrunc(ValVReg, PhysRegToVReg);
384 assert(NextVA.needsCustom() &&
"Value doesn't need custom handling");
388 "Values belong to different arguments");
391 assert(NextVA.isRegLoc() &&
"Value should be in reg");
396 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
397 assignValueToReg(NewRegs[1], NextVA.getLocReg(), NextVA);
411 virtual void markPhysRegUsed(
unsigned PhysReg) = 0;
414 struct FormalArgHandler :
public IncomingValueHandler {
417 : IncomingValueHandler(MIRBuilder, MRI, AssignFn) {}
419 void markPhysRegUsed(
unsigned PhysReg)
override {
429 auto &TLI = *getTLI<ARMTargetLowering>();
430 auto Subtarget = TLI.getSubtarget();
432 if (Subtarget->isThumb1Only())
442 auto &MF = MIRBuilder.
getMF();
443 auto &MBB = MIRBuilder.
getMBB();
449 if (
Arg.hasByValOrInAllocaAttr())
456 FormalArgHandler ArgHandler(MIRBuilder, MIRBuilder.
getMF().
getRegInfo(),
468 splitToValueTypes(AInfo, ArgInfos, MF, [&](
unsigned Reg, uint64_t
Offset) {
472 if (!SplitRegs.
empty())
491 struct CallReturnHandler :
public IncomingValueHandler {
494 : IncomingValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB) {}
496 void markPhysRegUsed(
unsigned PhysReg)
override {
504 unsigned getCallOpcode(
const ARMSubtarget &STI,
bool isDirect) {
517 return ARM::BMOVPCRX_CALL;
527 const auto &TLI = *getTLI<ARMTargetLowering>();
533 if (STI.genLongCalls())
536 if (STI.isThumb1Only())
539 auto CallSeqStart = MIRBuilder.
buildInstr(ARM::ADJCALLSTACKDOWN);
543 bool isDirect = !Callee.
isReg();
544 auto CallOpcode = getCallOpcode(STI, isDirect);
553 auto CalleeReg = Callee.
getReg();
554 if (CalleeReg && !TRI->isPhysicalRegister(CalleeReg)) {
555 unsigned CalleeIdx = isThumb ? 2 : 0;
557 MF, *TRI, MRI, *STI.getInstrInfo(), *STI.getRegBankInfo(),
558 *MIB.getInstr(), MIB->getDesc(), Callee, CalleeIdx));
562 MIB.addRegMask(TRI->getCallPreservedMask(MF, CallConv));
565 for (
auto Arg : OrigArgs) {
572 if (
Arg.Flags.isByVal())
576 splitToValueTypes(
Arg, ArgInfos, MF, [&](
unsigned Reg, uint64_t
Offset) {
584 auto ArgAssignFn = TLI.CCAssignFnForCall(CallConv,
false);
585 OutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB, ArgAssignFn);
598 splitToValueTypes(OrigRet, ArgInfos, MF,
603 auto RetAssignFn = TLI.CCAssignFnForReturn(CallConv,
false);
604 CallReturnHandler RetHandler(MIRBuilder, MRI, MIB, RetAssignFn);
608 if (!SplitRegs.
empty()) {
620 .
addImm(ArgHandler.StackSize)
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
const MachineInstrBuilder & add(const MachineOperand &MO) const
A parsed version of the target data layout string in and methods for querying it. ...
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res = G_GEP Op0, Op1.
This class represents lattice values for constants.
void push_back(const T &Elt)
unsigned getReg() const
getReg - Returns the register number.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
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...
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
unsigned getValNo() const
unsigned const TargetRegisterInfo * TRI
bool isInteger() const
Return true if this is an integer or a vector integer type.
static bool isThumb(const MCSubtargetInfo &STI)
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
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...
Type * getTypeForEVT(LLVMContext &Context) const
This method returns an LLVM type corresponding to the specified EVT.
ARMCallLowering(const ARMTargetLowering &TLI)
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
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.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineFunction & getMF()
Getter for the function we currently build.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
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.
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...
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.
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.
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
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...
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
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.
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...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
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.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
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...
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned getReturnOpcode() const
Returns the correct return opcode for the current feature set.
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.
bool isVector() const
Return true if this is a vector value type.
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.
static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI, Type *T)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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...
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
LLVM Value Representation.
static LLT pointer(uint16_t AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space (defaulting to 0).
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
bool functionArgumentNeedsConsecutiveRegisters(Type *Ty, CallingConv::ID CallConv, bool isVarArg) const override
Returns true if an argument of type Ty needs to be passed in a contiguous block of registers in calli...
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...
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
This file describes how to lower LLVM calls to machine code calls.
unsigned getLocReg() const
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
iterator_range< arg_iterator > args()
bool isStructTy() const
True if this is an instance of StructType.
bool empty() const
empty - Check if the array is empty.
bool isArrayTy() const
True if this is an instance of ArrayType.