61 if (
T->isStructTy()) {
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 : OutgoingValueHandler(MIRBuilder,
MRI), MIB(MIB) {}
102 auto SPReg = MIRBuilder.buildCopy(p0,
Register(ARM::SP));
104 auto OffsetReg = MIRBuilder.buildConstant(s32,
Offset);
106 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
109 return AddrReg.getReg(0);
120 Register ExtReg = extendRegister(ValVReg, VA);
121 MIRBuilder.buildCopy(PhysReg, ExtReg);
127 Register ExtReg = extendRegister(ValVReg, VA);
128 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
130 MIRBuilder.buildStore(ExtReg,
Addr, *MMO);
135 std::function<
void()> *Thunk)
override {
136 assert(
Arg.Regs.size() == 1 &&
"Can't handle multple regs yet");
150 "Values belong to different arguments");
157 MIRBuilder.buildUnmerge(NewRegs,
Arg.Regs[0]);
159 bool IsLittle = MIRBuilder.getMF().getSubtarget<
ARMSubtarget>().isLittle();
165 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
166 assignValueToReg(NewRegs[1], NextVA.
getLocReg(), NextVA);
170 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
171 assignValueToReg(NewRegs[1], NextVA.
getLocReg(), NextVA);
189 auto &MF = MIRBuilder.
getMF();
190 const auto &
F = MF.getFunction();
192 const auto &
DL = MF.getDataLayout();
193 auto &TLI = *getTLI<ARMTargetLowering>();
204 TLI.CCAssignFnForReturn(
F.getCallingConv(),
F.isVarArg());
206 OutgoingValueAssigner RetAssigner(AssignFn);
207 ARMOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
209 MIRBuilder,
F.getCallingConv(),
216 assert(!Val == VRegs.
empty() &&
"Return value without a vreg");
219 unsigned Opcode = ST.getReturnOpcode();
222 if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
236 : IncomingValueHandler(MIRBuilder,
MRI) {}
248 const bool IsImmutable = !
Flags.isByVal();
250 int FI = MFI.CreateFixedObject(
Size,
Offset, IsImmutable);
264 assert(
MRI.getType(ValVReg).isScalar() &&
"Only scalars supported atm");
270 buildLoad(ValVReg,
Addr, MemTy, MPO);
291 assert(ValSize <= 64 &&
"Unsupported value size");
292 assert(LocSize <= 64 &&
"Unsupported location size");
294 markPhysRegUsed(PhysReg);
295 if (ValSize == LocSize) {
298 assert(ValSize < LocSize &&
"Extensions not supported");
304 MIRBuilder.
buildTrunc(ValVReg, PhysRegToVReg);
310 std::function<
void()> *Thunk)
override {
311 assert(
Arg.Regs.size() == 1 &&
"Can't handle multple regs yet");
325 "Values belong to different arguments");
333 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
334 assignValueToReg(NewRegs[1], NextVA.
getLocReg(), NextVA);
348 virtual void markPhysRegUsed(
unsigned PhysReg) = 0;
355 void markPhysRegUsed(
unsigned PhysReg)
override {
367 auto &TLI = *getTLI<ARMTargetLowering>();
368 auto Subtarget = TLI.getSubtarget();
370 if (Subtarget->isThumb1Only())
380 auto &MF = MIRBuilder.
getMF();
384 for (
auto &
Arg :
F.args()) {
387 if (
Arg.hasPassPointeeByValueCopyAttr())
392 TLI.CCAssignFnForCall(
F.getCallingConv(),
F.isVarArg());
399 for (
auto &
Arg :
F.args()) {
412 MIRBuilder,
F.getCallingConv(),
428 void markPhysRegUsed(
unsigned PhysReg)
override {
439 return STI.isThumb() ? ARM::tBL : ARM::BL;
450 return ARM::BMOVPCRX_CALL;
456 const auto &TLI = *getTLI<ARMTargetLowering>();
462 if (STI.genLongCalls())
468 auto CallSeqStart = MIRBuilder.
buildInstr(ARM::ADJCALLSTACKDOWN);
472 bool IsDirect = !
Info.Callee.isReg();
476 bool IsThumb = STI.isThumb();
480 MIB.add(
Info.Callee);
482 auto CalleeReg =
Info.Callee.getReg();
483 if (CalleeReg && !CalleeReg.isPhysical()) {
484 unsigned CalleeIdx = IsThumb ? 2 : 0;
487 *MIB.getInstr(), MIB->getDesc(),
Info.Callee, CalleeIdx));
491 MIB.addRegMask(
TRI->getCallPreservedMask(MF,
Info.CallConv));
494 for (
auto Arg :
Info.OrigArgs) {
498 if (
Arg.Flags[0].isByVal())
504 auto ArgAssignFn = TLI.CCAssignFnForCall(
Info.CallConv,
Info.IsVarArg);
506 ARMOutgoingValueHandler ArgHandler(MIRBuilder,
MRI, MIB);
508 MIRBuilder,
Info.CallConv,
Info.IsVarArg))
514 if (!
Info.OrigRet.Ty->isVoidTy()) {
520 auto RetAssignFn = TLI.CCAssignFnForReturn(
Info.CallConv,
Info.IsVarArg);
524 MIRBuilder,
Info.CallConv,
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI, Type *T)
This file describes how to lower LLVM calls to machine code calls.
This file contains the simple types necessary to represent the attributes associated with functions a...
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Implement a low-level type suitable for MachineInstr level instruction selection.
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineIRBuilder class.
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
ARMCallLowering(const ARMTargetLowering &TLI)
bool lowerReturn(MachineIRBuilder &MIRBuilder, const Value *Val, ArrayRef< Register > VRegs, FunctionLoweringInfo &FLI) const override
This hook behaves as the extended lowerReturn function, but for targets that do not support swifterro...
bool lowerFormalArguments(MachineIRBuilder &MIRBuilder, const Function &F, ArrayRef< ArrayRef< Register > > VRegs, FunctionLoweringInfo &FLI) const override
This hook must be implemented to lower the incoming (formal) arguments, described by VRegs,...
bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override
This hook must be implemented to lower the given call instruction, including argument and return valu...
const RegisterBankInfo * getRegBankInfo() const override
const ARMBaseInstrInfo * getInstrInfo() const override
bool isThumb1Only() const
const ARMBaseRegisterInfo * getRegisterInfo() const override
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
unsigned getValNo() const
bool determineAndHandleAssignments(ValueHandler &Handler, ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, bool IsVarArg, ArrayRef< Register > ThisReturnRegs=std::nullopt) const
Invoke ValueAssigner::assignArg on each of the given Args and then use Handler to move them to the as...
void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl< ArgInfo > &SplitArgs, const DataLayout &DL, CallingConv::ID CallConv, SmallVectorImpl< uint64_t > *Offsets=nullptr) const
Break OrigArgInfo into one or more pieces the calling convention can process, returned in SplitArgs.
void setArgFlags(ArgInfo &Arg, unsigned OpIdx, const DataLayout &DL, const FuncInfoTy &FuncInfo) const
A parsed version of the target data layout string in and methods for querying it.
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align 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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Helper class to build MachineInstr.
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
MachineInstrBuilder buildMergeLikeInstr(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ... or Res = G_BUILD_VECTOR Op0, ... or Res = G_CONCAT_VEC...
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
MachineFunction & getMF()
Getter for the function we currently build.
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.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Wrapper class representing virtual and physical registers.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
This is an optimization pass for GlobalISel generic memory operations.
Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
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.
unsigned gettBLXrOpcode(const MachineFunction &MF)
unsigned getBLXOpcode(const MachineFunction &MF)
Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Helper struct shared between Function Specialization and SCCP Solver.
Base class for ValueHandlers used for arguments coming into the current function, or for return value...
Base class for ValueHandlers used for arguments passed to a function call, or for return values.
uint64_t StackSize
The size of the currently allocated portion of the stack.
MachineIRBuilder & MIRBuilder
MachineRegisterInfo & MRI
bool isSimple() const
Test if the given EVT is simple (as opposed to being extended).
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
bool isVector() const
Return true if this is a vector value type.
bool isInteger() const
Return true if this is an integer or a vector integer type.
This class contains a discriminated union of information about pointers in memory operands,...
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
static MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.