LLVM 22.0.0git
LoopIdiomVectorize.cpp
Go to the documentation of this file.
1//===-------- LoopIdiomVectorize.cpp - Loop idiom vectorization -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass implements a pass that recognizes certain loop idioms and
10// transforms them into more optimized versions of the same loop. In cases
11// where this happens, it can be a significant performance win.
12//
13// We currently support two loops:
14//
15// 1. A loop that finds the first mismatched byte in an array and returns the
16// index, i.e. something like:
17//
18// while (++i != n) {
19// if (a[i] != b[i])
20// break;
21// }
22//
23// In this example we can actually vectorize the loop despite the early exit,
24// although the loop vectorizer does not support it. It requires some extra
25// checks to deal with the possibility of faulting loads when crossing page
26// boundaries. However, even with these checks it is still profitable to do the
27// transformation.
28//
29// TODO List:
30//
31// * Add support for the inverse case where we scan for a matching element.
32// * Permit 64-bit induction variable types.
33// * Recognize loops that increment the IV *after* comparing bytes.
34// * Allow 32-bit sign-extends of the IV used by the GEP.
35//
36// 2. A loop that finds the first matching character in an array among a set of
37// possible matches, e.g.:
38//
39// for (; first != last; ++first)
40// for (s_it = s_first; s_it != s_last; ++s_it)
41// if (*first == *s_it)
42// return first;
43// return last;
44//
45// This corresponds to std::find_first_of (for arrays of bytes) from the C++
46// standard library. This function can be implemented efficiently for targets
47// that support @llvm.experimental.vector.match. For example, on AArch64 targets
48// that implement SVE2, this lower to a MATCH instruction, which enables us to
49// perform up to 16x16=256 comparisons in one go. This can lead to very
50// significant speedups.
51//
52// TODO:
53//
54// * Add support for `find_first_not_of' loops (i.e. with not-equal comparison).
55// * Make VF a configurable parameter (right now we assume 128-bit vectors).
56// * Potentially adjust the cost model to let the transformation kick-in even if
57// @llvm.experimental.vector.match doesn't have direct support in hardware.
58//
59//===----------------------------------------------------------------------===//
60//
61// NOTE: This Pass matches really specific loop patterns because it's only
62// supposed to be a temporary solution until our LoopVectorizer is powerful
63// enough to vectorize them automatically.
64//
65//===----------------------------------------------------------------------===//
66
71#include "llvm/IR/Dominators.h"
72#include "llvm/IR/IRBuilder.h"
73#include "llvm/IR/Intrinsics.h"
74#include "llvm/IR/MDBuilder.h"
77
78using namespace llvm;
79using namespace PatternMatch;
80
81#define DEBUG_TYPE "loop-idiom-vectorize"
82
83static cl::opt<bool> DisableAll("disable-loop-idiom-vectorize-all", cl::Hidden,
84 cl::init(false),
85 cl::desc("Disable Loop Idiom Vectorize Pass."));
86
88 LITVecStyle("loop-idiom-vectorize-style", cl::Hidden,
89 cl::desc("The vectorization style for loop idiom transform."),
91 "Use masked vector intrinsics"),
93 "predicated", "Use VP intrinsics")),
95
96static cl::opt<bool>
97 DisableByteCmp("disable-loop-idiom-vectorize-bytecmp", cl::Hidden,
98 cl::init(false),
99 cl::desc("Proceed with Loop Idiom Vectorize Pass, but do "
100 "not convert byte-compare loop(s)."));
101
103 ByteCmpVF("loop-idiom-vectorize-bytecmp-vf", cl::Hidden,
104 cl::desc("The vectorization factor for byte-compare patterns."),
105 cl::init(16));
106
107static cl::opt<bool>
108 DisableFindFirstByte("disable-loop-idiom-vectorize-find-first-byte",
109 cl::Hidden, cl::init(false),
110 cl::desc("Do not convert find-first-byte loop(s)."));
111
112static cl::opt<bool>
113 VerifyLoops("loop-idiom-vectorize-verify", cl::Hidden, cl::init(false),
114 cl::desc("Verify loops generated Loop Idiom Vectorize Pass."));
115
116namespace {
117class LoopIdiomVectorize {
118 LoopIdiomVectorizeStyle VectorizeStyle;
119 unsigned ByteCompareVF;
120 Loop *CurLoop = nullptr;
121 DominatorTree *DT;
122 LoopInfo *LI;
124 const DataLayout *DL;
125
126 // Blocks that will be used for inserting vectorized code.
127 BasicBlock *EndBlock = nullptr;
128 BasicBlock *VectorLoopPreheaderBlock = nullptr;
129 BasicBlock *VectorLoopStartBlock = nullptr;
130 BasicBlock *VectorLoopMismatchBlock = nullptr;
131 BasicBlock *VectorLoopIncBlock = nullptr;
132
133public:
134 LoopIdiomVectorize(LoopIdiomVectorizeStyle S, unsigned VF, DominatorTree *DT,
135 LoopInfo *LI, const TargetTransformInfo *TTI,
136 const DataLayout *DL)
137 : VectorizeStyle(S), ByteCompareVF(VF), DT(DT), LI(LI), TTI(TTI), DL(DL) {
138 }
139
140 bool run(Loop *L);
141
142private:
143 /// \name Countable Loop Idiom Handling
144 /// @{
145
146 bool runOnCountableLoop();
147 bool runOnLoopBlock(BasicBlock *BB, const SCEV *BECount,
148 SmallVectorImpl<BasicBlock *> &ExitBlocks);
149
150 bool recognizeByteCompare();
151
152 Value *expandFindMismatch(IRBuilder<> &Builder, DomTreeUpdater &DTU,
153 GetElementPtrInst *GEPA, GetElementPtrInst *GEPB,
154 Instruction *Index, Value *Start, Value *MaxLen);
155
156 Value *createMaskedFindMismatch(IRBuilder<> &Builder, DomTreeUpdater &DTU,
157 GetElementPtrInst *GEPA,
158 GetElementPtrInst *GEPB, Value *ExtStart,
159 Value *ExtEnd);
160 Value *createPredicatedFindMismatch(IRBuilder<> &Builder, DomTreeUpdater &DTU,
161 GetElementPtrInst *GEPA,
162 GetElementPtrInst *GEPB, Value *ExtStart,
163 Value *ExtEnd);
164
165 void transformByteCompare(GetElementPtrInst *GEPA, GetElementPtrInst *GEPB,
166 PHINode *IndPhi, Value *MaxLen, Instruction *Index,
167 Value *Start, bool IncIdx, BasicBlock *FoundBB,
168 BasicBlock *EndBB);
169
170 bool recognizeFindFirstByte();
171
172 Value *expandFindFirstByte(IRBuilder<> &Builder, DomTreeUpdater &DTU,
173 unsigned VF, Type *CharTy, Value *IndPhi,
174 BasicBlock *ExitSucc, BasicBlock *ExitFail,
175 Value *SearchStart, Value *SearchEnd,
176 Value *NeedleStart, Value *NeedleEnd);
177
178 void transformFindFirstByte(PHINode *IndPhi, unsigned VF, Type *CharTy,
179 BasicBlock *ExitSucc, BasicBlock *ExitFail,
180 Value *SearchStart, Value *SearchEnd,
181 Value *NeedleStart, Value *NeedleEnd);
182 /// @}
183};
184} // anonymous namespace
185
188 LPMUpdater &) {
189 if (DisableAll)
190 return PreservedAnalyses::all();
191
192 const auto *DL = &L.getHeader()->getDataLayout();
193
194 LoopIdiomVectorizeStyle VecStyle = VectorizeStyle;
195 if (LITVecStyle.getNumOccurrences())
196 VecStyle = LITVecStyle;
197
198 unsigned BCVF = ByteCompareVF;
199 if (ByteCmpVF.getNumOccurrences())
200 BCVF = ByteCmpVF;
201
202 LoopIdiomVectorize LIV(VecStyle, BCVF, &AR.DT, &AR.LI, &AR.TTI, DL);
203 if (!LIV.run(&L))
204 return PreservedAnalyses::all();
205
207}
208
209//===----------------------------------------------------------------------===//
210//
211// Implementation of LoopIdiomVectorize
212//
213//===----------------------------------------------------------------------===//
214
215bool LoopIdiomVectorize::run(Loop *L) {
216 CurLoop = L;
217
218 Function &F = *L->getHeader()->getParent();
219 if (DisableAll || F.hasOptSize())
220 return false;
221
222 if (F.hasFnAttribute(Attribute::NoImplicitFloat)) {
223 LLVM_DEBUG(dbgs() << DEBUG_TYPE << " is disabled on " << F.getName()
224 << " due to its NoImplicitFloat attribute");
225 return false;
226 }
227
228 // If the loop could not be converted to canonical form, it must have an
229 // indirectbr in it, just give up.
230 if (!L->getLoopPreheader())
231 return false;
232
233 LLVM_DEBUG(dbgs() << DEBUG_TYPE " Scanning: F[" << F.getName() << "] Loop %"
234 << CurLoop->getHeader()->getName() << "\n");
235
236 if (recognizeByteCompare())
237 return true;
238
239 if (recognizeFindFirstByte())
240 return true;
241
242 return false;
243}
244
245static void fixSuccessorPhis(Loop *L, Value *ScalarRes, Value *VectorRes,
246 BasicBlock *SuccBB, BasicBlock *IncBB) {
247 for (PHINode &PN : SuccBB->phis()) {
248 // Look through the incoming values to find ScalarRes, meaning this is a
249 // PHI collecting the results of the transformation.
250 bool ResPhi = false;
251 for (Value *Op : PN.incoming_values())
252 if (Op == ScalarRes) {
253 ResPhi = true;
254 break;
255 }
256
257 // Any PHI that depended upon the result of the transformation needs a new
258 // incoming value from IncBB.
259 if (ResPhi)
260 PN.addIncoming(VectorRes, IncBB);
261 else {
262 // There should be no other outside uses of other values in the
263 // original loop. Any incoming values should either:
264 // 1. Be for blocks outside the loop, which aren't interesting. Or ..
265 // 2. These are from blocks in the loop with values defined outside
266 // the loop. We should a similar incoming value from CmpBB.
267 for (BasicBlock *BB : PN.blocks())
268 if (L->contains(BB)) {
269 PN.addIncoming(PN.getIncomingValueForBlock(BB), IncBB);
270 break;
271 }
272 }
273 }
274}
275
276bool LoopIdiomVectorize::recognizeByteCompare() {
277 // Currently the transformation only works on scalable vector types, although
278 // there is no fundamental reason why it cannot be made to work for fixed
279 // width too.
280
281 // We also need to know the minimum page size for the target in order to
282 // generate runtime memory checks to ensure the vector version won't fault.
283 if (!TTI->supportsScalableVectors() || !TTI->getMinPageSize().has_value() ||
285 return false;
286
287 BasicBlock *Header = CurLoop->getHeader();
288
289 // In LoopIdiomVectorize::run we have already checked that the loop
290 // has a preheader so we can assume it's in a canonical form.
291 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 2)
292 return false;
293
294 PHINode *PN = dyn_cast<PHINode>(&Header->front());
295 if (!PN || PN->getNumIncomingValues() != 2)
296 return false;
297
298 auto LoopBlocks = CurLoop->getBlocks();
299 // The first block in the loop should contain only 4 instructions, e.g.
300 //
301 // while.cond:
302 // %res.phi = phi i32 [ %start, %ph ], [ %inc, %while.body ]
303 // %inc = add i32 %res.phi, 1
304 // %cmp.not = icmp eq i32 %inc, %n
305 // br i1 %cmp.not, label %while.end, label %while.body
306 //
307 if (LoopBlocks[0]->sizeWithoutDebug() > 4)
308 return false;
309
310 // The second block should contain 7 instructions, e.g.
311 //
312 // while.body:
313 // %idx = zext i32 %inc to i64
314 // %idx.a = getelementptr inbounds i8, ptr %a, i64 %idx
315 // %load.a = load i8, ptr %idx.a
316 // %idx.b = getelementptr inbounds i8, ptr %b, i64 %idx
317 // %load.b = load i8, ptr %idx.b
318 // %cmp.not.ld = icmp eq i8 %load.a, %load.b
319 // br i1 %cmp.not.ld, label %while.cond, label %while.end
320 //
321 if (LoopBlocks[1]->sizeWithoutDebug() > 7)
322 return false;
323
324 // The incoming value to the PHI node from the loop should be an add of 1.
325 Value *StartIdx = nullptr;
326 Instruction *Index = nullptr;
327 if (!CurLoop->contains(PN->getIncomingBlock(0))) {
328 StartIdx = PN->getIncomingValue(0);
330 } else {
331 StartIdx = PN->getIncomingValue(1);
333 }
334
335 // Limit to 32-bit types for now
336 if (!Index || !Index->getType()->isIntegerTy(32) ||
337 !match(Index, m_c_Add(m_Specific(PN), m_One())))
338 return false;
339
340 // If we match the pattern, PN and Index will be replaced with the result of
341 // the cttz.elts intrinsic. If any other instructions are used outside of
342 // the loop, we cannot replace it.
343 for (BasicBlock *BB : LoopBlocks)
344 for (Instruction &I : *BB)
345 if (&I != PN && &I != Index)
346 for (User *U : I.users())
347 if (!CurLoop->contains(cast<Instruction>(U)))
348 return false;
349
350 // Match the branch instruction for the header
351 Value *MaxLen;
352 BasicBlock *EndBB, *WhileBB;
353 if (!match(Header->getTerminator(),
355 m_Value(MaxLen)),
356 m_BasicBlock(EndBB), m_BasicBlock(WhileBB))) ||
357 !CurLoop->contains(WhileBB))
358 return false;
359
360 // WhileBB should contain the pattern of load & compare instructions. Match
361 // the pattern and find the GEP instructions used by the loads.
362 BasicBlock *FoundBB;
363 BasicBlock *TrueBB;
364 Value *LoadA, *LoadB;
365 if (!match(WhileBB->getTerminator(),
367 m_Value(LoadB)),
368 m_BasicBlock(TrueBB), m_BasicBlock(FoundBB))) ||
369 !CurLoop->contains(TrueBB))
370 return false;
371
372 Value *A, *B;
373 if (!match(LoadA, m_Load(m_Value(A))) || !match(LoadB, m_Load(m_Value(B))))
374 return false;
375
376 LoadInst *LoadAI = cast<LoadInst>(LoadA);
377 LoadInst *LoadBI = cast<LoadInst>(LoadB);
378 if (!LoadAI->isSimple() || !LoadBI->isSimple())
379 return false;
380
383
384 if (!GEPA || !GEPB)
385 return false;
386
387 Value *PtrA = GEPA->getPointerOperand();
388 Value *PtrB = GEPB->getPointerOperand();
389
390 // Check we are loading i8 values from two loop invariant pointers
391 if (!CurLoop->isLoopInvariant(PtrA) || !CurLoop->isLoopInvariant(PtrB) ||
392 !GEPA->getResultElementType()->isIntegerTy(8) ||
393 !GEPB->getResultElementType()->isIntegerTy(8) ||
394 !LoadAI->getType()->isIntegerTy(8) ||
395 !LoadBI->getType()->isIntegerTy(8) || PtrA == PtrB)
396 return false;
397
398 // Check that the index to the GEPs is the index we found earlier
399 if (GEPA->getNumIndices() > 1 || GEPB->getNumIndices() > 1)
400 return false;
401
402 Value *IdxA = GEPA->getOperand(GEPA->getNumIndices());
403 Value *IdxB = GEPB->getOperand(GEPB->getNumIndices());
404 if (IdxA != IdxB || !match(IdxA, m_ZExt(m_Specific(Index))))
405 return false;
406
407 // We only ever expect the pre-incremented index value to be used inside the
408 // loop.
409 if (!PN->hasOneUse())
410 return false;
411
412 // Ensure that when the Found and End blocks are identical the PHIs have the
413 // supported format. We don't currently allow cases like this:
414 // while.cond:
415 // ...
416 // br i1 %cmp.not, label %while.end, label %while.body
417 //
418 // while.body:
419 // ...
420 // br i1 %cmp.not2, label %while.cond, label %while.end
421 //
422 // while.end:
423 // %final_ptr = phi ptr [ %c, %while.body ], [ %d, %while.cond ]
424 //
425 // Where the incoming values for %final_ptr are unique and from each of the
426 // loop blocks, but not actually defined in the loop. This requires extra
427 // work setting up the byte.compare block, i.e. by introducing a select to
428 // choose the correct value.
429 // TODO: We could add support for this in future.
430 if (FoundBB == EndBB) {
431 for (PHINode &EndPN : EndBB->phis()) {
432 Value *WhileCondVal = EndPN.getIncomingValueForBlock(Header);
433 Value *WhileBodyVal = EndPN.getIncomingValueForBlock(WhileBB);
434
435 // The value of the index when leaving the while.cond block is always the
436 // same as the end value (MaxLen) so we permit either. The value when
437 // leaving the while.body block should only be the index. Otherwise for
438 // any other values we only allow ones that are same for both blocks.
439 if (WhileCondVal != WhileBodyVal &&
440 ((WhileCondVal != Index && WhileCondVal != MaxLen) ||
441 (WhileBodyVal != Index)))
442 return false;
443 }
444 }
445
446 LLVM_DEBUG(dbgs() << "FOUND IDIOM IN LOOP: \n"
447 << *(EndBB->getParent()) << "\n\n");
448
449 // The index is incremented before the GEP/Load pair so we need to
450 // add 1 to the start value.
451 transformByteCompare(GEPA, GEPB, PN, MaxLen, Index, StartIdx, /*IncIdx=*/true,
452 FoundBB, EndBB);
453 return true;
454}
455
456Value *LoopIdiomVectorize::createMaskedFindMismatch(
457 IRBuilder<> &Builder, DomTreeUpdater &DTU, GetElementPtrInst *GEPA,
458 GetElementPtrInst *GEPB, Value *ExtStart, Value *ExtEnd) {
459 Type *I64Type = Builder.getInt64Ty();
460 Type *ResType = Builder.getInt32Ty();
461 Type *LoadType = Builder.getInt8Ty();
462 Value *PtrA = GEPA->getPointerOperand();
463 Value *PtrB = GEPB->getPointerOperand();
464
465 ScalableVectorType *PredVTy =
466 ScalableVectorType::get(Builder.getInt1Ty(), ByteCompareVF);
467
468 Value *InitialPred = Builder.CreateIntrinsic(
469 Intrinsic::get_active_lane_mask, {PredVTy, I64Type}, {ExtStart, ExtEnd});
470
471 Value *VecLen = Builder.CreateVScale(I64Type);
472 VecLen =
473 Builder.CreateMul(VecLen, ConstantInt::get(I64Type, ByteCompareVF), "",
474 /*HasNUW=*/true, /*HasNSW=*/true);
475
476 Value *PFalse = Builder.CreateVectorSplat(PredVTy->getElementCount(),
477 Builder.getInt1(false));
478
479 BranchInst *JumpToVectorLoop = BranchInst::Create(VectorLoopStartBlock);
480 Builder.Insert(JumpToVectorLoop);
481
482 DTU.applyUpdates({{DominatorTree::Insert, VectorLoopPreheaderBlock,
483 VectorLoopStartBlock}});
484
485 // Set up the first vector loop block by creating the PHIs, doing the vector
486 // loads and comparing the vectors.
487 Builder.SetInsertPoint(VectorLoopStartBlock);
488 PHINode *LoopPred = Builder.CreatePHI(PredVTy, 2, "mismatch_vec_loop_pred");
489 LoopPred->addIncoming(InitialPred, VectorLoopPreheaderBlock);
490 PHINode *VectorIndexPhi = Builder.CreatePHI(I64Type, 2, "mismatch_vec_index");
491 VectorIndexPhi->addIncoming(ExtStart, VectorLoopPreheaderBlock);
492 Type *VectorLoadType =
493 ScalableVectorType::get(Builder.getInt8Ty(), ByteCompareVF);
494 Value *Passthru = ConstantInt::getNullValue(VectorLoadType);
495
496 Value *VectorLhsGep =
497 Builder.CreateGEP(LoadType, PtrA, VectorIndexPhi, "", GEPA->isInBounds());
498 Value *VectorLhsLoad = Builder.CreateMaskedLoad(VectorLoadType, VectorLhsGep,
499 Align(1), LoopPred, Passthru);
500
501 Value *VectorRhsGep =
502 Builder.CreateGEP(LoadType, PtrB, VectorIndexPhi, "", GEPB->isInBounds());
503 Value *VectorRhsLoad = Builder.CreateMaskedLoad(VectorLoadType, VectorRhsGep,
504 Align(1), LoopPred, Passthru);
505
506 Value *VectorMatchCmp = Builder.CreateICmpNE(VectorLhsLoad, VectorRhsLoad);
507 VectorMatchCmp = Builder.CreateSelect(LoopPred, VectorMatchCmp, PFalse);
508 Value *VectorMatchHasActiveLanes = Builder.CreateOrReduce(VectorMatchCmp);
509 BranchInst *VectorEarlyExit = BranchInst::Create(
510 VectorLoopMismatchBlock, VectorLoopIncBlock, VectorMatchHasActiveLanes);
511 Builder.Insert(VectorEarlyExit);
512
513 DTU.applyUpdates(
514 {{DominatorTree::Insert, VectorLoopStartBlock, VectorLoopMismatchBlock},
515 {DominatorTree::Insert, VectorLoopStartBlock, VectorLoopIncBlock}});
516
517 // Increment the index counter and calculate the predicate for the next
518 // iteration of the loop. We branch back to the start of the loop if there
519 // is at least one active lane.
520 Builder.SetInsertPoint(VectorLoopIncBlock);
521 Value *NewVectorIndexPhi =
522 Builder.CreateAdd(VectorIndexPhi, VecLen, "",
523 /*HasNUW=*/true, /*HasNSW=*/true);
524 VectorIndexPhi->addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
525 Value *NewPred =
526 Builder.CreateIntrinsic(Intrinsic::get_active_lane_mask,
527 {PredVTy, I64Type}, {NewVectorIndexPhi, ExtEnd});
528 LoopPred->addIncoming(NewPred, VectorLoopIncBlock);
529
530 Value *PredHasActiveLanes =
531 Builder.CreateExtractElement(NewPred, uint64_t(0));
532 BranchInst *VectorLoopBranchBack =
533 BranchInst::Create(VectorLoopStartBlock, EndBlock, PredHasActiveLanes);
534 Builder.Insert(VectorLoopBranchBack);
535
536 DTU.applyUpdates(
537 {{DominatorTree::Insert, VectorLoopIncBlock, VectorLoopStartBlock},
538 {DominatorTree::Insert, VectorLoopIncBlock, EndBlock}});
539
540 // If we found a mismatch then we need to calculate which lane in the vector
541 // had a mismatch and add that on to the current loop index.
542 Builder.SetInsertPoint(VectorLoopMismatchBlock);
543 PHINode *FoundPred = Builder.CreatePHI(PredVTy, 1, "mismatch_vec_found_pred");
544 FoundPred->addIncoming(VectorMatchCmp, VectorLoopStartBlock);
545 PHINode *LastLoopPred =
546 Builder.CreatePHI(PredVTy, 1, "mismatch_vec_last_loop_pred");
547 LastLoopPred->addIncoming(LoopPred, VectorLoopStartBlock);
548 PHINode *VectorFoundIndex =
549 Builder.CreatePHI(I64Type, 1, "mismatch_vec_found_index");
550 VectorFoundIndex->addIncoming(VectorIndexPhi, VectorLoopStartBlock);
551
552 Value *PredMatchCmp = Builder.CreateAnd(LastLoopPred, FoundPred);
553 Value *Ctz = Builder.CreateCountTrailingZeroElems(ResType, PredMatchCmp);
554 Ctz = Builder.CreateZExt(Ctz, I64Type);
555 Value *VectorLoopRes64 = Builder.CreateAdd(VectorFoundIndex, Ctz, "",
556 /*HasNUW=*/true, /*HasNSW=*/true);
557 return Builder.CreateTrunc(VectorLoopRes64, ResType);
558}
559
560Value *LoopIdiomVectorize::createPredicatedFindMismatch(
561 IRBuilder<> &Builder, DomTreeUpdater &DTU, GetElementPtrInst *GEPA,
562 GetElementPtrInst *GEPB, Value *ExtStart, Value *ExtEnd) {
563 Type *I64Type = Builder.getInt64Ty();
564 Type *I32Type = Builder.getInt32Ty();
565 Type *ResType = I32Type;
566 Type *LoadType = Builder.getInt8Ty();
567 Value *PtrA = GEPA->getPointerOperand();
568 Value *PtrB = GEPB->getPointerOperand();
569
570 auto *JumpToVectorLoop = BranchInst::Create(VectorLoopStartBlock);
571 Builder.Insert(JumpToVectorLoop);
572
573 DTU.applyUpdates({{DominatorTree::Insert, VectorLoopPreheaderBlock,
574 VectorLoopStartBlock}});
575
576 // Set up the first Vector loop block by creating the PHIs, doing the vector
577 // loads and comparing the vectors.
578 Builder.SetInsertPoint(VectorLoopStartBlock);
579 auto *VectorIndexPhi = Builder.CreatePHI(I64Type, 2, "mismatch_vector_index");
580 VectorIndexPhi->addIncoming(ExtStart, VectorLoopPreheaderBlock);
581
582 // Calculate AVL by subtracting the vector loop index from the trip count
583 Value *AVL = Builder.CreateSub(ExtEnd, VectorIndexPhi, "avl", /*HasNUW=*/true,
584 /*HasNSW=*/true);
585
586 auto *VectorLoadType = ScalableVectorType::get(LoadType, ByteCompareVF);
587 auto *VF = ConstantInt::get(I32Type, ByteCompareVF);
588
589 Value *VL = Builder.CreateIntrinsic(Intrinsic::experimental_get_vector_length,
590 {I64Type}, {AVL, VF, Builder.getTrue()});
591 Value *GepOffset = VectorIndexPhi;
592
593 Value *VectorLhsGep =
594 Builder.CreateGEP(LoadType, PtrA, GepOffset, "", GEPA->isInBounds());
595 VectorType *TrueMaskTy =
596 VectorType::get(Builder.getInt1Ty(), VectorLoadType->getElementCount());
597 Value *AllTrueMask = Constant::getAllOnesValue(TrueMaskTy);
598 Value *VectorLhsLoad = Builder.CreateIntrinsic(
599 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->getType()},
600 {VectorLhsGep, AllTrueMask, VL}, nullptr, "lhs.load");
601
602 Value *VectorRhsGep =
603 Builder.CreateGEP(LoadType, PtrB, GepOffset, "", GEPB->isInBounds());
604 Value *VectorRhsLoad = Builder.CreateIntrinsic(
605 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->getType()},
606 {VectorRhsGep, AllTrueMask, VL}, nullptr, "rhs.load");
607
608 Value *VectorMatchCmp =
609 Builder.CreateICmpNE(VectorLhsLoad, VectorRhsLoad, "mismatch.cmp");
610 Value *CTZ = Builder.CreateIntrinsic(
611 Intrinsic::vp_cttz_elts, {ResType, VectorMatchCmp->getType()},
612 {VectorMatchCmp, /*ZeroIsPoison=*/Builder.getInt1(false), AllTrueMask,
613 VL});
614 Value *MismatchFound = Builder.CreateICmpNE(CTZ, VL);
615 auto *VectorEarlyExit = BranchInst::Create(VectorLoopMismatchBlock,
616 VectorLoopIncBlock, MismatchFound);
617 Builder.Insert(VectorEarlyExit);
618
619 DTU.applyUpdates(
620 {{DominatorTree::Insert, VectorLoopStartBlock, VectorLoopMismatchBlock},
621 {DominatorTree::Insert, VectorLoopStartBlock, VectorLoopIncBlock}});
622
623 // Increment the index counter and calculate the predicate for the next
624 // iteration of the loop. We branch back to the start of the loop if there
625 // is at least one active lane.
626 Builder.SetInsertPoint(VectorLoopIncBlock);
627 Value *VL64 = Builder.CreateZExt(VL, I64Type);
628 Value *NewVectorIndexPhi =
629 Builder.CreateAdd(VectorIndexPhi, VL64, "",
630 /*HasNUW=*/true, /*HasNSW=*/true);
631 VectorIndexPhi->addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
632 Value *ExitCond = Builder.CreateICmpNE(NewVectorIndexPhi, ExtEnd);
633 auto *VectorLoopBranchBack =
634 BranchInst::Create(VectorLoopStartBlock, EndBlock, ExitCond);
635 Builder.Insert(VectorLoopBranchBack);
636
637 DTU.applyUpdates(
638 {{DominatorTree::Insert, VectorLoopIncBlock, VectorLoopStartBlock},
639 {DominatorTree::Insert, VectorLoopIncBlock, EndBlock}});
640
641 // If we found a mismatch then we need to calculate which lane in the vector
642 // had a mismatch and add that on to the current loop index.
643 Builder.SetInsertPoint(VectorLoopMismatchBlock);
644
645 // Add LCSSA phis for CTZ and VectorIndexPhi.
646 auto *CTZLCSSAPhi = Builder.CreatePHI(CTZ->getType(), 1, "ctz");
647 CTZLCSSAPhi->addIncoming(CTZ, VectorLoopStartBlock);
648 auto *VectorIndexLCSSAPhi =
649 Builder.CreatePHI(VectorIndexPhi->getType(), 1, "mismatch_vector_index");
650 VectorIndexLCSSAPhi->addIncoming(VectorIndexPhi, VectorLoopStartBlock);
651
652 Value *CTZI64 = Builder.CreateZExt(CTZLCSSAPhi, I64Type);
653 Value *VectorLoopRes64 = Builder.CreateAdd(VectorIndexLCSSAPhi, CTZI64, "",
654 /*HasNUW=*/true, /*HasNSW=*/true);
655 return Builder.CreateTrunc(VectorLoopRes64, ResType);
656}
657
658Value *LoopIdiomVectorize::expandFindMismatch(
659 IRBuilder<> &Builder, DomTreeUpdater &DTU, GetElementPtrInst *GEPA,
660 GetElementPtrInst *GEPB, Instruction *Index, Value *Start, Value *MaxLen) {
661 Value *PtrA = GEPA->getPointerOperand();
662 Value *PtrB = GEPB->getPointerOperand();
663
664 // Get the arguments and types for the intrinsic.
665 BasicBlock *Preheader = CurLoop->getLoopPreheader();
666 BranchInst *PHBranch = cast<BranchInst>(Preheader->getTerminator());
667 LLVMContext &Ctx = PHBranch->getContext();
668 Type *LoadType = Type::getInt8Ty(Ctx);
669 Type *ResType = Builder.getInt32Ty();
670
671 // Split block in the original loop preheader.
672 EndBlock = SplitBlock(Preheader, PHBranch, DT, LI, nullptr, "mismatch_end");
673
674 // Create the blocks that we're going to need:
675 // 1. A block for checking the zero-extended length exceeds 0
676 // 2. A block to check that the start and end addresses of a given array
677 // lie on the same page.
678 // 3. The vector loop preheader.
679 // 4. The first vector loop block.
680 // 5. The vector loop increment block.
681 // 6. A block we can jump to from the vector loop when a mismatch is found.
682 // 7. The first block of the scalar loop itself, containing PHIs , loads
683 // and cmp.
684 // 8. A scalar loop increment block to increment the PHIs and go back
685 // around the loop.
686
687 BasicBlock *MinItCheckBlock = BasicBlock::Create(
688 Ctx, "mismatch_min_it_check", EndBlock->getParent(), EndBlock);
689
690 // Update the terminator added by SplitBlock to branch to the first block
691 Preheader->getTerminator()->setSuccessor(0, MinItCheckBlock);
692
693 BasicBlock *MemCheckBlock = BasicBlock::Create(
694 Ctx, "mismatch_mem_check", EndBlock->getParent(), EndBlock);
695
696 VectorLoopPreheaderBlock = BasicBlock::Create(
697 Ctx, "mismatch_vec_loop_preheader", EndBlock->getParent(), EndBlock);
698
699 VectorLoopStartBlock = BasicBlock::Create(Ctx, "mismatch_vec_loop",
700 EndBlock->getParent(), EndBlock);
701
702 VectorLoopIncBlock = BasicBlock::Create(Ctx, "mismatch_vec_loop_inc",
703 EndBlock->getParent(), EndBlock);
704
705 VectorLoopMismatchBlock = BasicBlock::Create(Ctx, "mismatch_vec_loop_found",
706 EndBlock->getParent(), EndBlock);
707
708 BasicBlock *LoopPreHeaderBlock = BasicBlock::Create(
709 Ctx, "mismatch_loop_pre", EndBlock->getParent(), EndBlock);
710
711 BasicBlock *LoopStartBlock =
712 BasicBlock::Create(Ctx, "mismatch_loop", EndBlock->getParent(), EndBlock);
713
714 BasicBlock *LoopIncBlock = BasicBlock::Create(
715 Ctx, "mismatch_loop_inc", EndBlock->getParent(), EndBlock);
716
717 DTU.applyUpdates({{DominatorTree::Insert, Preheader, MinItCheckBlock},
718 {DominatorTree::Delete, Preheader, EndBlock}});
719
720 // Update LoopInfo with the new vector & scalar loops.
721 auto VectorLoop = LI->AllocateLoop();
722 auto ScalarLoop = LI->AllocateLoop();
723
724 if (CurLoop->getParentLoop()) {
725 CurLoop->getParentLoop()->addBasicBlockToLoop(MinItCheckBlock, *LI);
726 CurLoop->getParentLoop()->addBasicBlockToLoop(MemCheckBlock, *LI);
727 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopPreheaderBlock,
728 *LI);
729 CurLoop->getParentLoop()->addChildLoop(VectorLoop);
730 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopMismatchBlock, *LI);
731 CurLoop->getParentLoop()->addBasicBlockToLoop(LoopPreHeaderBlock, *LI);
732 CurLoop->getParentLoop()->addChildLoop(ScalarLoop);
733 } else {
734 LI->addTopLevelLoop(VectorLoop);
735 LI->addTopLevelLoop(ScalarLoop);
736 }
737
738 // Add the new basic blocks to their associated loops.
739 VectorLoop->addBasicBlockToLoop(VectorLoopStartBlock, *LI);
740 VectorLoop->addBasicBlockToLoop(VectorLoopIncBlock, *LI);
741
742 ScalarLoop->addBasicBlockToLoop(LoopStartBlock, *LI);
743 ScalarLoop->addBasicBlockToLoop(LoopIncBlock, *LI);
744
745 // Set up some types and constants that we intend to reuse.
746 Type *I64Type = Builder.getInt64Ty();
747
748 // Check the zero-extended iteration count > 0
749 Builder.SetInsertPoint(MinItCheckBlock);
750 Value *ExtStart = Builder.CreateZExt(Start, I64Type);
751 Value *ExtEnd = Builder.CreateZExt(MaxLen, I64Type);
752 // This check doesn't really cost us very much.
753
754 Value *LimitCheck = Builder.CreateICmpULE(Start, MaxLen);
755 BranchInst *MinItCheckBr =
756 BranchInst::Create(MemCheckBlock, LoopPreHeaderBlock, LimitCheck);
757 MinItCheckBr->setMetadata(
758 LLVMContext::MD_prof,
759 MDBuilder(MinItCheckBr->getContext()).createBranchWeights(99, 1));
760 Builder.Insert(MinItCheckBr);
761
762 DTU.applyUpdates(
763 {{DominatorTree::Insert, MinItCheckBlock, MemCheckBlock},
764 {DominatorTree::Insert, MinItCheckBlock, LoopPreHeaderBlock}});
765
766 // For each of the arrays, check the start/end addresses are on the same
767 // page.
768 Builder.SetInsertPoint(MemCheckBlock);
769
770 // The early exit in the original loop means that when performing vector
771 // loads we are potentially reading ahead of the early exit. So we could
772 // fault if crossing a page boundary. Therefore, we create runtime memory
773 // checks based on the minimum page size as follows:
774 // 1. Calculate the addresses of the first memory accesses in the loop,
775 // i.e. LhsStart and RhsStart.
776 // 2. Get the last accessed addresses in the loop, i.e. LhsEnd and RhsEnd.
777 // 3. Determine which pages correspond to all the memory accesses, i.e
778 // LhsStartPage, LhsEndPage, RhsStartPage, RhsEndPage.
779 // 4. If LhsStartPage == LhsEndPage and RhsStartPage == RhsEndPage, then
780 // we know we won't cross any page boundaries in the loop so we can
781 // enter the vector loop! Otherwise we fall back on the scalar loop.
782 Value *LhsStartGEP = Builder.CreateGEP(LoadType, PtrA, ExtStart);
783 Value *RhsStartGEP = Builder.CreateGEP(LoadType, PtrB, ExtStart);
784 Value *RhsStart = Builder.CreatePtrToInt(RhsStartGEP, I64Type);
785 Value *LhsStart = Builder.CreatePtrToInt(LhsStartGEP, I64Type);
786 Value *LhsEndGEP = Builder.CreateGEP(LoadType, PtrA, ExtEnd);
787 Value *RhsEndGEP = Builder.CreateGEP(LoadType, PtrB, ExtEnd);
788 Value *LhsEnd = Builder.CreatePtrToInt(LhsEndGEP, I64Type);
789 Value *RhsEnd = Builder.CreatePtrToInt(RhsEndGEP, I64Type);
790
791 const uint64_t MinPageSize = TTI->getMinPageSize().value();
792 const uint64_t AddrShiftAmt = llvm::Log2_64(MinPageSize);
793 Value *LhsStartPage = Builder.CreateLShr(LhsStart, AddrShiftAmt);
794 Value *LhsEndPage = Builder.CreateLShr(LhsEnd, AddrShiftAmt);
795 Value *RhsStartPage = Builder.CreateLShr(RhsStart, AddrShiftAmt);
796 Value *RhsEndPage = Builder.CreateLShr(RhsEnd, AddrShiftAmt);
797 Value *LhsPageCmp = Builder.CreateICmpNE(LhsStartPage, LhsEndPage);
798 Value *RhsPageCmp = Builder.CreateICmpNE(RhsStartPage, RhsEndPage);
799
800 Value *CombinedPageCmp = Builder.CreateOr(LhsPageCmp, RhsPageCmp);
801 BranchInst *CombinedPageCmpCmpBr = BranchInst::Create(
802 LoopPreHeaderBlock, VectorLoopPreheaderBlock, CombinedPageCmp);
803 CombinedPageCmpCmpBr->setMetadata(
804 LLVMContext::MD_prof, MDBuilder(CombinedPageCmpCmpBr->getContext())
805 .createBranchWeights(10, 90));
806 Builder.Insert(CombinedPageCmpCmpBr);
807
808 DTU.applyUpdates(
809 {{DominatorTree::Insert, MemCheckBlock, LoopPreHeaderBlock},
810 {DominatorTree::Insert, MemCheckBlock, VectorLoopPreheaderBlock}});
811
812 // Set up the vector loop preheader, i.e. calculate initial loop predicate,
813 // zero-extend MaxLen to 64-bits, determine the number of vector elements
814 // processed in each iteration, etc.
815 Builder.SetInsertPoint(VectorLoopPreheaderBlock);
816
817 // At this point we know two things must be true:
818 // 1. Start <= End
819 // 2. ExtMaxLen <= MinPageSize due to the page checks.
820 // Therefore, we know that we can use a 64-bit induction variable that
821 // starts from 0 -> ExtMaxLen and it will not overflow.
822 Value *VectorLoopRes = nullptr;
823 switch (VectorizeStyle) {
825 VectorLoopRes =
826 createMaskedFindMismatch(Builder, DTU, GEPA, GEPB, ExtStart, ExtEnd);
827 break;
829 VectorLoopRes = createPredicatedFindMismatch(Builder, DTU, GEPA, GEPB,
830 ExtStart, ExtEnd);
831 break;
832 }
833
834 Builder.Insert(BranchInst::Create(EndBlock));
835
836 DTU.applyUpdates(
837 {{DominatorTree::Insert, VectorLoopMismatchBlock, EndBlock}});
838
839 // Generate code for scalar loop.
840 Builder.SetInsertPoint(LoopPreHeaderBlock);
841 Builder.Insert(BranchInst::Create(LoopStartBlock));
842
843 DTU.applyUpdates(
844 {{DominatorTree::Insert, LoopPreHeaderBlock, LoopStartBlock}});
845
846 Builder.SetInsertPoint(LoopStartBlock);
847 PHINode *IndexPhi = Builder.CreatePHI(ResType, 2, "mismatch_index");
848 IndexPhi->addIncoming(Start, LoopPreHeaderBlock);
849
850 // Otherwise compare the values
851 // Load bytes from each array and compare them.
852 Value *GepOffset = Builder.CreateZExt(IndexPhi, I64Type);
853
854 Value *LhsGep =
855 Builder.CreateGEP(LoadType, PtrA, GepOffset, "", GEPA->isInBounds());
856 Value *LhsLoad = Builder.CreateLoad(LoadType, LhsGep);
857
858 Value *RhsGep =
859 Builder.CreateGEP(LoadType, PtrB, GepOffset, "", GEPB->isInBounds());
860 Value *RhsLoad = Builder.CreateLoad(LoadType, RhsGep);
861
862 Value *MatchCmp = Builder.CreateICmpEQ(LhsLoad, RhsLoad);
863 // If we have a mismatch then exit the loop ...
864 BranchInst *MatchCmpBr = BranchInst::Create(LoopIncBlock, EndBlock, MatchCmp);
865 Builder.Insert(MatchCmpBr);
866
867 DTU.applyUpdates({{DominatorTree::Insert, LoopStartBlock, LoopIncBlock},
868 {DominatorTree::Insert, LoopStartBlock, EndBlock}});
869
870 // Have we reached the maximum permitted length for the loop?
871 Builder.SetInsertPoint(LoopIncBlock);
872 Value *PhiInc = Builder.CreateAdd(IndexPhi, ConstantInt::get(ResType, 1), "",
873 /*HasNUW=*/Index->hasNoUnsignedWrap(),
874 /*HasNSW=*/Index->hasNoSignedWrap());
875 IndexPhi->addIncoming(PhiInc, LoopIncBlock);
876 Value *IVCmp = Builder.CreateICmpEQ(PhiInc, MaxLen);
877 BranchInst *IVCmpBr = BranchInst::Create(EndBlock, LoopStartBlock, IVCmp);
878 Builder.Insert(IVCmpBr);
879
880 DTU.applyUpdates({{DominatorTree::Insert, LoopIncBlock, EndBlock},
881 {DominatorTree::Insert, LoopIncBlock, LoopStartBlock}});
882
883 // In the end block we need to insert a PHI node to deal with three cases:
884 // 1. We didn't find a mismatch in the scalar loop, so we return MaxLen.
885 // 2. We exitted the scalar loop early due to a mismatch and need to return
886 // the index that we found.
887 // 3. We didn't find a mismatch in the vector loop, so we return MaxLen.
888 // 4. We exitted the vector loop early due to a mismatch and need to return
889 // the index that we found.
890 Builder.SetInsertPoint(EndBlock, EndBlock->getFirstInsertionPt());
891 PHINode *ResPhi = Builder.CreatePHI(ResType, 4, "mismatch_result");
892 ResPhi->addIncoming(MaxLen, LoopIncBlock);
893 ResPhi->addIncoming(IndexPhi, LoopStartBlock);
894 ResPhi->addIncoming(MaxLen, VectorLoopIncBlock);
895 ResPhi->addIncoming(VectorLoopRes, VectorLoopMismatchBlock);
896
897 Value *FinalRes = Builder.CreateTrunc(ResPhi, ResType);
898
899 if (VerifyLoops) {
900 ScalarLoop->verifyLoop();
901 VectorLoop->verifyLoop();
902 if (!VectorLoop->isRecursivelyLCSSAForm(*DT, *LI))
903 report_fatal_error("Loops must remain in LCSSA form!");
904 if (!ScalarLoop->isRecursivelyLCSSAForm(*DT, *LI))
905 report_fatal_error("Loops must remain in LCSSA form!");
906 }
907
908 return FinalRes;
909}
910
911void LoopIdiomVectorize::transformByteCompare(GetElementPtrInst *GEPA,
912 GetElementPtrInst *GEPB,
913 PHINode *IndPhi, Value *MaxLen,
914 Instruction *Index, Value *Start,
915 bool IncIdx, BasicBlock *FoundBB,
916 BasicBlock *EndBB) {
917
918 // Insert the byte compare code at the end of the preheader block
919 BasicBlock *Preheader = CurLoop->getLoopPreheader();
920 BasicBlock *Header = CurLoop->getHeader();
921 BranchInst *PHBranch = cast<BranchInst>(Preheader->getTerminator());
922 IRBuilder<> Builder(PHBranch);
923 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
924 Builder.SetCurrentDebugLocation(PHBranch->getDebugLoc());
925
926 // Increment the pointer if this was done before the loads in the loop.
927 if (IncIdx)
928 Start = Builder.CreateAdd(Start, ConstantInt::get(Start->getType(), 1));
929
930 Value *ByteCmpRes =
931 expandFindMismatch(Builder, DTU, GEPA, GEPB, Index, Start, MaxLen);
932
933 // Replaces uses of index & induction Phi with intrinsic (we already
934 // checked that the the first instruction of Header is the Phi above).
935 assert(IndPhi->hasOneUse() && "Index phi node has more than one use!");
936 Index->replaceAllUsesWith(ByteCmpRes);
937
938 assert(PHBranch->isUnconditional() &&
939 "Expected preheader to terminate with an unconditional branch.");
940
941 // If no mismatch was found, we can jump to the end block. Create a
942 // new basic block for the compare instruction.
943 auto *CmpBB = BasicBlock::Create(Preheader->getContext(), "byte.compare",
944 Preheader->getParent());
945 CmpBB->moveBefore(EndBB);
946
947 // Replace the branch in the preheader with an always-true conditional branch.
948 // This ensures there is still a reference to the original loop.
949 Builder.CreateCondBr(Builder.getTrue(), CmpBB, Header);
950 PHBranch->eraseFromParent();
951
952 BasicBlock *MismatchEnd = cast<Instruction>(ByteCmpRes)->getParent();
953 DTU.applyUpdates({{DominatorTree::Insert, MismatchEnd, CmpBB}});
954
955 // Create the branch to either the end or found block depending on the value
956 // returned by the intrinsic.
957 Builder.SetInsertPoint(CmpBB);
958 if (FoundBB != EndBB) {
959 Value *FoundCmp = Builder.CreateICmpEQ(ByteCmpRes, MaxLen);
960 Builder.CreateCondBr(FoundCmp, EndBB, FoundBB);
961 DTU.applyUpdates({{DominatorTree::Insert, CmpBB, FoundBB},
962 {DominatorTree::Insert, CmpBB, EndBB}});
963
964 } else {
965 Builder.CreateBr(FoundBB);
966 DTU.applyUpdates({{DominatorTree::Insert, CmpBB, FoundBB}});
967 }
968
969 // Ensure all Phis in the successors of CmpBB have an incoming value from it.
970 fixSuccessorPhis(CurLoop, ByteCmpRes, ByteCmpRes, EndBB, CmpBB);
971 if (EndBB != FoundBB)
972 fixSuccessorPhis(CurLoop, ByteCmpRes, ByteCmpRes, FoundBB, CmpBB);
973
974 // The new CmpBB block isn't part of the loop, but will need to be added to
975 // the outer loop if there is one.
976 if (!CurLoop->isOutermost())
977 CurLoop->getParentLoop()->addBasicBlockToLoop(CmpBB, *LI);
978
979 if (VerifyLoops && CurLoop->getParentLoop()) {
980 CurLoop->getParentLoop()->verifyLoop();
981 if (!CurLoop->getParentLoop()->isRecursivelyLCSSAForm(*DT, *LI))
982 report_fatal_error("Loops must remain in LCSSA form!");
983 }
984}
985
986bool LoopIdiomVectorize::recognizeFindFirstByte() {
987 // Currently the transformation only works on scalable vector types, although
988 // there is no fundamental reason why it cannot be made to work for fixed
989 // vectors. We also need to know the target's minimum page size in order to
990 // generate runtime memory checks to ensure the vector version won't fault.
991 if (!TTI->supportsScalableVectors() || !TTI->getMinPageSize().has_value() ||
993 return false;
994
995 // Define some constants we need throughout.
996 BasicBlock *Header = CurLoop->getHeader();
997 LLVMContext &Ctx = Header->getContext();
998
999 // We are expecting the four blocks defined below: Header, MatchBB, InnerBB,
1000 // and OuterBB. For now, we will bail our for almost anything else. The Four
1001 // blocks contain one nested loop.
1002 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 4 ||
1003 CurLoop->getSubLoops().size() != 1)
1004 return false;
1005
1006 auto *InnerLoop = CurLoop->getSubLoops().front();
1007 PHINode *IndPhi = dyn_cast<PHINode>(&Header->front());
1008 if (!IndPhi || IndPhi->getNumIncomingValues() != 2)
1009 return false;
1010
1011 // Check instruction counts.
1012 auto LoopBlocks = CurLoop->getBlocks();
1013 if (LoopBlocks[0]->sizeWithoutDebug() > 3 ||
1014 LoopBlocks[1]->sizeWithoutDebug() > 4 ||
1015 LoopBlocks[2]->sizeWithoutDebug() > 3 ||
1016 LoopBlocks[3]->sizeWithoutDebug() > 3)
1017 return false;
1018
1019 // Check that no instruction other than IndPhi has outside uses.
1020 for (BasicBlock *BB : LoopBlocks)
1021 for (Instruction &I : *BB)
1022 if (&I != IndPhi)
1023 for (User *U : I.users())
1024 if (!CurLoop->contains(cast<Instruction>(U)))
1025 return false;
1026
1027 // Match the branch instruction in the header. We are expecting an
1028 // unconditional branch to the inner loop.
1029 //
1030 // Header:
1031 // %14 = phi ptr [ %24, %OuterBB ], [ %3, %Header.preheader ]
1032 // %15 = load i8, ptr %14, align 1
1033 // br label %MatchBB
1034 BasicBlock *MatchBB;
1035 if (!match(Header->getTerminator(), m_UnconditionalBr(MatchBB)) ||
1036 !InnerLoop->contains(MatchBB))
1037 return false;
1038
1039 // MatchBB should be the entrypoint into the inner loop containing the
1040 // comparison between a search element and a needle.
1041 //
1042 // MatchBB:
1043 // %20 = phi ptr [ %7, %Header ], [ %17, %InnerBB ]
1044 // %21 = load i8, ptr %20, align 1
1045 // %22 = icmp eq i8 %15, %21
1046 // br i1 %22, label %ExitSucc, label %InnerBB
1047 BasicBlock *ExitSucc, *InnerBB;
1048 Value *LoadSearch, *LoadNeedle;
1049 CmpPredicate MatchPred;
1050 if (!match(MatchBB->getTerminator(),
1051 m_Br(m_ICmp(MatchPred, m_Value(LoadSearch), m_Value(LoadNeedle)),
1052 m_BasicBlock(ExitSucc), m_BasicBlock(InnerBB))) ||
1053 MatchPred != ICmpInst::ICMP_EQ || !InnerLoop->contains(InnerBB))
1054 return false;
1055
1056 // We expect outside uses of `IndPhi' in ExitSucc (and only there).
1057 for (User *U : IndPhi->users())
1058 if (!CurLoop->contains(cast<Instruction>(U))) {
1059 auto *PN = dyn_cast<PHINode>(U);
1060 if (!PN || PN->getParent() != ExitSucc)
1061 return false;
1062 }
1063
1064 // Match the loads and check they are simple.
1065 Value *Search, *Needle;
1066 if (!match(LoadSearch, m_Load(m_Value(Search))) ||
1067 !match(LoadNeedle, m_Load(m_Value(Needle))) ||
1068 !cast<LoadInst>(LoadSearch)->isSimple() ||
1069 !cast<LoadInst>(LoadNeedle)->isSimple())
1070 return false;
1071
1072 // Check we are loading valid characters.
1073 Type *CharTy = LoadSearch->getType();
1074 if (!CharTy->isIntegerTy() || LoadNeedle->getType() != CharTy)
1075 return false;
1076
1077 // Pick the vectorisation factor based on CharTy, work out the cost of the
1078 // match intrinsic and decide if we should use it.
1079 // Note: For the time being we assume 128-bit vectors.
1080 unsigned VF = 128 / CharTy->getIntegerBitWidth();
1082 ScalableVectorType::get(CharTy, VF), FixedVectorType::get(CharTy, VF),
1084 IntrinsicCostAttributes Attrs(Intrinsic::experimental_vector_match, Args[2],
1085 Args);
1086 if (TTI->getIntrinsicInstrCost(Attrs, TTI::TCK_SizeAndLatency) > 4)
1087 return false;
1088
1089 // The loads come from two PHIs, each with two incoming values.
1090 PHINode *PSearch = dyn_cast<PHINode>(Search);
1091 PHINode *PNeedle = dyn_cast<PHINode>(Needle);
1092 if (!PSearch || PSearch->getNumIncomingValues() != 2 || !PNeedle ||
1093 PNeedle->getNumIncomingValues() != 2)
1094 return false;
1095
1096 // One PHI comes from the outer loop (PSearch), the other one from the inner
1097 // loop (PNeedle). PSearch effectively corresponds to IndPhi.
1098 if (InnerLoop->contains(PSearch))
1099 std::swap(PSearch, PNeedle);
1100 if (PSearch != &Header->front() || PNeedle != &MatchBB->front())
1101 return false;
1102
1103 // The incoming values of both PHI nodes should be a gep of 1.
1104 Value *SearchStart = PSearch->getIncomingValue(0);
1105 Value *SearchIndex = PSearch->getIncomingValue(1);
1106 if (CurLoop->contains(PSearch->getIncomingBlock(0)))
1107 std::swap(SearchStart, SearchIndex);
1108
1109 Value *NeedleStart = PNeedle->getIncomingValue(0);
1110 Value *NeedleIndex = PNeedle->getIncomingValue(1);
1111 if (InnerLoop->contains(PNeedle->getIncomingBlock(0)))
1112 std::swap(NeedleStart, NeedleIndex);
1113
1114 // Match the GEPs.
1115 if (!match(SearchIndex, m_GEP(m_Specific(PSearch), m_One())) ||
1116 !match(NeedleIndex, m_GEP(m_Specific(PNeedle), m_One())))
1117 return false;
1118
1119 // Check the GEPs result type matches `CharTy'.
1120 GetElementPtrInst *GEPSearch = cast<GetElementPtrInst>(SearchIndex);
1121 GetElementPtrInst *GEPNeedle = cast<GetElementPtrInst>(NeedleIndex);
1122 if (GEPSearch->getResultElementType() != CharTy ||
1123 GEPNeedle->getResultElementType() != CharTy)
1124 return false;
1125
1126 // InnerBB should increment the address of the needle pointer.
1127 //
1128 // InnerBB:
1129 // %17 = getelementptr inbounds i8, ptr %20, i64 1
1130 // %18 = icmp eq ptr %17, %10
1131 // br i1 %18, label %OuterBB, label %MatchBB
1132 BasicBlock *OuterBB;
1133 Value *NeedleEnd;
1134 if (!match(InnerBB->getTerminator(),
1136 m_Value(NeedleEnd)),
1137 m_BasicBlock(OuterBB), m_Specific(MatchBB))) ||
1138 !CurLoop->contains(OuterBB))
1139 return false;
1140
1141 // OuterBB should increment the address of the search element pointer.
1142 //
1143 // OuterBB:
1144 // %24 = getelementptr inbounds i8, ptr %14, i64 1
1145 // %25 = icmp eq ptr %24, %6
1146 // br i1 %25, label %ExitFail, label %Header
1147 BasicBlock *ExitFail;
1148 Value *SearchEnd;
1149 if (!match(OuterBB->getTerminator(),
1151 m_Value(SearchEnd)),
1152 m_BasicBlock(ExitFail), m_Specific(Header))))
1153 return false;
1154
1155 if (!CurLoop->isLoopInvariant(SearchStart) ||
1156 !CurLoop->isLoopInvariant(SearchEnd) ||
1157 !CurLoop->isLoopInvariant(NeedleStart) ||
1158 !CurLoop->isLoopInvariant(NeedleEnd))
1159 return false;
1160
1161 LLVM_DEBUG(dbgs() << "Found idiom in loop: \n" << *CurLoop << "\n\n");
1162
1163 transformFindFirstByte(IndPhi, VF, CharTy, ExitSucc, ExitFail, SearchStart,
1164 SearchEnd, NeedleStart, NeedleEnd);
1165 return true;
1166}
1167
1168Value *LoopIdiomVectorize::expandFindFirstByte(
1169 IRBuilder<> &Builder, DomTreeUpdater &DTU, unsigned VF, Type *CharTy,
1170 Value *IndPhi, BasicBlock *ExitSucc, BasicBlock *ExitFail,
1171 Value *SearchStart, Value *SearchEnd, Value *NeedleStart,
1172 Value *NeedleEnd) {
1173 // Set up some types and constants that we intend to reuse.
1174 auto *PtrTy = Builder.getPtrTy();
1175 auto *I64Ty = Builder.getInt64Ty();
1176 auto *PredVTy = ScalableVectorType::get(Builder.getInt1Ty(), VF);
1177 auto *CharVTy = ScalableVectorType::get(CharTy, VF);
1178 auto *ConstVF = ConstantInt::get(I64Ty, VF);
1179
1180 // Other common arguments.
1181 BasicBlock *Preheader = CurLoop->getLoopPreheader();
1182 LLVMContext &Ctx = Preheader->getContext();
1183 Value *Passthru = ConstantInt::getNullValue(CharVTy);
1184
1185 // Split block in the original loop preheader.
1186 // SPH is the new preheader to the old scalar loop.
1187 BasicBlock *SPH = SplitBlock(Preheader, Preheader->getTerminator(), DT, LI,
1188 nullptr, "scalar_preheader");
1189
1190 // Create the blocks that we're going to use.
1191 //
1192 // We will have the following loops:
1193 // (O) Outer loop where we iterate over the elements of the search array.
1194 // (I) Inner loop where we iterate over the elements of the needle array.
1195 //
1196 // Overall, the blocks do the following:
1197 // (0) Check if the arrays can't cross page boundaries. If so go to (1),
1198 // otherwise fall back to the original scalar loop.
1199 // (1) Load the search array. Go to (2).
1200 // (2) (a) Load the needle array.
1201 // (b) Splat the first element to the inactive lanes.
1202 // (c) Check if any elements match. If so go to (3), otherwise go to (4).
1203 // (3) Compute the index of the first match and exit.
1204 // (4) Check if we've reached the end of the needle array. If not loop back to
1205 // (2), otherwise go to (5).
1206 // (5) Check if we've reached the end of the search array. If not loop back to
1207 // (1), otherwise exit.
1208 // Blocks (0,3) are not part of any loop. Blocks (1,5) and (2,4) belong to
1209 // the outer and inner loops, respectively.
1210 BasicBlock *BB0 = BasicBlock::Create(Ctx, "mem_check", SPH->getParent(), SPH);
1211 BasicBlock *BB1 =
1212 BasicBlock::Create(Ctx, "find_first_vec_header", SPH->getParent(), SPH);
1213 BasicBlock *BB2 =
1214 BasicBlock::Create(Ctx, "match_check_vec", SPH->getParent(), SPH);
1215 BasicBlock *BB3 =
1216 BasicBlock::Create(Ctx, "calculate_match", SPH->getParent(), SPH);
1217 BasicBlock *BB4 =
1218 BasicBlock::Create(Ctx, "needle_check_vec", SPH->getParent(), SPH);
1219 BasicBlock *BB5 =
1220 BasicBlock::Create(Ctx, "search_check_vec", SPH->getParent(), SPH);
1221
1222 // Update LoopInfo with the new loops.
1223 auto OuterLoop = LI->AllocateLoop();
1224 auto InnerLoop = LI->AllocateLoop();
1225
1226 if (auto ParentLoop = CurLoop->getParentLoop()) {
1227 ParentLoop->addBasicBlockToLoop(BB0, *LI);
1228 ParentLoop->addChildLoop(OuterLoop);
1229 ParentLoop->addBasicBlockToLoop(BB3, *LI);
1230 } else {
1231 LI->addTopLevelLoop(OuterLoop);
1232 }
1233
1234 // Add the inner loop to the outer.
1235 OuterLoop->addChildLoop(InnerLoop);
1236
1237 // Add the new basic blocks to the corresponding loops.
1238 OuterLoop->addBasicBlockToLoop(BB1, *LI);
1239 OuterLoop->addBasicBlockToLoop(BB5, *LI);
1240 InnerLoop->addBasicBlockToLoop(BB2, *LI);
1241 InnerLoop->addBasicBlockToLoop(BB4, *LI);
1242
1243 // Update the terminator added by SplitBlock to branch to the first block.
1244 Preheader->getTerminator()->setSuccessor(0, BB0);
1245 DTU.applyUpdates({{DominatorTree::Delete, Preheader, SPH},
1246 {DominatorTree::Insert, Preheader, BB0}});
1247
1248 // (0) Check if we could be crossing a page boundary; if so, fallback to the
1249 // old scalar loops. Also create a predicate of VF elements to be used in the
1250 // vector loops.
1251 Builder.SetInsertPoint(BB0);
1252 Value *ISearchStart =
1253 Builder.CreatePtrToInt(SearchStart, I64Ty, "search_start_int");
1254 Value *ISearchEnd =
1255 Builder.CreatePtrToInt(SearchEnd, I64Ty, "search_end_int");
1256 Value *INeedleStart =
1257 Builder.CreatePtrToInt(NeedleStart, I64Ty, "needle_start_int");
1258 Value *INeedleEnd =
1259 Builder.CreatePtrToInt(NeedleEnd, I64Ty, "needle_end_int");
1260 Value *PredVF =
1261 Builder.CreateIntrinsic(Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1262 {ConstantInt::get(I64Ty, 0), ConstVF});
1263
1264 const uint64_t MinPageSize = TTI->getMinPageSize().value();
1265 const uint64_t AddrShiftAmt = llvm::Log2_64(MinPageSize);
1266 Value *SearchStartPage =
1267 Builder.CreateLShr(ISearchStart, AddrShiftAmt, "search_start_page");
1268 Value *SearchEndPage =
1269 Builder.CreateLShr(ISearchEnd, AddrShiftAmt, "search_end_page");
1270 Value *NeedleStartPage =
1271 Builder.CreateLShr(INeedleStart, AddrShiftAmt, "needle_start_page");
1272 Value *NeedleEndPage =
1273 Builder.CreateLShr(INeedleEnd, AddrShiftAmt, "needle_end_page");
1274 Value *SearchPageCmp =
1275 Builder.CreateICmpNE(SearchStartPage, SearchEndPage, "search_page_cmp");
1276 Value *NeedlePageCmp =
1277 Builder.CreateICmpNE(NeedleStartPage, NeedleEndPage, "needle_page_cmp");
1278
1279 Value *CombinedPageCmp =
1280 Builder.CreateOr(SearchPageCmp, NeedlePageCmp, "combined_page_cmp");
1281 BranchInst *CombinedPageBr = Builder.CreateCondBr(CombinedPageCmp, SPH, BB1);
1282 CombinedPageBr->setMetadata(LLVMContext::MD_prof,
1283 MDBuilder(Ctx).createBranchWeights(10, 90));
1284 DTU.applyUpdates(
1285 {{DominatorTree::Insert, BB0, SPH}, {DominatorTree::Insert, BB0, BB1}});
1286
1287 // (1) Load the search array and branch to the inner loop.
1288 Builder.SetInsertPoint(BB1);
1289 PHINode *Search = Builder.CreatePHI(PtrTy, 2, "psearch");
1290 Value *PredSearch = Builder.CreateIntrinsic(
1291 Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1292 {Builder.CreatePtrToInt(Search, I64Ty), ISearchEnd}, nullptr,
1293 "search_pred");
1294 PredSearch = Builder.CreateAnd(PredVF, PredSearch, "search_masked");
1295 Value *LoadSearch = Builder.CreateMaskedLoad(
1296 CharVTy, Search, Align(1), PredSearch, Passthru, "search_load_vec");
1297 Builder.CreateBr(BB2);
1298 DTU.applyUpdates({{DominatorTree::Insert, BB1, BB2}});
1299
1300 // (2) Inner loop.
1301 Builder.SetInsertPoint(BB2);
1302 PHINode *Needle = Builder.CreatePHI(PtrTy, 2, "pneedle");
1303
1304 // (2.a) Load the needle array.
1305 Value *PredNeedle = Builder.CreateIntrinsic(
1306 Intrinsic::get_active_lane_mask, {PredVTy, I64Ty},
1307 {Builder.CreatePtrToInt(Needle, I64Ty), INeedleEnd}, nullptr,
1308 "needle_pred");
1309 PredNeedle = Builder.CreateAnd(PredVF, PredNeedle, "needle_masked");
1310 Value *LoadNeedle = Builder.CreateMaskedLoad(
1311 CharVTy, Needle, Align(1), PredNeedle, Passthru, "needle_load_vec");
1312
1313 // (2.b) Splat the first element to the inactive lanes.
1314 Value *Needle0 =
1315 Builder.CreateExtractElement(LoadNeedle, uint64_t(0), "needle0");
1316 Value *Needle0Splat = Builder.CreateVectorSplat(ElementCount::getScalable(VF),
1317 Needle0, "needle0");
1318 LoadNeedle = Builder.CreateSelect(PredNeedle, LoadNeedle, Needle0Splat,
1319 "needle_splat");
1320 LoadNeedle = Builder.CreateExtractVector(
1321 FixedVectorType::get(CharTy, VF), LoadNeedle, uint64_t(0), "needle_vec");
1322
1323 // (2.c) Test if there's a match.
1324 Value *MatchPred = Builder.CreateIntrinsic(
1325 Intrinsic::experimental_vector_match, {CharVTy, LoadNeedle->getType()},
1326 {LoadSearch, LoadNeedle, PredSearch}, nullptr, "match_pred");
1327 Value *IfAnyMatch = Builder.CreateOrReduce(MatchPred);
1328 Builder.CreateCondBr(IfAnyMatch, BB3, BB4);
1329 DTU.applyUpdates(
1330 {{DominatorTree::Insert, BB2, BB3}, {DominatorTree::Insert, BB2, BB4}});
1331
1332 // (3) We found a match. Compute the index of its location and exit.
1333 Builder.SetInsertPoint(BB3);
1334 PHINode *MatchLCSSA = Builder.CreatePHI(PtrTy, 1, "match_start");
1335 PHINode *MatchPredLCSSA =
1336 Builder.CreatePHI(MatchPred->getType(), 1, "match_vec");
1337 Value *MatchCnt = Builder.CreateIntrinsic(
1338 Intrinsic::experimental_cttz_elts, {I64Ty, MatchPred->getType()},
1339 {MatchPredLCSSA, /*ZeroIsPoison=*/Builder.getInt1(true)}, nullptr,
1340 "match_idx");
1341 Value *MatchVal =
1342 Builder.CreateGEP(CharTy, MatchLCSSA, MatchCnt, "match_res");
1343 Builder.CreateBr(ExitSucc);
1344 DTU.applyUpdates({{DominatorTree::Insert, BB3, ExitSucc}});
1345
1346 // (4) Check if we've reached the end of the needle array.
1347 Builder.SetInsertPoint(BB4);
1348 Value *NextNeedle =
1349 Builder.CreateGEP(CharTy, Needle, ConstVF, "needle_next_vec");
1350 Builder.CreateCondBr(Builder.CreateICmpULT(NextNeedle, NeedleEnd), BB2, BB5);
1351 DTU.applyUpdates(
1352 {{DominatorTree::Insert, BB4, BB2}, {DominatorTree::Insert, BB4, BB5}});
1353
1354 // (5) Check if we've reached the end of the search array.
1355 Builder.SetInsertPoint(BB5);
1356 Value *NextSearch =
1357 Builder.CreateGEP(CharTy, Search, ConstVF, "search_next_vec");
1358 Builder.CreateCondBr(Builder.CreateICmpULT(NextSearch, SearchEnd), BB1,
1359 ExitFail);
1360 DTU.applyUpdates({{DominatorTree::Insert, BB5, BB1},
1361 {DominatorTree::Insert, BB5, ExitFail}});
1362
1363 // Set up the PHI nodes.
1364 Search->addIncoming(SearchStart, BB0);
1365 Search->addIncoming(NextSearch, BB5);
1366 Needle->addIncoming(NeedleStart, BB1);
1367 Needle->addIncoming(NextNeedle, BB4);
1368 // These are needed to retain LCSSA form.
1369 MatchLCSSA->addIncoming(Search, BB2);
1370 MatchPredLCSSA->addIncoming(MatchPred, BB2);
1371
1372 // Ensure all Phis in the successors of BB3/BB5 have an incoming value from
1373 // them.
1374 fixSuccessorPhis(CurLoop, IndPhi, MatchVal, ExitSucc, BB3);
1375 if (ExitSucc != ExitFail)
1376 fixSuccessorPhis(CurLoop, IndPhi, MatchVal, ExitFail, BB5);
1377
1378 if (VerifyLoops) {
1379 OuterLoop->verifyLoop();
1380 InnerLoop->verifyLoop();
1381 if (!OuterLoop->isRecursivelyLCSSAForm(*DT, *LI))
1382 report_fatal_error("Loops must remain in LCSSA form!");
1383 }
1384
1385 return MatchVal;
1386}
1387
1388void LoopIdiomVectorize::transformFindFirstByte(
1389 PHINode *IndPhi, unsigned VF, Type *CharTy, BasicBlock *ExitSucc,
1390 BasicBlock *ExitFail, Value *SearchStart, Value *SearchEnd,
1391 Value *NeedleStart, Value *NeedleEnd) {
1392 // Insert the find first byte code at the end of the preheader block.
1393 BasicBlock *Preheader = CurLoop->getLoopPreheader();
1394 BranchInst *PHBranch = cast<BranchInst>(Preheader->getTerminator());
1395 IRBuilder<> Builder(PHBranch);
1396 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
1397 Builder.SetCurrentDebugLocation(PHBranch->getDebugLoc());
1398
1399 expandFindFirstByte(Builder, DTU, VF, CharTy, IndPhi, ExitSucc, ExitFail,
1400 SearchStart, SearchEnd, NeedleStart, NeedleEnd);
1401
1402 assert(PHBranch->isUnconditional() &&
1403 "Expected preheader to terminate with an unconditional branch.");
1404
1405 if (VerifyLoops && CurLoop->getParentLoop()) {
1406 CurLoop->getParentLoop()->verifyLoop();
1407 if (!CurLoop->getParentLoop()->isRecursivelyLCSSAForm(*DT, *LI))
1408 report_fatal_error("Loops must remain in LCSSA form!");
1409 }
1410}
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)
#define DEBUG_TYPE
static MDNode * createBranchWeights(LLVMContext &Context, uint64_t TrueWeight, uint64_t FalseWeight)
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)."))
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
static bool isSimple(Instruction *I)
#define LLVM_DEBUG(...)
Definition Debug.h:114
static cl::opt< unsigned > MinPageSize("min-page-size", cl::init(0), cl::Hidden, cl::desc("Use this to override the target's minimum page size."))
This pass exposes codegen information to IR-level passes.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
Definition BasicBlock.h:528
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction & front() const
Definition BasicBlock.h:482
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...
Definition BasicBlock.h:233
Conditional or Unconditional Branch instruction.
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
bool isUnconditional() const
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
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.
Definition DataLayout.h:63
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:165
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition TypeSize.h:312
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:803
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.
Type * getResultElementType() const
unsigned getNumIndices() const
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
Definition IRBuilder.h:497
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2345
CallInst * CreateExtractVector(Type *DstType, Value *SrcVec, Value *Idx, const Twine &Name="")
Create a call to the vector.extract intrinsic.
Definition IRBuilder.h:1093
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Definition IRBuilder.h:547
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2559
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.
Definition IRBuilder.h:502
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)
Definition IRBuilder.h:1513
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:562
Value * CreateVScale(Type *Ty, const Twine &Name="")
Create a call to llvm.vscale.<Ty>().
Definition IRBuilder.h:958
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
Definition IRBuilder.h:247
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition IRBuilder.h:567
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2333
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:1923
LLVM_ABI CallInst * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
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="")
Definition IRBuilder.h:2494
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2329
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Definition IRBuilder.h:172
Value * CreateCountTrailingZeroElems(Type *ResTy, Value *Mask, bool ZeroIsPoison=true, const Twine &Name="")
Create a call to llvm.experimental_cttz_elts.
Definition IRBuilder.h:1134
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1420
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
Definition IRBuilder.h:1197
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition IRBuilder.h:1847
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2082
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1551
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1403
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2194
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2068
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition IRBuilder.h:605
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
Definition IRBuilder.h:1191
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:207
Value * CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2349
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1573
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition IRBuilder.h:552
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1437
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2780
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.
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.
Definition LLVMContext.h:68
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 isSimple() const
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
Definition MDBuilder.cpp:38
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.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
Class to represent scalable SIMD vectors.
static LLVM_ABI ScalableVectorType * get(Type *ElementType, unsigned MinNumElts)
Definition Type.cpp:825
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
@ TCK_SizeAndLatency
The weighted sum of size and latency.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM_ABI unsigned getIntegerBitWidth() const
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:295
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:294
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:240
Value * getOperand(unsigned i) const
Definition User.h:232
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:439
iterator_range< user_iterator > users()
Definition Value.h:426
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.cpp:1101
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
Definition ilist_node.h:34
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
Definition InstrProf.h:137
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:348
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.
Definition Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
TargetTransformInfo TTI
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)
Split the specified block at the specified instruction.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:853
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...