30 RISCVOutgoingValueHandler(MachineIRBuilder &
B, MachineRegisterInfo &MRI,
31 MachineInstrBuilder MIB)
32 : OutgoingValueHandler(
B, MRI), MIB(MIB),
33 Subtarget(MIRBuilder.getMF().getSubtarget<RISCVSubtarget>()) {}
35 MachinePointerInfo &MPO,
36 ISD::ArgFlagsTy Flags)
override {
37 MachineFunction &MF = MIRBuilder.getMF();
42 SPReg = MIRBuilder.buildCopy(p0,
Register(RISCV::X2)).getReg(0);
44 auto OffsetReg = MIRBuilder.buildConstant(sXLen,
Offset);
46 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
49 return AddrReg.getReg(0);
53 const MachinePointerInfo &MPO,
54 const CCValAssign &VA)
override {
55 MachineFunction &MF = MIRBuilder.getMF();
63 Register ExtReg = extendRegister(ValVReg, VA);
64 MIRBuilder.buildStore(ExtReg, Addr, *MMO);
68 const CCValAssign &VA,
69 ISD::ArgFlagsTy Flags = {})
override {
70 Register ExtReg = extendRegister(ValVReg, VA);
71 MIRBuilder.buildCopy(PhysReg, ExtReg);
72 MIB.addUse(PhysReg, RegState::Implicit);
75 unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
77 std::function<
void()> *Thunk)
override {
78 const CCValAssign &VA = VAs[0];
83 auto assignFunc = [=]() {
84 auto Trunc = MIRBuilder.buildAnyExt(LLT(VA.
getLocVT()), Arg.
Regs[0]);
85 MIRBuilder.buildCopy(PhysReg, Trunc);
86 MIB.addUse(PhysReg, RegState::Implicit);
90 *
Thunk = std::move(assignFunc);
98 assert(VAs.
size() >= 2 &&
"Expected at least 2 VAs.");
99 const CCValAssign &VAHi = VAs[1];
103 "Values belong to different arguments");
107 "unexpected custom value");
110 MRI.createGenericVirtualRegister(
LLT::scalar(32))};
111 MIRBuilder.buildUnmerge(NewRegs, Arg.
Regs[0]);
116 MachinePointerInfo MPO;
117 Register StackAddr = getStackAddress(
120 assignValueToAddress(NewRegs[1], StackAddr, MemTy, MPO,
121 const_cast<CCValAssign &
>(VAHi));
124 auto assignFunc = [=]() {
125 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
127 assignValueToReg(NewRegs[1], VAHi.
getLocReg(), VAHi);
131 *
Thunk = std::move(assignFunc);
140 MachineInstrBuilder MIB;
145 const RISCVSubtarget &Subtarget;
149 RISCVIncomingValueHandler(MachineIRBuilder &
B, MachineRegisterInfo &MRI)
150 : IncomingValueHandler(
B, MRI),
151 Subtarget(MIRBuilder.getMF().getSubtarget<RISCVSubtarget>()) {}
154 MachinePointerInfo &MPO,
155 ISD::ArgFlagsTy Flags)
override {
156 MachineFrameInfo &MFI = MIRBuilder.getMF().getFrameInfo();
160 return MIRBuilder.buildFrameIndex(
LLT::pointer(0, Subtarget.getXLen()), FI)
165 const MachinePointerInfo &MPO,
166 const CCValAssign &VA)
override {
167 MachineFunction &MF = MIRBuilder.getMF();
170 MIRBuilder.buildLoad(ValVReg, Addr, *MMO);
174 const CCValAssign &VA,
175 ISD::ArgFlagsTy Flags = {})
override {
176 markPhysRegUsed(PhysReg);
177 IncomingValueHandler::assignValueToReg(ValVReg, PhysReg, VA);
180 unsigned assignCustomValue(CallLowering::ArgInfo &Arg,
182 std::function<
void()> *Thunk)
override {
183 const CCValAssign &VA = VAs[0];
188 markPhysRegUsed(PhysReg);
191 auto Copy = MIRBuilder.buildCopy(LocTy, PhysReg);
193 MIRBuilder.buildTrunc(Arg.
Regs[0],
Copy.getReg(0));
197 assert(VAs.
size() >= 2 &&
"Expected at least 2 VAs.");
198 const CCValAssign &VAHi = VAs[1];
202 "Values belong to different arguments");
206 "unexpected custom value");
209 MRI.createGenericVirtualRegister(
LLT::scalar(32))};
214 MachinePointerInfo MPO;
215 Register StackAddr = getStackAddress(
218 assignValueToAddress(NewRegs[1], StackAddr, MemTy, MPO,
219 const_cast<CCValAssign &
>(VAHi));
222 assignValueToReg(NewRegs[0], VA.
getLocReg(), VA);
224 assignValueToReg(NewRegs[1], VAHi.
getLocReg(), VAHi);
226 MIRBuilder.buildMergeLikeInstr(Arg.
Regs[0], NewRegs);
234 virtual void markPhysRegUsed(MCRegister PhysReg) = 0;
237 const RISCVSubtarget &Subtarget;
240struct RISCVFormalArgHandler :
public RISCVIncomingValueHandler {
241 RISCVFormalArgHandler(MachineIRBuilder &
B, MachineRegisterInfo &MRI)
242 : RISCVIncomingValueHandler(
B, MRI) {}
244 void markPhysRegUsed(MCRegister PhysReg)
override {
245 MIRBuilder.getMRI()->addLiveIn(PhysReg);
246 MIRBuilder.getMBB().addLiveIn(PhysReg);
250struct RISCVCallReturnHandler :
public RISCVIncomingValueHandler {
251 RISCVCallReturnHandler(MachineIRBuilder &
B, MachineRegisterInfo &MRI,
252 MachineInstrBuilder &MIB)
253 : RISCVIncomingValueHandler(
B, MRI), MIB(MIB) {}
255 void markPhysRegUsed(MCRegister PhysReg)
override {
256 MIB.addDef(PhysReg, RegState::Implicit);
259 MachineInstrBuilder MIB;
291 bool IsLowerArgs =
false) {
292 if (
T->isIntegerTy())
294 if (
T->isHalfTy() ||
T->isFloatTy() ||
T->isDoubleTy() ||
T->isFP128Ty())
296 if (
T->isPointerTy())
313 bool IsLowerRetVal =
false) {
314 if (
T->isIntegerTy() ||
T->isFloatingPointTy() ||
T->isPointerTy())
320 if (
T->isStructTy()) {
322 for (
unsigned i = 0, e = StructT->getNumElements(); i != e; ++i)
339 assert(!Val == VRegs.
empty() &&
"Return value without a vreg");
344 }
else if (!VRegs.
empty()) {
363 RISCVOutgoingValueHandler Handler(MIRBuilder, MF.
getRegInfo(), Ret);
366 CCState CCInfo(CC,
F.isVarArg(), MF, RetLocs,
F.getContext());
384 bool IsVarArg)
const {
386 CCState CCInfo(CallConv, IsVarArg, MF, RetLocs,
394void RISCVCallLowering::saveVarArgRegisters(
396 IncomingValueAssigner &Assigner,
CCState &CCInfo)
const {
399 unsigned XLenInBytes = Subtarget.
getXLen() / 8;
408 int VarArgsSaveSize = XLenInBytes * (ArgRegs.
size() - Idx);
413 if (VarArgsSaveSize == 0) {
414 int VaArgOffset = Assigner.StackSize;
417 int VaArgOffset = -VarArgsSaveSize;
425 VaArgOffset -
static_cast<int>(XLenInBytes),
true);
426 VarArgsSaveSize += XLenInBytes;
439 const MVT XLenVT = Subtarget.
getXLenVT();
440 for (
unsigned I = Idx;
I < ArgRegs.
size(); ++
I) {
467 for (
auto &Arg :
F.args()) {
485 for (
auto &Arg :
F.args()) {
487 ArgInfo AInfo(VRegs[Index], Arg.getType(), Index);
499 RISCVFormalArgHandler Handler(MIRBuilder, MF.
getRegInfo());
502 CCState CCInfo(CC,
F.isVarArg(), MIRBuilder.
getMF(), ArgLocs,
F.getContext());
512 saveVarArgRegisters(MIRBuilder, Handler, Assigner, CCInfo);
525 for (
auto &AInfo : Info.OrigArgs) {
528 if (AInfo.Flags[0].isByVal())
532 if (!Info.OrigRet.Ty->isVoidTy() &&
537 MIRBuilder.
buildInstr(RISCV::ADJCALLSTACKDOWN);
540 for (
auto &AInfo : Info.OrigArgs) {
548 Info.IsTailCall =
false;
551 if (!Info.Callee.isReg())
560 Call.addRegMask(
TRI->getCallPreservedMask(MF, Info.CallConv));
563 RISCVOutgoingValueHandler ArgHandler(MIRBuilder, MF.
getRegInfo(),
Call);
565 MIRBuilder, CC, Info.IsVarArg))
578 if (
Call->getOperand(0).isReg())
582 Call->getDesc(),
Call->getOperand(0), 0);
584 if (Info.CanLowerReturn && !Info.OrigRet.Ty->isVoidTy()) {
589 RISCVCallReturnHandler RetHandler(MIRBuilder, MF.
getRegInfo(),
Call);
591 MIRBuilder, CC, Info.IsVarArg))
595 if (!Info.CanLowerReturn)
597 Info.DemoteRegister, Info.DemoteStackIndex);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static bool isSupportedReturnType(Type *T)
static bool isSupportedArgumentType(Type *T)
static bool isLegalElementTypeForRVV(Type *EltTy, const RISCVSubtarget &Subtarget)
Return true if scalable vector with ScalarTy is legal for lowering.
This file describes how to lower LLVM calls to machine code calls.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
CCState - This class holds information needed while lowering arguments and return values.
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
void insertSRetLoads(MachineIRBuilder &MIRBuilder, Type *RetTy, ArrayRef< Register > VRegs, Register DemoteReg, int FI) const
Load the returned value from the stack into virtual registers in VRegs.
bool handleAssignments(ValueHandler &Handler, SmallVectorImpl< ArgInfo > &Args, CCState &CCState, SmallVectorImpl< CCValAssign > &ArgLocs, MachineIRBuilder &MIRBuilder, ArrayRef< Register > ThisReturnRegs={}) const
Use Handler to insert code to handle the argument/return values represented by Args.
void insertSRetIncomingArgument(const Function &F, SmallVectorImpl< ArgInfo > &SplitArgs, Register &DemoteReg, MachineRegisterInfo &MRI, const DataLayout &DL) const
Insert the hidden sret ArgInfo to the beginning of SplitArgs.
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...
void insertSRetStores(MachineIRBuilder &MIRBuilder, Type *RetTy, ArrayRef< Register > VRegs, Register DemoteReg) const
Store the return value given by VRegs into stack starting at the offset specified in DemoteReg.
bool determineAssignments(ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, CCState &CCInfo) const
Analyze the argument list in Args, using Assigner to populate CCInfo.
bool checkReturn(CCState &CCInfo, SmallVectorImpl< BaseArgInfo > &Outs, CCAssignFn *Fn) const
CallLowering(const TargetLowering *TLI)
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.
unsigned getAllocaAddrSpace() const
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
Register DemoteRegister
DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg allocated to hold a pointer to ...
bool CanLowerReturn
CanLowerReturn - true iff the function's return value can be lowered to registers.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
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.
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
bool isInteger() const
Return true if this is an integer or a vector integer type.
bool isScalableVector() const
Return true if this is a vector value type where the runtime length is machine dependent.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Helper class to build MachineInstr.
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
MachineInstrBuilder buildPtrAdd(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_PTR_ADD Op0, Op1.
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, 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 buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
bool lowerReturn(MachineIRBuilder &MIRBuiler, 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 canLowerReturn(MachineFunction &MF, CallingConv::ID CallConv, SmallVectorImpl< BaseArgInfo > &Outs, bool IsVarArg) const override
This hook must be implemented to check whether the return values described by Outs can fit into the r...
bool lowerCall(MachineIRBuilder &MIRBuilder, CallLoweringInfo &Info) const override
This hook must be implemented to lower the given call instruction, including argument and return valu...
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,...
RISCVCallLowering(const RISCVTargetLowering &TLI)
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
void setVarArgsFrameIndex(int Index)
void setVarArgsSaveSize(int Size)
RISCVABI::ABI getTargetABI() const
bool hasVInstructionsI64() const
bool hasVInstructionsF64() const
bool hasVInstructionsBF16Minimal() const
bool hasVInstructionsF16Minimal() const
const RISCVRegisterBankInfo * getRegBankInfo() const override
bool hasVInstructions() const
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
bool hasVInstructionsF32() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
bool isPointerTy() const
True if this is an instance of PointerType.
bool isFloatTy() const
Return true if this is 'float', a 32-bit IEEE fp type.
bool isBFloatTy() const
Return true if this is 'bfloat', a 16-bit bfloat type.
bool isHalfTy() const
Return true if this is 'half', a 16-bit IEEE fp type.
bool isDoubleTy() const
Return true if this is 'double', a 64-bit IEEE fp type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
unsigned getNumOperands() const
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
ArrayRef< MCPhysReg > getArgGPRs(const RISCVABI::ABI ABI)
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...
CCAssignFn RetCC_RISCV
This is used for assigning return values to locations when making calls.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
CCAssignFn CC_RISCV
This is used for assigining arguments to locations when making calls.
LLVM_ABI Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
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...
void assignValueToReg(Register ValVReg, Register PhysReg, const CCValAssign &VA, ISD::ArgFlagsTy Flags={}) override
Provides a default implementation for argument handling.
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.
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.