84#define DEBUG_TYPE "loop-idiom-vectorize"
87class LoopIdiomVectorize {
88 const VectorizeOptions &Opts;
90 unsigned ByteCompareVF;
91 Loop *CurLoop =
nullptr;
101 BasicBlock *VectorLoopPreheaderBlock =
nullptr;
103 BasicBlock *VectorLoopMismatchBlock =
nullptr;
111 : Opts(Opts), VectorizeStyle(S), ByteCompareVF(VF), DT(DT), LI(LI),
123 bool recognizeByteCompare();
143 bool recognizeFindFirstByte();
146 unsigned VF,
Type *CharTy,
Value *IndPhi,
151 void transformFindFirstByte(
PHINode *IndPhi,
unsigned VF,
Type *CharTy,
163 if (Opts.disable_loop_idiom_vectorize_all)
167 Opts.loop_idiom_vectorize_style.value_or(VectorizeStyle);
168 unsigned BCVF = Opts.loop_idiom_vectorize_bytecmp_vf.value_or(ByteCompareVF);
170 Function &
F = *L.getHeader()->getParent();
174 std::optional<OptimizationRemarkEmitter> ORELocal;
176 ORELocal.emplace(&
F);
180 LoopIdiomVectorize LIV(Opts, VecStyle, BCVF, &AR.
DT, &AR.
LI, &AR.
TTI, *ORE);
193bool LoopIdiomVectorize::run(
Loop *L) {
196 Function &
F = *L->getHeader()->getParent();
197 if (Opts.disable_loop_idiom_vectorize_all ||
F.hasOptSize())
202 if (!Hints.allowVectorization(L,
false)) {
204 <<
" due to vectorization hints\n");
208 if (
F.hasFnAttribute(Attribute::NoImplicitFloat)) {
210 <<
" due to its NoImplicitFloat attribute");
216 if (!
L->getLoopPreheader())
220 << CurLoop->getHeader()->getName() <<
"\n");
222 if (recognizeByteCompare())
225 if (recognizeFindFirstByte())
237 for (
Value *
Op : PN.incoming_values())
238 if (
Op == ScalarRes) {
246 PN.addIncoming(VectorRes, IncBB);
254 if (L->contains(BB)) {
255 PN.addIncoming(PN.getIncomingValueForBlock(BB), IncBB);
262bool LoopIdiomVectorize::recognizeByteCompare() {
269 if (!
TTI->supportsScalableVectors() || !
TTI->getMinPageSize().has_value() ||
270 Opts.disable_loop_idiom_vectorize_bytecmp)
277 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 2)
284 auto LoopBlocks = CurLoop->getBlocks();
293 if (LoopBlocks[0]->
size() > 4)
307 if (LoopBlocks[1]->
size() > 7)
311 Value *StartIdx =
nullptr;
322 if (!Index || !
Index->getType()->isIntegerTy(32) ||
331 if (&
I != PN && &
I != Index)
339 if (!
match(Header->getTerminator(),
343 !CurLoop->contains(WhileBB))
350 Value *LoadA, *LoadB;
355 !CurLoop->contains(TrueBB))
377 if (!CurLoop->isLoopInvariant(PtrA) || !CurLoop->isLoopInvariant(PtrB) ||
416 if (FoundBB == EndBB) {
418 Value *WhileCondVal = EndPN.getIncomingValueForBlock(Header);
419 Value *WhileBodyVal = EndPN.getIncomingValueForBlock(WhileBB);
425 if (WhileCondVal != WhileBodyVal &&
426 ((WhileCondVal != Index && WhileCondVal != MaxLen) ||
427 (WhileBodyVal != Index)))
437 transformByteCompare(GEPA, GEPB, PN, MaxLen, Index, StartIdx,
true,
442Value *LoopIdiomVectorize::createMaskedFindMismatch(
455 Intrinsic::get_active_lane_mask, {PredVTy, I64Type}, {ExtStart, ExtEnd});
459 Builder.
CreateMul(VecLen, ConstantInt::get(I64Type, ByteCompareVF),
"",
465 Builder.
CreateBr(VectorLoopStartBlock);
468 VectorLoopStartBlock}});
473 PHINode *LoopPred = Builder.
CreatePHI(PredVTy, 2,
"mismatch_vec_loop_pred");
474 LoopPred->
addIncoming(InitialPred, VectorLoopPreheaderBlock);
475 PHINode *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vec_index");
476 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
477 Type *VectorLoadType =
481 Value *VectorLhsGep =
484 Align(1), LoopPred, Passthru);
486 Value *VectorRhsGep =
489 Align(1), LoopPred, Passthru);
492 VectorMatchCmp = Builder.
CreateSelect(LoopPred, VectorMatchCmp, PFalse);
494 Builder.
CreateCondBr(VectorMatchHasActiveLanes, VectorLoopMismatchBlock,
505 Value *NewVectorIndexPhi =
506 Builder.
CreateAdd(VectorIndexPhi, VecLen,
"",
508 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
511 {PredVTy, I64Type}, {NewVectorIndexPhi, ExtEnd});
512 LoopPred->
addIncoming(NewPred, VectorLoopIncBlock);
514 Value *PredHasActiveLanes =
516 Builder.
CreateCondBr(PredHasActiveLanes, VectorLoopStartBlock, EndBlock);
525 PHINode *FoundPred = Builder.
CreatePHI(PredVTy, 1,
"mismatch_vec_found_pred");
526 FoundPred->
addIncoming(VectorMatchCmp, VectorLoopStartBlock);
528 Builder.
CreatePHI(PredVTy, 1,
"mismatch_vec_last_loop_pred");
529 LastLoopPred->
addIncoming(LoopPred, VectorLoopStartBlock);
531 Builder.
CreatePHI(I64Type, 1,
"mismatch_vec_found_index");
532 VectorFoundIndex->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
537 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorFoundIndex, Ctz,
"",
539 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
542Value *LoopIdiomVectorize::createPredicatedFindMismatch(
547 Type *ResType = I32Type;
553 Builder.
Insert(JumpToVectorLoop);
556 VectorLoopStartBlock}});
561 auto *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vector_index");
562 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
565 Value *AVL = Builder.
CreateSub(ExtEnd, VectorIndexPhi,
"avl",
true,
569 auto *VF = ConstantInt::get(I32Type, ByteCompareVF);
572 {I64Type}, {AVL, VF, Builder.
getTrue()});
573 Value *GepOffset = VectorIndexPhi;
575 Value *VectorLhsGep =
581 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
582 {VectorLhsGep, AllTrueMask, VL},
nullptr,
"lhs.load");
584 Value *VectorRhsGep =
587 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
588 {VectorRhsGep, AllTrueMask, VL},
nullptr,
"rhs.load");
590 Value *VectorMatchCmp =
591 Builder.
CreateICmpNE(VectorLhsLoad, VectorRhsLoad,
"mismatch.cmp");
593 Intrinsic::vp_cttz_elts, {ResType, VectorMatchCmp->
getType()},
594 {VectorMatchCmp, Builder.
getInt1(
false), AllTrueMask,
598 MismatchFound, VectorLoopMismatchBlock, VectorLoopIncBlock);
599 Builder.
Insert(VectorEarlyExit);
610 Value *NewVectorIndexPhi =
611 Builder.
CreateAdd(VectorIndexPhi, VL64,
"",
613 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
615 auto *VectorLoopBranchBack =
617 Builder.
Insert(VectorLoopBranchBack);
629 CTZLCSSAPhi->
addIncoming(CTZ, VectorLoopStartBlock);
630 auto *VectorIndexLCSSAPhi =
632 VectorIndexLCSSAPhi->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
635 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorIndexLCSSAPhi, CTZI64,
"",
637 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
640Value *LoopIdiomVectorize::expandFindMismatch(
647 BasicBlock *Preheader = CurLoop->getLoopPreheader();
654 EndBlock =
SplitBlock(Preheader, PHBranch, DT, LI,
nullptr,
"mismatch_end");
670 Ctx,
"mismatch_min_it_check", EndBlock->getParent(), EndBlock);
676 Ctx,
"mismatch_mem_check", EndBlock->getParent(), EndBlock);
679 Ctx,
"mismatch_vec_loop_preheader", EndBlock->getParent(), EndBlock);
682 EndBlock->getParent(), EndBlock);
685 EndBlock->getParent(), EndBlock);
688 EndBlock->getParent(), EndBlock);
691 Ctx,
"mismatch_loop_pre", EndBlock->getParent(), EndBlock);
697 Ctx,
"mismatch_loop_inc", EndBlock->getParent(), EndBlock);
703 auto VectorLoop = LI->AllocateLoop();
704 auto ScalarLoop = LI->AllocateLoop();
706 if (CurLoop->getParentLoop()) {
707 CurLoop->getParentLoop()->addBasicBlockToLoop(MinItCheckBlock, *LI);
708 CurLoop->getParentLoop()->addBasicBlockToLoop(MemCheckBlock, *LI);
709 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopPreheaderBlock,
711 CurLoop->getParentLoop()->addChildLoop(VectorLoop);
712 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopMismatchBlock, *LI);
713 CurLoop->getParentLoop()->addBasicBlockToLoop(LoopPreHeaderBlock, *LI);
714 CurLoop->getParentLoop()->addChildLoop(ScalarLoop);
716 LI->addTopLevelLoop(VectorLoop);
717 LI->addTopLevelLoop(ScalarLoop);
721 VectorLoop->addBasicBlockToLoop(VectorLoopStartBlock, *LI);
722 VectorLoop->addBasicBlockToLoop(VectorLoopIncBlock, *LI);
724 ScalarLoop->addBasicBlockToLoop(LoopStartBlock, *LI);
725 ScalarLoop->addBasicBlockToLoop(LoopIncBlock, *LI);
740 LLVMContext::MD_prof,
742 Builder.
Insert(MinItCheckBr);
782 Value *CombinedPageCmp = Builder.
CreateOr(LhsPageCmp, RhsPageCmp);
784 CombinedPageCmp, LoopPreHeaderBlock, VectorLoopPreheaderBlock);
788 Builder.
Insert(CombinedPageCmpCmpBr);
804 Value *VectorLoopRes =
nullptr;
805 switch (VectorizeStyle) {
808 createMaskedFindMismatch(Builder, DTU, GEPA, GEPB, ExtStart, ExtEnd);
811 VectorLoopRes = createPredicatedFindMismatch(Builder, DTU, GEPA, GEPB,
853 Value *PhiInc = Builder.
CreateAdd(IndexPhi, ConstantInt::get(ResType, 1),
"",
854 Index->hasNoUnsignedWrap(),
855 Index->hasNoSignedWrap());
875 ResPhi->
addIncoming(VectorLoopRes, VectorLoopMismatchBlock);
879 if (Opts.loop_idiom_vectorize_verify) {
880 ScalarLoop->verifyLoop();
881 VectorLoop->verifyLoop();
882 if (!VectorLoop->isRecursivelyLCSSAForm(*DT, *LI))
884 if (!ScalarLoop->isRecursivelyLCSSAForm(*DT, *LI))
899 BasicBlock *Preheader = CurLoop->getLoopPreheader();
911 expandFindMismatch(Builder, DTU, GEPA, GEPB, Index, Start, MaxLen);
915 assert(IndPhi->
hasOneUse() &&
"Index phi node has more than one use!");
916 Index->replaceAllUsesWith(ByteCmpRes);
922 CmpBB->moveBefore(EndBB);
935 if (FoundBB != EndBB) {
948 if (EndBB != FoundBB)
953 if (!CurLoop->isOutermost())
954 CurLoop->getParentLoop()->addBasicBlockToLoop(CmpBB, *LI);
956 if (Opts.loop_idiom_vectorize_verify && CurLoop->getParentLoop()) {
957 CurLoop->getParentLoop()->verifyLoop();
958 if (!CurLoop->getParentLoop()->isRecursivelyLCSSAForm(*DT, *LI))
963bool LoopIdiomVectorize::recognizeFindFirstByte() {
968 if (!
TTI->supportsScalableVectors() || !
TTI->getMinPageSize().has_value() ||
969 Opts.disable_loop_idiom_vectorize_find_first_byte)
976 (std::numeric_limits<uint64_t>::max() / 2))
986 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 4 ||
987 CurLoop->getSubLoops().size() != 1)
990 auto *InnerLoop = CurLoop->getSubLoops().front();
995 if (!Hints.allowVectorization(InnerLoop,
false)) {
997 << InnerLoop->getName()
998 <<
" due to vectorization hints\n");
1007 auto LoopBlocks = CurLoop->getBlocks();
1008 if (LoopBlocks[0]->
size() > 3 || LoopBlocks[1]->
size() > 4 ||
1009 LoopBlocks[2]->
size() > 3 || LoopBlocks[3]->
size() > 3)
1029 !InnerLoop->contains(MatchBB))
1041 Value *LoadSearch, *LoadNeedle;
1089 if (InnerLoop->contains(PSearch))
1091 if (PSearch != &Header->front() || PNeedle != &MatchBB->
front())
1129 !CurLoop->contains(OuterBB))
1146 if (!CurLoop->isLoopInvariant(SearchStart) ||
1147 !CurLoop->isLoopInvariant(SearchEnd) ||
1148 !CurLoop->isLoopInvariant(NeedleStart) ||
1149 !CurLoop->isLoopInvariant(NeedleEnd))
1152 LLVM_DEBUG(
dbgs() <<
"Found idiom in loop: \n" << *CurLoop <<
"\n\n");
1154 transformFindFirstByte(IndPhi, VF, CharTy, ExitSucc, ExitFail, SearchStart,
1155 SearchEnd, NeedleStart, NeedleEnd);
1159Value *LoopIdiomVectorize::expandFindFirstByte(
1168 auto *ConstVF = ConstantInt::get(I64Ty, VF);
1171 BasicBlock *Preheader = CurLoop->getLoopPreheader();
1178 nullptr,
"scalar_preheader");
1213 auto OuterLoop = LI->AllocateLoop();
1214 auto InnerLoop = LI->AllocateLoop();
1216 if (
auto ParentLoop = CurLoop->getParentLoop()) {
1217 ParentLoop->addBasicBlockToLoop(BB0, *LI);
1218 ParentLoop->addChildLoop(OuterLoop);
1220 LI->addTopLevelLoop(OuterLoop);
1227 while (ExitLoop && !ExitLoop->
contains(ExitSucc))
1233 OuterLoop->addChildLoop(InnerLoop);
1236 OuterLoop->addBasicBlockToLoop(BB1, *LI);
1237 OuterLoop->addBasicBlockToLoop(BB3, *LI);
1238 OuterLoop->addBasicBlockToLoop(BB5, *LI);
1239 InnerLoop->addBasicBlockToLoop(BB2, *LI);
1250 Value *ISearchStart =
1255 Value *SearchTripCount =
1257 "search_trip_count"),
1259 Value *INeedleStart =
1264 Value *NeedleTripCount =
1266 "needle_trip_count"),
1269 Builder.
CreateIntrinsic(Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1270 {ConstantInt::get(I64Ty, 0), ConstVF});
1274 Value *SearchStartPage =
1275 Builder.
CreateLShr(ISearchStart, AddrShiftAmt,
"search_start_page");
1276 Value *SearchEndPage =
1277 Builder.
CreateLShr(ISearchEnd, AddrShiftAmt,
"search_end_page");
1278 Value *NeedleStartPage =
1279 Builder.
CreateLShr(INeedleStart, AddrShiftAmt,
"needle_start_page");
1280 Value *NeedleEndPage =
1281 Builder.
CreateLShr(INeedleEnd, AddrShiftAmt,
"needle_end_page");
1282 Value *SearchPageCmp =
1283 Builder.
CreateICmpNE(SearchStartPage, SearchEndPage,
"search_page_cmp");
1284 Value *NeedlePageCmp =
1285 Builder.
CreateICmpNE(NeedleStartPage, NeedleEndPage,
"needle_page_cmp");
1287 Value *CombinedPageCmp =
1288 Builder.
CreateOr(SearchPageCmp, NeedlePageCmp,
"combined_page_cmp");
1299 Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1300 {SearchIdx, SearchTripCount},
nullptr,
"search_pred");
1301 PredSearch = Builder.
CreateAnd(PredVF, PredSearch,
"search_masked");
1302 Value *Search = Builder.
CreateGEP(CharTy, SearchStart, SearchIdx,
"psearch");
1304 CharVTy, Search,
Align(1), PredSearch, Passthru,
"search_load_vec");
1316 Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1317 {NeedleIdx, NeedleTripCount},
nullptr,
"needle_pred");
1318 PredNeedle = Builder.
CreateAnd(PredVF, PredNeedle,
"needle_masked");
1319 Value *Needle = Builder.
CreateGEP(CharTy, NeedleStart, NeedleIdx,
"pneedle");
1321 CharVTy, Needle,
Align(1), PredNeedle, Passthru,
"needle_load_vec");
1327 Needle0,
"needle0");
1328 LoadNeedle = Builder.
CreateSelect(PredNeedle, LoadNeedle, Needle0Splat,
1335 Intrinsic::experimental_vector_match, {CharVTy, LoadNeedle->
getType()},
1336 {LoadSearch, LoadNeedle, PredSearch},
nullptr,
"match_segment");
1337 Value *MatchAcc = Builder.
CreateOr(Match, MatchSeg,
"match_accumulator");
1338 Value *NextNeedleIdx =
1339 Builder.
CreateAdd(NeedleIdx, ConstVF,
"needle_idx_next");
1359 Intrinsic::experimental_cttz_elts, {I64Ty, PredVTy},
1360 {MatchPredLCSSA, Builder.
getInt1(
true)},
nullptr,
1363 Builder.
CreateGEP(CharTy, MatchLCSSA, MatchCnt,
"match_res");
1369 Value *NextSearchIdx =
1370 Builder.
CreateAdd(SearchIdx, ConstVF,
"search_idx_next");
1386 MatchPredLCSSA->
addIncoming(MatchPredAccLCSSA, BB3);
1391 if (ExitSucc != ExitFail)
1394 if (Opts.loop_idiom_vectorize_verify) {
1395 OuterLoop->verifyLoop();
1396 InnerLoop->verifyLoop();
1397 if (!OuterLoop->isRecursivelyLCSSAForm(*DT, *LI))
1404void LoopIdiomVectorize::transformFindFirstByte(
1409 BasicBlock *Preheader = CurLoop->getLoopPreheader();
1416 expandFindFirstByte(Builder, DTU, VF, CharTy, IndPhi, ExitSucc, ExitFail,
1417 SearchStart, SearchEnd, NeedleStart, NeedleEnd);
1419 if (Opts.loop_idiom_vectorize_verify && CurLoop->getParentLoop()) {
1420 CurLoop->getParentLoop()->verifyLoop();
1421 if (!CurLoop->getParentLoop()->isRecursivelyLCSSAForm(*DT, *LI))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static void fixSuccessorPhis(Loop *L, Value *ScalarRes, Value *VectorRes, BasicBlock *SuccBB, BasicBlock *IncBB)
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.
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
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.
LLVM_ABI Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
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.
void disableGEPCanonicalization()
Disable canonicalization of getelementptr instructions to ptradd form.
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.
This class represents an analyzed expression in the program.
Class to represent scalable SIMD vectors.
static LLVM_ABI ScalableVectorType * get(Type *ElementType, unsigned MinNumElts)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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)
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.
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.
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
const VectorizeOptions & getVectorizeOptions(const LLVMContext &C)
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