58 cl::desc(
"Enable Global-ISel Big Endian Lowering"));
68 if (
T->isStructTy()) {
72 for (
unsigned i = 1, e = StructT->getNumElements(); i != e; ++i)
73 if (StructT->getElementType(i) != StructT->getElementType(0))
89 return VTSize == 1 || VTSize == 8 || VTSize == 16 || VTSize == 32;
97 ARMOutgoingValueHandler(MachineIRBuilder &MIRBuilder,
98 MachineRegisterInfo &MRI, MachineInstrBuilder &MIB)
99 : OutgoingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
102 MachinePointerInfo &MPO,
103 ISD::ArgFlagsTy Flags)
override {
111 auto OffsetReg = MIRBuilder.buildConstant(s32,
Offset);
113 auto AddrReg = MIRBuilder.buildPtrAdd(p0,
SPReg, OffsetReg);
116 return AddrReg.getReg(0);
120 const CCValAssign &VA,
121 ISD::ArgFlagsTy Flags = {})
override {
128 Register ExtReg = extendRegister(ValVReg, VA);
129 MIRBuilder.buildCopy(PhysReg, ExtReg);
130 MIB.addUse(PhysReg, RegState::Implicit);
134 const MachinePointerInfo &MPO,
135 const CCValAssign &VA)
override {
136 Register ExtReg = extendRegister(ValVReg, VA);
137 auto MMO = MIRBuilder.getMF().getMachineMemOperand(
139 MIRBuilder.buildStore(ExtReg, Addr, *MMO);
142 unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
144 std::function<
void()> *Thunk)
override {
145 assert(Arg.
Regs.size() == 1 &&
"Can't handle multiple regs yet");
147 const CCValAssign &VA = VAs[0];
154 const CCValAssign &NextVA = VAs[1];
159 "Values belong to different arguments");
165 MRI.createGenericVirtualRegister(
LLT::scalar(32))};
166 MIRBuilder.buildUnmerge(NewRegs, Arg.
Regs[0]);
168 bool IsLittle = MIRBuilder.getMF().getSubtarget<ARMSubtarget>().isLittle();
174 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
175 assignValueToReg(NewRegs[1], NextVA.
getLocReg(), NextVA);
179 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
180 assignValueToReg(NewRegs[1], NextVA.
getLocReg(), NextVA);
184 MachineInstrBuilder MIB;
198 auto &MF = MIRBuilder.
getMF();
201 const auto &
DL = MF.getDataLayout();
213 TLI.CCAssignFnForReturn(
F.getCallingConv(),
F.isVarArg());
216 ARMOutgoingValueHandler RetHandler(MIRBuilder, MF.getRegInfo(), Ret);
218 MIRBuilder,
F.getCallingConv(),
225 assert(!Val == VRegs.
empty() &&
"Return value without a vreg");
228 unsigned Opcode = ST.getReturnOpcode();
231 if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
245 : IncomingValueHandler(MIRBuilder, MRI) {}
257 const bool IsImmutable = !Flags.isByVal();
267 const MachinePointerInfo &MPO,
268 const CCValAssign &VA)
override {
274 assert(MRI.getType(ValVReg).isScalar() &&
"Only scalars supported atm");
276 auto LoadVReg = buildLoad(
LLT::scalar(32), Addr, MemTy, MPO);
280 buildLoad(ValVReg, Addr, MemTy, MPO);
284 MachineInstrBuilder buildLoad(
const DstOp &Res,
Register Addr, LLT MemTy,
285 const MachinePointerInfo &MPO) {
286 MachineFunction &MF = MIRBuilder.
getMF();
290 return MIRBuilder.
buildLoad(Res, Addr, *MMO);
294 const CCValAssign &VA,
295 ISD::ArgFlagsTy Flags = {})
override {
302 assert(ValSize <= 64 &&
"Unsupported value size");
303 assert(LocSize <= 64 &&
"Unsupported location size");
305 markPhysRegUsed(PhysReg);
306 if (ValSize == LocSize) {
309 assert(ValSize < LocSize &&
"Extensions not supported");
315 MIRBuilder.
buildTrunc(ValVReg, PhysRegToVReg);
319 unsigned assignCustomValue(ARMCallLowering::ArgInfo &Arg,
321 std::function<
void()> *Thunk)
override {
322 assert(Arg.
Regs.size() == 1 &&
"Can't handle multiple regs yet");
324 const CCValAssign &VA = VAs[0];
331 const CCValAssign &NextVA = VAs[1];
336 "Values belong to different arguments");
342 MRI.createGenericVirtualRegister(
LLT::scalar(32))};
344 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
345 assignValueToReg(NewRegs[1], NextVA.
getLocReg(), NextVA);
359 virtual void markPhysRegUsed(
unsigned PhysReg) = 0;
366 void markPhysRegUsed(
unsigned PhysReg)
override {
379 auto Subtarget = TLI.getSubtarget();
381 if (Subtarget->isThumb1Only())
391 auto &MF = MIRBuilder.
getMF();
395 for (
auto &Arg :
F.args()) {
398 if (Arg.hasPassPointeeByValueCopyAttr())
403 TLI.CCAssignFnForCall(
F.getCallingConv(),
F.isVarArg());
410 for (
auto &Arg :
F.args()) {
411 ArgInfo OrigArgInfo(VRegs[Idx], Arg.getType(), Idx);
413 setArgFlags(OrigArgInfo, Idx + AttributeList::FirstArgIndex,
DL,
F);
423 MIRBuilder,
F.getCallingConv(),
434struct CallReturnHandler :
public ARMIncomingValueHandler {
437 : ARMIncomingValueHandler(MIRBuilder, MRI), MIB(MIB) {}
439 void markPhysRegUsed(
unsigned PhysReg)
override {
443 MachineInstrBuilder MIB;
450 return STI.isThumb() ? ARM::tBL : ARM::BL;
461 return ARM::BMOVPCRX_CALL;
473 if (STI.genLongCalls())
479 auto CallSeqStart = MIRBuilder.
buildInstr(ARM::ADJCALLSTACKDOWN);
483 bool IsDirect = !Info.Callee.isReg();
487 bool IsThumb = STI.isThumb();
491 MIB.add(Info.Callee);
493 auto CalleeReg = Info.Callee.getReg();
494 if (CalleeReg && !CalleeReg.isPhysical()) {
495 unsigned CalleeIdx = IsThumb ? 2 : 0;
498 *MIB.getInstr(), MIB->getDesc(), Info.Callee, CalleeIdx));
502 MIB.addRegMask(
TRI->getCallPreservedMask(MF, Info.CallConv));
505 for (
auto Arg : Info.OrigArgs) {
509 if (Arg.
Flags[0].isByVal())
515 auto ArgAssignFn = TLI.CCAssignFnForCall(Info.CallConv, Info.IsVarArg);
517 ARMOutgoingValueHandler ArgHandler(MIRBuilder, MRI, MIB);
519 MIRBuilder, Info.CallConv, Info.IsVarArg))
525 if (!Info.OrigRet.Ty->isVoidTy()) {
531 auto RetAssignFn = TLI.CCAssignFnForReturn(Info.CallConv, Info.IsVarArg);
533 CallReturnHandler RetHandler(MIRBuilder, MRI, MIB);
535 MIRBuilder, Info.CallConv,
static unsigned getCallOpcode(const MachineFunction &CallerF, bool IsIndirect, bool IsTailCall, std::optional< CallLowering::PtrAuthInfo > &PAI, MachineRegisterInfo &MRI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isSupportedType(const DataLayout &DL, const ARMTargetLowering &TLI, Type *T)
static cl::opt< bool > EnableGISelBigEndian("enable-arm-gisel-bigendian", cl::Hidden, cl::init(false), cl::desc("Enable Global-ISel Big Endian Lowering"))
This file describes how to lower LLVM calls to machine code calls.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
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.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static constexpr MCPhysReg SPReg
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 enableBigEndian() const override
For targets which want to use big-endian can enable it with enableBigEndian() hook.
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
Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
Check if the array is empty.
Register getLocReg() const
LocInfo getLocInfo() const
unsigned getValNo() const
void splitToValueTypes(const ArgInfo &OrigArgInfo, SmallVectorImpl< ArgInfo > &SplitArgs, const DataLayout &DL, CallingConv::ID CallConv, SmallVectorImpl< TypeSize > *Offsets=nullptr) const
Break OrigArgInfo into one or more pieces the calling convention can process, returned in SplitArgs.
bool determineAndHandleAssignments(ValueHandler &Handler, ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, MachineIRBuilder &MIRBuilder, CallingConv::ID CallConv, bool IsVarArg, ArrayRef< Register > ThisReturnRegs={}) const
Invoke ValueAssigner::assignArg on each of the given Args and then use Handler to move them to the as...
CallLowering(const TargetLowering *TLI)
const TargetLowering * getTLI() const
Getter for generic TargetLowering class.
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.
LLVM_ABI 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 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.
Function & getFunction()
Return the LLVM function that this machine code represents.
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.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_TRUNC Op.
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 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, RegState Flags={}, 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,...
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.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI 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...
@ Implicit
Not emitted register (e.g. carry, or temporary result).
bool CCAssignFn(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
CCAssignFn - This function assigns a location for Val, updating State to reflect the change.
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
unsigned gettBLXrOpcode(const MachineFunction &MF)
unsigned getBLXOpcode(const MachineFunction &MF)
LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
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,...
LLVM_ABI unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.