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.");
207 unsigned Width = cast<VTSDNode>(
Op.getOperand(1))->getVT().getSizeInBits();
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,
234 auto *
N = cast<JumpTableSDNode>(
Op);
236 return DAG.
getNode(ARCISD::GAWRAPPER,
SDLoc(
N), MVT::i32, GA);
239#include "ARCGenCallingConv.inc"
265 CCInfo.AnalyzeCallOperands(Outs, CC_ARC);
271 RetCCInfo.AllocateStack(CCInfo.getStackSize(),
Align(4));
272 RetCCInfo.AnalyzeCallResult(Ins, RetCC_ARC);
275 unsigned NumBytes = RetCCInfo.getStackSize();
284 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
328 if (!MemOpChains.
empty())
336 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
337 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
338 RegsToPass[i].second, Glue);
345 bool IsDirect =
true;
346 if (
auto *
G = dyn_cast<GlobalAddressSDNode>(Callee))
348 else if (
auto *E = dyn_cast<ExternalSymbolSDNode>(Callee))
361 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i)
363 RegsToPass[i].second.getValueType()));
369 assert(Mask &&
"Missing call preserved mask for calling convention");
375 Chain = DAG.
getNode(IsDirect ? ARCISD::BL : ARCISD::JL, dl, NodeTys, Ops);
397 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
418 for (
unsigned i = 0, e = ResultMemLocs.
size(); i != e; ++i) {
419 int Offset = ResultMemLocs[i].first;
420 unsigned Index = ResultMemLocs[i].second;
426 InVals[Index] = Load;
432 if (!MemOpChains.
empty())
452SDValue ARCTargetLowering::LowerFormalArguments(
461 return LowerCallArguments(Chain, CallConv, IsVarArg, Ins, dl, DAG, InVals);
467SDValue ARCTargetLowering::LowerCallArguments(
481 CCInfo.AnalyzeFormalArguments(Ins, CC_ARC);
483 unsigned StackSlotSize = 4;
486 AFI->setReturnStackOffset(CCInfo.getStackSize());
500 for (
unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
509 LLVM_DEBUG(
errs() <<
"LowerFormalArguments Unhandled argument type: "
514 unsigned VReg =
RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
524 assert((ObjSize <= StackSlotSize) &&
"Unhandled argument");
535 const ArgDataPair ADP = {ArgIn,
Ins[i].Flags};
542 static const MCPhysReg ArgRegs[] = {ARC::R0, ARC::R1, ARC::R2, ARC::R3,
543 ARC::R4, ARC::R5, ARC::R6, ARC::R7};
545 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs);
546 if (FirstVAReg < std::size(ArgRegs)) {
553 CCInfo.getStackSize(),
true);
554 AFI->setVarArgsFrameIndex(VarFI);
556 for (
unsigned i = FirstVAReg; i < std::size(ArgRegs); i++) {
558 unsigned VReg =
RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
559 RegInfo.addLiveIn(ArgRegs[i], VReg);
576 if (!CFRegNode.
empty())
583 for (
const auto &ArgDI : ArgData) {
584 if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) {
585 unsigned Size = ArgDI.Flags.getByValSize();
587 std::max(
Align(StackSlotSize), ArgDI.Flags.getNonZeroByValAlign());
602 if (!MemOps.
empty()) {
614bool ARCTargetLowering::CanLowerReturn(
619 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
620 if (!CCInfo.CheckReturn(Outs, RetCC_ARC))
622 if (CCInfo.getStackSize() != 0 && IsVarArg)
646 CCInfo.AllocateStack(AFI->getReturnStackOffset(),
Align(4));
648 CCInfo.AnalyzeReturn(Outs, RetCC_ARC);
654 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
666 int FI = MFI.CreateFixedObject(ObjSize,
Offset,
false);
672 Chain, dl, OutVals[i], FIN,
678 if (!MemOpChains.
empty())
682 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
699 RetOps.push_back(Glue);
702 return DAG.
getNode(ARCISD::RET, dl, MVT::Other, RetOps);
710 DAGCombinerInfo &DCI)
const {
724 return AM.
Scale == 0;
728bool ARCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
738 EVT VT =
Op.getValueType();
740 assert(
Op.getConstantOperandVal(0) == 0 &&
741 "Only support lowering frame addr of current frame.");
753 return DAG.
getNode(ARCISD::GAWRAPPER, dl, MVT::i32, GA);
765 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
766 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
771 switch (
Op.getOpcode()) {
773 return LowerGlobalAddress(
Op, DAG);
775 return LowerFRAMEADDR(
Op, DAG);
777 return LowerSELECT_CC(
Op, DAG);
779 return LowerBR_CC(
Op, DAG);
781 return LowerSIGN_EXTEND_INREG(
Op, DAG);
783 return LowerJumpTable(
Op, DAG);
791 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
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.
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.
This class represents an Operation in the Expression.
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...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
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 Alignment, 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.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
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 std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ 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.
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)
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
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