32#define DEBUG_TYPE "arc-lower"
72void ARCTargetLowering::ReplaceNodeResults(
SDNode *
N,
79 switch (
N->getOpcode()) {
81 if (
N->getValueType(0) == MVT::i64) {
86 DAG.
getVTList(MVT::i32, MVT::Other),
N->getOperand(0));
194 assert(LHS.getValueType() == MVT::i32 &&
"Only know how to SELECT_CC i32");
204 assert(
Op.getValueType() == MVT::i32 &&
205 "Unhandled target sign_extend_inreg.");
208 if (Width == 16 || Width == 8)
228 assert(
LHS.getValueType() == MVT::i32 &&
"Only know how to BR_CC i32");
229 return DAG.
getNode(ARCISD::BRcc, dl, MVT::Other, Chain, Dest,
LHS,
RHS,
236 return DAG.
getNode(ARCISD::GAWRAPPER, SDLoc(
N), MVT::i32, GA);
239#define GET_CALLING_CONV_IMPL
240#include "ARCGenCallingConv.inc"
285 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
312 if (!StackPtr.getNode())
329 if (!MemOpChains.
empty())
337 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
338 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
339 RegsToPass[i].second, Glue);
346 bool IsDirect =
true;
359 Ops.push_back(Chain);
360 Ops.push_back(Callee);
362 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i)
364 RegsToPass[i].second.getValueType()));
370 assert(Mask &&
"Missing call preserved mask for calling convention");
376 Chain = DAG.
getNode(IsDirect ? ARCISD::BL : ARCISD::JL, dl, NodeTys,
Ops);
398 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
419 for (
unsigned i = 0, e = ResultMemLocs.
size(); i != e; ++i) {
420 int Offset = ResultMemLocs[i].first;
421 unsigned Index = ResultMemLocs[i].second;
427 InVals[Index] = Load;
433 if (!MemOpChains.
empty())
447 ISD::ArgFlagsTy
Flags;
453SDValue ARCTargetLowering::LowerFormalArguments(
462 return LowerCallArguments(Chain, CallConv, IsVarArg, Ins, dl, DAG, InVals);
468SDValue ARCTargetLowering::LowerCallArguments(
474 MachineRegisterInfo &RegInfo = MF.
getRegInfo();
475 auto *AFI = MF.
getInfo<ARCFunctionInfo>();
482 CCInfo.AnalyzeFormalArguments(Ins, CC_ARC);
484 unsigned StackSlotSize = 4;
487 AFI->setReturnStackOffset(CCInfo.getStackSize());
501 for (
unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
502 CCValAssign &VA = ArgLocs[i];
510 LLVM_DEBUG(
errs() <<
"LowerFormalArguments Unhandled argument type: "
525 assert((ObjSize <= StackSlotSize) &&
"Unhandled argument");
536 const ArgDataPair ADP = {ArgIn, Ins[i].Flags};
543 static const MCPhysReg ArgRegs[] = {ARC::R0, ARC::R1, ARC::R2, ARC::R3,
544 ARC::R4, ARC::R5, ARC::R6, ARC::R7};
545 auto *AFI = MF.
getInfo<ARCFunctionInfo>();
546 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs);
547 if (FirstVAReg < std::size(ArgRegs)) {
554 CCInfo.getStackSize(),
true);
555 AFI->setVarArgsFrameIndex(VarFI);
557 for (
unsigned i = FirstVAReg; i < std::size(ArgRegs); i++) {
577 if (!CFRegNode.
empty())
584 for (
const auto &ArgDI : ArgData) {
585 if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) {
586 unsigned Size = ArgDI.Flags.getByValSize();
588 std::max(
Align(StackSlotSize), ArgDI.Flags.getNonZeroByValAlign());
595 Alignment, Alignment,
false,
false,
nullptr,
false,
596 MachinePointerInfo(), MachinePointerInfo()));
603 if (!MemOps.
empty()) {
615bool ARCTargetLowering::CanLowerReturn(
618 const Type *RetTy)
const {
620 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs,
Context);
621 if (!CCInfo.CheckReturn(Outs, RetCC_ARC))
623 if (CCInfo.getStackSize() != 0 && IsVarArg)
647 CCInfo.AllocateStack(AFI->getReturnStackOffset(),
Align(4));
649 CCInfo.AnalyzeReturn(Outs, RetCC_ARC);
655 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
656 CCValAssign &VA = RVLocs[i];
667 int FI = MFI.CreateFixedObject(ObjSize,
Offset,
false);
673 Chain, dl, OutVals[i], FIN,
679 if (!MemOpChains.
empty())
683 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
684 CCValAssign &VA = RVLocs[i];
700 RetOps.push_back(Glue);
703 return DAG.
getNode(ARCISD::RET, dl, MVT::Other, RetOps);
711 DAGCombinerInfo &DCI)
const {
725 return AM.
Scale == 0;
729bool ARCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
739 EVT VT =
Op.getValueType();
741 assert(
Op.getConstantOperandVal(0) == 0 &&
742 "Only support lowering frame addr of current frame.");
754 return DAG.
getNode(ARCISD::GAWRAPPER, dl, MVT::i32, GA);
767 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
772 switch (
Op.getOpcode()) {
774 return LowerGlobalAddress(
Op, DAG);
776 return LowerFRAMEADDR(
Op, DAG);
778 return LowerSELECT_CC(
Op, DAG);
780 return LowerBR_CC(
Op, DAG);
782 return LowerSIGN_EXTEND_INREG(
Op, DAG);
784 return LowerJumpTable(
Op, DAG);
792 assert(
Op.getSimpleValueType() == MVT::i32);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static ARCCC::CondCode ISDCCtoARCCC(ISD::CondCode isdCC)
static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG)
static SDValue lowerCallResult(SDValue Chain, SDValue InGlue, const SmallVectorImpl< CCValAssign > &RVLocs, SDLoc dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals)
Lower the result values of a call into the appropriate copies out of physical registers / memory loca...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
ARCFunctionInfo - This class is derived from MachineFunction private ARC target-specific information ...
const ARCRegisterInfo * getRegisterInfo() const override
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
Provide custom lowering hooks for some operations.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
ARCTargetLowering(const TargetMachine &TM, const ARCSubtarget &Subtarget)
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
LLVM_ABI void AnalyzeCallOperands(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeCallOperands - Analyze the outgoing arguments to a call, incorporating info about the passed v...
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
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
This class represents a function call, abstracting a target machine's calling convention.
A parsed version of the target data layout string in and methods for querying it.
int64_t getOffset() const
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
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.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Wrapper class representing virtual and physical registers.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
const TargetLowering & getTargetLoweringInfo() const
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
@ ZeroOrOneBooleanContent
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
TargetLowering(const TargetLowering &)=delete
Primary interface to the complete machine description for the target machine.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Fast
Attempts to make calls as fast as possible (e.g.
@ C
The default llvm calling convention, compatible with C.
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
@ ADD
Simple integer binary arithmetic operators.
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ SIGN_EXTEND
Conversion operators.
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ UNDEF
UNDEF - An undefined node.
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
@ SHL
Shift and rotation operations.
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
@ AND
Bitwise operators - logical and, logical or, logical xor.
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Register getFrameRegister(const MachineFunction &MF) const override
This struct is a compact representation of a valid (non-zero power of two) alignment.
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs
SmallVector< SDValue, 32 > OutVals