31#define DEBUG_TYPE "arc-lower"
71void ARCTargetLowering::ReplaceNodeResults(
SDNode *
N,
78 switch (
N->getOpcode()) {
80 if (
N->getValueType(0) == MVT::i64) {
85 DAG.
getVTList(MVT::i32, MVT::Other),
N->getOperand(0));
186 return "ARCISD::CMOV";
188 return "ARCISD::CMP";
190 return "ARCISD::BRcc";
192 return "ARCISD::RET";
194 return "ARCISD::GAWRAPPER";
211 assert(
LHS.getValueType() == MVT::i32 &&
"Only know how to SELECT_CC i32");
221 assert(
Op.getValueType() == MVT::i32 &&
222 "Unhandled target sign_extend_inreg.");
224 unsigned Width = cast<VTSDNode>(
Op.getOperand(1))->getVT().getSizeInBits();
225 if (Width == 16 || Width == 8)
245 assert(
LHS.getValueType() == MVT::i32 &&
"Only know how to BR_CC i32");
251 auto *
N = cast<JumpTableSDNode>(
Op);
256#include "ARCGenCallingConv.inc"
282 CCInfo.AnalyzeCallOperands(Outs, CC_ARC);
288 RetCCInfo.AllocateStack(CCInfo.getStackSize(),
Align(4));
289 RetCCInfo.AnalyzeCallResult(Ins, RetCC_ARC);
292 unsigned NumBytes = RetCCInfo.getStackSize();
301 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
345 if (!MemOpChains.
empty())
353 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
354 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
355 RegsToPass[i].second, Glue);
362 bool IsDirect =
true;
363 if (
auto *
G = dyn_cast<GlobalAddressSDNode>(Callee))
365 else if (
auto *E = dyn_cast<ExternalSymbolSDNode>(Callee))
378 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i)
380 RegsToPass[i].second.getValueType()));
386 assert(Mask &&
"Missing call preserved mask for calling convention");
414 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
435 for (
unsigned i = 0, e = ResultMemLocs.
size(); i != e; ++i) {
436 int Offset = ResultMemLocs[i].first;
437 unsigned Index = ResultMemLocs[i].second;
443 InVals[
Index] = Load;
449 if (!MemOpChains.
empty())
469SDValue ARCTargetLowering::LowerFormalArguments(
478 return LowerCallArguments(Chain, CallConv, IsVarArg, Ins, dl, DAG, InVals);
484SDValue ARCTargetLowering::LowerCallArguments(
498 CCInfo.AnalyzeFormalArguments(Ins, CC_ARC);
500 unsigned StackSlotSize = 4;
503 AFI->setReturnStackOffset(CCInfo.getStackSize());
517 for (
unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
526 LLVM_DEBUG(
errs() <<
"LowerFormalArguments Unhandled argument type: "
531 unsigned VReg =
RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
541 assert((ObjSize <= StackSlotSize) &&
"Unhandled argument");
552 const ArgDataPair ADP = {ArgIn,
Ins[i].Flags};
559 static const MCPhysReg ArgRegs[] = {ARC::R0, ARC::R1, ARC::R2, ARC::R3,
560 ARC::R4, ARC::R5, ARC::R6, ARC::R7};
562 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs);
563 if (FirstVAReg < std::size(ArgRegs)) {
570 CCInfo.getStackSize(),
true);
571 AFI->setVarArgsFrameIndex(VarFI);
573 for (
unsigned i = FirstVAReg; i < std::size(ArgRegs); i++) {
575 unsigned VReg =
RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
576 RegInfo.addLiveIn(ArgRegs[i], VReg);
593 if (!CFRegNode.
empty())
600 for (
const auto &ArgDI : ArgData) {
601 if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) {
602 unsigned Size = ArgDI.Flags.getByValSize();
604 std::max(
Align(StackSlotSize), ArgDI.Flags.getNonZeroByValAlign());
619 if (!MemOps.
empty()) {
631bool ARCTargetLowering::CanLowerReturn(
635 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
636 if (!CCInfo.CheckReturn(Outs, RetCC_ARC))
638 if (CCInfo.getStackSize() != 0 && IsVarArg)
662 CCInfo.AllocateStack(AFI->getReturnStackOffset(),
Align(4));
664 CCInfo.AnalyzeReturn(Outs, RetCC_ARC);
670 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
682 int FI = MFI.CreateFixedObject(ObjSize,
Offset,
false);
688 Chain, dl, OutVals[i], FIN,
694 if (!MemOpChains.
empty())
698 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
715 RetOps.push_back(Glue);
726 DAGCombinerInfo &DCI)
const {
740 return AM.
Scale == 0;
744bool ARCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
754 EVT VT =
Op.getValueType();
756 assert(
Op.getConstantOperandVal(0) == 0 &&
757 "Only support lowering frame addr of current frame.");
781 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
782 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
787 switch (
Op.getOpcode()) {
789 return LowerGlobalAddress(
Op, DAG);
791 return LowerFRAMEADDR(
Op, DAG);
793 return LowerSELECT_CC(
Op, DAG);
795 return LowerBR_CC(
Op, DAG);
797 return LowerSIGN_EXTEND_INREG(
Op, DAG);
799 return LowerJumpTable(
Op, DAG);
807 assert(
Op.getSimpleValueType() == MVT::i32);
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
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
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.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
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)
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
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(), AAResults *AA=nullptr)
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,...
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).
const DataLayout & getDataLayout() const
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
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 ...
SDValue getRegister(unsigned Reg, EVT VT)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, unsigned Reg, SDValue N)
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
MachineFunction & getMachineFunction() const
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, unsigned Reg, EVT VT)
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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 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