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 runOnCountableLoop();
152 bool runOnLoopBlock(BasicBlock *BB,
const SCEV *BECount,
153 SmallVectorImpl<BasicBlock *> &ExitBlocks);
155 bool recognizeByteCompare();
158 GetElementPtrInst *GEPA, GetElementPtrInst *GEPB,
159 Instruction *Index,
Value *Start,
Value *MaxLen);
162 GetElementPtrInst *GEPA,
163 GetElementPtrInst *GEPB,
Value *ExtStart,
165 Value *createPredicatedFindMismatch(
IRBuilder<> &Builder, DomTreeUpdater &DTU,
166 GetElementPtrInst *GEPA,
167 GetElementPtrInst *GEPB,
Value *ExtStart,
170 void transformByteCompare(GetElementPtrInst *GEPA, GetElementPtrInst *GEPB,
171 PHINode *IndPhi,
Value *MaxLen, Instruction *Index,
172 Value *Start,
bool IncIdx, BasicBlock *FoundBB,
175 bool recognizeFindFirstByte();
178 unsigned VF,
Type *CharTy,
Value *IndPhi,
179 BasicBlock *ExitSucc, BasicBlock *ExitFail,
183 void transformFindFirstByte(PHINode *IndPhi,
unsigned VF,
Type *CharTy,
184 BasicBlock *ExitSucc, BasicBlock *ExitFail,
197 const auto *
DL = &L.getHeader()->getDataLayout();
203 unsigned BCVF = ByteCompareVF;
207 Function &
F = *L.getHeader()->getParent();
211 std::optional<OptimizationRemarkEmitter> ORELocal;
213 ORELocal.emplace(&
F);
217 LoopIdiomVectorize LIV(VecStyle, BCVF, &AR.
DT, &AR.
LI, &AR.
TTI,
DL, *ORE);
230bool LoopIdiomVectorize::run(
Loop *L) {
233 Function &
F = *L->getHeader()->getParent();
239 if (!Hints.allowVectorization(&
F, L,
false)) {
241 <<
" due to vectorization hints\n");
245 if (
F.hasFnAttribute(Attribute::NoImplicitFloat)) {
247 <<
" due to its NoImplicitFloat attribute");
253 if (!
L->getLoopPreheader())
257 << CurLoop->getHeader()->getName() <<
"\n");
259 if (recognizeByteCompare())
262 if (recognizeFindFirstByte())
274 for (
Value *
Op : PN.incoming_values())
275 if (
Op == ScalarRes) {
283 PN.addIncoming(VectorRes, IncBB);
291 if (L->contains(BB)) {
292 PN.addIncoming(PN.getIncomingValueForBlock(BB), IncBB);
299bool LoopIdiomVectorize::recognizeByteCompare() {
306 if (!
TTI->supportsScalableVectors() || !
TTI->getMinPageSize().has_value() ||
314 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 2)
321 auto LoopBlocks = CurLoop->getBlocks();
330 if (LoopBlocks[0]->
size() > 4)
344 if (LoopBlocks[1]->
size() > 7)
348 Value *StartIdx =
nullptr;
359 if (!Index || !
Index->getType()->isIntegerTy(32) ||
368 if (&
I != PN && &
I != Index)
376 if (!
match(Header->getTerminator(),
380 !CurLoop->contains(WhileBB))
387 Value *LoadA, *LoadB;
392 !CurLoop->contains(TrueBB))
414 if (!CurLoop->isLoopInvariant(PtrA) || !CurLoop->isLoopInvariant(PtrB) ||
453 if (FoundBB == EndBB) {
455 Value *WhileCondVal = EndPN.getIncomingValueForBlock(Header);
456 Value *WhileBodyVal = EndPN.getIncomingValueForBlock(WhileBB);
462 if (WhileCondVal != WhileBodyVal &&
463 ((WhileCondVal != Index && WhileCondVal != MaxLen) ||
464 (WhileBodyVal != Index)))
474 transformByteCompare(GEPA, GEPB, PN, MaxLen, Index, StartIdx,
true,
479Value *LoopIdiomVectorize::createMaskedFindMismatch(
492 Intrinsic::get_active_lane_mask, {PredVTy, I64Type}, {ExtStart, ExtEnd});
496 Builder.
CreateMul(VecLen, ConstantInt::get(I64Type, ByteCompareVF),
"",
502 Builder.
CreateBr(VectorLoopStartBlock);
505 VectorLoopStartBlock}});
510 PHINode *LoopPred = Builder.
CreatePHI(PredVTy, 2,
"mismatch_vec_loop_pred");
511 LoopPred->
addIncoming(InitialPred, VectorLoopPreheaderBlock);
512 PHINode *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vec_index");
513 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
514 Type *VectorLoadType =
518 Value *VectorLhsGep =
521 Align(1), LoopPred, Passthru);
523 Value *VectorRhsGep =
526 Align(1), LoopPred, Passthru);
529 VectorMatchCmp = Builder.
CreateSelect(LoopPred, VectorMatchCmp, PFalse);
531 Builder.
CreateCondBr(VectorMatchHasActiveLanes, VectorLoopMismatchBlock,
542 Value *NewVectorIndexPhi =
543 Builder.
CreateAdd(VectorIndexPhi, VecLen,
"",
545 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
548 {PredVTy, I64Type}, {NewVectorIndexPhi, ExtEnd});
549 LoopPred->
addIncoming(NewPred, VectorLoopIncBlock);
551 Value *PredHasActiveLanes =
553 Builder.
CreateCondBr(PredHasActiveLanes, VectorLoopStartBlock, EndBlock);
562 PHINode *FoundPred = Builder.
CreatePHI(PredVTy, 1,
"mismatch_vec_found_pred");
563 FoundPred->
addIncoming(VectorMatchCmp, VectorLoopStartBlock);
565 Builder.
CreatePHI(PredVTy, 1,
"mismatch_vec_last_loop_pred");
566 LastLoopPred->
addIncoming(LoopPred, VectorLoopStartBlock);
568 Builder.
CreatePHI(I64Type, 1,
"mismatch_vec_found_index");
569 VectorFoundIndex->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
574 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorFoundIndex, Ctz,
"",
576 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
579Value *LoopIdiomVectorize::createPredicatedFindMismatch(
584 Type *ResType = I32Type;
590 Builder.
Insert(JumpToVectorLoop);
593 VectorLoopStartBlock}});
598 auto *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vector_index");
599 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
602 Value *AVL = Builder.
CreateSub(ExtEnd, VectorIndexPhi,
"avl",
true,
606 auto *VF = ConstantInt::get(I32Type, ByteCompareVF);
609 {I64Type}, {AVL, VF, Builder.
getTrue()});
610 Value *GepOffset = VectorIndexPhi;
612 Value *VectorLhsGep =
618 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
619 {VectorLhsGep, AllTrueMask, VL},
nullptr,
"lhs.load");
621 Value *VectorRhsGep =
624 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
625 {VectorRhsGep, AllTrueMask, VL},
nullptr,
"rhs.load");
627 Value *VectorMatchCmp =
628 Builder.
CreateICmpNE(VectorLhsLoad, VectorRhsLoad,
"mismatch.cmp");
630 Intrinsic::vp_cttz_elts, {ResType, VectorMatchCmp->
getType()},
631 {VectorMatchCmp, Builder.
getInt1(
false), AllTrueMask,
635 MismatchFound, VectorLoopMismatchBlock, VectorLoopIncBlock);
636 Builder.
Insert(VectorEarlyExit);
647 Value *NewVectorIndexPhi =
648 Builder.
CreateAdd(VectorIndexPhi, VL64,
"",
650 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
652 auto *VectorLoopBranchBack =
654 Builder.
Insert(VectorLoopBranchBack);
666 CTZLCSSAPhi->
addIncoming(CTZ, VectorLoopStartBlock);
667 auto *VectorIndexLCSSAPhi =
669 VectorIndexLCSSAPhi->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
672 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorIndexLCSSAPhi, CTZI64,
"",
674 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
677Value *LoopIdiomVectorize::expandFindMismatch(
684 BasicBlock *Preheader = CurLoop->getLoopPreheader();
691 EndBlock =
SplitBlock(Preheader, PHBranch, DT, LI,
nullptr,
"mismatch_end");
707 Ctx,
"mismatch_min_it_check", EndBlock->getParent(), EndBlock);
713 Ctx,
"mismatch_mem_check", EndBlock->getParent(), EndBlock);
716 Ctx,
"mismatch_vec_loop_preheader", EndBlock->getParent(), EndBlock);
719 EndBlock->getParent(), EndBlock);
722 EndBlock->getParent(), EndBlock);
725 EndBlock->getParent(), EndBlock);
728 Ctx,
"mismatch_loop_pre", EndBlock->getParent(), EndBlock);
734 Ctx,
"mismatch_loop_inc", EndBlock->getParent(), EndBlock);
740 auto VectorLoop = LI->AllocateLoop();
741 auto ScalarLoop = LI->AllocateLoop();
743 if (CurLoop->getParentLoop()) {
744 CurLoop->getParentLoop()->addBasicBlockToLoop(MinItCheckBlock, *LI);
745 CurLoop->getParentLoop()->addBasicBlockToLoop(MemCheckBlock, *LI);
746 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopPreheaderBlock,
748 CurLoop->getParentLoop()->addChildLoop(VectorLoop);
749 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopMismatchBlock, *LI);
750 CurLoop->getParentLoop()->addBasicBlockToLoop(LoopPreHeaderBlock, *LI);
751 CurLoop->getParentLoop()->addChildLoop(ScalarLoop);
753 LI->addTopLevelLoop(VectorLoop);
754 LI->addTopLevelLoop(ScalarLoop);
758 VectorLoop->addBasicBlockToLoop(VectorLoopStartBlock, *LI);
759 VectorLoop->addBasicBlockToLoop(VectorLoopIncBlock, *LI);
761 ScalarLoop->addBasicBlockToLoop(LoopStartBlock, *LI);
762 ScalarLoop->addBasicBlockToLoop(LoopIncBlock, *LI);
776 MinItCheckBr->setMetadata(
777 LLVMContext::MD_prof,
779 Builder.
Insert(MinItCheckBr);
819 Value *CombinedPageCmp = Builder.
CreateOr(LhsPageCmp, RhsPageCmp);
821 CombinedPageCmp, LoopPreHeaderBlock, VectorLoopPreheaderBlock);
822 CombinedPageCmpCmpBr->setMetadata(
823 LLVMContext::MD_prof,
MDBuilder(CombinedPageCmpCmpBr->getContext())
825 Builder.
Insert(CombinedPageCmpCmpBr);
841 Value *VectorLoopRes =
nullptr;
842 switch (VectorizeStyle) {
845 createMaskedFindMismatch(Builder, DTU, GEPA, GEPB, ExtStart, ExtEnd);
848 VectorLoopRes = createPredicatedFindMismatch(Builder, DTU, GEPA, GEPB,
890 Value *PhiInc = Builder.
CreateAdd(IndexPhi, ConstantInt::get(ResType, 1),
"",
891 Index->hasNoUnsignedWrap(),
892 Index->hasNoSignedWrap());
907 Builder.
SetInsertPoint(EndBlock, EndBlock->getFirstInsertionPt());
912 ResPhi->
addIncoming(VectorLoopRes, VectorLoopMismatchBlock);
917 ScalarLoop->verifyLoop();
918 VectorLoop->verifyLoop();
919 if (!VectorLoop->isRecursivelyLCSSAForm(*DT, *LI))
921 if (!ScalarLoop->isRecursivelyLCSSAForm(*DT, *LI))
936 BasicBlock *Preheader = CurLoop->getLoopPreheader();
948 expandFindMismatch(Builder, DTU, GEPA, GEPB, Index, Start, MaxLen);
952 assert(IndPhi->
hasOneUse() &&
"Index phi node has more than one use!");
953 Index->replaceAllUsesWith(ByteCmpRes);
959 CmpBB->moveBefore(EndBB);
964 PHBranch->eraseFromParent();
972 if (FoundBB != EndBB) {
985 if (EndBB != FoundBB)
990 if (!CurLoop->isOutermost())
991 CurLoop->getParentLoop()->addBasicBlockToLoop(CmpBB, *LI);
994 CurLoop->getParentLoop()->verifyLoop();
995 if (!CurLoop->getParentLoop()->isRecursivelyLCSSAForm(*DT, *LI))
1000bool LoopIdiomVectorize::recognizeFindFirstByte() {
1005 if (!
TTI->supportsScalableVectors() || !
TTI->getMinPageSize().has_value() ||
1012 if (uint64_t(*
TTI->getMinPageSize()) >
1013 (std::numeric_limits<uint64_t>::max() / 2))
1023 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 4 ||
1024 CurLoop->getSubLoops().size() != 1)
1027 auto *InnerLoop = CurLoop->getSubLoops().front();
1032 if (!Hints.allowVectorization(&
F, InnerLoop,
1035 << InnerLoop->getName()
1036 <<
" due to vectorization hints\n");
1045 auto LoopBlocks = CurLoop->getBlocks();
1046 if (LoopBlocks[0]->
size() > 3 || LoopBlocks[1]->
size() > 4 ||
1047 LoopBlocks[2]->
size() > 3 || LoopBlocks[3]->
size() > 3)
1067 !InnerLoop->contains(MatchBB))
1079 Value *LoadSearch, *LoadNeedle;
1096 Value *Search, *Needle;
1129 if (InnerLoop->contains(PSearch))
1131 if (PSearch != &Header->front() || PNeedle != &MatchBB->
front())
1169 !CurLoop->contains(OuterBB))
1186 if (!CurLoop->isLoopInvariant(SearchStart) ||
1187 !CurLoop->isLoopInvariant(SearchEnd) ||
1188 !CurLoop->isLoopInvariant(NeedleStart) ||
1189 !CurLoop->isLoopInvariant(NeedleEnd))
1192 LLVM_DEBUG(
dbgs() <<
"Found idiom in loop: \n" << *CurLoop <<
"\n\n");
1194 transformFindFirstByte(IndPhi, VF, CharTy, ExitSucc, ExitFail, SearchStart,
1195 SearchEnd, NeedleStart, NeedleEnd);
1199Value *LoopIdiomVectorize::expandFindFirstByte(
1208 auto *ConstVF = ConstantInt::get(I64Ty, VF);
1211 BasicBlock *Preheader = CurLoop->getLoopPreheader();
1218 nullptr,
"scalar_preheader");
1253 auto OuterLoop = LI->AllocateLoop();
1254 auto InnerLoop = LI->AllocateLoop();
1256 if (
auto ParentLoop = CurLoop->getParentLoop()) {
1257 ParentLoop->addBasicBlockToLoop(BB0, *LI);
1258 ParentLoop->addChildLoop(OuterLoop);
1259 ParentLoop->addBasicBlockToLoop(BB4, *LI);
1261 LI->addTopLevelLoop(OuterLoop);
1265 OuterLoop->addChildLoop(InnerLoop);
1268 OuterLoop->addBasicBlockToLoop(BB1, *LI);
1269 OuterLoop->addBasicBlockToLoop(BB3, *LI);
1270 OuterLoop->addBasicBlockToLoop(BB5, *LI);
1271 InnerLoop->addBasicBlockToLoop(BB2, *LI);
1282 Value *ISearchStart =
1287 Value *SearchTripCount =
1289 "search_trip_count"),
1291 Value *INeedleStart =
1296 Value *NeedleTripCount =
1298 "needle_trip_count"),
1301 Builder.
CreateIntrinsic(Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1302 {ConstantInt::get(I64Ty, 0), ConstVF});
1306 Value *SearchStartPage =
1307 Builder.
CreateLShr(ISearchStart, AddrShiftAmt,
"search_start_page");
1308 Value *SearchEndPage =
1309 Builder.
CreateLShr(ISearchEnd, AddrShiftAmt,
"search_end_page");
1310 Value *NeedleStartPage =
1311 Builder.
CreateLShr(INeedleStart, AddrShiftAmt,
"needle_start_page");
1312 Value *NeedleEndPage =
1313 Builder.
CreateLShr(INeedleEnd, AddrShiftAmt,
"needle_end_page");
1314 Value *SearchPageCmp =
1315 Builder.
CreateICmpNE(SearchStartPage, SearchEndPage,
"search_page_cmp");
1316 Value *NeedlePageCmp =
1317 Builder.
CreateICmpNE(NeedleStartPage, NeedleEndPage,
"needle_page_cmp");
1319 Value *CombinedPageCmp =
1320 Builder.
CreateOr(SearchPageCmp, NeedlePageCmp,
"combined_page_cmp");
1322 CombinedPageBr->setMetadata(LLVMContext::MD_prof,
1331 Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1332 {SearchIdx, SearchTripCount},
nullptr,
"search_pred");
1333 PredSearch = Builder.
CreateAnd(PredVF, PredSearch,
"search_masked");
1334 Value *Search = Builder.
CreateGEP(CharTy, SearchStart, SearchIdx,
"psearch");
1336 CharVTy, Search,
Align(1), PredSearch, Passthru,
"search_load_vec");
1348 Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1349 {NeedleIdx, NeedleTripCount},
nullptr,
"needle_pred");
1350 PredNeedle = Builder.
CreateAnd(PredVF, PredNeedle,
"needle_masked");
1351 Value *Needle = Builder.
CreateGEP(CharTy, NeedleStart, NeedleIdx,
"pneedle");
1353 CharVTy, Needle,
Align(1), PredNeedle, Passthru,
"needle_load_vec");
1359 Needle0,
"needle0");
1360 LoadNeedle = Builder.
CreateSelect(PredNeedle, LoadNeedle, Needle0Splat,
1367 Intrinsic::experimental_vector_match, {CharVTy, LoadNeedle->
getType()},
1368 {LoadSearch, LoadNeedle, PredSearch},
nullptr,
"match_segment");
1369 Value *MatchAcc = Builder.
CreateOr(Match, MatchSeg,
"match_accumulator");
1370 Value *NextNeedleIdx =
1371 Builder.
CreateAdd(NeedleIdx, ConstVF,
"needle_idx_next");
1391 Intrinsic::experimental_cttz_elts, {I64Ty, PredVTy},
1392 {MatchPredLCSSA, Builder.
getInt1(
true)},
nullptr,
1395 Builder.
CreateGEP(CharTy, MatchLCSSA, MatchCnt,
"match_res");
1401 Value *NextSearchIdx =
1402 Builder.
CreateAdd(SearchIdx, ConstVF,
"search_idx_next");
1418 MatchPredLCSSA->
addIncoming(MatchPredAccLCSSA, BB3);
1423 if (ExitSucc != ExitFail)
1427 OuterLoop->verifyLoop();
1428 InnerLoop->verifyLoop();
1429 if (!OuterLoop->isRecursivelyLCSSAForm(*DT, *LI))
1436void LoopIdiomVectorize::transformFindFirstByte(
1441 BasicBlock *Preheader = CurLoop->getLoopPreheader();
1447 expandFindFirstByte(Builder, DTU, VF, CharTy, IndPhi, ExitSucc, ExitFail,
1448 SearchStart, SearchEnd, NeedleStart, NeedleEnd);
1451 CurLoop->getParentLoop()->verifyLoop();
1452 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.
static bool isSimple(Instruction *I)
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 if the block is well formed or null if the block is not well forme...
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="")
CallInst * CreateExtractVector(Type *DstType, Value *SrcVec, Value *Idx, const Twine &Name="")
Create a call to the vector.extract intrinsic.
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)
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreateVScale(Type *Ty, const Twine &Name="")
Create a call to llvm.vscale.<Ty>().
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
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())
LLVM_ABI CallInst * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
UncondBrInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
LLVM_ABI CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
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="")
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...
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.
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.
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_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.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
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.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
class_match< BasicBlock > m_BasicBlock()
Match an arbitrary basic block value and ignore it.
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.
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.
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
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