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));
184 return "ARCISD::CMOV";
186 return "ARCISD::CMP";
188 return "ARCISD::BRcc";
190 return "ARCISD::RET";
192 return "ARCISD::GAWRAPPER";
209 assert(
LHS.getValueType() == MVT::i32 &&
"Only know how to SELECT_CC i32");
219 assert(
Op.getValueType() == MVT::i32 &&
220 "Unhandled target sign_extend_inreg.");
222 unsigned Width = cast<VTSDNode>(
Op.getOperand(1))->getVT().getSizeInBits();
223 if (Width == 16 || Width == 8)
243 assert(
LHS.getValueType() == MVT::i32 &&
"Only know how to BR_CC i32");
249 auto *
N = cast<JumpTableSDNode>(
Op);
254#include "ARCGenCallingConv.inc"
280 CCInfo.AnalyzeCallOperands(Outs, CC_ARC);
286 RetCCInfo.AllocateStack(CCInfo.getStackSize(),
Align(4));
287 RetCCInfo.AnalyzeCallResult(Ins, RetCC_ARC);
290 unsigned NumBytes = RetCCInfo.getStackSize();
299 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
343 if (!MemOpChains.
empty())
351 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i) {
352 Chain = DAG.
getCopyToReg(Chain, dl, RegsToPass[i].first,
353 RegsToPass[i].second, Glue);
360 bool IsDirect =
true;
361 if (
auto *
G = dyn_cast<GlobalAddressSDNode>(Callee))
363 else if (
auto *
E = dyn_cast<ExternalSymbolSDNode>(Callee))
376 for (
unsigned i = 0, e = RegsToPass.
size(); i != e; ++i)
378 RegsToPass[i].second.getValueType()));
384 assert(Mask &&
"Missing call preserved mask for calling convention");
412 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
433 for (
unsigned i = 0, e = ResultMemLocs.
size(); i != e; ++i) {
434 int Offset = ResultMemLocs[i].first;
435 unsigned Index = ResultMemLocs[i].second;
441 InVals[
Index] = Load;
447 if (!MemOpChains.
empty())
467SDValue ARCTargetLowering::LowerFormalArguments(
476 return LowerCallArguments(Chain, CallConv, IsVarArg, Ins, dl, DAG, InVals);
482SDValue ARCTargetLowering::LowerCallArguments(
496 CCInfo.AnalyzeFormalArguments(Ins, CC_ARC);
498 unsigned StackSlotSize = 4;
501 AFI->setReturnStackOffset(CCInfo.getStackSize());
515 for (
unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
524 LLVM_DEBUG(
errs() <<
"LowerFormalArguments Unhandled argument type: "
529 unsigned VReg =
RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
539 assert((ObjSize <= StackSlotSize) &&
"Unhandled argument");
550 const ArgDataPair ADP = {ArgIn,
Ins[i].Flags};
557 static const MCPhysReg ArgRegs[] = {ARC::R0, ARC::R1, ARC::R2, ARC::R3,
558 ARC::R4, ARC::R5, ARC::R6, ARC::R7};
560 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs);
561 if (FirstVAReg < std::size(ArgRegs)) {
568 CCInfo.getStackSize(),
true);
569 AFI->setVarArgsFrameIndex(VarFI);
571 for (
unsigned i = FirstVAReg; i < std::size(ArgRegs); i++) {
573 unsigned VReg =
RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
574 RegInfo.addLiveIn(ArgRegs[i], VReg);
591 if (!CFRegNode.
empty())
598 for (
const auto &ArgDI : ArgData) {
599 if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) {
600 unsigned Size = ArgDI.Flags.getByValSize();
602 std::max(
Align(StackSlotSize), ArgDI.Flags.getNonZeroByValAlign());
617 if (!MemOps.
empty()) {
629bool ARCTargetLowering::CanLowerReturn(
633 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
634 if (!CCInfo.CheckReturn(Outs, RetCC_ARC))
636 if (CCInfo.getStackSize() != 0 && IsVarArg)
660 CCInfo.AllocateStack(AFI->getReturnStackOffset(),
Align(4));
662 CCInfo.AnalyzeReturn(Outs, RetCC_ARC);
668 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
680 int FI = MFI.CreateFixedObject(ObjSize,
Offset,
false);
686 Chain, dl, OutVals[i], FIN,
692 if (!MemOpChains.
empty())
696 for (
unsigned i = 0, e = RVLocs.
size(); i != e; ++i) {
713 RetOps.push_back(Glue);
724 DAGCombinerInfo &DCI)
const {
738 return AM.
Scale == 0;
742bool ARCTargetLowering::mayBeEmittedAsTailCall(
const CallInst *CI)
const {
752 EVT VT =
Op.getValueType();
754 assert(cast<ConstantSDNode>(
Op.getOperand(0))->getZExtValue() == 0 &&
755 "Only support lowering frame addr of current frame.");
779 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
780 return DAG.
getStore(
Op.getOperand(0), dl, FR,
Op.getOperand(1),
785 switch (
Op.getOpcode()) {
787 return LowerGlobalAddress(
Op, DAG);
789 return LowerFRAMEADDR(
Op, DAG);
791 return LowerSELECT_CC(
Op, DAG);
793 return LowerBR_CC(
Op, DAG);
795 return LowerSIGN_EXTEND_INREG(
Op, DAG);
797 return LowerJumpTable(
Op, DAG);
805 assert(
Op.getSimpleValueType() == MVT::i32);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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...
Function Alias Analysis Results
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
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 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).
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, bool isTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
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 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 If BaseGV is null...
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