21#include "llvm/IR/IntrinsicsHexagon.h"
36 "hexagon-widen-short-vector",
54 HexagonGenWideningVecInstr(
const HexagonTargetMachine *TM)
55 : FunctionPass(ID), TM(TM) {
59 StringRef getPassName()
const override {
60 return "Hexagon generate widening vector instructions";
65 void getAnalysisUsage(AnalysisUsage &AU)
const override {
66 FunctionPass::getAnalysisUsage(AU);
71 const HexagonTargetMachine *TM =
nullptr;
72 const HexagonSubtarget *HST =
nullptr;
74 enum OPKind { OP_None = 0, OP_Add, OP_Sub, OP_Mul, OP_Shl };
78 Value *ExtInOP =
nullptr;
80 unsigned ExtInSize = 0;
81 bool IsScalar =
false;
84 bool visitBlock(BasicBlock *
B);
85 bool processInstruction(Instruction *Inst);
86 bool replaceWithIntrinsic(Instruction *Inst, OPKind OPK, OPInfo &OP1Info,
89 bool isExtendedConstant(Constant *
C,
bool IsSigned);
90 unsigned getElementSizeInBits(
Value *V,
bool IsZExt);
94 unsigned NewEltsize,
unsigned NumElts);
96 Intrinsic::ID getIntrinsic(OPKind OPK,
bool IsOP1ZExt,
bool IsOP2ZExt,
97 unsigned NewOpEltSize,
unsigned NewResEltSize,
98 bool IsConstScalar,
int ConstOpNum);
100 std::pair<Value *, Value *> opSplit(
Value *
OP, Instruction *Inst,
104 Value *NewOP2,
Type *ResType,
unsigned NumElts,
106 bool processInstructionForVMPA(Instruction *Inst);
107 bool getVmpaOperandInfo(
Value *V, OPInfo &OPI);
108 void reorderVmpaOperands(OPInfo *OPI);
109 bool replaceWithVmpaIntrinsic(Instruction *Inst, OPInfo *OPI);
110 bool genSaturatingInst(Instruction *Inst);
111 bool getMinMax(Constant *MinC, Constant *MaxC, std::pair<int, int> &MinMax);
112 bool isSaturatingVAsr(Instruction *Inst,
Value *S,
int MinV,
int MaxV,
115 Intrinsic::ID getVAsrIntrinsic(
bool IsInSigned,
bool IsResSigned);
116 Value *createVAsrIntrinsic(Instruction *Inst,
Value *VecOP,
Value *ShiftByVal,
118 bool genVAvg(Instruction *Inst);
119 bool checkConstantVector(
Value *
OP, int64_t &SplatVal,
bool IsOPZExt);
120 void updateMPYConst(
Intrinsic::ID IntId, int64_t &SplatVal,
bool IsOPZExt,
128char HexagonGenWideningVecInstr::ID = 0;
132 "widening vector instructions",
137 "widening vector instructions",
141 if (
Value *SplatV =
C->getSplatValue()) {
142 auto *CI = dyn_cast<ConstantInt>(SplatV);
144 return CI->getValue().isNegative();
147 for (
unsigned i = 0, e = NumElts; i != e; ++i) {
150 if (CI->getValue().isNegative())
157bool HexagonGenWideningVecInstr::getOperandInfo(
Value *V, OPInfo &OPI) {
158 using namespace PatternMatch;
160 Value *ExtV =
nullptr;
200 if (!isExtendedConstant(
C,
false) && !isExtendedConstant(
C,
true))
211 OPI.ExtInSize = getElementSizeInBits(OPI.ExtInOP, OPI.IsZExt);
215bool HexagonGenWideningVecInstr::isExtendedConstant(Constant *
C,
219 unsigned HalfSize = EltSize / 2;
220 if (
Value *SplatV =
C->getSplatValue()) {
222 return IsSigned ?
isIntN(HalfSize, CI->getSExtValue())
223 :
isUIntN(HalfSize, CI->getZExtValue());
227 for (
unsigned i = 0, e = NumElts; i !=
e; ++i) {
229 if ((IsSigned && !
isIntN(HalfSize, CI->getSExtValue())) ||
230 (!IsSigned && !
isUIntN(HalfSize, CI->getZExtValue())))
239unsigned HexagonGenWideningVecInstr::getElementSizeInBits(
Value *V,
240 bool IsZExt =
false) {
241 using namespace PatternMatch;
242 Type *ValTy =
V->getType();
248 ->getPrimitiveSizeInBits()
250 unsigned ReducedSize = EltSize / 2;
252 while (ReducedSize >= 8) {
253 for (
unsigned i = 0, e = NumElts; i !=
e; ++i) {
256 if (!
isUIntN(ReducedSize, CI->getZExtValue()))
258 }
else if (!
isIntN(ReducedSize, CI->getSExtValue()))
262 EltSize = ReducedSize;
263 ReducedSize = ReducedSize / 2;
273Value *HexagonGenWideningVecInstr::adjustExtensionForOp(OPInfo &OPI,
278 bool IsZExt = OPI.IsZExt;
279 unsigned EltSize = getElementSizeInBits(OPI.ExtInOP, OPI.IsZExt);
280 Type *EltType = getElementTy(NewExtSize, IRB);
286 if (
V->getType()->isVectorTy()) {
287 if (NewExtSize == EltSize)
298 assert(
I &&
I->getOpcode() == Instruction::ShuffleVector);
300 if (NewExtSize > EltSize)
302 else if (NewExtSize < EltSize)
309 for (
unsigned i = 0; i < NumElts; ++i)
317 OPKind OPK,
bool IsOP1ZExt,
bool IsOP2ZExt,
unsigned InEltSize,
318 unsigned ResEltSize,
bool IsConstScalar,
int ConstOpNum) {
323 assert(IsOP1ZExt == IsOP2ZExt);
324 if (InEltSize == 8 && ResEltSize == 16) {
327 assert(IsOP1ZExt &&
"Operands must be zero-extended");
328 return Intrinsic::hexagon_vadd_uu;
330 if (InEltSize == 16 && ResEltSize == 32)
331 return (IsOP1ZExt) ? Intrinsic::hexagon_vadd_uu
332 : Intrinsic::hexagon_vadd_ss;
338 assert(IsOP1ZExt == IsOP2ZExt);
339 if (InEltSize == 8 && ResEltSize == 16) {
342 assert(IsOP1ZExt &&
"Operands must be zero-extended");
343 return Intrinsic::hexagon_vsub_uu;
345 if (InEltSize == 16 && ResEltSize == 32)
346 return (IsOP1ZExt) ? Intrinsic::hexagon_vsub_uu
347 : Intrinsic::hexagon_vsub_ss;
352 assert(ResEltSize == 2 * InEltSize);
356 if (InEltSize == 8 && ResEltSize == 16) {
359 if (ConstOpNum == 2 && IsOP1ZExt) {
362 return (IsOP2ZExt) ? Intrinsic::hexagon_vmpy_ub_ub
363 : Intrinsic::hexagon_vmpy_ub_b;
364 }
else if (ConstOpNum == 1 && IsOP2ZExt) {
365 return (IsOP1ZExt) ? Intrinsic::hexagon_vmpy_ub_ub
366 : Intrinsic::hexagon_vmpy_ub_b;
371 if (InEltSize == 16 && ResEltSize == 32) {
372 if (IsOP1ZExt && IsOP2ZExt) {
375 return Intrinsic::hexagon_vmpy_uh_uh;
376 }
else if (!IsOP1ZExt && !IsOP2ZExt) {
379 return Intrinsic::hexagon_vmpy_h_h;
384 return IsOP2ZExt ? Intrinsic::hexagon_vmpy_uu
385 : Intrinsic::hexagon_vmpy_us;
387 return IsOP2ZExt ? Intrinsic::hexagon_vmpy_su
388 : Intrinsic::hexagon_vmpy_ss;
394Type *HexagonGenWideningVecInstr::getElementTy(
unsigned size,
408Value *HexagonGenWideningVecInstr::createIntrinsic(
410 Type *ResType,
unsigned NumElts,
bool Interleave =
true) {
417 unsigned HalfElts = NumElts / 2;
418 for (
unsigned i = 0; i < HalfElts; ++i) {
428std::pair<Value *, Value *>
429HexagonGenWideningVecInstr::opSplit(
Value *
OP, Instruction *Inst,
440 assert(NumElts % 2 == 0 &&
"Unexpected Vector Type!!");
441 unsigned HalfElts = NumElts / 2;
444 for (
unsigned i = 0; i < HalfElts; ++i)
446 for (
unsigned i = 0; i < HalfElts; ++i)
453 return std::pair<Value *, Value *>(
Hi,
Lo);
466 return std::pair<Value *, Value *>(
Hi,
Lo);
469bool HexagonGenWideningVecInstr::checkConstantVector(
Value *
OP,
473 if (
Value *SplatV = C1->getSplatValue()) {
476 SplatVal = CI->getZExtValue();
478 SplatVal = CI->getSExtValue();
486void HexagonGenWideningVecInstr::updateMPYConst(
Intrinsic::ID IntId,
490 if ((IntId == Intrinsic::hexagon_vmpy_uu ||
491 IntId == Intrinsic::hexagon_vmpy_us ||
492 IntId == Intrinsic::hexagon_vmpy_su ||
493 IntId == Intrinsic::hexagon_vmpy_ss) &&
494 OP->getType()->isVectorTy()) {
497 Value *scalar = IRB.
getIntN(VecTy->getScalarSizeInBits(),
498 static_cast<uint32_t
>(SplatVal));
504 packConstant(IntId, SplatVal,
OP, IRB);
508void HexagonGenWideningVecInstr::packConstant(
Intrinsic::ID IntId,
511 uint32_t Val32 =
static_cast<uint32_t
>(SplatVal);
512 if (IntId == Intrinsic::hexagon_vmpy_ub_ub) {
513 assert(SplatVal >= 0 && SplatVal <= UINT8_MAX);
514 uint32_t
packed = (Val32 << 24) | (Val32 << 16) | (Val32 << 8) | Val32;
516 }
else if (IntId == Intrinsic::hexagon_vmpy_ub_b) {
517 assert(SplatVal >= INT8_MIN && SplatVal <= INT8_MAX);
518 uint32_t
packed = (Val32 << 24) | ((Val32 << 16) & ((1 << 24) - 1)) |
519 ((Val32 << 8) & ((1 << 16) - 1)) |
520 (Val32 & ((1 << 8) - 1));
522 }
else if (IntId == Intrinsic::hexagon_vmpy_uh_uh) {
523 assert(SplatVal >= 0 && SplatVal <= UINT16_MAX);
524 uint32_t
packed = (Val32 << 16) | Val32;
526 }
else if (IntId == Intrinsic::hexagon_vmpy_h_h) {
527 assert(SplatVal >= INT16_MIN && SplatVal <= INT16_MAX);
528 uint32_t
packed = (Val32 << 16) | (Val32 & ((1 << 16) - 1));
533bool HexagonGenWideningVecInstr::replaceWithIntrinsic(Instruction *Inst,
542 bool IsOP1ZExt = OP1Info.IsZExt;
543 bool IsOP2ZExt = OP2Info.IsZExt;
546 bool IsResZExt = (OPK == OP_Mul || OPK == OP_Shl)
547 ? (OP1Info.IsZExt && OP2Info.IsZExt)
550 unsigned MaxEltSize = std::max(OP1Info.ExtInSize, OP2Info.ExtInSize);
551 unsigned NewOpEltSize = MaxEltSize;
552 unsigned NewResEltSize = 2 * MaxEltSize;
560 if (OPK != OP_Mul && OPK != OP_Shl &&
561 (IsOP1ZExt != IsOP2ZExt || (!IsOP1ZExt && NewOpEltSize == 8)))
562 NewOpEltSize = 2 * NewOpEltSize;
564 unsigned ResVLen = NewResEltSize * NumElts;
567 if (NewOpEltSize > 16 || ((ResVLen > HwVLen) && (ResVLen % HwVLen) != 0))
571 Value *NewOP1 = adjustExtensionForOp(OP1Info, IRB, NewOpEltSize, NumElts);
572 Value *NewOP2 = adjustExtensionForOp(OP2Info, IRB, NewOpEltSize, NumElts);
574 if (NewOpEltSize == NewResEltSize) {
575 assert(OPK != OP_Mul && OPK != OP_Shl);
579 if (InstEltSize > NewResEltSize)
585 bool IsConstScalar =
false;
586 int64_t SplatVal = 0;
588 if (OPK == OP_Mul || OPK == OP_Shl) {
589 IsConstScalar = checkConstantVector(NewOP1, SplatVal, IsOP1ZExt);
590 if (!IsConstScalar) {
591 IsConstScalar = checkConstantVector(NewOP2, SplatVal, IsOP2ZExt);
596 if (IsConstScalar && OPK == OP_Shl) {
597 if (((NewOpEltSize == 8) && (SplatVal > 0) && (SplatVal < 8)) ||
598 ((NewOpEltSize == 16) && (SplatVal > 0) && (SplatVal < 16))) {
599 SplatVal = 1 << SplatVal;
604 }
else if (!IsConstScalar && OPK == OP_Shl) {
608 Intrinsic::ID IntId = getIntrinsic(OPK, IsOP1ZExt, IsOP2ZExt, NewOpEltSize,
609 NewResEltSize, IsConstScalar, ConstOpNum);
612 updateMPYConst(IntId, SplatVal, IsOP2ZExt, NewOP2, IRB);
616 if (ResVLen > 2 * HwVLen) {
617 assert(ResVLen == 4 * HwVLen);
619 unsigned HalfElts = NumElts / 2;
624 std::pair<Value *, Value *> SplitOP1 = opSplit(NewOP1, Inst, NewOpType);
625 std::pair<Value *, Value *> SplitOP2;
626 if (IsConstScalar && (IntId == Intrinsic::hexagon_vmpy_h_h ||
627 IntId == Intrinsic::hexagon_vmpy_uh_uh)) {
628 SplitOP2 = std::pair<Value *, Value *>(NewOP2, NewOP2);
630 SplitOP2 = opSplit(NewOP2, Inst, NewOpType);
632 Value *NewInHi = createIntrinsic(IntId, Inst, SplitOP1.first,
633 SplitOP2.first, ResType, HalfElts,
true);
634 Value *NewInLo = createIntrinsic(IntId, Inst, SplitOP1.second,
635 SplitOP2.second, ResType, HalfElts,
true);
636 assert(InstEltSize == NewResEltSize);
638 for (
unsigned i = 0; i < NumElts; ++i)
651 createIntrinsic(IntId, Inst, NewOP1, NewOP2, ResType, NumElts,
true);
652 if (InstEltSize > NewResEltSize)
653 NewIn = (IsResZExt) ? IRB.
CreateZExt(NewIn, InstTy)
663bool HexagonGenWideningVecInstr::processInstruction(Instruction *Inst) {
674 using namespace PatternMatch;
689 OPInfo OP1Info, OP2Info;
695 if (!OP1Info.ExtInOP || !OP2Info.ExtInOP)
698 return replaceWithIntrinsic(Inst, OPK, OP1Info, OP2Info);
701bool HexagonGenWideningVecInstr::getVmpaOperandInfo(
Value *V, OPInfo &OPI) {
702 using namespace PatternMatch;
719 ConstantInt *
I =
nullptr;
723 uint32_t IValue =
I->getZExtValue();
739bool HexagonGenWideningVecInstr::processInstructionForVMPA(Instruction *Inst) {
740 using namespace PatternMatch;
751 Value *
OP[4] = {
nullptr,
nullptr,
nullptr,
nullptr};
757 for (
unsigned i = 0; i < 4; i++)
758 if (!getVmpaOperandInfo(
OP[i], OP_Info[i]) || !OP_Info[i].ExtInOP)
761 return replaceWithVmpaIntrinsic(Inst, OP_Info);
766void HexagonGenWideningVecInstr::reorderVmpaOperands(OPInfo *OPI) {
767 for (
unsigned i = 0; i < 2; i++)
768 if (!OPI[2 * i].ExtInOP->getType()->isVectorTy()) {
771 OPI[2 * i] = OPI[2 * i + 1];
772 OPI[2 * i + 1] = Temp;
779bool HexagonGenWideningVecInstr::replaceWithVmpaIntrinsic(Instruction *Inst,
781 reorderVmpaOperands(OPI);
785 if (!OPI[1].IsScalar || !OPI[3].IsScalar || OPI[0].IsScalar ||
789 OPInfo SOPI1 = OPI[1];
790 OPInfo SOPI2 = OPI[3];
793 if (SOPI1.ExtInSize != SOPI2.ExtInSize || SOPI1.ExtInSize != 8)
801 unsigned MaxVEltSize = std::max(OPI[0].ExtInSize, OPI[2].ExtInSize);
802 unsigned NewVOpEltSize = MaxVEltSize;
803 unsigned NewResEltSize = 2 * MaxVEltSize;
805 if (NumElts * NewVOpEltSize < HwVLen) {
807 NewVOpEltSize = 2 * NewVOpEltSize;
808 NewResEltSize = 2 * NewResEltSize;
814 Value *NewSOP1 = SOPI1.ExtInOP;
815 Value *NewSOP2 = SOPI2.ExtInOP;
826 Intrinsic::ID CombineIntID = Intrinsic::hexagon_A2_combine_ll;
831 Value *NewVOP1 = adjustExtensionForOp(OPI[0], IRB, NewVOpEltSize, NumElts);
832 Value *NewVOP2 = adjustExtensionForOp(OPI[2], IRB, NewVOpEltSize, NumElts);
835 Intrinsic::ID VCombineIntID = Intrinsic::hexagon_V6_vcombine_128B;
843 ? Intrinsic::hexagon_V6_vmpabus_128B
851 if (InstEltSize > NewResEltSize)
857 unsigned HalfElts = NumElts / 2;
858 for (
unsigned i = 0; i < HalfElts; ++i) {
869bool HexagonGenWideningVecInstr::genSaturatingInst(Instruction *Inst) {
875 using namespace PatternMatch;
877 Value *L1 =
nullptr, *
T1 =
nullptr, *L2 =
nullptr, *T2 =
nullptr,
879 Constant *RC1 =
nullptr, *FC1 =
nullptr, *RC2 =
nullptr, *FC2 =
nullptr,
890 std::pair<int, int> MinMax;
892 if (getMinMax(RC1, RC2, MinMax)) {
895 if (isSaturatingVAsr(Inst, L2, MinMax.first, MinMax.second,
898 ConstantInt *shift_val =
902 createVAsrIntrinsic(Inst, L3, shift_val, IsResSigned);
914 (
T1 != L1 || FC1 != RC1))
919 (T2 != L2 || FC2 != RC2))
926 std::pair<int, int> MinMax;
928 if (!getMinMax(RC1, RC2, MinMax))
930 }
else if (!getMinMax(RC2, RC1, MinMax))
937 Value *
OP1 =
nullptr, *ShiftByVal =
nullptr;
945 if (!isSaturatingVAsr(Inst, S, MinMax.first, MinMax.second, IsResSigned))
948 Value *NewIn = createVAsrIntrinsic(Inst, OP1, ShiftByVal, IsResSigned);
953Value *HexagonGenWideningVecInstr::extendShiftByVal(
Value *ShiftByVal,
955 using namespace PatternMatch;
962bool HexagonGenWideningVecInstr::getMinMax(Constant *MinC, Constant *MaxC,
963 std::pair<int, int> &MinMax) {
976bool HexagonGenWideningVecInstr::isSaturatingVAsr(Instruction *Inst,
Value *S,
987 int MaxRange, MinRange;
989 MaxRange = (1 << (TruncSize - 1)) - 1;
990 MinRange = -(1 << (TruncSize - 1));
991 }
else if (MinV == 0) {
992 MaxRange = (1 << (TruncSize)) - 1;
998 if (MinV != MinRange || MaxV != MaxRange)
1002 if (SInst->getOpcode() == Instruction::AShr) {
1003 Type *SInstTy = SInst->getType();
1006 if (SInstEltSize != 2 * TruncSize || TruncSize > 16)
1012Intrinsic::ID HexagonGenWideningVecInstr::getVAsrIntrinsic(
bool IsInSigned,
1015 return (IsInSigned) ? Intrinsic::hexagon_vasrsat_su
1016 : Intrinsic::hexagon_vasrsat_uu;
1017 return Intrinsic::hexagon_vasrsat_ss;
1020Value *HexagonGenWideningVecInstr::createVAsrIntrinsic(Instruction *Inst,
1027 ShiftByVal = extendShiftByVal(ShiftByVal, IRB);
1038 unsigned HalfElts = NumElts / 2;
1040 for (
unsigned i = 0; i < HalfElts; ++i)
1043 for (
unsigned i = 0; i < HalfElts; ++i)
1051 std::pair<Value *, Value *> HiLo = opSplit(VecOP, Inst, InVecOPTy);
1059bool HexagonGenWideningVecInstr::genVAvg(Instruction *Inst) {
1060 using namespace PatternMatch;
1082 unsigned OP1EltSize = getElementSizeInBits(OP1);
1083 unsigned OP2EltSize = getElementSizeInBits(OP2);
1084 unsigned NewEltSize = std::max(OP1EltSize, OP2EltSize);
1092 if (InstEltSize < NewEltSize || (InstLen > 2 * HwVLen))
1095 if ((InstLen > HwVLen) && (InstLen % HwVLen != 0))
1102 if (OP1EltSize < NewEltSize)
1105 if (OP2EltSize < NewEltSize)
1110 (IsSigned) ? Intrinsic::hexagon_vavgs :
Intrinsic::hexagon_vavgu;
1111 Value *NewIn =
nullptr;
1114 if (NewEltSize * NumElts > HwVLen) {
1115 unsigned HalfElts = NumElts / 2;
1118 std::pair<Value *, Value *> SplitOP1 = opSplit(OP1, Inst, ResType);
1119 std::pair<Value *, Value *> SplitOP2 = opSplit(OP2, Inst, ResType);
1120 Value *NewHi = createIntrinsic(AvgIntID, Inst, SplitOP1.first,
1121 SplitOP2.first, ResType, NumElts,
false);
1122 Value *NewLo = createIntrinsic(AvgIntID, Inst, SplitOP1.second,
1123 SplitOP2.second, ResType, NumElts,
false);
1125 for (
unsigned i = 0; i < NumElts; ++i)
1132 createIntrinsic(AvgIntID, Inst, OP1, OP2, AvgInstTy, NumElts,
false);
1134 if (InstEltSize > NewEltSize)
1136 NewIn = (IsSigned) ? IRB.
CreateSExt(NewIn, InstTy)
1142bool HexagonGenWideningVecInstr::visitBlock(BasicBlock *
B) {
1144 for (
auto &
I : *
B) {
1145 Type *InstTy =
I.getType();
1153 Changed |= processInstructionForVMPA(&
I);
1163bool HexagonGenWideningVecInstr::runOnFunction(Function &
F) {
1183 return new HexagonGenWideningVecInstr(&TM);
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool runOnFunction(Function &F, bool PostInlining)
widening Hexagon generate widening vector static false bool hasNegativeValues(Constant *C)
static cl::opt< bool > WidenShortVector("hexagon-widen-short-vector", cl::desc("Generate widening instructions for short vectors."), cl::Hidden)
Machine Check Debug Module
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static std::optional< OperandInfo > getOperandInfo(const MachineOperand &MO)
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
@ ICMP_SLT
signed less than
@ ICMP_SGT
signed greater than
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
LLVM_ABI Constant * getSplatValue(bool AllowPoison=false) const
If all elements of the vector constant have the same value, return that value.
Legacy analysis pass which computes a DominatorTree.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
unsigned getVectorLength() const
bool useHVX128BOps() const
bool isTypeForHVX(Type *VecTy, bool IncludeBool=false) const
const HexagonSubtarget * getSubtargetImpl(const Function &F) const override
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
IntegerType * getInt16Ty()
Fetch the type representing a 16-bit integer.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended or truncated from a 64-bit value.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
void push_back(const T &Elt)
bool isVectorTy() const
True if this is an instance of VectorType.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ SHL
Shift and rotation operations.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
class_match< PoisonValue > m_Poison()
Match an arbitrary poison constant.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
ThreeOps_match< Val_t, Elt_t, Idx_t, Instruction::InsertElement > m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx)
Matches InsertElementInst.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
support::detail::packed_endian_specific_integral< T, E, support::unaligned > packed
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
void initializeHexagonGenWideningVecInstrPass(PassRegistry &)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
FunctionPass * createHexagonGenWideningVecInstr(const HexagonTargetMachine &)