38 bool AssignedFirstMaskArg =
false;
41 RISCVOutgoingValueAssigner(
44 RISCVAssignFn(RISCVAssignFn_), IsRet(IsRet) {}
54 std::optional<unsigned> FirstMaskArgument;
57 FirstMaskArgument = ValNo;
58 AssignedFirstMaskArg =
true;
61 if (RISCVAssignFn(
DL, Subtarget.
getTargetABI(), ValNo, ValVT, LocVT,
62 LocInfo, Flags, State,
Info.IsFixed, IsRet,
Info.Ty,
74 : OutgoingValueHandler(
B,
MRI), MIB(MIB),
84 SPReg = MIRBuilder.buildCopy(p0,
Register(RISCV::X2)).getReg(0);
86 auto OffsetReg = MIRBuilder.buildConstant(sXLen,
Offset);
88 auto AddrReg = MIRBuilder.buildPtrAdd(p0, SPReg, OffsetReg);
91 return AddrReg.getReg(0);
106 MIRBuilder.buildStore(ExtReg,
Addr, *MMO);
113 ValVReg = MIRBuilder.buildAnyExt(
LLT::scalar(64), ValVReg).getReg(0);
116 MIRBuilder.buildCopy(PhysReg, ExtReg);
122 std::function<
void()> *Thunk)
override {
123 assert(VAs.
size() >= 2 &&
"Expected at least 2 VAs.");
129 "Values belong to different arguments");
133 "unexpected custom value");
137 MIRBuilder.buildUnmerge(NewRegs, Arg.
Regs[0]);
150 auto assignFunc = [=]() {
185 bool AssignedFirstMaskArg =
false;
188 RISCVIncomingValueAssigner(
191 RISCVAssignFn(RISCVAssignFn_), IsRet(IsRet) {}
204 std::optional<unsigned> FirstMaskArgument;
207 FirstMaskArgument = ValNo;
208 AssignedFirstMaskArg =
true;
211 if (RISCVAssignFn(
DL, Subtarget.
getTargetABI(), ValNo, ValVT, LocVT,
212 LocInfo, Flags, State,
true, IsRet,
Info.Ty,
223 : IncomingValueHandler(
B,
MRI),
243 MIRBuilder.buildLoad(ValVReg,
Addr, *MMO);
248 markPhysRegUsed(PhysReg);
254 std::function<
void()> *Thunk)
override {
255 assert(VAs.
size() >= 2 &&
"Expected at least 2 VAs.");
261 "Values belong to different arguments");
265 "unexpected custom value");
285 MIRBuilder.buildMergeLikeInstr(Arg.
Regs[0], NewRegs);
293 virtual void markPhysRegUsed(
MCRegister PhysReg) = 0;
299struct RISCVFormalArgHandler :
public RISCVIncomingValueHandler {
301 : RISCVIncomingValueHandler(
B,
MRI) {}
303 void markPhysRegUsed(
MCRegister PhysReg)
override {
304 MIRBuilder.getMRI()->addLiveIn(PhysReg);
305 MIRBuilder.getMBB().addLiveIn(PhysReg);
309struct RISCVCallReturnHandler :
public RISCVIncomingValueHandler {
312 : RISCVIncomingValueHandler(
B,
MRI), MIB(MIB) {}
314 void markPhysRegUsed(
MCRegister PhysReg)
override {
350 bool IsLowerArgs =
false) {
353 if (
T->isIntegerTy())
354 return T->getIntegerBitWidth() <= Subtarget.
getXLen() * 2;
355 if (
T->isFloatTy() ||
T->isDoubleTy())
357 if (
T->isPointerTy())
371 bool IsLowerRetVal =
false) {
374 if (
T->isIntegerTy())
375 return T->getIntegerBitWidth() <= Subtarget.
getXLen() * 2;
376 if (
T->isFloatTy() ||
T->isDoubleTy())
378 if (
T->isPointerTy())
384 if (
T->isStructTy()) {
385 auto StructT = cast<StructType>(
T);
386 for (
unsigned i = 0, e = StructT->getNumElements(); i != e; ++i)
423 RISCVOutgoingValueAssigner Assigner(
426 RISCVOutgoingValueHandler Handler(MIRBuilder, MF.
getRegInfo(), Ret);
428 MIRBuilder,
CC,
F.isVarArg());
434 assert(!Val == VRegs.
empty() &&
"Return value without a vreg");
437 if (!lowerReturnVal(MIRBuilder, Val, VRegs, Ret))
446void RISCVCallLowering::saveVarArgRegisters(
448 IncomingValueAssigner &Assigner,
CCState &CCInfo)
const {
451 unsigned XLenInBytes = Subtarget.
getXLen() / 8;
460 int VarArgsSaveSize = XLenInBytes * (ArgRegs.
size() -
Idx);
465 if (VarArgsSaveSize == 0) {
466 int VaArgOffset = Assigner.StackSize;
469 int VaArgOffset = -VarArgsSaveSize;
477 VaArgOffset -
static_cast<int>(XLenInBytes),
true);
478 VarArgsSaveSize += XLenInBytes;
487 MRI.createGenericVirtualRegister(sXLen), XLenInBytes);
492 for (
unsigned I =
Idx;
I < ArgRegs.
size(); ++
I) {
493 const Register VReg =
MRI.createGenericVirtualRegister(sXLen);
501 FIN = MIRBuilder.
buildPtrAdd(
MRI.createGenericVirtualRegister(p0),
518 if (
F.arg_empty() && !
F.isVarArg())
523 for (
auto &Arg :
F.args()) {
535 for (
auto &Arg :
F.args()) {
548 RISCVIncomingValueAssigner Assigner(
551 RISCVFormalArgHandler Handler(MIRBuilder, MF.
getRegInfo());
554 CCState CCInfo(
CC,
F.isVarArg(), MIRBuilder.
getMF(), ArgLocs,
F.getContext());
560 saveVarArgRegisters(MIRBuilder, Handler, Assigner, CCInfo);
574 for (
auto &AInfo :
Info.OrigArgs) {
579 if (!
Info.OrigRet.Ty->isVoidTy() &&
584 MIRBuilder.
buildInstr(RISCV::ADJCALLSTACKDOWN);
588 for (
auto &AInfo :
Info.OrigArgs) {
596 Info.IsTailCall =
false;
599 if (!
Info.Callee.isReg())
608 Call.addRegMask(
TRI->getCallPreservedMask(MF,
Info.CallConv));
610 RISCVOutgoingValueAssigner ArgAssigner(
613 RISCVOutgoingValueHandler ArgHandler(MIRBuilder, MF.
getRegInfo(), Call);
615 MIRBuilder,
CC,
Info.IsVarArg))
622 .
addImm(ArgAssigner.StackSize)
628 if (Call->getOperand(0).isReg())
632 Call->getDesc(), Call->getOperand(0), 0);
634 if (
Info.OrigRet.Ty->isVoidTy())
640 RISCVIncomingValueAssigner RetAssigner(
643 RISCVCallReturnHandler RetHandler(MIRBuilder, MF.
getRegInfo(), Call);
645 MIRBuilder,
CC,
Info.IsVarArg))
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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
This file declares the MachineIRBuilder class.
unsigned const TargetRegisterInfo * TRI
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
MachineFunction & getMachineFunction() const
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
unsigned getValNo() const
bool handleAssignments(ValueHandler &Handler, SmallVectorImpl< ArgInfo > &Args, CCState &CCState, SmallVectorImpl< CCValAssign > &ArgLocs, MachineIRBuilder &MIRBuilder, ArrayRef< Register > ThisReturnRegs=std::nullopt) const
Use Handler to insert code to handle the argument/return values represented by Args.
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.
bool determineAssignments(ValueAssigner &Assigner, SmallVectorImpl< ArgInfo > &Args, CCState &CCInfo) const
Analyze the argument list in Args, using Assigner to populate CCInfo.
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...
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.
Wrapper class representing physical registers. Should be passed by value.
bool isVector() const
Return true if this is a vector value type.
bool isScalableVector() const
Return true if this is a vector value type where the runtime length is machine dependent.
MVT getVectorElementType() const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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
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,...
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 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
const RegisterBankInfo * getRegBankInfo() const override
bool hasVInstructionsI64() const
bool hasVInstructionsF64() const
bool hasVInstructionsF16() const
bool hasVInstructionsBF16() const
bool hasVInstructions() const
const RISCVRegisterInfo * getRegisterInfo() const override
const RISCVInstrInfo * getInstrInfo() const override
const RISCVTargetLowering * getTargetLowering() const override
bool hasVInstructionsF32() const
bool RISCVCCAssignFn(const DataLayout &DL, RISCVABI::ABI, unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed, bool IsRet, Type *OrigTy, const RISCVTargetLowering &TLI, std::optional< unsigned > FirstMaskArgument)
RISCVCCAssignFn - This target-specific function extends the default CCValAssign with additional infor...
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.
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.
@ Fast
Attempts to make calls as fast as possible (e.g.
ArrayRef< MCPhysReg > getArgGPRs(const RISCVABI::ABI ABI)
bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed, bool IsRet, Type *OrigTy, const RISCVTargetLowering &TLI, std::optional< unsigned > FirstMaskArgument)
bool CC_RISCV_FastCC(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed, bool IsRet, Type *OrigTy, const RISCVTargetLowering &TLI, std::optional< unsigned > FirstMaskArgument)
@ 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...
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO)
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...
void assignValueToReg(Register ValVReg, Register PhysReg, const CCValAssign &VA) override
Provides a default implementation for argument handling.
Base class for ValueHandlers used for arguments passed to a function call, or for return values.
virtual bool assignArg(unsigned ValNo, EVT OrigVT, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, const ArgInfo &Info, ISD::ArgFlagsTy Flags, CCState &State)
Wrap call to (typically tablegenerated CCAssignFn).
virtual Register getStackAddress(uint64_t MemSize, int64_t Offset, MachinePointerInfo &MPO, ISD::ArgFlagsTy Flags)=0
Materialize a VReg containing the address of the specified stack-based object.
virtual void assignValueToAddress(Register ValVReg, Register Addr, LLT MemTy, const MachinePointerInfo &MPO, const CCValAssign &VA)=0
The specified value has been assigned to a stack location.
Register extendRegister(Register ValReg, const CCValAssign &VA, unsigned MaxSizeBits=0)
Extend a register to the location type given in VA, capped at extending to at most MaxSize bits.
virtual unsigned assignCustomValue(ArgInfo &Arg, ArrayRef< CCValAssign > VAs, std::function< void()> *Thunk=nullptr)
Handle custom values, which may be passed into one or more of VAs.
virtual void assignValueToReg(Register ValVReg, Register PhysReg, const CCValAssign &VA)=0
The specified value has been assigned to a physical register, handle the appropriate COPY (either to ...
This class contains a discriminated union of information about pointers in memory operands,...
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.