84#define DEBUG_TYPE "loop-idiom-vectorize"
87class LoopIdiomVectorize {
88 const VectorizeOptions &Opts;
90 unsigned ByteCompareVF;
91 Loop *CurLoop =
nullptr;
102 BasicBlock *VectorLoopPreheaderBlock =
nullptr;
104 BasicBlock *VectorLoopMismatchBlock =
nullptr;
112 : Opts(Opts), VectorizeStyle(S), ByteCompareVF(VF), DT(DT), LI(LI),
124 bool recognizeByteCompare();
144 bool recognizeFindFirstByte();
147 unsigned VF,
Type *CharTy,
Value *IndPhi,
152 void transformFindFirstByte(
PHINode *IndPhi,
unsigned VF,
Type *CharTy,
163 const VectorizeOptions &Opts =
164 L.getHeader()->getContext().getLibraryOptions().get<VectorizeOptions>();
165 if (Opts.disable_loop_idiom_vectorize_all)
168 const auto *
DL = &L.getHeader()->getDataLayout();
171 Opts.loop_idiom_vectorize_style.value_or(VectorizeStyle);
172 unsigned BCVF = Opts.loop_idiom_vectorize_bytecmp_vf.value_or(ByteCompareVF);
174 Function &
F = *L.getHeader()->getParent();
178 std::optional<OptimizationRemarkEmitter> ORELocal;
180 ORELocal.emplace(&
F);
184 LoopIdiomVectorize LIV(Opts, VecStyle, BCVF, &AR.
DT, &AR.
LI, &AR.
TTI,
DL,
198bool LoopIdiomVectorize::run(
Loop *L) {
201 Function &
F = *L->getHeader()->getParent();
202 if (Opts.disable_loop_idiom_vectorize_all ||
F.hasOptSize())
207 if (!Hints.allowVectorization(&
F, L,
false)) {
209 <<
" due to vectorization hints\n");
213 if (
F.hasFnAttribute(Attribute::NoImplicitFloat)) {
215 <<
" due to its NoImplicitFloat attribute");
221 if (!
L->getLoopPreheader())
225 << CurLoop->getHeader()->getName() <<
"\n");
227 if (recognizeByteCompare())
230 if (recognizeFindFirstByte())
242 for (
Value *
Op : PN.incoming_values())
243 if (
Op == ScalarRes) {
251 PN.addIncoming(VectorRes, IncBB);
259 if (L->contains(BB)) {
260 PN.addIncoming(PN.getIncomingValueForBlock(BB), IncBB);
267bool LoopIdiomVectorize::recognizeByteCompare() {
274 if (!
TTI->supportsScalableVectors() || !
TTI->getMinPageSize().has_value() ||
275 Opts.disable_loop_idiom_vectorize_bytecmp)
282 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 2)
289 auto LoopBlocks = CurLoop->getBlocks();
298 if (LoopBlocks[0]->
size() > 4)
312 if (LoopBlocks[1]->
size() > 7)
316 Value *StartIdx =
nullptr;
327 if (!Index || !
Index->getType()->isIntegerTy(32) ||
336 if (&
I != PN && &
I != Index)
344 if (!
match(Header->getTerminator(),
348 !CurLoop->contains(WhileBB))
355 Value *LoadA, *LoadB;
360 !CurLoop->contains(TrueBB))
382 if (!CurLoop->isLoopInvariant(PtrA) || !CurLoop->isLoopInvariant(PtrB) ||
421 if (FoundBB == EndBB) {
423 Value *WhileCondVal = EndPN.getIncomingValueForBlock(Header);
424 Value *WhileBodyVal = EndPN.getIncomingValueForBlock(WhileBB);
430 if (WhileCondVal != WhileBodyVal &&
431 ((WhileCondVal != Index && WhileCondVal != MaxLen) ||
432 (WhileBodyVal != Index)))
442 transformByteCompare(GEPA, GEPB, PN, MaxLen, Index, StartIdx,
true,
447Value *LoopIdiomVectorize::createMaskedFindMismatch(
460 Intrinsic::get_active_lane_mask, {PredVTy, I64Type}, {ExtStart, ExtEnd});
464 Builder.
CreateMul(VecLen, ConstantInt::get(I64Type, ByteCompareVF),
"",
470 Builder.
CreateBr(VectorLoopStartBlock);
473 VectorLoopStartBlock}});
478 PHINode *LoopPred = Builder.
CreatePHI(PredVTy, 2,
"mismatch_vec_loop_pred");
479 LoopPred->
addIncoming(InitialPred, VectorLoopPreheaderBlock);
480 PHINode *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vec_index");
481 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
482 Type *VectorLoadType =
486 Value *VectorLhsGep =
489 Align(1), LoopPred, Passthru);
491 Value *VectorRhsGep =
494 Align(1), LoopPred, Passthru);
497 VectorMatchCmp = Builder.
CreateSelect(LoopPred, VectorMatchCmp, PFalse);
499 Builder.
CreateCondBr(VectorMatchHasActiveLanes, VectorLoopMismatchBlock,
510 Value *NewVectorIndexPhi =
511 Builder.
CreateAdd(VectorIndexPhi, VecLen,
"",
513 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
516 {PredVTy, I64Type}, {NewVectorIndexPhi, ExtEnd});
517 LoopPred->
addIncoming(NewPred, VectorLoopIncBlock);
519 Value *PredHasActiveLanes =
521 Builder.
CreateCondBr(PredHasActiveLanes, VectorLoopStartBlock, EndBlock);
530 PHINode *FoundPred = Builder.
CreatePHI(PredVTy, 1,
"mismatch_vec_found_pred");
531 FoundPred->
addIncoming(VectorMatchCmp, VectorLoopStartBlock);
533 Builder.
CreatePHI(PredVTy, 1,
"mismatch_vec_last_loop_pred");
534 LastLoopPred->
addIncoming(LoopPred, VectorLoopStartBlock);
536 Builder.
CreatePHI(I64Type, 1,
"mismatch_vec_found_index");
537 VectorFoundIndex->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
542 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorFoundIndex, Ctz,
"",
544 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
547Value *LoopIdiomVectorize::createPredicatedFindMismatch(
552 Type *ResType = I32Type;
558 Builder.
Insert(JumpToVectorLoop);
561 VectorLoopStartBlock}});
566 auto *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vector_index");
567 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
570 Value *AVL = Builder.
CreateSub(ExtEnd, VectorIndexPhi,
"avl",
true,
574 auto *VF = ConstantInt::get(I32Type, ByteCompareVF);
577 {I64Type}, {AVL, VF, Builder.
getTrue()});
578 Value *GepOffset = VectorIndexPhi;
580 Value *VectorLhsGep =
586 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
587 {VectorLhsGep, AllTrueMask, VL},
nullptr,
"lhs.load");
589 Value *VectorRhsGep =
592 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
593 {VectorRhsGep, AllTrueMask, VL},
nullptr,
"rhs.load");
595 Value *VectorMatchCmp =
596 Builder.
CreateICmpNE(VectorLhsLoad, VectorRhsLoad,
"mismatch.cmp");
598 Intrinsic::vp_cttz_elts, {ResType, VectorMatchCmp->
getType()},
599 {VectorMatchCmp, Builder.
getInt1(
false), AllTrueMask,
603 MismatchFound, VectorLoopMismatchBlock, VectorLoopIncBlock);
604 Builder.
Insert(VectorEarlyExit);
615 Value *NewVectorIndexPhi =
616 Builder.
CreateAdd(VectorIndexPhi, VL64,
"",
618 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
620 auto *VectorLoopBranchBack =
622 Builder.
Insert(VectorLoopBranchBack);
634 CTZLCSSAPhi->
addIncoming(CTZ, VectorLoopStartBlock);
635 auto *VectorIndexLCSSAPhi =
637 VectorIndexLCSSAPhi->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
640 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorIndexLCSSAPhi, CTZI64,
"",
642 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
645Value *LoopIdiomVectorize::expandFindMismatch(
652 BasicBlock *Preheader = CurLoop->getLoopPreheader();
659 EndBlock =
SplitBlock(Preheader, PHBranch, DT, LI,
nullptr,
"mismatch_end");
675 Ctx,
"mismatch_min_it_check", EndBlock->getParent(), EndBlock);
681 Ctx,
"mismatch_mem_check", EndBlock->getParent(), EndBlock);
684 Ctx,
"mismatch_vec_loop_preheader", EndBlock->getParent(), EndBlock);
687 EndBlock->getParent(), EndBlock);
690 EndBlock->getParent(), EndBlock);
693 EndBlock->getParent(), EndBlock);
696 Ctx,
"mismatch_loop_pre", EndBlock->getParent(), EndBlock);
702 Ctx,
"mismatch_loop_inc", EndBlock->getParent(), EndBlock);
708 auto VectorLoop = LI->AllocateLoop();
709 auto ScalarLoop = LI->AllocateLoop();
711 if (CurLoop->getParentLoop()) {
712 CurLoop->getParentLoop()->addBasicBlockToLoop(MinItCheckBlock, *LI);
713 CurLoop->getParentLoop()->addBasicBlockToLoop(MemCheckBlock, *LI);
714 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopPreheaderBlock,
716 CurLoop->getParentLoop()->addChildLoop(VectorLoop);
717 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopMismatchBlock, *LI);
718 CurLoop->getParentLoop()->addBasicBlockToLoop(LoopPreHeaderBlock, *LI);
719 CurLoop->getParentLoop()->addChildLoop(ScalarLoop);
721 LI->addTopLevelLoop(VectorLoop);
722 LI->addTopLevelLoop(ScalarLoop);
726 VectorLoop->addBasicBlockToLoop(VectorLoopStartBlock, *LI);
727 VectorLoop->addBasicBlockToLoop(VectorLoopIncBlock, *LI);
729 ScalarLoop->addBasicBlockToLoop(LoopStartBlock, *LI);
730 ScalarLoop->addBasicBlockToLoop(LoopIncBlock, *LI);
745 LLVMContext::MD_prof,
747 Builder.
Insert(MinItCheckBr);
787 Value *CombinedPageCmp = Builder.
CreateOr(LhsPageCmp, RhsPageCmp);
789 CombinedPageCmp, LoopPreHeaderBlock, VectorLoopPreheaderBlock);
793 Builder.
Insert(CombinedPageCmpCmpBr);
809 Value *VectorLoopRes =
nullptr;
810 switch (VectorizeStyle) {
813 createMaskedFindMismatch(Builder, DTU, GEPA, GEPB, ExtStart, ExtEnd);
816 VectorLoopRes = createPredicatedFindMismatch(Builder, DTU, GEPA, GEPB,
858 Value *PhiInc = Builder.
CreateAdd(IndexPhi, ConstantInt::get(ResType, 1),
"",
859 Index->hasNoUnsignedWrap(),
860 Index->hasNoSignedWrap());
880 ResPhi->
addIncoming(VectorLoopRes, VectorLoopMismatchBlock);
884 if (Opts.loop_idiom_vectorize_verify) {
885 ScalarLoop->verifyLoop();
886 VectorLoop->verifyLoop();
887 if (!VectorLoop->isRecursivelyLCSSAForm(*DT, *LI))
889 if (!ScalarLoop->isRecursivelyLCSSAForm(*DT, *LI))
904 BasicBlock *Preheader = CurLoop->getLoopPreheader();
916 expandFindMismatch(Builder, DTU, GEPA, GEPB, Index, Start, MaxLen);
920 assert(IndPhi->
hasOneUse() &&
"Index phi node has more than one use!");
921 Index->replaceAllUsesWith(ByteCmpRes);
927 CmpBB->moveBefore(EndBB);
940 if (FoundBB != EndBB) {
953 if (EndBB != FoundBB)
958 if (!CurLoop->isOutermost())
959 CurLoop->getParentLoop()->addBasicBlockToLoop(CmpBB, *LI);
961 if (Opts.loop_idiom_vectorize_verify && CurLoop->getParentLoop()) {
962 CurLoop->getParentLoop()->verifyLoop();
963 if (!CurLoop->getParentLoop()->isRecursivelyLCSSAForm(*DT, *LI))
968bool LoopIdiomVectorize::recognizeFindFirstByte() {
973 if (!
TTI->supportsScalableVectors() || !
TTI->getMinPageSize().has_value() ||
974 Opts.disable_loop_idiom_vectorize_find_first_byte)
981 (std::numeric_limits<uint64_t>::max() / 2))
991 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 4 ||
992 CurLoop->getSubLoops().size() != 1)
995 auto *InnerLoop = CurLoop->getSubLoops().front();
1001 if (!Hints.allowVectorization(&
F, InnerLoop,
1004 << InnerLoop->getName()
1005 <<
" due to vectorization hints\n");
1014 auto LoopBlocks = CurLoop->getBlocks();
1015 if (LoopBlocks[0]->
size() > 3 || LoopBlocks[1]->
size() > 4 ||
1016 LoopBlocks[2]->
size() > 3 || LoopBlocks[3]->
size() > 3)
1036 !InnerLoop->contains(MatchBB))
1048 Value *LoadSearch, *LoadNeedle;
1096 if (InnerLoop->contains(PSearch))
1098 if (PSearch != &Header->front() || PNeedle != &MatchBB->
front())
1136 !CurLoop->contains(OuterBB))
1153 if (!CurLoop->isLoopInvariant(SearchStart) ||
1154 !CurLoop->isLoopInvariant(SearchEnd) ||
1155 !CurLoop->isLoopInvariant(NeedleStart) ||
1156 !CurLoop->isLoopInvariant(NeedleEnd))
1159 LLVM_DEBUG(
dbgs() <<
"Found idiom in loop: \n" << *CurLoop <<
"\n\n");
1161 transformFindFirstByte(IndPhi, VF, CharTy, ExitSucc, ExitFail, SearchStart,
1162 SearchEnd, NeedleStart, NeedleEnd);
1166Value *LoopIdiomVectorize::expandFindFirstByte(
1175 auto *ConstVF = ConstantInt::get(I64Ty, VF);
1178 BasicBlock *Preheader = CurLoop->getLoopPreheader();
1185 nullptr,
"scalar_preheader");
1220 auto OuterLoop = LI->AllocateLoop();
1221 auto InnerLoop = LI->AllocateLoop();
1223 if (
auto ParentLoop = CurLoop->getParentLoop()) {
1224 ParentLoop->addBasicBlockToLoop(BB0, *LI);
1225 ParentLoop->addChildLoop(OuterLoop);
1227 LI->addTopLevelLoop(OuterLoop);
1234 while (ExitLoop && !ExitLoop->
contains(ExitSucc))
1240 OuterLoop->addChildLoop(InnerLoop);
1243 OuterLoop->addBasicBlockToLoop(BB1, *LI);
1244 OuterLoop->addBasicBlockToLoop(BB3, *LI);
1245 OuterLoop->addBasicBlockToLoop(BB5, *LI);
1246 InnerLoop->addBasicBlockToLoop(BB2, *LI);
1257 Value *ISearchStart =
1262 Value *SearchTripCount =
1264 "search_trip_count"),
1266 Value *INeedleStart =
1271 Value *NeedleTripCount =
1273 "needle_trip_count"),
1276 Builder.
CreateIntrinsic(Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1277 {ConstantInt::get(I64Ty, 0), ConstVF});
1281 Value *SearchStartPage =
1282 Builder.
CreateLShr(ISearchStart, AddrShiftAmt,
"search_start_page");
1283 Value *SearchEndPage =
1284 Builder.
CreateLShr(ISearchEnd, AddrShiftAmt,
"search_end_page");
1285 Value *NeedleStartPage =
1286 Builder.
CreateLShr(INeedleStart, AddrShiftAmt,
"needle_start_page");
1287 Value *NeedleEndPage =
1288 Builder.
CreateLShr(INeedleEnd, AddrShiftAmt,
"needle_end_page");
1289 Value *SearchPageCmp =
1290 Builder.
CreateICmpNE(SearchStartPage, SearchEndPage,
"search_page_cmp");
1291 Value *NeedlePageCmp =
1292 Builder.
CreateICmpNE(NeedleStartPage, NeedleEndPage,
"needle_page_cmp");
1294 Value *CombinedPageCmp =
1295 Builder.
CreateOr(SearchPageCmp, NeedlePageCmp,
"combined_page_cmp");
1306 Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1307 {SearchIdx, SearchTripCount},
nullptr,
"search_pred");
1308 PredSearch = Builder.
CreateAnd(PredVF, PredSearch,
"search_masked");
1309 Value *Search = Builder.
CreateGEP(CharTy, SearchStart, SearchIdx,
"psearch");
1311 CharVTy, Search,
Align(1), PredSearch, Passthru,
"search_load_vec");
1323 Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1324 {NeedleIdx, NeedleTripCount},
nullptr,
"needle_pred");
1325 PredNeedle = Builder.
CreateAnd(PredVF, PredNeedle,
"needle_masked");
1326 Value *Needle = Builder.
CreateGEP(CharTy, NeedleStart, NeedleIdx,
"pneedle");
1328 CharVTy, Needle,
Align(1), PredNeedle, Passthru,
"needle_load_vec");
1334 Needle0,
"needle0");
1335 LoadNeedle = Builder.
CreateSelect(PredNeedle, LoadNeedle, Needle0Splat,
1342 Intrinsic::experimental_vector_match, {CharVTy, LoadNeedle->
getType()},
1343 {LoadSearch, LoadNeedle, PredSearch},
nullptr,
"match_segment");
1344 Value *MatchAcc = Builder.
CreateOr(Match, MatchSeg,
"match_accumulator");
1345 Value *NextNeedleIdx =
1346 Builder.
CreateAdd(NeedleIdx, ConstVF,
"needle_idx_next");
1366 Intrinsic::experimental_cttz_elts, {I64Ty, PredVTy},
1367 {MatchPredLCSSA, Builder.
getInt1(
true)},
nullptr,
1370 Builder.
CreateGEP(CharTy, MatchLCSSA, MatchCnt,
"match_res");
1376 Value *NextSearchIdx =
1377 Builder.
CreateAdd(SearchIdx, ConstVF,
"search_idx_next");
1393 MatchPredLCSSA->
addIncoming(MatchPredAccLCSSA, BB3);
1398 if (ExitSucc != ExitFail)
1401 if (Opts.loop_idiom_vectorize_verify) {
1402 OuterLoop->verifyLoop();
1403 InnerLoop->verifyLoop();
1404 if (!OuterLoop->isRecursivelyLCSSAForm(*DT, *LI))
1411void LoopIdiomVectorize::transformFindFirstByte(
1416 BasicBlock *Preheader = CurLoop->getLoopPreheader();
1422 expandFindFirstByte(Builder, DTU, VF, CharTy, IndPhi, ExitSucc, ExitFail,
1423 SearchStart, SearchEnd, NeedleStart, NeedleEnd);
1425 if (Opts.loop_idiom_vectorize_verify && CurLoop->getParentLoop()) {
1426 CurLoop->getParentLoop()->verifyLoop();
1427 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")
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.
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.
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
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