46#include "llvm/IR/IntrinsicsHexagon.h"
66#define DEBUG_TYPE "hexagon-lowering"
70 cl::desc(
"Control jump table emission on Hexagon target"));
74 cl::desc(
"Enable Hexagon SDNode scheduling"));
77 cl::desc(
"Enable Fast Math processing"));
81 cl::desc(
"Set minimum jump tables"));
85 cl::desc(
"Max #stores to inline memcpy"));
89 cl::desc(
"Max #stores to inline memcpy"));
93 cl::desc(
"Max #stores to inline memmove"));
98 cl::desc(
"Max #stores to inline memmove"));
102 cl::desc(
"Max #stores to inline memset"));
106 cl::desc(
"Max #stores to inline memset"));
110 cl::desc(
"Rewrite unaligned loads as a pair of aligned loads"));
115 cl::desc(
"Disable minimum alignment of 1 for "
116 "arguments passed by value on stack"));
120 class HexagonCCState :
public CCState {
121 unsigned NumNamedVarArgParams = 0;
126 unsigned NumNamedArgs)
128 NumNamedVarArgParams(NumNamedArgs) {}
129 unsigned getNumNamedVarArgParams()
const {
return NumNamedVarArgParams; }
141 Hexagon::R0, Hexagon::R1, Hexagon::R2,
142 Hexagon::R3, Hexagon::R4, Hexagon::R5
144 const unsigned NumArgRegs = std::size(ArgRegs);
148 if (RegNum != NumArgRegs && RegNum % 2 == 1)
157#include "HexagonGenCallingConv.inc"
176 Chain, dl, Dst, Src, SizeNode, Flags.getNonZeroByValAlign(),
187 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
190 return CCInfo.
CheckReturn(Outs, RetCC_Hexagon_HVX);
220 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
269 .
Case(
"r0", Hexagon::R0)
270 .
Case(
"r1", Hexagon::R1)
271 .
Case(
"r2", Hexagon::R2)
272 .
Case(
"r3", Hexagon::R3)
273 .
Case(
"r4", Hexagon::R4)
274 .
Case(
"r5", Hexagon::R5)
275 .
Case(
"r6", Hexagon::R6)
276 .
Case(
"r7", Hexagon::R7)
277 .
Case(
"r8", Hexagon::R8)
278 .
Case(
"r9", Hexagon::R9)
279 .
Case(
"r10", Hexagon::R10)
280 .
Case(
"r11", Hexagon::R11)
281 .
Case(
"r12", Hexagon::R12)
282 .
Case(
"r13", Hexagon::R13)
283 .
Case(
"r14", Hexagon::R14)
284 .
Case(
"r15", Hexagon::R15)
285 .
Case(
"r16", Hexagon::R16)
286 .
Case(
"r17", Hexagon::R17)
287 .
Case(
"r18", Hexagon::R18)
288 .
Case(
"r19", Hexagon::R19)
289 .
Case(
"r20", Hexagon::R20)
290 .
Case(
"r21", Hexagon::R21)
291 .
Case(
"r22", Hexagon::R22)
292 .
Case(
"r23", Hexagon::R23)
293 .
Case(
"r24", Hexagon::R24)
294 .
Case(
"r25", Hexagon::R25)
295 .
Case(
"r26", Hexagon::R26)
296 .
Case(
"r27", Hexagon::R27)
297 .
Case(
"r28", Hexagon::R28)
298 .
Case(
"r29", Hexagon::R29)
299 .
Case(
"r30", Hexagon::R30)
300 .
Case(
"r31", Hexagon::R31)
301 .
Case(
"r1:0", Hexagon::D0)
302 .
Case(
"r3:2", Hexagon::D1)
303 .
Case(
"r5:4", Hexagon::D2)
304 .
Case(
"r7:6", Hexagon::D3)
305 .
Case(
"r9:8", Hexagon::D4)
306 .
Case(
"r11:10", Hexagon::D5)
307 .
Case(
"r13:12", Hexagon::D6)
308 .
Case(
"r15:14", Hexagon::D7)
309 .
Case(
"r17:16", Hexagon::D8)
310 .
Case(
"r19:18", Hexagon::D9)
311 .
Case(
"r21:20", Hexagon::D10)
312 .
Case(
"r23:22", Hexagon::D11)
313 .
Case(
"r25:24", Hexagon::D12)
314 .
Case(
"r27:26", Hexagon::D13)
315 .
Case(
"r29:28", Hexagon::D14)
316 .
Case(
"r31:30", Hexagon::D15)
317 .
Case(
"sp", Hexagon::R29)
318 .
Case(
"fp", Hexagon::R30)
319 .
Case(
"lr", Hexagon::R31)
320 .
Case(
"p0", Hexagon::P0)
321 .
Case(
"p1", Hexagon::P1)
322 .
Case(
"p2", Hexagon::P2)
323 .
Case(
"p3", Hexagon::P3)
324 .
Case(
"sa0", Hexagon::SA0)
325 .
Case(
"lc0", Hexagon::LC0)
326 .
Case(
"sa1", Hexagon::SA1)
327 .
Case(
"lc1", Hexagon::LC1)
328 .
Case(
"m0", Hexagon::M0)
329 .
Case(
"m1", Hexagon::M1)
330 .
Case(
"usr", Hexagon::USR)
331 .
Case(
"ugp", Hexagon::UGP)
332 .
Case(
"cs0", Hexagon::CS0)
333 .
Case(
"cs1", Hexagon::CS1)
363 for (
unsigned i = 0; i != RVLocs.
size(); ++i) {
365 if (RVLocs[i].getValVT() == MVT::i1) {
375 Register PredR =
MRI.createVirtualRegister(&Hexagon::PredRegsRegClass);
387 RVLocs[i].getValVT(), Glue);
413 bool IsStructRet = Outs.
empty() ?
false : Outs[0].Flags.isSRet();
427 HexagonCCState CCInfo(CallConv, TreatAsVarArg, MF, ArgLocs, *DAG.
getContext(),
431 CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon_HVX);
433 CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon_Legacy);
435 CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon);
440 IsVarArg, IsStructRet, StructAttrFlag, Outs,
449 :
"Argument must be passed on stack. "
450 "Not eligible for Tail Call\n"));
453 unsigned NumBytes = CCInfo.getStackSize();
461 bool NeedsArgAlign =
false;
462 Align LargestAlignSeen;
464 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
470 NeedsArgAlign |= ArgAlign;
496 StackPtr.getValueType());
499 LargestAlignSeen = std::max(
501 if (Flags.isByVal()) {
521 if (NeedsArgAlign && Subtarget.
hasV60Ops()) {
522 LLVM_DEBUG(
dbgs() <<
"Function needs byte stack align due to call args\n");
523 Align VecAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
524 LargestAlignSeen = std::max(LargestAlignSeen, VecAlign);
529 if (!MemOpChains.
empty())
543 for (
const auto &R : RegsToPass) {
544 Chain = DAG.
getCopyToReg(Chain, dl, R.first, R.second, Glue);
559 for (
const auto &R : RegsToPass) {
560 Chain = DAG.
getCopyToReg(Chain, dl, R.first, R.second, Glue);
575 dyn_cast<ExternalSymbolSDNode>(Callee)) {
586 for (
const auto &R : RegsToPass)
590 assert(Mask &&
"Missing call preserved mask for calling convention");
607 Chain = DAG.
getNode(OpCode, dl, {MVT::Other, MVT::Glue}, Ops);
617 InVals, OutVals, Callee);
632 bool IsLegalType = VT == MVT::i8 || VT == MVT::i16 || VT == MVT::i32 ||
633 VT == MVT::i64 || VT == MVT::f32 || VT == MVT::f64 ||
634 VT == MVT::v2i16 || VT == MVT::v2i32 || VT == MVT::v4i8 ||
635 VT == MVT::v4i16 || VT == MVT::v8i8 ||
644 if (!isa<ConstantSDNode>(
Offset.getNode()))
648 int32_t V = cast<ConstantSDNode>(
Offset.getNode())->getSExtValue();
664 unsigned LR = HRI.getRARegister();
671 if (
Op.getOperand(NumOps-1).getValueType() == MVT::Glue)
676 unsigned NumVals = Flags.getNumOperandRegisters();
679 switch (Flags.getKind()) {
690 for (; NumVals; --NumVals, ++i) {
691 Register Reg = cast<RegisterSDNode>(
Op.getOperand(i))->getReg();
694 HMFI.setHasClobberLR(
true);
746 unsigned IntNo =
Op.getConstantOperandVal(1);
748 if (IntNo == Intrinsic::hexagon_prefetch) {
766 assert(AlignConst &&
"Non-constant Align in LowerDYNAMIC_STACKALLOC");
772 A = HFI.getStackAlign().value();
775 dbgs () << __func__ <<
" Align: " <<
A <<
" Size: ";
776 Size.getNode()->dump(&DAG);
801 HexagonCCState CCInfo(CallConv, TreatAsVarArg, MF, ArgLocs,
806 CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon_HVX);
808 CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon_Legacy);
810 CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon);
819 switch (RC.
getID()) {
820 case Hexagon::IntRegsRegClassID:
821 return Reg - Hexagon::R0 + 1;
822 case Hexagon::DoubleRegsRegClassID:
823 return (Reg - Hexagon::D0 + 1) * 2;
824 case Hexagon::HvxVRRegClassID:
825 return Reg - Hexagon::V0 + 1;
826 case Hexagon::HvxWRRegClassID:
827 return (Reg - Hexagon::W0 + 1) * 2;
834 HFL.FirstVarArgSavedReg = 0;
837 for (
unsigned i = 0, e = ArgLocs.
size(); i != e; ++i) {
840 bool ByVal = Flags.isByVal();
846 if (VA.
isRegLoc() && ByVal && Flags.getByValSize() <= 8)
850 (!ByVal || (ByVal && Flags.getByValSize() > 8));
879 HFL.FirstVarArgSavedReg = NextSingleReg(*RC, VA.
getLocReg());
885 unsigned ObjSize = Flags.isByVal()
886 ? Flags.getByValSize()
894 if (Flags.isByVal()) {
908 for (
int i = HFL.FirstVarArgSavedReg; i < 6; i++)
909 MRI.addLiveIn(Hexagon::R0+i);
913 HMFI.setFirstNamedArgFrameIndex(HMFI.getFirstNamedArgFrameIndex() - 1);
917 int NumVarArgRegs = 6 - HFL.FirstVarArgSavedReg;
918 bool RequiresPadding = (NumVarArgRegs & 1);
919 int RegSaveAreaSizePlusPadding = RequiresPadding
920 ? (NumVarArgRegs + 1) * 4
923 if (RegSaveAreaSizePlusPadding > 0) {
926 if (!(RegAreaStart % 8))
927 RegAreaStart = (RegAreaStart + 7) & -8;
929 int RegSaveAreaFrameIndex =
931 HMFI.setRegSavedAreaStartFrameIndex(RegSaveAreaFrameIndex);
934 int Offset = RegAreaStart + RegSaveAreaSizePlusPadding;
936 HMFI.setVarArgsFrameIndex(FI);
942 HMFI.setRegSavedAreaStartFrameIndex(FI);
943 HMFI.setVarArgsFrameIndex(FI);
952 HMFI.setVarArgsFrameIndex(FI);
965 const Value *SV = cast<SrcValueSDNode>(
Op.getOperand(2))->getValue();
985 SDValue SavedRegAreaStartFrameIndex =
986 DAG.
getFrameIndex(FuncInfo.getRegSavedAreaStartFrameIndex(), MVT::i32);
990 if (HFL.FirstVarArgSavedReg & 1)
991 SavedRegAreaStartFrameIndex =
1000 SavedRegAreaStartFrameIndex,
1032 const Value *DestSV = cast<SrcValueSDNode>(
Op.getOperand(3))->getValue();
1033 const Value *SrcSV = cast<SrcValueSDNode>(
Op.getOperand(4))->getValue();
1039 false,
false,
nullptr, std::nullopt,
1051 if (OpTy == MVT::v2i16 || OpTy == MVT::v4i8) {
1068 auto isSExtFree = [
this](
SDValue N) {
1069 switch (
N.getOpcode()) {
1075 EVT OrigTy = cast<VTSDNode>(
Op.getOperand(1))->getVT();
1081 return ThisBW >= OrigBW;
1090 if (OpTy == MVT::i8 || OpTy == MVT::i16) {
1092 bool IsNegative =
C &&
C->getAPIntValue().isNegative();
1093 if (IsNegative || isSExtFree(
LHS) || isSExtFree(
RHS))
1105 SDValue Op1 =
Op.getOperand(1), Op2 =
Op.getOperand(2);
1109 if (OpTy == MVT::v2i16 || OpTy == MVT::v4i8) {
1127 EVT ValTy =
Op.getValueType();
1130 bool isVTi1Type =
false;
1131 if (
auto *CV = dyn_cast<ConstantVector>(CPN->
getConstVal())) {
1132 if (cast<VectorType>(CV->getType())->getElementType()->isIntegerTy(1)) {
1135 unsigned VecLen = CV->getNumOperands();
1137 "conversion only supported for pow2 VectorSize");
1138 for (
unsigned i = 0; i < VecLen; ++i)
1154 else if (isVTi1Type)
1160 assert(cast<ConstantPoolSDNode>(
T)->getTargetFlags() == TF &&
1161 "Inconsistent target flag encountered");
1163 if (IsPositionIndependent)
1170 EVT VT =
Op.getValueType();
1171 int Idx = cast<JumpTableSDNode>(
Op)->getIndex();
1191 EVT VT =
Op.getValueType();
1193 unsigned Depth =
Op.getConstantOperandVal(0);
1213 EVT VT =
Op.getValueType();
1215 unsigned Depth =
Op.getConstantOperandVal(0);
1233 auto *GAN = cast<GlobalAddressSDNode>(
Op);
1235 auto *GV = GAN->getGlobal();
1236 int64_t
Offset = GAN->getOffset();
1244 if (GO && Subtarget.
useSmallData() && HLOF.isGlobalInSmallSection(GO, HTM))
1266 const BlockAddress *BA = cast<BlockAddressSDNode>(
Op)->getBlockAddress();
1292 unsigned char OperandFlags)
const {
1311 assert(Mask &&
"Missing call preserved mask for calling convention");
1346 if (IsPositionIndependent) {
1418 Hexagon::R0, Flags);
1556 for (
unsigned LegalIntOp :
1596 for (
unsigned IntExpOp :
1605 for (
unsigned FPExpOp :
1641 static const unsigned VectExpOps[] = {
1667 for (
unsigned VectExpOp : VectExpOps)
1681 if (VT.getVectorElementType() != MVT::i32) {
1705 for (
MVT NativeVT : {MVT::v8i1, MVT::v4i1, MVT::v2i1, MVT::v4i8,
1706 MVT::v8i8, MVT::v2i16, MVT::v4i16, MVT::v2i32}) {
1721 if (NativeVT.getVectorElementType() != MVT::i1) {
1728 for (
MVT VT : {MVT::v8i8, MVT::v4i16, MVT::v2i32}) {
1739 for (
MVT VT : {MVT::i16, MVT::i32, MVT::v4i8, MVT::i64, MVT::v8i8,
1740 MVT::v2i16, MVT::v4i16, MVT::v2i32}) {
1746 for (
MVT VT : {MVT::v2i1, MVT::v4i1, MVT::v8i1}) {
1752 for (
MVT VT : {MVT::v2i16, MVT::v4i8, MVT::v8i8, MVT::v2i32, MVT::v4i16,
1764 for (
MVT VT : {MVT::i1, MVT::v2i1, MVT::v4i1, MVT::v8i1}) {
1817 for (
MVT VT : {MVT::i8, MVT::i16, MVT::i32, MVT::i64, MVT::f32, MVT::f64,
1818 MVT::v2i16, MVT::v2i32, MVT::v4i8, MVT::v4i16, MVT::v8i8}) {
1846 initializeHVXLowering();
1866 setLibcallName(RTLIB::FPTOUINT_F32_I128,
"__hexagon_fixunssfti");
1867 setLibcallName(RTLIB::FPTOUINT_F64_I128,
"__hexagon_fixunsdfti");
1962HexagonTargetLowering::validateConstPtrAlignment(
SDValue Ptr,
Align NeedAlign,
1964 auto *CA = dyn_cast<ConstantSDNode>(
Ptr);
1967 unsigned Addr = CA->getZExtValue();
1970 if (HaveAlign >= NeedAlign)
1976 DiagnosticInfoMisalignedTrap(
StringRef M)
1982 return DI->
getKind() == DK_MisalignedTrap;
1990 <<
" has alignment " << HaveAlign.
value()
1991 <<
", but the memory access requires " << NeedAlign.
value();
1994 O <<
". The instruction has been replaced with a trap.";
2004 auto *
LS = cast<LSBaseSDNode>(
Op.getNode());
2005 assert(!
LS->isIndexed() &&
"Not expecting indexed ops on constant address");
2017 unsigned ID = cast<IntrinsicInst>(Inst)->getIntrinsicID();
2018 return (
ID == Intrinsic::hexagon_L2_loadrd_pbr ||
2019 ID == Intrinsic::hexagon_L2_loadri_pbr ||
2020 ID == Intrinsic::hexagon_L2_loadrh_pbr ||
2021 ID == Intrinsic::hexagon_L2_loadruh_pbr ||
2022 ID == Intrinsic::hexagon_L2_loadrb_pbr ||
2023 ID == Intrinsic::hexagon_L2_loadrub_pbr);
2032 V = cast<Operator>(V)->getOperand(0);
2034 V = cast<Instruction>(V)->getOperand(0);
2047 if (Blk == Parent) {
2052 BaseVal = BackEdgeVal;
2054 }
while ((BaseVal != BackEdgeVal) && (IntrBaseVal != BackEdgeVal));
2057 if (IntrBaseVal == BackEdgeVal)
2064 assert(
Idx >= 0 &&
"Unexpected index to incoming argument in PHI");
2072 Value *IntrBaseVal = V;
2079 }
while (BaseVal != V);
2082 if (
const PHINode *PN = dyn_cast<PHINode>(V))
2096 unsigned Intrinsic)
const {
2097 switch (Intrinsic) {
2098 case Intrinsic::hexagon_L2_loadrd_pbr:
2099 case Intrinsic::hexagon_L2_loadri_pbr:
2100 case Intrinsic::hexagon_L2_loadrh_pbr:
2101 case Intrinsic::hexagon_L2_loadruh_pbr:
2102 case Intrinsic::hexagon_L2_loadrb_pbr:
2103 case Intrinsic::hexagon_L2_loadrub_pbr: {
2105 auto &
DL =
I.getDataLayout();
2106 auto &Cont =
I.getCalledFunction()->getParent()->getContext();
2110 Type *ElTy =
I.getCalledFunction()->getReturnType()->getStructElementType(0);
2117 Info.align =
DL.getABITypeAlign(
Info.memVT.getTypeForEVT(Cont));
2121 case Intrinsic::hexagon_V6_vgathermw:
2122 case Intrinsic::hexagon_V6_vgathermw_128B:
2123 case Intrinsic::hexagon_V6_vgathermh:
2124 case Intrinsic::hexagon_V6_vgathermh_128B:
2125 case Intrinsic::hexagon_V6_vgathermhw:
2126 case Intrinsic::hexagon_V6_vgathermhw_128B:
2127 case Intrinsic::hexagon_V6_vgathermwq:
2128 case Intrinsic::hexagon_V6_vgathermwq_128B:
2129 case Intrinsic::hexagon_V6_vgathermhq:
2130 case Intrinsic::hexagon_V6_vgathermhq_128B:
2131 case Intrinsic::hexagon_V6_vgathermhwq:
2132 case Intrinsic::hexagon_V6_vgathermhwq_128B: {
2133 const Module &M = *
I.getParent()->getParent()->getParent();
2135 Type *VecTy =
I.getArgOperand(1)->getType();
2137 Info.ptrVal =
I.getArgOperand(0);
2140 MaybeAlign(M.getDataLayout().getTypeAllocSizeInBits(VecTy) / 8);
2153 return X.getValueType().isScalarInteger();
2173 unsigned DefinedValues)
const {
2178 unsigned Index)
const {
2210 unsigned Action = getPreferredHvxVectorAction(VT);
2216 if (ElemTy == MVT::i1)
2230 unsigned Action = getCustomHvxOperationAction(
Op);
2237std::pair<SDValue, int>
2238HexagonTargetLowering::getBaseAndOffset(
SDValue Addr)
const {
2241 if (
auto *CN = dyn_cast<const ConstantSDNode>(Op1.
getNode()))
2242 return {
Addr.getOperand(0), CN->getSExtValue() };
2252 const auto *SVN = cast<ShuffleVectorSDNode>(
Op);
2254 assert(AM.
size() <= 8 &&
"Unexpected shuffle mask");
2255 unsigned VecLen = AM.
size();
2259 "HVX shuffles should be legal");
2269 if (ty(Op0) != VecTy || ty(Op1) != VecTy)
2278 if (AM[
F] >=
int(VecLen)) {
2286 for (
int M : Mask) {
2288 for (
unsigned j = 0; j != ElemBytes; ++j)
2291 for (
unsigned j = 0; j != ElemBytes; ++j)
2304 for (
unsigned i = 0, e = ByteMask.
size(); i != e; ++i) {
2312 if (ByteMask.
size() == 4) {
2314 if (MaskIdx == (0x03020100 | MaskUnd))
2317 if (MaskIdx == (0x00010203 | MaskUnd)) {
2325 getCombine(Op1, Op0, dl, typeJoin({ty(Op1), ty(Op0)}), DAG);
2326 if (MaskIdx == (0x06040200 | MaskUnd))
2327 return getInstr(Hexagon::S2_vtrunehb, dl, VecTy, {Concat10}, DAG);
2328 if (MaskIdx == (0x07050301 | MaskUnd))
2329 return getInstr(Hexagon::S2_vtrunohb, dl, VecTy, {Concat10}, DAG);
2332 getCombine(Op0, Op1, dl, typeJoin({ty(Op0), ty(Op1)}), DAG);
2333 if (MaskIdx == (0x02000604 | MaskUnd))
2334 return getInstr(Hexagon::S2_vtrunehb, dl, VecTy, {Concat01}, DAG);
2335 if (MaskIdx == (0x03010705 | MaskUnd))
2336 return getInstr(Hexagon::S2_vtrunohb, dl, VecTy, {Concat01}, DAG);
2339 if (ByteMask.
size() == 8) {
2341 if (MaskIdx == (0x0706050403020100ull | MaskUnd))
2344 if (MaskIdx == (0x0001020304050607ull | MaskUnd)) {
2351 if (MaskIdx == (0x0d0c050409080100ull | MaskUnd))
2352 return getInstr(Hexagon::S2_shuffeh, dl, VecTy, {Op1, Op0}, DAG);
2353 if (MaskIdx == (0x0f0e07060b0a0302ull | MaskUnd))
2354 return getInstr(Hexagon::S2_shuffoh, dl, VecTy, {Op1, Op0}, DAG);
2355 if (MaskIdx == (0x0d0c090805040100ull | MaskUnd))
2356 return getInstr(Hexagon::S2_vtrunewh, dl, VecTy, {Op1, Op0}, DAG);
2357 if (MaskIdx == (0x0f0e0b0a07060302ull | MaskUnd))
2358 return getInstr(Hexagon::S2_vtrunowh, dl, VecTy, {Op1, Op0}, DAG);
2359 if (MaskIdx == (0x0706030205040100ull | MaskUnd)) {
2360 VectorPair
P = opSplit(Op0, dl, DAG);
2361 return getInstr(Hexagon::S2_packhl, dl, VecTy, {
P.second,
P.first}, DAG);
2365 if (MaskIdx == (0x0e060c040a020800ull | MaskUnd))
2366 return getInstr(Hexagon::S2_shuffeb, dl, VecTy, {Op1, Op0}, DAG);
2367 if (MaskIdx == (0x0f070d050b030901ull | MaskUnd))
2368 return getInstr(Hexagon::S2_shuffob, dl, VecTy, {Op1, Op0}, DAG);
2376 switch (
Op.getOpcode()) {
2378 if (
SDValue S = cast<BuildVectorSDNode>(
Op)->getSplatValue())
2382 return Op.getOperand(0);
2392 switch (
Op.getOpcode()) {
2406 if (
SDValue Sp = getSplatValue(
Op.getOperand(1), DAG))
2419 if (
SDValue S = getVectorShiftByInt(
Op, DAG))
2433 MVT ResTy = ty(Res);
2441 auto ShiftPartI8 = [&dl, &DAG,
this](
unsigned Opc,
SDValue V,
SDValue A) {
2451 return ShiftPartI8(Opc, Val, Amt);
2453 auto [LoV, HiV] = opSplit(Val, dl, DAG);
2455 {ShiftPartI8(Opc, LoV, Amt), ShiftPartI8(Opc, HiV, Amt)});
2460 if (isa<ConstantSDNode>(
Op.getOperand(1).getNode()))
2469 MVT InpTy = ty(InpV);
2474 if (InpTy == MVT::i8) {
2475 if (ResTy == MVT::v8i1) {
2478 return getInstr(Hexagon::C2_tfrrp, dl, ResTy, Ext, DAG);
2493 bool AllConst =
true;
2495 for (
unsigned i = 0, e = Values.
size(); i != e; ++i) {
2498 Consts[i] = ConstantInt::get(IntTy, 0);
2502 if (
auto *CN = dyn_cast<ConstantSDNode>(V.getNode())) {
2503 const ConstantInt *CI = CN->getConstantIntValue();
2505 }
else if (
auto *CN = dyn_cast<ConstantFPSDNode>(
V.getNode())) {
2506 const ConstantFP *CF = CN->getConstantFPValue();
2508 Consts[i] = ConstantInt::get(IntTy,
A.getZExtValue());
2523 bool AllConst = getBuildVectorConstInts(Elem, VecTy, DAG, Consts);
2527 if (!isUndef(Elem[
First]))
2535 return getZero(dl, VecTy, DAG);
2537 if (ElemTy == MVT::i16 || ElemTy == MVT::f16) {
2542 uint32_t V = (Consts[0]->getZExtValue() & 0xFFFF) |
2543 Consts[1]->getZExtValue() << 16;
2547 if (ElemTy == MVT::f16) {
2554 SDValue N = getInstr(Hexagon::A2_combine_ll, dl, MVT::i32, {E1, E0}, DAG);
2558 if (ElemTy == MVT::i8) {
2561 uint32_t V = (Consts[0]->getZExtValue() & 0xFF) |
2562 (Consts[1]->getZExtValue() & 0xFF) << 8 |
2563 (Consts[2]->getZExtValue() & 0xFF) << 16 |
2564 Consts[3]->getZExtValue() << 24;
2569 bool IsSplat =
true;
2570 for (
unsigned i =
First+1; i != Num; ++i) {
2571 if (Elem[i] == Elem[
First] || isUndef(Elem[i]))
2587 for (
unsigned i = 0; i != 4; ++i) {
2597 SDValue R = getInstr(Hexagon::A2_combine_ll, dl, MVT::i32, {B1, B0}, DAG);
2602 dbgs() <<
"VecTy: " << VecTy <<
'\n';
2614 bool AllConst = getBuildVectorConstInts(Elem, VecTy, DAG, Consts);
2618 if (!isUndef(Elem[
First]))
2626 return getZero(dl, VecTy, DAG);
2629 if (ElemTy == MVT::i16 || ElemTy == MVT::f16) {
2630 bool IsSplat =
true;
2631 for (
unsigned i =
First+1; i != Num; ++i) {
2632 if (Elem[i] == Elem[
First] || isUndef(Elem[i]))
2651 for (
unsigned i = 0; i != Num; ++i)
2652 Val = (Val << W) | (Consts[Num-1-i]->getZExtValue() &
Mask);
2661 : buildVector32(Elem.
take_front(Num/2), dl, HalfTy, DAG);
2664 : buildVector32(Elem.
drop_front(Num/2), dl, HalfTy, DAG);
2665 return getCombine(
H, L, dl, VecTy, DAG);
2672 MVT VecTy = ty(VecV);
2676 return extractVectorPred(VecV, IdxV, dl, ValTy, ResTy, DAG);
2681 assert((VecWidth % ElemWidth) == 0);
2682 assert(VecWidth == 32 || VecWidth == 64);
2685 MVT ScalarTy = tyScalar(VecTy);
2691 if (
auto *IdxN = dyn_cast<ConstantSDNode>(IdxV)) {
2692 unsigned Off = IdxN->getZExtValue() * ElemWidth;
2693 if (VecWidth == 64 && ValWidth == 32) {
2694 assert(Off == 0 || Off == 32);
2695 ExtV =
Off == 0 ? LoHalf(VecV, DAG) : HiHalf(VecV, DAG);
2696 }
else if (Off == 0 && (ValWidth % 8) == 0) {
2703 {VecV, WidthV, OffV});
2706 if (ty(IdxV) != MVT::i32)
2711 {VecV, WidthV, OffV});
2721HexagonTargetLowering::extractVectorPred(
SDValue VecV,
SDValue IdxV,
2726 MVT VecTy = ty(VecV);
2730 "Vector elements should equal vector width size");
2731 assert(VecWidth == 8 || VecWidth == 4 || VecWidth == 2);
2742 if (ValWidth == 1) {
2743 SDValue A0 = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32, {VecV}, DAG);
2753 unsigned Scale = VecWidth / ValWidth;
2757 assert(ty(IdxV) == MVT::i32);
2758 unsigned VecRep = 8 / VecWidth;
2766 T1 = LoHalf(T1, DAG);
2767 T1 = expandPredicate(T1, dl, DAG);
2778 MVT VecTy = ty(VecV);
2780 return insertVectorPred(VecV, ValV, IdxV, dl, ValTy, DAG);
2784 assert(VecWidth == 32 || VecWidth == 64);
2785 assert((VecWidth % ValWidth) == 0);
2801 unsigned W =
C->getZExtValue() * ValWidth;
2804 {VecV, ValV, WidthV, OffV});
2806 if (ty(IdxV) != MVT::i32)
2810 {VecV, ValV, WidthV, OffV});
2817HexagonTargetLowering::insertVectorPred(
SDValue VecV,
SDValue ValV,
2820 MVT VecTy = ty(VecV);
2823 if (ValTy == MVT::i1) {
2824 SDValue ToReg = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32, {VecV}, DAG);
2830 return getInstr(Hexagon::C2_tfrrp, dl, VecTy, {
Ins}, DAG);
2841 for (
unsigned R = Scale;
R > 1;
R /= 2) {
2842 ValR = contractPredicate(ValR, dl, DAG);
2843 ValR = getCombine(DAG.
getUNDEF(MVT::i32), ValR, dl, MVT::i64, DAG);
2855HexagonTargetLowering::expandPredicate(
SDValue Vec32,
const SDLoc &dl,
2857 assert(ty(Vec32).getSizeInBits() == 32);
2866HexagonTargetLowering::contractPredicate(
SDValue Vec64,
const SDLoc &dl,
2868 assert(ty(Vec64).getSizeInBits() == 64);
2874 {0, 2, 4, 6, 1, 3, 5, 7});
2875 return extractVector(S, DAG.
getConstant(0, dl, MVT::i32), dl, MVT::v4i8,
2899 MVT ValTy = ty(Val);
2904 if (ValLen == ResLen)
2907 const SDLoc &dl(Val);
2909 assert(ResLen % ValLen == 0);
2912 for (
unsigned i = 1, e = ResLen / ValLen; i <
e; ++i)
2921 MVT ElemTy = ty(
Hi);
2950 return buildVector32(Ops, dl, VecTy, DAG);
2952 return buildVector64(Ops, dl, VecTy, DAG);
2954 if (VecTy == MVT::v8i1 || VecTy == MVT::v4i1 || VecTy == MVT::v2i1) {
2956 bool All0 =
true, All1 =
true;
2958 auto *CN = dyn_cast<ConstantSDNode>(
P.getNode());
2959 if (CN ==
nullptr) {
2960 All0 = All1 =
false;
2976 SDValue Z = getZero(dl, MVT::i32, DAG);
2979 for (
unsigned i = 0; i != 8; ++i) {
2981 Rs[i] = DAG.
getSelect(dl, MVT::i32, Ops[i/Rep], S, Z);
2984 for (
unsigned i = 0, e =
A.size()/2; i != e; ++i)
2988 return getInstr(Hexagon::C2_tfrrp, dl, VecTy, {Rs[0]}, DAG);
3001 return getCombine(
Op.getOperand(1),
Op.getOperand(0), dl, VecTy, DAG);
3005 if (ElemTy == MVT::i1) {
3006 assert(VecTy == MVT::v2i1 || VecTy == MVT::v4i1 || VecTy == MVT::v8i1);
3007 MVT OpTy = ty(
Op.getOperand(0));
3020 for (
SDValue P :
Op.getNode()->op_values()) {
3022 for (
unsigned R = Scale; R > 1; R /= 2) {
3023 W = contractPredicate(W, dl, DAG);
3024 W = getCombine(DAG.
getUNDEF(MVT::i32), W, dl, MVT::i64, DAG);
3032 Words[IdxW ^ 1].
clear();
3034 for (
unsigned i = 0, e = Words[IdxW].
size(); i != e; i += 2) {
3035 SDValue W0 = Words[IdxW][i], W1 = Words[IdxW][i+1];
3038 {W0, W1, WidthV, WidthV});
3046 assert(Scale == 2 && Words[IdxW].
size() == 2);
3048 SDValue WW = getCombine(Words[IdxW][1], Words[IdxW][0], dl, MVT::i64, DAG);
3060 return extractVector(Vec,
Op.getOperand(1),
SDLoc(
Op), ElemTy, ty(
Op), DAG);
3066 return extractVector(
Op.getOperand(0),
Op.getOperand(1),
SDLoc(
Op),
3067 ty(
Op), ty(
Op), DAG);
3073 return insertVector(
Op.getOperand(0),
Op.getOperand(1),
Op.getOperand(2),
3081 return insertVector(
Op.getOperand(0), ValV,
Op.getOperand(2),
3106 bool LoadPred = MemTy == MVT::v2i1 || MemTy == MVT::v4i1 || MemTy == MVT::v8i1;
3113 LN = cast<LoadSDNode>(NL.
getNode());
3117 if (!validateConstPtrAlignment(LN->
getBasePtr(), ClaimAlign, dl, DAG))
3118 return replaceMemWithUndef(
Op, DAG);
3124 SDValue TP = getInstr(Hexagon::C2_tfrrp, dl, MemTy, {LU}, DAG);
3143 if (Ty == MVT::v2i1 || Ty == MVT::v4i1 || Ty == MVT::v8i1) {
3145 SDValue TR = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32, {Val}, DAG);
3152 SN = cast<StoreSDNode>(NS.getNode());
3156 if (!validateConstPtrAlignment(SN->
getBasePtr(), ClaimAlign, dl, DAG))
3157 return replaceMemWithUndef(
Op, DAG);
3161 if (ClaimAlign < NeedAlign)
3170 MVT LoadTy = ty(
Op);
3173 if (HaveAlign >= NeedAlign)
3182 bool DoDefault =
false;
3193 if (!DoDefault && (2 * HaveAlign) == NeedAlign) {
3212 unsigned LoadLen = NeedAlign;
3215 auto BO = getBaseAndOffset(
Base);
3216 unsigned BaseOpc = BO.first.getOpcode();
3220 if (BO.second % LoadLen != 0) {
3222 DAG.
getConstant(BO.second % LoadLen, dl, MVT::i32));
3223 BO.second -= BO.second % LoadLen;
3238 MMO->getPointerInfo(), MMO->getFlags(), 2 * LoadLen,
Align(LoadLen),
3239 MMO->getAAInfo(), MMO->getRanges(), MMO->getSyncScopeID(),
3240 MMO->getSuccessOrdering(), MMO->getFailureOrdering());
3257 auto *CY = dyn_cast<ConstantSDNode>(
Y);
3265 unsigned Opc =
Op.getOpcode();
3269 assert(VY != 0 &&
"This should have been folded");
3294 unsigned Opc =
Op.getOpcode();
3301 EVT CarryTy =
C.getValueType();
3303 { X, Y, DAG.getLogicalNOT(dl, C, CarryTy) });
3322 unsigned OffsetReg = Hexagon::R28;
3338 unsigned Opc =
Op.getOpcode();
3344 if (isHvxOperation(
Op.getNode(), DAG)) {
3346 if (
SDValue V = LowerHvxOperation(
Op, DAG))
3353 Op.getNode()->dumpr(&DAG);
3355 errs() <<
"Error: check for a non-legal type in this operation\n";
3409 if (isHvxOperation(
N, DAG)) {
3410 LowerHvxOperationWrapper(
N,
Results, DAG);
3416 unsigned Opc =
N->getOpcode();
3440 if (isHvxOperation(
N, DAG)) {
3441 ReplaceHvxNodeResults(
N,
Results, DAG);
3447 switch (
N->getOpcode()) {
3454 if (
N->getValueType(0) == MVT::i8) {
3455 if (
N->getOperand(0).getValueType() == MVT::v8i1) {
3456 SDValue P = getInstr(Hexagon::C2_tfrpr, dl, MVT::i32,
3457 N->getOperand(0), DAG);
3469 if (isHvxOperation(
N, DCI.
DAG)) {
3470 if (
SDValue V = PerformHvxDAGCombine(
N, DCI))
3477 unsigned Opc =
Op.getOpcode();
3483 EVT TruncTy =
Op.getValueType();
3499 switch (
P.getOpcode()) {
3503 return getZero(dl, ty(
Op), DCI.
DAG);
3516 Op.getOperand(2),
Op.getOperand(1));
3524 MVT TruncTy = ty(
Op);
3527 if (ty(Elem0) == TruncTy)
3530 if (ty(Elem0).bitsGT(TruncTy))
3537 if (ty(
Op) != MVT::i64)
3548 auto *Amt = dyn_cast<ConstantSDNode>(Shl.
getOperand(1));
3549 if (Amt && Amt->getZExtValue() >= 32 && ty(Z).getSizeInBits() <= 32) {
3550 unsigned A = Amt->getZExtValue();
3572 int Idx = cast<JumpTableSDNode>(Table)->getIndex();
3584 if (Constraint.
size() == 1) {
3585 switch (Constraint[0]) {
3600std::pair<unsigned, const TargetRegisterClass*>
3604 if (Constraint.
size() == 1) {
3605 switch (Constraint[0]) {
3609 return {0u,
nullptr};
3615 return {0u, &Hexagon::IntRegsRegClass};
3618 return {0u, &Hexagon::DoubleRegsRegClass};
3623 return {0u,
nullptr};
3624 return {0u, &Hexagon::ModRegsRegClass};
3628 return {0u,
nullptr};
3631 return {0u, &Hexagon::HvxQRRegClass};
3637 return {0u,
nullptr};
3639 return {0u, &Hexagon::HvxVRRegClass};
3642 return {0u, &Hexagon::HvxVRRegClass};
3643 return {0u, &Hexagon::HvxWRRegClass};
3645 return {0u, &Hexagon::HvxWRRegClass};
3649 return {0u,
nullptr};
3660 bool ForCodeSize)
const {
3690 int Scale = AM.
Scale;
3714 return Imm >= -512 && Imm <= 511;
3724 bool IsCalleeStructRet,
3725 bool IsCallerStructRet,
3732 bool CCMatch = CallerCC == CalleeCC;
3740 if (!isa<GlobalAddressSDNode>(Callee) &&
3741 !isa<ExternalSymbolSDNode>(Callee)) {
3761 if (IsCalleeStructRet || IsCallerStructRet)
3784 if (
Op.size() >= 8 &&
Op.isAligned(
Align(8)))
3786 if (
Op.size() >= 4 &&
Op.isAligned(
Align(4)))
3788 if (
Op.size() >= 2 &&
Op.isAligned(
Align(2)))
3800 return allowsHvxMemoryAccess(SVT, Flags,
Fast);
3802 Context,
DL, VT, AddrSpace, Alignment, Flags,
Fast);
3807 unsigned *
Fast)
const {
3812 return allowsHvxMisalignedMemoryAccesses(SVT, Flags,
Fast);
3818std::pair<const TargetRegisterClass*, uint8_t>
3826 return std::make_pair(&Hexagon::HvxQRRegClass, 1);
3828 return std::make_pair(&Hexagon::HvxVRRegClass, 1);
3830 return std::make_pair(&Hexagon::HvxWRRegClass, 1);
3842 auto *L = cast<LoadSDNode>(Load);
3843 std::pair<SDValue,int> BO = getBaseAndOffset(L->getBasePtr());
3849 const auto *GO = dyn_cast_or_null<const GlobalObject>(GA->getGlobal());
3857 AdjustHvxInstrPostInstrSelection(
MI, Node);
3864 assert((SZ == 32 || SZ == 64) &&
"Only 32/64-bit atomic loads supported");
3865 Intrinsic::ID IntID = (SZ == 32) ? Intrinsic::hexagon_L2_loadw_locked
3866 : Intrinsic::hexagon_L4_loadd_locked;
3885 assert((SZ == 32 || SZ == 64) &&
"Only 32/64-bit atomic stores supported");
3886 Intrinsic::ID IntID = (SZ == 32) ? Intrinsic::hexagon_S2_storew_locked
3887 : Intrinsic::hexagon_S4_stored_locked;
3909 return SI->getValueOperand()->getType()->getPrimitiveSizeInBits() > 64
unsigned const MachineRegisterInfo * MRI
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static cl::opt< int > MaxStoresPerMemcpyCL("max-store-memcpy", cl::Hidden, cl::init(6), cl::desc("Max #stores to inline memcpy"))
static Value * getUnderLyingObjectForBrevLdIntr(Value *V)
static bool CC_SkipOdd(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
static cl::opt< bool > AlignLoads("hexagon-align-loads", cl::Hidden, cl::init(false), cl::desc("Rewrite unaligned loads as a pair of aligned loads"))
static bool isBrevLdIntrinsic(const Value *Inst)
static cl::opt< int > MaxStoresPerMemmoveOptSizeCL("max-store-memmove-Os", cl::Hidden, cl::init(4), cl::desc("Max #stores to inline memmove"))
static cl::opt< int > MaxStoresPerMemmoveCL("max-store-memmove", cl::Hidden, cl::init(6), cl::desc("Max #stores to inline memmove"))
static Value * getBrevLdObject(Value *V)
static cl::opt< int > MaxStoresPerMemsetCL("max-store-memset", cl::Hidden, cl::init(8), cl::desc("Max #stores to inline memset"))
static cl::opt< bool > DisableArgsMinAlignment("hexagon-disable-args-min-alignment", cl::Hidden, cl::init(false), cl::desc("Disable minimum alignment of 1 for " "arguments passed by value on stack"))
static Value * returnEdge(const PHINode *PN, Value *IntrBaseVal)
static cl::opt< int > MaxStoresPerMemcpyOptSizeCL("max-store-memcpy-Os", cl::Hidden, cl::init(4), cl::desc("Max #stores to inline memcpy"))
static SDValue CreateCopyOfByValArgument(SDValue Src, SDValue Dst, SDValue Chain, ISD::ArgFlagsTy Flags, SelectionDAG &DAG, const SDLoc &dl)
CreateCopyOfByValArgument - Make a copy of an aggregate at address specified by "Src" to address "Dst...
static cl::opt< int > MaxStoresPerMemsetOptSizeCL("max-store-memset-Os", cl::Hidden, cl::init(4), cl::desc("Max #stores to inline memset"))
static cl::opt< bool > EmitJumpTables("hexagon-emit-jump-tables", cl::init(true), cl::Hidden, cl::desc("Control jump table emission on Hexagon target"))
static cl::opt< int > MinimumJumpTables("minimum-jump-tables", cl::Hidden, cl::init(5), cl::desc("Set minimum jump tables"))
static cl::opt< bool > EnableHexSDNodeSched("enable-hexagon-sdnode-sched", cl::Hidden, cl::desc("Enable Hexagon SDNode scheduling"))
static cl::opt< bool > EnableFastMath("ffast-math", cl::Hidden, cl::desc("Enable Fast Math processing"))
#define Hexagon_PointerSize
#define HEXAGON_LRFP_SIZE
#define HEXAGON_GOT_SYM_NAME
Module.h This file contains the declarations for the Module class.
std::pair< MCSymbol *, MachineModuleInfoImpl::StubValueTy > PairTy
unsigned const TargetRegisterInfo * TRI
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
int64_t getSExtValue() const
Get sign extended value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
size_t size() const
size - Get the array size.
An instruction that atomically checks whether a specified value is in a memory location,...
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
The address of a basic block.
CCState - This class holds information needed while lowering arguments and return values.
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
void AnalyzeCallResult(const SmallVectorImpl< ISD::InputArg > &Ins, CCAssignFn Fn)
AnalyzeCallResult - Analyze the return values of a call, incorporating info about the passed values i...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
void AnalyzeReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
AnalyzeReturn - Analyze the returned values of a return, incorporating info about the result values i...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
int64_t getLocMemOffset() const
FunctionType * getFunctionType() const
This class represents a function call, abstracting a target machine's calling convention.
ConstantFP - Floating Point Values [float, double].
const APFloat & getValueAPF() const
This is the shared class of boolean and integer constants.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
const APInt & getValue() const
Return the constant as an APInt value reference.
MachineConstantPoolValue * getMachineCPVal() const
bool isMachineConstantPoolEntry() const
const Constant * getConstVal() const
int64_t getSExtValue() const
static Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
This class represents an Operation in the Expression.
uint64_t getNumOperands() const
A parsed version of the target data layout string in and methods for querying it.
This is the base abstract class for diagnostic reporting in the backend.
Interface for custom diagnostic printing.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
FunctionType * getFunctionType() const
Returns the FunctionType for me.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
int64_t getOffset() const
const GlobalValue * getGlobal() const
Module * getParent()
Get the module that this global value is contained inside of...
const GlobalObject * getAliaseeObject() const
bool isValidAutoIncImm(const EVT VT, const int Offset) const
Hexagon target-specific information for each MachineFunction.
int getVarArgsFrameIndex()
void setFirstNamedArgFrameIndex(int v)
void setHasEHReturn(bool H=true)
Register getStackRegister() const
Register getFrameRegister(const MachineFunction &MF) const override
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
const HexagonInstrInfo * getInstrInfo() const override
const HexagonFrameLowering * getFrameLowering() const override
bool useSmallData() const
const HexagonRegisterInfo * getRegisterInfo() const override
bool isHVXVectorType(EVT VecTy, bool IncludeBool=false) const