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);
128 Register ExtReg = extendRegister(ValVReg, VA);
129 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
131 MIRBuilder.buildStore(ExtReg,
Addr, *MMO);
136 std::function<
void()> *Thunk)
override {
137 assert(Arg.
Regs.size() == 1 &&
"Can't handle multple regs yet");
151 "Values belong to different arguments");
158 MIRBuilder.buildUnmerge(NewRegs, Arg.
Regs[0]);
160 bool IsLittle = MIRBuilder.getMF().getSubtarget<
ARMSubtarget>().isLittle();
166 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
167 assignValueToReg(NewRegs[1], NextVA.
getLocReg(), NextVA);
171 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
172 assignValueToReg(NewRegs[1], NextVA.
getLocReg(), NextVA);
190 auto &MF = MIRBuilder.
getMF();
191 const auto &
F = MF.getFunction();
193 const auto &
DL = MF.getDataLayout();
194 auto &TLI = *getTLI<ARMTargetLowering>();
205 TLI.CCAssignFnForReturn(
F.getCallingConv(),
F.isVarArg());
207 OutgoingValueAssigner RetAssigner(AssignFn);
208 ARMOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
210 MIRBuilder,
F.getCallingConv(),
217 assert(!Val == VRegs.
empty() &&
"Return value without a vreg");
220 unsigned Opcode = ST.getReturnOpcode();
223 if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
237 : IncomingValueHandler(MIRBuilder,
MRI) {}
249 const bool IsImmutable = !Flags.isByVal();
251 int FI = MFI.CreateFixedObject(
Size,
Offset, IsImmutable);
266 assert(
MRI.getType(ValVReg).isScalar() &&
"Only scalars supported atm");
272 buildLoad(ValVReg,
Addr, MemTy, MPO);
293 assert(ValSize <= 64 &&
"Unsupported value size");
294 assert(LocSize <= 64 &&
"Unsupported location size");
296 markPhysRegUsed(PhysReg);
297 if (ValSize == LocSize) {
300 assert(ValSize < LocSize &&
"Extensions not supported");
306 MIRBuilder.
buildTrunc(ValVReg, PhysRegToVReg);
312 std::function<
void()> *Thunk)
override {
313 assert(Arg.
Regs.size() == 1 &&
"Can't handle multple regs yet");
327 "Values belong to different arguments");
335 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
336 assignValueToReg(NewRegs[1], NextVA.
getLocReg(), NextVA);
350 virtual void markPhysRegUsed(
unsigned PhysReg) = 0;
357 void markPhysRegUsed(
unsigned PhysReg)
override {
369 auto &TLI = *getTLI<ARMTargetLowering>();
370 auto Subtarget = TLI.getSubtarget();
372 if (Subtarget->isThumb1Only())
382 auto &MF = MIRBuilder.
getMF();
386 for (
auto &Arg :
F.args()) {
389 if (Arg.hasPassPointeeByValueCopyAttr())
394 TLI.CCAssignFnForCall(
F.getCallingConv(),
F.isVarArg());
401 for (
auto &Arg :
F.args()) {
414 MIRBuilder,
F.getCallingConv(),
425struct CallReturnHandler :
public ARMIncomingValueHandler {
428 : ARMIncomingValueHandler(MIRBuilder,
MRI), MIB(MIB) {}
430 void markPhysRegUsed(
unsigned PhysReg)
override {
441 return STI.isThumb() ? ARM::tBL : ARM::BL;
452 return ARM::BMOVPCRX_CALL;
458 const auto &TLI = *getTLI<ARMTargetLowering>();
464 if (STI.genLongCalls())
470 auto CallSeqStart = MIRBuilder.
buildInstr(ARM::ADJCALLSTACKDOWN);
474 bool IsDirect = !
Info.Callee.isReg();
478 bool IsThumb = STI.isThumb();
482 MIB.add(
Info.Callee);
484 auto CalleeReg =
Info.Callee.getReg();
485 if (CalleeReg && !CalleeReg.isPhysical()) {
486 unsigned CalleeIdx = IsThumb ? 2 : 0;
489 *MIB.getInstr(), MIB->getDesc(),
Info.Callee, CalleeIdx));
493 MIB.addRegMask(
TRI->getCallPreservedMask(MF,
Info.CallConv));
496 for (
auto Arg :
Info.OrigArgs) {
500 if (Arg.
Flags[0].isByVal())
506 auto ArgAssignFn = TLI.CCAssignFnForCall(
Info.CallConv,
Info.IsVarArg);
508 ARMOutgoingValueHandler ArgHandler(MIRBuilder,
MRI, MIB);
510 MIRBuilder,
Info.CallConv,
Info.IsVarArg))
516 if (!
Info.OrigRet.Ty->isVoidTy()) {
522 auto RetAssignFn = TLI.CCAssignFnForReturn(
Info.CallConv,
Info.IsVarArg);
524 CallReturnHandler RetHandler(MIRBuilder,
MRI, MIB);
526 MIRBuilder,
Info.CallConv,
unsigned const MachineRegisterInfo * MRI
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, 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.
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.
SmallVector< Register, 4 > Regs
SmallVector< ISD::ArgFlagsTy, 4 > Flags
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.