83#define DEBUG_TYPE "loop-idiom-vectorize"
87 cl::desc(
"Disable Loop Idiom Vectorize Pass."));
91 cl::desc(
"The vectorization style for loop idiom transform."),
93 "Use masked vector intrinsics"),
95 "predicated",
"Use VP intrinsics")),
101 cl::desc(
"Proceed with Loop Idiom Vectorize Pass, but do "
102 "not convert byte-compare loop(s)."));
106 cl::desc(
"The vectorization factor for byte-compare patterns."),
112 cl::desc(
"Do not convert find-first-byte loop(s)."));
116 cl::desc(
"Verify loops generated Loop Idiom Vectorize Pass."));
119class LoopIdiomVectorize {
121 unsigned ByteCompareVF;
122 Loop *CurLoop =
nullptr;
133 BasicBlock *VectorLoopPreheaderBlock =
nullptr;
135 BasicBlock *VectorLoopMismatchBlock =
nullptr;
142 : VectorizeStyle(S), ByteCompareVF(VF), DT(DT), LI(LI),
TTI(
TTI),
DL(
DL),
151 bool runOnLoopBlock(BasicBlock *BB,
const SCEV *BECount,
152 SmallVectorImpl<BasicBlock *> &ExitBlocks);
154 bool recognizeByteCompare();
157 GetElementPtrInst *GEPA, GetElementPtrInst *GEPB,
158 Instruction *Index,
Value *Start,
Value *MaxLen);
161 GetElementPtrInst *GEPA,
162 GetElementPtrInst *GEPB,
Value *ExtStart,
164 Value *createPredicatedFindMismatch(
IRBuilder<> &Builder, DomTreeUpdater &DTU,
165 GetElementPtrInst *GEPA,
166 GetElementPtrInst *GEPB,
Value *ExtStart,
169 void transformByteCompare(GetElementPtrInst *GEPA, GetElementPtrInst *GEPB,
170 PHINode *IndPhi,
Value *MaxLen, Instruction *Index,
171 Value *Start,
bool IncIdx, BasicBlock *FoundBB,
174 bool recognizeFindFirstByte();
177 unsigned VF,
Type *CharTy,
Value *IndPhi,
178 BasicBlock *ExitSucc, BasicBlock *ExitFail,
182 void transformFindFirstByte(PHINode *IndPhi,
unsigned VF,
Type *CharTy,
183 BasicBlock *ExitSucc, BasicBlock *ExitFail,
196 const auto *
DL = &L.getHeader()->getDataLayout();
202 unsigned BCVF = ByteCompareVF;
206 Function &
F = *L.getHeader()->getParent();
210 std::optional<OptimizationRemarkEmitter> ORELocal;
212 ORELocal.emplace(&
F);
216 LoopIdiomVectorize LIV(VecStyle, BCVF, &AR.
DT, &AR.
LI, &AR.
TTI,
DL, *ORE);
229bool LoopIdiomVectorize::run(
Loop *L) {
232 Function &
F = *L->getHeader()->getParent();
238 if (!Hints.allowVectorization(&
F, L,
false)) {
240 <<
" due to vectorization hints\n");
244 if (
F.hasFnAttribute(Attribute::NoImplicitFloat)) {
246 <<
" due to its NoImplicitFloat attribute");
252 if (!
L->getLoopPreheader())
256 << CurLoop->getHeader()->getName() <<
"\n");
258 if (recognizeByteCompare())
261 if (recognizeFindFirstByte())
273 for (
Value *
Op : PN.incoming_values())
274 if (
Op == ScalarRes) {
282 PN.addIncoming(VectorRes, IncBB);
290 if (L->contains(BB)) {
291 PN.addIncoming(PN.getIncomingValueForBlock(BB), IncBB);
298bool LoopIdiomVectorize::recognizeByteCompare() {
305 if (!
TTI->supportsScalableVectors() || !
TTI->getMinPageSize().has_value() ||
313 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 2)
320 auto LoopBlocks = CurLoop->getBlocks();
329 if (LoopBlocks[0]->
size() > 4)
343 if (LoopBlocks[1]->
size() > 7)
347 Value *StartIdx =
nullptr;
358 if (!Index || !
Index->getType()->isIntegerTy(32) ||
367 if (&
I != PN && &
I != Index)
375 if (!
match(Header->getTerminator(),
379 !CurLoop->contains(WhileBB))
386 Value *LoadA, *LoadB;
391 !CurLoop->contains(TrueBB))
413 if (!CurLoop->isLoopInvariant(PtrA) || !CurLoop->isLoopInvariant(PtrB) ||
452 if (FoundBB == EndBB) {
454 Value *WhileCondVal = EndPN.getIncomingValueForBlock(Header);
455 Value *WhileBodyVal = EndPN.getIncomingValueForBlock(WhileBB);
461 if (WhileCondVal != WhileBodyVal &&
462 ((WhileCondVal != Index && WhileCondVal != MaxLen) ||
463 (WhileBodyVal != Index)))
473 transformByteCompare(GEPA, GEPB, PN, MaxLen, Index, StartIdx,
true,
478Value *LoopIdiomVectorize::createMaskedFindMismatch(
491 Intrinsic::get_active_lane_mask, {PredVTy, I64Type}, {ExtStart, ExtEnd});
495 Builder.
CreateMul(VecLen, ConstantInt::get(I64Type, ByteCompareVF),
"",
501 Builder.
CreateBr(VectorLoopStartBlock);
504 VectorLoopStartBlock}});
509 PHINode *LoopPred = Builder.
CreatePHI(PredVTy, 2,
"mismatch_vec_loop_pred");
510 LoopPred->
addIncoming(InitialPred, VectorLoopPreheaderBlock);
511 PHINode *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vec_index");
512 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
513 Type *VectorLoadType =
517 Value *VectorLhsGep =
520 Align(1), LoopPred, Passthru);
522 Value *VectorRhsGep =
525 Align(1), LoopPred, Passthru);
528 VectorMatchCmp = Builder.
CreateSelect(LoopPred, VectorMatchCmp, PFalse);
530 Builder.
CreateCondBr(VectorMatchHasActiveLanes, VectorLoopMismatchBlock,
541 Value *NewVectorIndexPhi =
542 Builder.
CreateAdd(VectorIndexPhi, VecLen,
"",
544 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
547 {PredVTy, I64Type}, {NewVectorIndexPhi, ExtEnd});
548 LoopPred->
addIncoming(NewPred, VectorLoopIncBlock);
550 Value *PredHasActiveLanes =
552 Builder.
CreateCondBr(PredHasActiveLanes, VectorLoopStartBlock, EndBlock);
561 PHINode *FoundPred = Builder.
CreatePHI(PredVTy, 1,
"mismatch_vec_found_pred");
562 FoundPred->
addIncoming(VectorMatchCmp, VectorLoopStartBlock);
564 Builder.
CreatePHI(PredVTy, 1,
"mismatch_vec_last_loop_pred");
565 LastLoopPred->
addIncoming(LoopPred, VectorLoopStartBlock);
567 Builder.
CreatePHI(I64Type, 1,
"mismatch_vec_found_index");
568 VectorFoundIndex->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
573 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorFoundIndex, Ctz,
"",
575 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
578Value *LoopIdiomVectorize::createPredicatedFindMismatch(
583 Type *ResType = I32Type;
589 Builder.
Insert(JumpToVectorLoop);
592 VectorLoopStartBlock}});
597 auto *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vector_index");
598 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
601 Value *AVL = Builder.
CreateSub(ExtEnd, VectorIndexPhi,
"avl",
true,
605 auto *VF = ConstantInt::get(I32Type, ByteCompareVF);
608 {I64Type}, {AVL, VF, Builder.
getTrue()});
609 Value *GepOffset = VectorIndexPhi;
611 Value *VectorLhsGep =
617 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
618 {VectorLhsGep, AllTrueMask, VL},
nullptr,
"lhs.load");
620 Value *VectorRhsGep =
623 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
624 {VectorRhsGep, AllTrueMask, VL},
nullptr,
"rhs.load");
626 Value *VectorMatchCmp =
627 Builder.
CreateICmpNE(VectorLhsLoad, VectorRhsLoad,
"mismatch.cmp");
629 Intrinsic::vp_cttz_elts, {ResType, VectorMatchCmp->
getType()},
630 {VectorMatchCmp, Builder.
getInt1(
false), AllTrueMask,
634 MismatchFound, VectorLoopMismatchBlock, VectorLoopIncBlock);
635 Builder.
Insert(VectorEarlyExit);
646 Value *NewVectorIndexPhi =
647 Builder.
CreateAdd(VectorIndexPhi, VL64,
"",
649 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
651 auto *VectorLoopBranchBack =
653 Builder.
Insert(VectorLoopBranchBack);
665 CTZLCSSAPhi->
addIncoming(CTZ, VectorLoopStartBlock);
666 auto *VectorIndexLCSSAPhi =
668 VectorIndexLCSSAPhi->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
671 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorIndexLCSSAPhi, CTZI64,
"",
673 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
676Value *LoopIdiomVectorize::expandFindMismatch(
683 BasicBlock *Preheader = CurLoop->getLoopPreheader();
690 EndBlock =
SplitBlock(Preheader, PHBranch, DT, LI,
nullptr,
"mismatch_end");
706 Ctx,
"mismatch_min_it_check", EndBlock->getParent(), EndBlock);
712 Ctx,
"mismatch_mem_check", EndBlock->getParent(), EndBlock);
715 Ctx,
"mismatch_vec_loop_preheader", EndBlock->getParent(), EndBlock);
718 EndBlock->getParent(), EndBlock);
721 EndBlock->getParent(), EndBlock);
724 EndBlock->getParent(), EndBlock);
727 Ctx,
"mismatch_loop_pre", EndBlock->getParent(), EndBlock);
733 Ctx,
"mismatch_loop_inc", EndBlock->getParent(), EndBlock);
739 auto VectorLoop = LI->AllocateLoop();
740 auto ScalarLoop = LI->AllocateLoop();
742 if (CurLoop->getParentLoop()) {
743 CurLoop->getParentLoop()->addBasicBlockToLoop(MinItCheckBlock, *LI);
744 CurLoop->getParentLoop()->addBasicBlockToLoop(MemCheckBlock, *LI);
745 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopPreheaderBlock,
747 CurLoop->getParentLoop()->addChildLoop(VectorLoop);
748 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopMismatchBlock, *LI);
749 CurLoop->getParentLoop()->addBasicBlockToLoop(LoopPreHeaderBlock, *LI);
750 CurLoop->getParentLoop()->addChildLoop(ScalarLoop);
752 LI->addTopLevelLoop(VectorLoop);
753 LI->addTopLevelLoop(ScalarLoop);
757 VectorLoop->addBasicBlockToLoop(VectorLoopStartBlock, *LI);
758 VectorLoop->addBasicBlockToLoop(VectorLoopIncBlock, *LI);
760 ScalarLoop->addBasicBlockToLoop(LoopStartBlock, *LI);
761 ScalarLoop->addBasicBlockToLoop(LoopIncBlock, *LI);
776 LLVMContext::MD_prof,
778 Builder.
Insert(MinItCheckBr);
818 Value *CombinedPageCmp = Builder.
CreateOr(LhsPageCmp, RhsPageCmp);
820 CombinedPageCmp, LoopPreHeaderBlock, VectorLoopPreheaderBlock);
824 Builder.
Insert(CombinedPageCmpCmpBr);
840 Value *VectorLoopRes =
nullptr;
841 switch (VectorizeStyle) {
844 createMaskedFindMismatch(Builder, DTU, GEPA, GEPB, ExtStart, ExtEnd);
847 VectorLoopRes = createPredicatedFindMismatch(Builder, DTU, GEPA, GEPB,
889 Value *PhiInc = Builder.
CreateAdd(IndexPhi, ConstantInt::get(ResType, 1),
"",
890 Index->hasNoUnsignedWrap(),
891 Index->hasNoSignedWrap());
911 ResPhi->
addIncoming(VectorLoopRes, VectorLoopMismatchBlock);
916 ScalarLoop->verifyLoop();
917 VectorLoop->verifyLoop();
918 if (!VectorLoop->isRecursivelyLCSSAForm(*DT, *LI))
920 if (!ScalarLoop->isRecursivelyLCSSAForm(*DT, *LI))
935 BasicBlock *Preheader = CurLoop->getLoopPreheader();
947 expandFindMismatch(Builder, DTU, GEPA, GEPB, Index, Start, MaxLen);
951 assert(IndPhi->
hasOneUse() &&
"Index phi node has more than one use!");
952 Index->replaceAllUsesWith(ByteCmpRes);
958 CmpBB->moveBefore(EndBB);
971 if (FoundBB != EndBB) {
984 if (EndBB != FoundBB)
989 if (!CurLoop->isOutermost())
990 CurLoop->getParentLoop()->addBasicBlockToLoop(CmpBB, *LI);
993 CurLoop->getParentLoop()->verifyLoop();
994 if (!CurLoop->getParentLoop()->isRecursivelyLCSSAForm(*DT, *LI))
999bool LoopIdiomVectorize::recognizeFindFirstByte() {
1004 if (!
TTI->supportsScalableVectors() || !
TTI->getMinPageSize().has_value() ||
1012 (std::numeric_limits<uint64_t>::max() / 2))
1022 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 4 ||
1023 CurLoop->getSubLoops().size() != 1)
1026 auto *InnerLoop = CurLoop->getSubLoops().front();
1031 if (!Hints.allowVectorization(&
F, InnerLoop,
1034 << InnerLoop->getName()
1035 <<
" due to vectorization hints\n");
1044 auto LoopBlocks = CurLoop->getBlocks();
1045 if (LoopBlocks[0]->
size() > 3 || LoopBlocks[1]->
size() > 4 ||
1046 LoopBlocks[2]->
size() > 3 || LoopBlocks[3]->
size() > 3)
1066 !InnerLoop->contains(MatchBB))
1078 Value *LoadSearch, *LoadNeedle;
1126 if (InnerLoop->contains(PSearch))
1128 if (PSearch != &Header->front() || PNeedle != &MatchBB->
front())
1166 !CurLoop->contains(OuterBB))
1183 if (!CurLoop->isLoopInvariant(SearchStart) ||
1184 !CurLoop->isLoopInvariant(SearchEnd) ||
1185 !CurLoop->isLoopInvariant(NeedleStart) ||
1186 !CurLoop->isLoopInvariant(NeedleEnd))
1189 LLVM_DEBUG(
dbgs() <<
"Found idiom in loop: \n" << *CurLoop <<
"\n\n");
1191 transformFindFirstByte(IndPhi, VF, CharTy, ExitSucc, ExitFail, SearchStart,
1192 SearchEnd, NeedleStart, NeedleEnd);
1196Value *LoopIdiomVectorize::expandFindFirstByte(
1205 auto *ConstVF = ConstantInt::get(I64Ty, VF);
1208 BasicBlock *Preheader = CurLoop->getLoopPreheader();
1215 nullptr,
"scalar_preheader");
1250 auto OuterLoop = LI->AllocateLoop();
1251 auto InnerLoop = LI->AllocateLoop();
1253 if (
auto ParentLoop = CurLoop->getParentLoop()) {
1254 ParentLoop->addBasicBlockToLoop(BB0, *LI);
1255 ParentLoop->addChildLoop(OuterLoop);
1257 LI->addTopLevelLoop(OuterLoop);
1264 while (ExitLoop && !ExitLoop->
contains(ExitSucc))
1270 OuterLoop->addChildLoop(InnerLoop);
1273 OuterLoop->addBasicBlockToLoop(BB1, *LI);
1274 OuterLoop->addBasicBlockToLoop(BB3, *LI);
1275 OuterLoop->addBasicBlockToLoop(BB5, *LI);
1276 InnerLoop->addBasicBlockToLoop(BB2, *LI);
1287 Value *ISearchStart =
1292 Value *SearchTripCount =
1294 "search_trip_count"),
1296 Value *INeedleStart =
1301 Value *NeedleTripCount =
1303 "needle_trip_count"),
1306 Builder.
CreateIntrinsic(Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1307 {ConstantInt::get(I64Ty, 0), ConstVF});
1311 Value *SearchStartPage =
1312 Builder.
CreateLShr(ISearchStart, AddrShiftAmt,
"search_start_page");
1313 Value *SearchEndPage =
1314 Builder.
CreateLShr(ISearchEnd, AddrShiftAmt,
"search_end_page");
1315 Value *NeedleStartPage =
1316 Builder.
CreateLShr(INeedleStart, AddrShiftAmt,
"needle_start_page");
1317 Value *NeedleEndPage =
1318 Builder.
CreateLShr(INeedleEnd, AddrShiftAmt,
"needle_end_page");
1319 Value *SearchPageCmp =
1320 Builder.
CreateICmpNE(SearchStartPage, SearchEndPage,
"search_page_cmp");
1321 Value *NeedlePageCmp =
1322 Builder.
CreateICmpNE(NeedleStartPage, NeedleEndPage,
"needle_page_cmp");
1324 Value *CombinedPageCmp =
1325 Builder.
CreateOr(SearchPageCmp, NeedlePageCmp,
"combined_page_cmp");
1336 Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1337 {SearchIdx, SearchTripCount},
nullptr,
"search_pred");
1338 PredSearch = Builder.
CreateAnd(PredVF, PredSearch,
"search_masked");
1339 Value *Search = Builder.
CreateGEP(CharTy, SearchStart, SearchIdx,
"psearch");
1341 CharVTy, Search,
Align(1), PredSearch, Passthru,
"search_load_vec");
1353 Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1354 {NeedleIdx, NeedleTripCount},
nullptr,
"needle_pred");
1355 PredNeedle = Builder.
CreateAnd(PredVF, PredNeedle,
"needle_masked");
1356 Value *Needle = Builder.
CreateGEP(CharTy, NeedleStart, NeedleIdx,
"pneedle");
1358 CharVTy, Needle,
Align(1), PredNeedle, Passthru,
"needle_load_vec");
1364 Needle0,
"needle0");
1365 LoadNeedle = Builder.
CreateSelect(PredNeedle, LoadNeedle, Needle0Splat,
1372 Intrinsic::experimental_vector_match, {CharVTy, LoadNeedle->
getType()},
1373 {LoadSearch, LoadNeedle, PredSearch},
nullptr,
"match_segment");
1374 Value *MatchAcc = Builder.
CreateOr(Match, MatchSeg,
"match_accumulator");
1375 Value *NextNeedleIdx =
1376 Builder.
CreateAdd(NeedleIdx, ConstVF,
"needle_idx_next");
1396 Intrinsic::experimental_cttz_elts, {I64Ty, PredVTy},
1397 {MatchPredLCSSA, Builder.
getInt1(
true)},
nullptr,
1400 Builder.
CreateGEP(CharTy, MatchLCSSA, MatchCnt,
"match_res");
1406 Value *NextSearchIdx =
1407 Builder.
CreateAdd(SearchIdx, ConstVF,
"search_idx_next");
1423 MatchPredLCSSA->
addIncoming(MatchPredAccLCSSA, BB3);
1428 if (ExitSucc != ExitFail)
1432 OuterLoop->verifyLoop();
1433 InnerLoop->verifyLoop();
1434 if (!OuterLoop->isRecursivelyLCSSAForm(*DT, *LI))
1441void LoopIdiomVectorize::transformFindFirstByte(
1446 BasicBlock *Preheader = CurLoop->getLoopPreheader();
1452 expandFindFirstByte(Builder, DTU, VF, CharTy, IndPhi, ExitSucc, ExitFail,
1453 SearchStart, SearchEnd, NeedleStart, NeedleEnd);
1456 CurLoop->getParentLoop()->verifyLoop();
1457 if (!CurLoop->getParentLoop()->isRecursivelyLCSSAForm(*DT, *LI))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static cl::opt< bool > VerifyLoops("loop-idiom-vectorize-verify", cl::Hidden, cl::init(false), cl::desc("Verify loops generated Loop Idiom Vectorize Pass."))
static cl::opt< bool > DisableAll("disable-loop-idiom-vectorize-all", cl::Hidden, cl::init(false), cl::desc("Disable Loop Idiom Vectorize Pass."))
static void fixSuccessorPhis(Loop *L, Value *ScalarRes, Value *VectorRes, BasicBlock *SuccBB, BasicBlock *IncBB)
static cl::opt< LoopIdiomVectorizeStyle > LITVecStyle("loop-idiom-vectorize-style", cl::Hidden, cl::desc("The vectorization style for loop idiom transform."), cl::values(clEnumValN(LoopIdiomVectorizeStyle::Masked, "masked", "Use masked vector intrinsics"), clEnumValN(LoopIdiomVectorizeStyle::Predicated, "predicated", "Use VP intrinsics")), cl::init(LoopIdiomVectorizeStyle::Masked))
static cl::opt< bool > DisableFindFirstByte("disable-loop-idiom-vectorize-find-first-byte", cl::Hidden, cl::init(false), cl::desc("Do not convert find-first-byte loop(s)."))
static cl::opt< unsigned > ByteCmpVF("loop-idiom-vectorize-bytecmp-vf", cl::Hidden, cl::desc("The vectorization factor for byte-compare patterns."), cl::init(16))
static cl::opt< bool > DisableByteCmp("disable-loop-idiom-vectorize-bytecmp", cl::Hidden, cl::init(false), cl::desc("Proceed with Loop Idiom Vectorize Pass, but do " "not convert byte-compare loop(s)."))
This file defines the LoopVectorizationLegality class.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
const Function * getParent() const
Return the enclosing method, or null if none.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Instruction & front() const
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
static constexpr ElementCount getScalable(ScalarTy MinVal)
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
LLVM_ABI bool isInBounds() const
Determine whether the GEP has the inbounds flag.
Value * getPointerOperand()
Type * getResultElementType() const
unsigned getNumIndices() const
Module * getParent()
Get the module that this global value is contained inside of...
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
CondBrInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
ConstantInt * getTrue()
Get the constant value for i1 true.
LLVM_ABI CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreateExtractVector(Type *DstType, Value *SrcVec, Value *Idx, const Twine &Name="")
Create a call to the vector.extract intrinsic.
Value * CreateVScale(Type *Ty, const Twine &Name="")
Create a call to llvm.vscale.<Ty>().
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
UncondBrInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
LLVM_ABI Value * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Value * CreateCountTrailingZeroElems(Type *ResTy, Value *Mask, bool ZeroIsPoison=true, const Twine &Name="")
Create a call to llvm.experimental_cttz_elts.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LLVM_ABI Value * CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name="", bool IsNUW=false)
Return the difference between two pointer values.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
iterator_range< user_iterator > users()
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
This is an important class for using LLVM in a threaded context.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
An instruction for reading from memory.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
LLVM_ABI PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
Utility class for getting and setting loop vectorizer hints in the form of loop metadata.
Represents a single loop in the control flow graph.
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Class to represent scalable SIMD vectors.
static LLVM_ABI ScalableVectorType * get(Type *ElementType, unsigned MinNumElts)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
Unconditional Branch instruction.
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< user_iterator > users()
Base class of all SIMD vector types.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
const ParentTy * getParent() const
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
match_bind< PHINode > m_Phi(PHINode *&PN)
Match a PHI node, capturing it if we match.
br_match m_UnconditionalBr(BasicBlock *&Succ)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
auto m_BasicBlock()
Match an arbitrary basic block value and ignore it.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_GEP(const OperandTypes &...Ops)
Matches GetElementPtrInst.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
bool isSimple(Instruction *I)
This is an optimization pass for GlobalISel generic memory operations.
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.
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
OuterAnalysisManagerProxy< FunctionAnalysisManager, Loop, LoopStandardAnalysisResults & > FunctionAnalysisManagerLoopProxy
A proxy from a FunctionAnalysisManager to a Loop.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
TargetTransformInfo & TTI