LLVM 24.0.0git
VPlanConstruction.cpp
Go to the documentation of this file.
1//===-- VPlanConstruction.cpp - Transforms for initial VPlan construction -===//
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/// \file
10/// This file implements transforms for initial VPlan construction.
11///
12//===----------------------------------------------------------------------===//
13
15#include "VPlan.h"
16#include "VPlanAnalysis.h"
17#include "VPlanCFG.h"
18#include "VPlanDominatorTree.h"
19#include "VPlanHelpers.h"
20#include "VPlanPatternMatch.h"
21#include "VPlanTransforms.h"
22#include "VPlanUtils.h"
23#include "llvm/ADT/Sequence.h"
26#include "llvm/Analysis/Loads.h"
33#include "llvm/IR/InstrTypes.h"
34#include "llvm/IR/MDBuilder.h"
35#include "llvm/Support/Debug.h"
39
40#define DEBUG_TYPE "vplan"
41
42using namespace llvm;
43using namespace LoopVectorizationUtils;
44using namespace VPlanPatternMatch;
45
46namespace {
47// Class that is used to build the plain CFG for the incoming IR.
48class PlainCFGBuilder {
49 // The outermost loop of the input loop nest considered for vectorization.
50 Loop *TheLoop;
51
52 // Loop Info analysis.
53 LoopInfo *LI;
54
55 // Loop versioning for alias metadata.
56 LoopVersioning *LVer;
57
58 // Lazily provides branch probabilities for the incoming IR.
59 function_ref<const BranchProbabilityInfo &()> GetBPI;
60
61 // The BranchProbabilityInfo returned by GetBPI, cached on first use.
62 const BranchProbabilityInfo *BPI = nullptr;
63
64 // Vectorization plan that we are working on.
65 std::unique_ptr<VPlan> Plan;
66
67 // Builder of the VPlan instruction-level representation.
68 VPBuilder VPIRBuilder;
69
70 // NOTE: The following maps are intentionally destroyed after the plain CFG
71 // construction because subsequent VPlan-to-VPlan transformation may
72 // invalidate them.
73 // Map incoming BasicBlocks to their newly-created VPBasicBlocks.
75 // Map incoming Value definitions to their newly-created VPValues.
76 DenseMap<Value *, VPValue *> IRDef2VPValue;
77
78 // Hold phi node's that need to be fixed once the plain CFG has been built.
80
81 // Utility functions.
82 void setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB);
83 void fixHeaderPhis();
84 VPBasicBlock *getOrCreateVPBB(BasicBlock *BB);
85#ifndef NDEBUG
86 bool isExternalDef(Value *Val);
87#endif
88 VPValue *getOrCreateVPOperand(Value *IRVal);
89 void createVPInstructionsForVPBB(VPBasicBlock *VPBB, BasicBlock *BB);
90 VPIRMetadata getTerminatorMetadata(Instruction &Term);
91
92public:
93 PlainCFGBuilder(Loop *Lp, LoopInfo *LI, LoopVersioning *LVer, Type *IdxTy,
94 function_ref<const BranchProbabilityInfo &()> GetBPI)
95 : TheLoop(Lp), LI(LI), LVer(LVer), GetBPI(GetBPI),
96 Plan(std::make_unique<VPlan>(Lp, IdxTy)) {}
97
98 /// Build plain CFG for TheLoop and connect it to Plan's entry.
99 std::unique_ptr<VPlan> buildPlainCFG();
100};
101} // anonymous namespace
102
103// Set predecessors of \p VPBB in the same order as they are in \p BB. \p VPBB
104// must have no predecessors.
105void PlainCFGBuilder::setVPBBPredsFromBB(VPBasicBlock *VPBB, BasicBlock *BB) {
106 // Collect VPBB predecessors.
108 for (BasicBlock *Pred : predecessors(BB))
109 VPBBPreds.push_back(getOrCreateVPBB(Pred));
110 VPBB->setPredecessors(VPBBPreds);
111}
112
113static bool isHeaderBB(BasicBlock *BB, Loop *L) {
114 return L && BB == L->getHeader();
115}
116
117// Add operands to VPInstructions representing phi nodes from the input IR.
118void PlainCFGBuilder::fixHeaderPhis() {
119 for (auto *Phi : PhisToFix) {
120 assert(IRDef2VPValue.count(Phi) && "Missing VPInstruction for PHINode.");
121 VPValue *VPVal = IRDef2VPValue[Phi];
122 assert(isa<VPPhi>(VPVal) && "Expected VPPhi for phi node.");
123 auto *PhiR = cast<VPPhi>(VPVal);
124 assert(PhiR->getNumOperands() == 0 && "Expected VPPhi with no operands.");
125 assert(isHeaderBB(Phi->getParent(), LI->getLoopFor(Phi->getParent())) &&
126 "Expected Phi in header block.");
127 assert(Phi->getNumOperands() == 2 &&
128 "header phi must have exactly 2 operands");
129 for (BasicBlock *Pred : predecessors(Phi->getParent()))
130 PhiR->addIncoming(
131 getOrCreateVPOperand(Phi->getIncomingValueForBlock(Pred)));
132 }
133}
134
135// Create a new empty VPBasicBlock for an incoming BasicBlock or retrieve an
136// existing one if it was already created.
137VPBasicBlock *PlainCFGBuilder::getOrCreateVPBB(BasicBlock *BB) {
138 if (auto *VPBB = BB2VPBB.lookup(BB)) {
139 // Retrieve existing VPBB.
140 return VPBB;
141 }
142
143 // Create new VPBB.
144 StringRef Name = BB->getName();
145 LLVM_DEBUG(dbgs() << "Creating VPBasicBlock for " << Name << "\n");
146 VPBasicBlock *VPBB = Plan->createVPBasicBlock(Name);
147 BB2VPBB[BB] = VPBB;
148 return VPBB;
149}
150
151#ifndef NDEBUG
152// Return true if \p Val is considered an external definition. An external
153// definition is either:
154// 1. A Value that is not an Instruction. This will be refined in the future.
155// 2. An Instruction that is outside of the IR region represented in VPlan,
156// i.e., is not part of the loop nest.
157bool PlainCFGBuilder::isExternalDef(Value *Val) {
158 // All the Values that are not Instructions are considered external
159 // definitions for now.
161 if (!Inst)
162 return true;
163
164 // Check whether Instruction definition is in loop body.
165 return !TheLoop->contains(Inst);
166}
167#endif
168
169// Create a new VPValue or retrieve an existing one for the Instruction's
170// operand \p IRVal. This function must only be used to create/retrieve VPValues
171// for *Instruction's operands* and not to create regular VPInstruction's. For
172// the latter, please, look at 'createVPInstructionsForVPBB'.
173VPValue *PlainCFGBuilder::getOrCreateVPOperand(Value *IRVal) {
174 auto VPValIt = IRDef2VPValue.find(IRVal);
175 if (VPValIt != IRDef2VPValue.end())
176 // Operand has an associated VPInstruction or VPValue that was previously
177 // created.
178 return VPValIt->second;
179
180 // Operand doesn't have a previously created VPInstruction/VPValue. This
181 // means that operand is:
182 // A) a definition external to VPlan,
183 // B) any other Value without specific representation in VPlan.
184 // For now, we use VPValue to represent A and B and classify both as external
185 // definitions. We may introduce specific VPValue subclasses for them in the
186 // future.
187 assert(isExternalDef(IRVal) && "Expected external definition as operand.");
188
189 // A and B: Create VPValue and add it to the pool of external definitions and
190 // to the Value->VPValue map.
191 VPValue *NewVPVal = Plan->getOrAddLiveIn(IRVal);
192 IRDef2VPValue[IRVal] = NewVPVal;
193 return NewVPVal;
194}
195
196// Returns the metadata to preserve for terminator \p Term.
197VPIRMetadata PlainCFGBuilder::getTerminatorMetadata(Instruction &Term) {
198 VPIRMetadata MD(Term);
199 if (MD.getMetadata(LLVMContext::MD_prof))
200 return MD;
201 // Estimates are only read for edges inside the loop region.
202 if (!TheLoop->isInnermost() || Term.getParent() == TheLoop->getLoopLatch())
203 return MD;
204 // The weights describe the edges leaving Term in the order of its successors,
205 // matching the successor order of the VPBasicBlock created for Term's parent.
206 if (!BPI)
207 BPI = &GetBPI();
208 auto Weights = map_to_vector(seq(Term.getNumSuccessors()), [&](unsigned I) {
209 return BPI->getEdgeProbability(Term.getParent(), I).getNumerator();
210 });
211 MD.setEstimatedBranchWeights(
212 MDBuilder(Plan->getContext()).createBranchWeights(Weights));
213 return MD;
214}
215
216// Create new VPInstructions in a VPBasicBlock, given its BasicBlock
217// counterpart. This function must be invoked in RPO so that the operands of a
218// VPInstruction in \p BB have been visited before (except for Phi nodes).
219void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
220 BasicBlock *BB) {
221 VPIRBuilder.setInsertPoint(VPBB);
222 // TODO: Model and preserve debug intrinsics in VPlan.
223 for (Instruction &InstRef : *BB) {
224 Instruction *Inst = &InstRef;
225
226 // There shouldn't be any VPValue for Inst at this point. Otherwise, we
227 // visited Inst when we shouldn't, breaking the RPO traversal order.
228 assert(!IRDef2VPValue.count(Inst) &&
229 "Instruction shouldn't have been visited.");
230
231 if (isa<UncondBrInst>(Inst))
232 // Skip the rest of the Instruction processing for Branch instructions.
233 continue;
234
235 if (auto *Br = dyn_cast<CondBrInst>(Inst)) {
236 // Conditional branch instruction are represented using BranchOnCond
237 // recipes.
238 VPValue *Cond = getOrCreateVPOperand(Br->getCondition());
239 VPIRBuilder.createNaryOp(VPInstruction::BranchOnCond, {Cond}, Inst, {},
240 getTerminatorMetadata(*Inst),
241 Inst->getDebugLoc());
242 continue;
243 }
244
245 if (auto *SI = dyn_cast<SwitchInst>(Inst)) {
246 // Don't emit recipes for unconditional switch instructions.
247 if (SI->getNumCases() == 0)
248 continue;
249 SmallVector<VPValue *> Ops = {getOrCreateVPOperand(SI->getCondition())};
250 for (auto Case : SI->cases())
251 Ops.push_back(getOrCreateVPOperand(Case.getCaseValue()));
252 VPIRBuilder.createNaryOp(Instruction::Switch, Ops, Inst, {},
253 getTerminatorMetadata(*Inst),
254 Inst->getDebugLoc());
255 continue;
256 }
257
258 VPSingleDefRecipe *NewR;
259 if (auto *Phi = dyn_cast<PHINode>(Inst)) {
260 // Phi node's operands may not have been visited at this point. We create
261 // an empty VPInstruction that we will fix once the whole plain CFG has
262 // been built.
263 NewR = VPIRBuilder.createScalarPhi({}, Phi->getDebugLoc(), "vec.phi",
264 *Phi, Phi->getType());
265 NewR->setUnderlyingValue(Phi);
266 if (isHeaderBB(Phi->getParent(), LI->getLoopFor(Phi->getParent()))) {
267 // Header phis need to be fixed after the VPBB for the latch has been
268 // created.
269 PhisToFix.push_back(Phi);
270 } else {
271 // Add operands for VPPhi in the order matching its predecessors in
272 // VPlan.
273 DenseMap<const VPBasicBlock *, VPValue *> VPPredToIncomingValue;
274 for (unsigned I = 0; I != Phi->getNumOperands(); ++I) {
275 VPPredToIncomingValue[BB2VPBB[Phi->getIncomingBlock(I)]] =
276 getOrCreateVPOperand(Phi->getIncomingValue(I));
277 }
278 for (VPBlockBase *Pred : VPBB->getPredecessors())
279 cast<VPPhi>(NewR)->addIncoming(
280 VPPredToIncomingValue.lookup(Pred->getExitingBasicBlock()));
281 }
282 } else {
283 // Build VPIRMetadata from the instruction and add loop versioning
284 // metadata for loads and stores.
285 VPIRMetadata MD(*Inst);
286 if (isa<LoadInst, StoreInst>(Inst) && LVer) {
287 const auto &[AliasScopeMD, NoAliasMD] =
288 LVer->getNoAliasMetadataFor(Inst);
289 if (AliasScopeMD)
290 MD.setMetadata(LLVMContext::MD_alias_scope, AliasScopeMD);
291 if (NoAliasMD)
292 MD.setMetadata(LLVMContext::MD_noalias, NoAliasMD);
293 }
294
295 // Translate LLVM-IR operands into VPValue operands and set them in the
296 // new VPInstruction.
297 SmallVector<VPValue *, 4> VPOperands;
298 for (Value *Op : Inst->operands())
299 VPOperands.push_back(getOrCreateVPOperand(Op));
300 NewR = VPIRBuilder.createNaryOp(Inst->getOpcode(), VPOperands, Inst,
301 VPIRFlags(*Inst), MD, Inst->getDebugLoc(),
302 "", Inst->getType());
303 }
304
305 IRDef2VPValue[Inst] = NewR;
306 }
307}
308
309// Main interface to build the plain CFG.
310std::unique_ptr<VPlan> PlainCFGBuilder::buildPlainCFG() {
311 VPIRBasicBlock *Entry = cast<VPIRBasicBlock>(Plan->getEntry());
312 BB2VPBB[Entry->getIRBasicBlock()] = Entry;
313 for (VPIRBasicBlock *ExitVPBB : Plan->getExitBlocks())
314 BB2VPBB[ExitVPBB->getIRBasicBlock()] = ExitVPBB;
315
316 // 1. Scan the body of the loop in a topological order to visit each basic
317 // block after having visited its predecessor basic blocks. Create a VPBB for
318 // each BB and link it to its successor and predecessor VPBBs. Note that
319 // predecessors must be set in the same order as they are in the incomming IR.
320 // Otherwise, there might be problems with existing phi nodes and algorithm
321 // based on predecessors traversal.
322
323 // Loop PH needs to be explicitly visited since it's not taken into account by
324 // LoopBlocksDFS.
325 BasicBlock *ThePreheaderBB = TheLoop->getLoopPreheader();
326 assert((ThePreheaderBB->getTerminator()->getNumSuccessors() == 1) &&
327 "Unexpected loop preheader");
328 for (auto &I : *ThePreheaderBB) {
329 if (I.getType()->isVoidTy())
330 continue;
331 IRDef2VPValue[&I] = Plan->getOrAddLiveIn(&I);
332 }
333
334 LoopBlocksRPO RPO(TheLoop);
335 RPO.perform(LI);
336
337 for (BasicBlock *BB : RPO) {
338 // Create or retrieve the VPBasicBlock for this BB.
339 VPBasicBlock *VPBB = getOrCreateVPBB(BB);
340 // Set VPBB predecessors in the same order as they are in the incoming BB.
341 setVPBBPredsFromBB(VPBB, BB);
342
343 // Create VPInstructions for BB.
344 createVPInstructionsForVPBB(VPBB, BB);
345
346 // Set VPBB successors. We create empty VPBBs for successors if they don't
347 // exist already. Recipes will be created when the successor is visited
348 // during the RPO traversal.
349 if (auto *SI = dyn_cast<SwitchInst>(BB->getTerminator())) {
351 getOrCreateVPBB(SI->getDefaultDest())};
352 for (auto Case : SI->cases())
353 Succs.push_back(getOrCreateVPBB(Case.getCaseSuccessor()));
354 VPBB->setSuccessors(Succs);
355 continue;
356 }
357 if (auto *BI = dyn_cast<UncondBrInst>(BB->getTerminator())) {
358 VPBB->setOneSuccessor(getOrCreateVPBB(BI->getSuccessor()));
359 continue;
360 }
361 auto *BI = cast<CondBrInst>(BB->getTerminator());
362 BasicBlock *IRSucc0 = BI->getSuccessor(0);
363 BasicBlock *IRSucc1 = BI->getSuccessor(1);
364 VPBasicBlock *Successor0 = getOrCreateVPBB(IRSucc0);
365 VPBasicBlock *Successor1 = getOrCreateVPBB(IRSucc1);
366 VPBB->setTwoSuccessors(Successor0, Successor1);
367 }
368
369 for (auto *EB : Plan->getExitBlocks())
370 setVPBBPredsFromBB(EB, EB->getIRBasicBlock());
371
372 // 2. The whole CFG has been built at this point so all the input Values must
373 // have a VPlan counterpart. Fix VPlan header phi by adding their
374 // corresponding VPlan operands.
375 fixHeaderPhis();
376
377 Plan->getEntry()->setOneSuccessor(getOrCreateVPBB(TheLoop->getHeader()));
378 Plan->getEntry()->setPlan(&*Plan);
379
380 // Fix VPlan loop-closed-ssa exit phi's by adding incoming operands to the
381 // VPIRInstructions wrapping them.
382 // // Note that the operand order corresponds to IR predecessor order, and may
383 // need adjusting when VPlan predecessors are added, if an exit block has
384 // multiple predecessor.
385 for (auto *EB : Plan->getExitBlocks()) {
386 for (VPRecipeBase &R : EB->phis()) {
387 auto *PhiR = cast<VPIRPhi>(&R);
388 PHINode &Phi = PhiR->getIRPhi();
389 assert(PhiR->getNumOperands() == 0 &&
390 "no phi operands should be added yet");
391 for (BasicBlock *Pred : predecessors(EB->getIRBasicBlock()))
392 PhiR->addIncoming(
393 getOrCreateVPOperand(Phi.getIncomingValueForBlock(Pred)));
394 }
395 }
396
397 LLVM_DEBUG(Plan->setName("Plain CFG\n"); dbgs() << *Plan);
398 return std::move(Plan);
399}
400
401/// Checks if \p HeaderVPB is a loop header block in the plain CFG; that is, it
402/// has exactly 2 predecessors (preheader and latch), where the block
403/// dominates the latch and the preheader dominates the block. If it is a
404/// header block return true and canonicalize the predecessors of the header
405/// (making sure the preheader appears first and the latch second) and the
406/// successors of the latch (making sure the loop exit comes first). Otherwise
407/// return false.
409 const VPDominatorTree &VPDT) {
410 ArrayRef<VPBlockBase *> Preds = HeaderVPB->getPredecessors();
411 if (Preds.size() != 2)
412 return false;
413
414 auto *PreheaderVPBB = Preds[0];
415 auto *LatchVPBB = Preds[1];
416 if (!VPDT.dominates(PreheaderVPBB, HeaderVPB) ||
417 !VPDT.dominates(HeaderVPB, LatchVPBB)) {
418 std::swap(PreheaderVPBB, LatchVPBB);
419
420 if (!VPDT.dominates(PreheaderVPBB, HeaderVPB) ||
421 !VPDT.dominates(HeaderVPB, LatchVPBB))
422 return false;
423
424 // Canonicalize predecessors of header so that preheader is first and
425 // latch second.
426 HeaderVPB->swapPredecessors();
427 for (VPRecipeBase &R : cast<VPBasicBlock>(HeaderVPB)->phis())
428 R.swapOperands();
429 }
430
431 // The two successors of conditional branch match the condition, with the
432 // first successor corresponding to true and the second to false. We
433 // canonicalize the successors of the latch when introducing the region, such
434 // that the latch exits the region when its condition is true; invert the
435 // original condition if the original CFG branches to the header on true.
436 // Note that the exit edge is not yet connected for top-level loops.
437 if (LatchVPBB->getSingleSuccessor() ||
438 LatchVPBB->getSuccessors()[0] != HeaderVPB)
439 return true;
440
441 assert(LatchVPBB->getNumSuccessors() == 2 && "Must have 2 successors");
442 auto *Term = cast<VPBasicBlock>(LatchVPBB)->getTerminator();
443 assert(cast<VPInstruction>(Term)->getOpcode() ==
445 "terminator must be a BranchOnCond");
446 auto *Not = new VPInstruction(VPInstruction::Not, {Term->getOperand(0)});
447 Not->insertBefore(Term);
448 Term->setOperand(0, Not);
449 LatchVPBB->swapSuccessors();
450
451 return true;
452}
453
454/// Create a new VPRegionBlock for the loop starting at \p HeaderVPB. For the
455/// outermost loop adjust the regions exiting terminator to be based on the
456/// canonical IV.
457static void createLoopRegion(VPlan &Plan, VPBlockBase *HeaderVPB, DebugLoc DL) {
458 auto *PreheaderVPBB = HeaderVPB->getPredecessors()[0];
459 auto *LatchVPBB = cast<VPBasicBlock>(HeaderVPB->getPredecessors()[1]);
460 auto *OutermostHeaderVPBB =
462
463 VPBlockUtils::disconnectBlocks(PreheaderVPBB, HeaderVPB);
464 VPBlockUtils::disconnectBlocks(LatchVPBB, HeaderVPB);
465
466 // Create an empty region first and insert it between PreheaderVPBB and
467 // the exit blocks, taking care to preserve the original predecessor &
468 // successor order of blocks. Set region entry and exiting after both
469 // HeaderVPB and LatchVPBB have been disconnected from their
470 // predecessors/successors. Only the outermost loop has a canonical IV. Nested
471 // loops are assigned a canonical IV of null type and unknown debug location.
472 bool IsOutermost = HeaderVPB == OutermostHeaderVPBB;
473 Type *CanIVTy = nullptr;
474 if (IsOutermost)
475 CanIVTy = Plan.getVectorTripCount().getType();
476 else
478 auto *R = Plan.createLoopRegion(CanIVTy, DL);
479
480 // Transfer latch's successors to the region.
482
483 VPBlockUtils::connectBlocks(PreheaderVPBB, R);
484 R->setEntry(HeaderVPB);
485 R->setExiting(LatchVPBB);
486
487 // All VPBB's reachable shallowly from HeaderVPB belong to the current region.
488 for (VPBlockBase *VPBB : vp_depth_first_shallow(HeaderVPB))
489 VPBB->setParent(R);
490
491 if (!IsOutermost)
492 return;
493
494 auto *LatchTerm = LatchVPBB->getTerminator();
495 VPBuilder Builder(LatchTerm);
496 // Add a VPInstruction to increment the scalar canonical IV by VF * UF.
497 // Initially the induction increment is guaranteed to not wrap, but that may
498 // change later, e.g. when tail-folding, when the flags need to be dropped.
499 auto *CanonicalIVIncrement = Builder.createAdd(
500 R->getCanonicalIV(), &Plan.getVFxUF(), DL, "index.next", {true, false});
501
502 if (match(LatchTerm, m_BranchOnTwoConds())) {
503 auto *IsLatchExitTaken = Builder.createICmp(
504 CmpInst::ICMP_EQ, CanonicalIVIncrement, &Plan.getVectorTripCount());
505 LatchTerm->setOperand(1, IsLatchExitTaken);
506 } else {
507 // We are replacing the branch to exit the region. Remove the original
508 // BranchOnCond.
509 assert(match(LatchTerm, m_BranchOnCond()) && "Unexpected terminator");
510 DebugLoc LatchDL = LatchTerm->getDebugLoc();
511 Builder.createNaryOp(VPInstruction::BranchOnCount,
512 {CanonicalIVIncrement, &Plan.getVectorTripCount()},
513 LatchDL);
514 LatchTerm->eraseFromParent();
515 }
516}
517
518/// Creates extracts for values in \p Plan defined in a loop region and used
519/// outside a loop region.
520static void createExtractsForLiveOuts(VPlan &Plan, VPBasicBlock *MiddleVPBB) {
521 VPBuilder B(MiddleVPBB, MiddleVPBB->getFirstNonPhi());
522 for (VPBasicBlock *EB : Plan.getExitBlocks()) {
523 if (!is_contained(EB->predecessors(), MiddleVPBB))
524 continue;
525
526 for (VPRecipeBase &R : EB->phis()) {
527 auto *ExitIRI = cast<VPIRPhi>(&R);
528 VPValue *Exiting = ExitIRI->getIncomingValueForBlock(MiddleVPBB);
529 if (isa<VPIRValue>(Exiting))
530 continue;
531 Exiting = B.createNaryOp(VPInstruction::ExtractLastPart, Exiting);
532 Exiting = B.createNaryOp(VPInstruction::ExtractLastLane, Exiting);
533 ExitIRI->setIncomingValueForBlock(MiddleVPBB, Exiting);
534 }
535 }
536}
537
538static void addInitialSkeleton(VPlan &Plan, Type *InductionTy,
539 PredicatedScalarEvolution &PSE, Loop *TheLoop) {
540 VPDominatorTree VPDT(Plan);
541
542 auto *HeaderVPBB = cast<VPBasicBlock>(Plan.getEntry()->getSingleSuccessor());
543 canonicalHeaderAndLatch(HeaderVPBB, VPDT);
544 auto *LatchVPBB = cast<VPBasicBlock>(HeaderVPBB->getPredecessors()[1]);
545
546 VPBasicBlock *VecPreheader = Plan.createVPBasicBlock("vector.ph");
547 VPBlockUtils::insertBlockAfter(VecPreheader, Plan.getEntry());
548
549 VPBasicBlock *MiddleVPBB = Plan.createVPBasicBlock("middle.block");
550 // The canonical LatchVPBB has the header block as last successor. If it has
551 // another successor, this successor is an exit block - insert middle block on
552 // its edge. Otherwise, add middle block as another successor retaining header
553 // as last. In the latter case, the latch has no conditional terminator yet,
554 // so insert a placeholder BranchOnCond that always continues to the header.
555 // It will be canonicalized to a BranchOnCount later
556 if (LatchVPBB->getNumSuccessors() == 2) {
557 VPBlockBase *LatchExitVPB = LatchVPBB->getSuccessors()[0];
558 VPBlockUtils::insertOnEdge(LatchVPBB, LatchExitVPB, MiddleVPBB);
559 } else {
560 VPBlockUtils::connectBlocks(LatchVPBB, MiddleVPBB);
561 LatchVPBB->swapSuccessors();
563 {Plan.getFalse()});
564 }
565
566 // Create SCEV and VPValue for the trip count.
567 // We use the symbolic max backedge-taken-count, which works also when
568 // vectorizing loops with uncountable early exits.
569 const SCEV *BackedgeTakenCountSCEV = PSE.getSymbolicMaxBackedgeTakenCount();
570 assert(!isa<SCEVCouldNotCompute>(BackedgeTakenCountSCEV) &&
571 "Invalid backedge-taken count");
572 ScalarEvolution &SE = *PSE.getSE();
573 const SCEV *TripCount = SE.getTripCountFromExitCount(BackedgeTakenCountSCEV,
574 InductionTy, TheLoop);
576
577 VPBasicBlock *ScalarPH = Plan.createVPBasicBlock("scalar.ph");
579
580 // The connection order corresponds to the operands of the conditional branch,
581 // with the middle block already connected to the exit block.
582 VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH);
583 // Also connect the entry block to the scalar preheader.
584 // TODO: Also introduce a branch recipe together with the minimum trip count
585 // check.
586 VPBlockUtils::connectBlocks(Plan.getEntry(), ScalarPH);
587 Plan.getEntry()->swapSuccessors();
588
589 createExtractsForLiveOuts(Plan, MiddleVPBB);
590
591 // Create resume phis in the scalar preheader for each phi in the scalar loop.
592 // Their incoming value from the vector loop will be the last lane of the
593 // corresponding vector loop header phi.
594 VPBuilder MiddleBuilder(MiddleVPBB, MiddleVPBB->getFirstNonPhi());
595 VPBuilder ScalarPHBuilder(ScalarPH);
596 assert(equal(ScalarPH->getPredecessors(),
597 ArrayRef<VPBlockBase *>({MiddleVPBB, Plan.getEntry()})) &&
598 "unexpected predecessor order of scalar ph");
599 for (const auto &[PhiR, ScalarPhiR] :
600 zip_equal(HeaderVPBB->phis(), Plan.getScalarHeader()->phis())) {
601 auto *VectorPhiR = cast<VPPhi>(&PhiR);
602 VPValue *BackedgeVal = VectorPhiR->getOperand(1);
603 VPValue *ResumeFromVectorLoop =
604 MiddleBuilder.createNaryOp(VPInstruction::ExtractLastPart, BackedgeVal);
605 ResumeFromVectorLoop = MiddleBuilder.createNaryOp(
606 VPInstruction::ExtractLastLane, ResumeFromVectorLoop);
607 // Create scalar resume phi, with the first operand being the incoming value
608 // from the middle block and the second operand coming from the entry block.
609 auto *ResumePhiR = ScalarPHBuilder.createScalarPhi(
610 {ResumeFromVectorLoop, VectorPhiR->getOperand(0)},
611 VectorPhiR->getDebugLoc());
612 cast<VPIRPhi>(&ScalarPhiR)->addIncoming(ResumePhiR);
613 }
614}
615
616/// To make RUN_VPLAN_PASS print initial VPlan.
618
619std::unique_ptr<VPlan> VPlanTransforms::buildVPlan0(
620 Loop *TheLoop, LoopInfo &LI, Type *InductionTy,
622 function_ref<const BranchProbabilityInfo &()> GetBPI) {
623 PlainCFGBuilder Builder(TheLoop, &LI, LVer, InductionTy, GetBPI);
624 std::unique_ptr<VPlan> VPlan0 = Builder.buildPlainCFG();
625 addInitialSkeleton(*VPlan0, InductionTy, PSE, TheLoop);
626 simplifyLiveInsWithSCEV(*VPlan0, PSE);
627
629 return VPlan0;
630}
631
635 auto Frequencies = vputils::computeExecutionFrequencies(Blocks);
636 LLVMContext &Ctx = Plan.getContext();
637 for (VPBasicBlock *VPBB : Blocks) {
638 std::optional<VPExecutionFrequency> Freq = Frequencies.lookup(VPBB);
640 VPI.setExecutionFrequency(Freq, Ctx);
641 }
642}
643
644/// Creates a VPWidenIntOrFpInductionRecipe or VPWidenPointerInductionRecipe
645/// for \p Phi based on \p IndDesc.
646static VPHeaderPHIRecipe *
648 const InductionDescriptor &IndDesc, VPlan &Plan,
649 PredicatedScalarEvolution &PSE, Loop &OrigLoop,
650 DebugLoc DL) {
651 [[maybe_unused]] ScalarEvolution &SE = *PSE.getSE();
652 assert(SE.isLoopInvariant(IndDesc.getStep(), &OrigLoop) &&
653 "step must be loop invariant");
654 assert((Plan.getLiveIn(IndDesc.getStartValue()) == Start ||
655 (SE.isSCEVable(IndDesc.getStartValue()->getType()) &&
656 PSE.getSCEV(IndDesc.getStartValue()) ==
657 vputils::getSCEVExprForVPValue(Start, PSE))) &&
658 "Start VPValue must match IndDesc's start value");
659
660 VPValue *Step =
662
663 VPValue *BackedgeVal = PhiR->getOperand(1);
664 // Replace live-out extracts of WideIV's backedge value by ExitingIVValue
665 // recipes. optimizeInductionLiveOutUsers will later compute the proper
666 // DerivedIV.
667 //
668 // For an IV that requires SCEV predicate, keep extracting the exit values
669 // from the loop directly, as the pre-computed exit value as-is would be
670 // incorrect outside the loop.
671 auto ReplaceExtractsWithExitingIVValueIfPossible = [&](VPWidenInductionRecipe
672 *WideIV) {
673 bool IsPredicated = !WideIV->getNoWrapPredicates().empty();
674 for (VPUser *U : to_vector(BackedgeVal->users())) {
676 continue;
677 auto *ExtractLastPart = cast<VPInstruction>(U);
678 VPUser *ExtractLastPartUser = ExtractLastPart->getSingleUser();
679 assert(ExtractLastPartUser && "must have a single user");
680 if (!match(ExtractLastPartUser, m_ExtractLastLane(m_VPValue())))
681 continue;
682 auto *ExtractLastLane = cast<VPInstruction>(ExtractLastPartUser);
683 assert(is_contained(ExtractLastLane->getParent()->successors(),
684 Plan.getScalarPreheader()) &&
685 "last lane must be extracted in the middle block");
686 // Keep the vector extract for exit-block live-out uses of a predicated
687 // IV.
688 if (IsPredicated &&
689 any_of(ExtractLastLane->users(), [&](VPUser *LaneUser) {
690 auto *R = cast<VPRecipeBase>(LaneUser);
691 return Plan.isExitBlock(R->getParent());
692 }))
693 continue;
694 VPBuilder Builder(ExtractLastLane);
695 ExtractLastLane->replaceAllUsesWith(
696 Builder.createNaryOp(VPInstruction::ExitingIVValue, {WideIV}));
697 ExtractLastLane->eraseFromParent();
698 ExtractLastPart->eraseFromParent();
699 }
700 };
701
703 auto *WideIV = new VPWidenPointerInductionRecipe(
704 Phi, Start, Step, &Plan.getVFxUF(), IndDesc, DL);
705 ReplaceExtractsWithExitingIVValueIfPossible(WideIV);
706 return WideIV;
707 }
708
711 "must have an integer or float induction at this point");
712
713 // Update wide induction increments to use the same step as the corresponding
714 // wide induction. This enables detecting induction increments directly in
715 // VPlan and removes redundant splats.
716 if (match(BackedgeVal, m_Add(m_Specific(PhiR), m_VPValue())))
717 BackedgeVal->getDefiningRecipe()->setOperand(1, Step);
718
719 // It is always safe to copy over the NoWrap and FastMath flags. In
720 // particular, when folding tail by masking, the masked-off lanes are never
721 // used, so it is safe.
723
724 auto *WideIV = new VPWidenIntOrFpInductionRecipe(
725 Phi, Start, Step, &Plan.getVF(), IndDesc, Flags, DL);
726
727 ReplaceExtractsWithExitingIVValueIfPossible(WideIV);
728 return WideIV;
729}
730
731/// Try to sink users of \p FOR after \p Previous. \returns true if sinking
732/// succeeded or was not necessary, and false otherwise.
733static bool
735 VPRecipeBase *Previous,
736 const VPDominatorTree &VPDT) {
737 // Collect recipes that need sinking.
740 Seen.insert(Previous);
741 auto TryToPushSinkCandidate = [&](VPRecipeBase *SinkCandidate) {
742 // The previous value must not depend on the users of the recurrence phi.
743 // In that case, FOR is not a fixed order recurrence.
744 if (SinkCandidate == Previous)
745 return false;
746
747 if (isa<VPHeaderPHIRecipe>(SinkCandidate) ||
748 !Seen.insert(SinkCandidate).second ||
749 VPDT.properlyDominates(Previous, SinkCandidate))
750 return true;
751
752 if (vputils::cannotHoistOrSinkRecipe(*SinkCandidate, /*Sinking=*/true))
753 return false;
754
755 WorkList.push_back(SinkCandidate);
756 return true;
757 };
758
759 // Recursively sink users of FOR after Previous.
760 WorkList.push_back(FOR);
761 for (unsigned I = 0; I != WorkList.size(); ++I) {
762 VPRecipeBase *Current = WorkList[I];
763 assert(Current->getNumDefinedValues() == 1 &&
764 "only recipes with a single defined value expected");
765
766 for (VPUser *User : Current->getVPSingleValue()->users()) {
767 if (!TryToPushSinkCandidate(cast<VPRecipeBase>(User)))
768 return false;
769 }
770 }
771
772 // Keep recipes to sink ordered by dominance so earlier instructions are
773 // processed first.
774 sort(WorkList, [&VPDT](const VPRecipeBase *A, const VPRecipeBase *B) {
775 return VPDT.properlyDominates(A, B);
776 });
777
778 for (VPRecipeBase *SinkCandidate : WorkList) {
779 if (SinkCandidate == FOR)
780 continue;
781
782 SinkCandidate->moveAfter(Previous);
783 Previous = SinkCandidate;
784 }
785 return true;
786}
787
788/// Try to hoist \p Previous and its operands before all users of \p FOR.
789/// \returns true if hoisting succeeded or was not necessary, and false
790/// otherwise.
792 VPRecipeBase *Previous,
793 const VPDominatorTree &VPDT) {
795 return false;
796
797 // Collect recipes that need hoisting.
798 SmallVector<VPRecipeBase *> HoistCandidates;
800 // Find the closest hoist point by looking at all users of FOR and selecting
801 // the recipe dominating all other users.
802 VPRecipeBase *HoistPoint = nullptr;
803 for (VPUser *U : FOR->users()) {
804 auto *R = cast<VPRecipeBase>(U);
805 if (!HoistPoint || VPDT.properlyDominates(R, HoistPoint))
806 HoistPoint = R;
807 }
808 // Dominance is only a partial order, so the users of FOR may not have a
809 // single user dominating all others. Bail out in that case.
810 if (!HoistPoint || HoistPoint->isPhi() ||
811 any_of(FOR->users(), [&VPDT, HoistPoint](VPUser *U) {
812 auto *R = cast<VPRecipeBase>(U);
813 return HoistPoint != R && !VPDT.properlyDominates(HoistPoint, R);
814 }))
815 return false;
816
817 auto NeedsHoisting = [HoistPoint, &VPDT,
818 &Visited](VPValue *HoistCandidateV) -> VPRecipeBase * {
819 VPRecipeBase *HoistCandidate = HoistCandidateV->getDefiningRecipe();
820 if (!HoistCandidate)
821 return nullptr;
822 // Hoist candidate was already visited, no need to hoist.
823 if (!Visited.insert(HoistCandidate).second)
824 return nullptr;
825 // If we reached a recipe that dominates HoistPoint, we don't need to
826 // hoist the recipe.
827 if (VPDT.properlyDominates(HoistCandidate, HoistPoint))
828 return nullptr;
829 return HoistCandidate;
830 };
831
832 if (!NeedsHoisting(Previous->getVPSingleValue()))
833 return true;
834
835 // Recursively try to hoist Previous and its operands before all users of
836 // FOR.
837 HoistCandidates.push_back(Previous);
838
839 for (unsigned I = 0; I != HoistCandidates.size(); ++I) {
840 VPRecipeBase *Current = HoistCandidates[I];
841 assert(Current->getNumDefinedValues() == 1 &&
842 "only recipes with a single defined value expected");
844 return false;
845
846 for (VPValue *Op : Current->operands()) {
847 // If we reach FOR, it means the original Previous depends on some other
848 // recurrence that in turn depends on FOR. If that is the case, we would
849 // also need to hoist recipes involving the other FOR, which may break
850 // dependencies.
851 if (Op == FOR)
852 return false;
853
854 if (auto *R = NeedsHoisting(Op)) {
855 // Bail out if the recipe defines multiple values.
856 // TODO: Hoisting such recipes requires additional handling.
857 if (R->getNumDefinedValues() != 1)
858 return false;
859 HoistCandidates.push_back(R);
860 }
861 }
862 }
863
864 // Moving a candidate to HoistPoint keeps it dominating its other users only
865 // if HoistPoint dominates the candidate's current position.
866 if (any_of(HoistCandidates, [&VPDT, HoistPoint](VPRecipeBase *R) {
867 return !VPDT.properlyDominates(HoistPoint, R);
868 }))
869 return false;
870
871 // Order recipes to hoist by dominance so earlier instructions are processed
872 // first.
873 sort(HoistCandidates, [&VPDT](const VPRecipeBase *A, const VPRecipeBase *B) {
874 return VPDT.properlyDominates(A, B);
875 });
876
877 for (VPRecipeBase *HoistCandidate : HoistCandidates) {
878 HoistCandidate->moveBefore(*HoistPoint->getParent(),
879 HoistPoint->getIterator());
880 }
881
882 return true;
883}
884
885/// Sink users of fixed-order recurrences past or hoist before the recipe
886/// defining the previous value, introduce FirstOrderRecurrenceSplice
887/// VPInstructions, and replace FOR uses. Returns false if hoisting or sinking
888/// fails.
890 const VPDominatorTree &VPDT) {
891 auto FORs =
894 [](VPRecipeBase &R) {
895 return cast<VPFirstOrderRecurrencePHIRecipe>(&R);
896 });
897 for (VPFirstOrderRecurrencePHIRecipe *FOR : FORs) {
898 // Follow through FOR phi chains to find the actual Previous recipe.
899 // Fixed-order recurrences do not contain cycles, so this loop is
900 // guaranteed to terminate.
902 VPRecipeBase *Previous = FOR->getBackedgeValue()->getDefiningRecipe();
903 while (auto *PrevPhi =
905 assert(PrevPhi->getParent() == FOR->getParent() &&
906 "PrevPhi must be in same block as FOR");
907 assert(SeenPhis.insert(PrevPhi).second &&
908 "PrevPhi must not be visited multiple times");
909 Previous = PrevPhi->getBackedgeValue()->getDefiningRecipe();
910 }
911
912 VPBasicBlock *InsertBlock = FOR->getParent();
913 VPBasicBlock::iterator InsertPt = InsertBlock->getFirstNonPhi();
914 if (Previous) {
915 // Sink FOR users after Previous or hoist Previous before FOR users.
916 if (!sinkRecurrenceUsersAfterPrevious(FOR, Previous, VPDT) &&
917 !hoistPreviousBeforeFORUsers(FOR, Previous, VPDT))
918 return false;
919 InsertBlock = Previous->getParent();
920 InsertPt = isa<VPHeaderPHIRecipe>(Previous)
921 ? InsertBlock->getFirstNonPhi()
922 : std::next(Previous->getIterator());
923 }
924
925 // Create FirstOrderRecurrenceSplice and replace FOR uses.
926 VPBuilder LoopBuilder(InsertBlock, InsertPt);
927 auto *RecurSplice =
929 {FOR, FOR->getBackedgeValue()});
930 FOR->replaceUsesWithIf(RecurSplice, [RecurSplice](VPUser &U, unsigned) {
931 return &U != RecurSplice;
932 });
933 }
934
935 return true;
936}
937
939 VPlan &Plan, PredicatedScalarEvolution &PSE, Loop &OrigLoop,
940 const VPDominatorTree &VPDT,
943 const SmallPtrSetImpl<const PHINode *> &FixedOrderRecurrences,
944 const SmallPtrSetImpl<PHINode *> &InLoopReductions, bool AllowReordering) {
945 // Retrieve the header manually from the intial plain-CFG VPlan.
946 auto [HeaderVPBB, LatchVPBB] = VPBlockUtils::getPlainCFGHeaderAndLatch(Plan);
947 assert(VPDT.dominates(HeaderVPBB, LatchVPBB) &&
948 "header must dominate its latch");
949
950 auto CreateHeaderPhiRecipe = [&](VPPhi *PhiR) -> VPHeaderPHIRecipe * {
951 // TODO: Gradually replace uses of underlying instruction by analyses on
952 // VPlan.
953 auto *Phi = cast<PHINode>(PhiR->getUnderlyingInstr());
954 assert(PhiR->getNumOperands() == 2 &&
955 "Must have 2 operands for header phis");
956
957 // Extract common values once.
958 VPIRValue *Start = cast<VPIRValue>(PhiR->getOperand(0));
959 VPValue *BackedgeValue = PhiR->getOperand(1);
960
961 if (FixedOrderRecurrences.contains(Phi)) {
962 // TODO: Currently fixed-order recurrences are modeled as chains of
963 // first-order recurrences. If there are no users of the intermediate
964 // recurrences in the chain, the fixed order recurrence should be
965 // modeled directly, enabling more efficient codegen.
966 return new VPFirstOrderRecurrencePHIRecipe(Phi, *Start, *BackedgeValue);
967 }
968
969 auto InductionIt = Inductions.find(Phi);
970 if (InductionIt != Inductions.end())
971 return createWidenInductionRecipe(Phi, PhiR, Start, InductionIt->second,
972 Plan, PSE, OrigLoop,
973 PhiR->getDebugLoc());
974
975 assert(Reductions.contains(Phi) && "only reductions are expected now");
976 const RecurrenceDescriptor &RdxDesc = Reductions.lookup(Phi);
978 Phi->getIncomingValueForBlock(OrigLoop.getLoopPreheader()) &&
979 "incoming value must match start value");
980 // Will be updated later to >1 if reduction is partial.
981 unsigned ScaleFactor = 1;
982 bool UseOrderedReductions = !AllowReordering && RdxDesc.isOrdered();
983 return new VPReductionPHIRecipe(
984 Phi, RdxDesc.getRecurrenceKind(), *Start, *BackedgeValue,
985 getReductionStyle(InLoopReductions.contains(Phi), UseOrderedReductions,
986 ScaleFactor),
987 Phi->getType()->isFloatingPointTy() ? RdxDesc.getFastMathFlags()
988 : VPIRFlags(),
990 };
991
992 for (VPRecipeBase &R : make_early_inc_range(HeaderVPBB->phis())) {
993 auto *PhiR = cast<VPPhi>(&R);
994 VPHeaderPHIRecipe *HeaderPhiR = CreateHeaderPhiRecipe(PhiR);
995 HeaderPhiR->insertBefore(PhiR);
996 PhiR->replaceAllUsesWith(HeaderPhiR);
997 PhiR->eraseFromParent();
998 }
999
1000 if (!tryToSinkOrHoistRecurrenceUsers(HeaderVPBB, VPDT))
1001 return false;
1002
1003 // Skip renaming resume phi recipes, if any header phi has been removed.
1004 if (range_size(HeaderVPBB->phis()) !=
1006 return true;
1007 for (const auto &[HeaderPhiR, ScalarPhiR] :
1008 zip_equal(HeaderVPBB->phis(), Plan.getScalarPreheader()->phis())) {
1009 auto *ResumePhiR = cast<VPPhi>(&ScalarPhiR);
1010 if (isa<VPFirstOrderRecurrencePHIRecipe>(&HeaderPhiR)) {
1011 ResumePhiR->setName("scalar.recur.init");
1012 auto *ExtractLastLane = cast<VPInstruction>(ResumePhiR->getOperand(0));
1013 ExtractLastLane->setName("vector.recur.extract");
1014 continue;
1015 }
1016 ResumePhiR->setName(isa<VPWidenInductionRecipe>(HeaderPhiR)
1017 ? "bc.resume.val"
1018 : "bc.merge.rdx");
1019 }
1020 return true;
1021}
1022
1025 bool OptForSize,
1026 unsigned SCEVCheckThreshold,
1028 Loop *TheLoop) {
1029 // Collect which wide IVs have predicates and add them to PSE.
1030 auto [HeaderVPBB, _] = VPBlockUtils::getPlainCFGHeaderAndLatch(Plan);
1032 for (VPWidenInductionRecipe &WideIV :
1033 make_isa_range<VPWidenInductionRecipe>(HeaderVPBB->phis())) {
1034 if (WideIV.getNoWrapPredicates().empty())
1035 continue;
1036 PredicatedIVs.insert(&WideIV);
1037 for (const auto *P : WideIV.getNoWrapPredicates())
1038 PSE.addPredicate(*P);
1039 }
1040
1041 unsigned TotalComplexity = PSE.getPredicate().getComplexity();
1042 if (TotalComplexity && OptForSize) {
1043 LLVM_DEBUG(
1044 dbgs() << "LV: Not vectorizing: SCEV predicates needed for induction "
1045 "but optimizing for size\n");
1047 "Runtime SCEV check is required with -Os/-Oz",
1048 "runtime SCEV checks needed but optimizing for size",
1049 "CantVersionLoopWithOptForSize", ORE, TheLoop);
1050 return false;
1051 }
1052
1053 if (TotalComplexity > SCEVCheckThreshold) {
1054 LLVM_DEBUG(dbgs() << "LV: Not vectorizing: Too many SCEV checks needed ("
1055 << TotalComplexity << " > " << SCEVCheckThreshold
1056 << ")\n");
1058 "Too many SCEV checks needed",
1059 "Too many SCEV assumptions need to be made and checked at runtime",
1060 "TooManySCEVRunTimeChecks", ORE, TheLoop);
1061 return false;
1062 }
1063
1064 return true;
1065}
1066
1068 ElementCount MinVF) {
1071
1072 for (VPRecipeBase &R : Header->phis()) {
1073 auto *PhiR = dyn_cast<VPReductionPHIRecipe>(&R);
1074 if (!PhiR || !PhiR->isInLoop() || (MinVF.isScalar() && !PhiR->isOrdered()))
1075 continue;
1076
1077 RecurKind Kind = PhiR->getRecurrenceKind();
1081 "AnyOf and Find reductions are not allowed for in-loop reductions");
1082
1083 bool IsFPRecurrence =
1085 FastMathFlags FMFs =
1086 IsFPRecurrence ? FastMathFlags::getFast() : FastMathFlags();
1087
1088 // Collect the chain of "link" recipes for the reduction starting at PhiR.
1090 Worklist.insert(PhiR);
1091 for (unsigned I = 0; I != Worklist.size(); ++I) {
1092 VPSingleDefRecipe *Cur = Worklist[I];
1093 for (VPUser *U : Cur->users()) {
1094 auto *UserRecipe = cast<VPSingleDefRecipe>(U);
1095 if (!UserRecipe->getParent()->getEnclosingLoopRegion()) {
1096 assert((UserRecipe->getParent() == Plan.getMiddleBlock() ||
1097 UserRecipe->getParent() == Plan.getScalarPreheader()) &&
1098 "U must be either in the loop region, the middle block or the "
1099 "scalar preheader.");
1100 continue;
1101 }
1102
1103 // Stores using instructions will be sunk later.
1104 if (match(UserRecipe, m_VPInstruction<Instruction::Store>()))
1105 continue;
1106 Worklist.insert(UserRecipe);
1107 }
1108 }
1109
1110 // Visit operation "Links" along the reduction chain top-down starting from
1111 // the phi until LoopExitValue. We keep track of the previous item
1112 // (PreviousLink) to tell which of the two operands of a Link will remain
1113 // scalar and which will be reduced. For minmax by select(cmp), Link will be
1114 // the select instructions. Blend recipes of in-loop reduction phi's will
1115 // get folded to their non-phi operand, as the reduction recipe handles the
1116 // condition directly.
1117 VPSingleDefRecipe *PreviousLink = PhiR; // Aka Worklist[0].
1118 for (VPSingleDefRecipe *CurrentLink : drop_begin(Worklist)) {
1119 if (auto *Blend = dyn_cast<VPBlendRecipe>(CurrentLink)) {
1120 assert(Blend->getNumIncomingValues() == 2 &&
1121 "Blend must have 2 incoming values");
1122 unsigned PhiRIdx = Blend->getIncomingValue(0) == PhiR ? 0 : 1;
1123 assert(Blend->getIncomingValue(PhiRIdx) == PhiR &&
1124 "PhiR must be an operand of the blend");
1125 Blend->replaceAllUsesWith(Blend->getIncomingValue(1 - PhiRIdx));
1126 continue;
1127 }
1128
1129 if (IsFPRecurrence) {
1130 FastMathFlags CurFMF =
1131 cast<VPRecipeWithIRFlags>(CurrentLink)->getFastMathFlagsOrNone();
1132 if (match(CurrentLink, m_Select(m_VPValue(), m_VPValue(), m_VPValue())))
1133 CurFMF |= cast<VPRecipeWithIRFlags>(CurrentLink->getOperand(0))
1134 ->getFastMathFlagsOrNone();
1135 FMFs &= CurFMF;
1136 }
1137
1138 Instruction *CurrentLinkI = CurrentLink->getUnderlyingInstr();
1139
1140 // Recognize a call to the llvm.fmuladd intrinsic.
1141 bool IsFMulAdd = Kind == RecurKind::FMulAdd;
1142 VPValue *VecOp;
1143 VPBasicBlock *LinkVPBB = CurrentLink->getParent();
1144 if (IsFMulAdd) {
1146 "Expected current VPInstruction to be a call to the "
1147 "llvm.fmuladd intrinsic");
1148 assert(CurrentLink->getOperand(2) == PreviousLink &&
1149 "expected a call where the previous link is the added operand");
1150
1151 // If the instruction is a call to the llvm.fmuladd intrinsic then we
1152 // need to create an fmul recipe (multiplying the first two operands of
1153 // the fmuladd together) to use as the vector operand for the fadd
1154 // reduction.
1155 auto *FMulRecipe = new VPInstruction(
1156 Instruction::FMul,
1157 {CurrentLink->getOperand(0), CurrentLink->getOperand(1)},
1158 CurrentLinkI->getFastMathFlags());
1159 LinkVPBB->insert(FMulRecipe, CurrentLink->getIterator());
1160 VecOp = FMulRecipe;
1161 } else if (Kind == RecurKind::AddChainWithSubs &&
1162 match(CurrentLink, m_Sub(m_VPValue(), m_VPValue()))) {
1163 Type *PhiTy = PhiR->getScalarType();
1164 auto *Zero = Plan.getConstantInt(PhiTy, 0);
1165 VPBuilder Builder(LinkVPBB, CurrentLink->getIterator());
1166 auto *Sub = Builder.createSub(Zero, CurrentLink->getOperand(1),
1167 CurrentLinkI->getDebugLoc());
1168 Sub->setUnderlyingValue(CurrentLinkI);
1169 VecOp = Sub;
1170 } else {
1171 // Index of the first operand which holds a non-mask vector operand.
1172 unsigned IndexOfFirstOperand = 0;
1174 if (match(CurrentLink, m_Cmp(m_VPValue(), m_VPValue())))
1175 continue;
1176 assert(match(CurrentLink,
1178 "must be a select recipe");
1179 IndexOfFirstOperand = 1;
1180 }
1181 // Note that for non-commutable operands (cmp-selects), the semantics of
1182 // the cmp-select are captured in the recurrence kind.
1183 unsigned VecOpId =
1184 CurrentLink->getOperand(IndexOfFirstOperand) == PreviousLink
1185 ? IndexOfFirstOperand + 1
1186 : IndexOfFirstOperand;
1187 VecOp = CurrentLink->getOperand(VecOpId);
1188 assert(
1189 VecOp != PreviousLink &&
1190 CurrentLink->getOperand(
1191 cast<VPInstruction>(CurrentLink)->getNumOperandsWithoutMask() -
1192 1 - (VecOpId - IndexOfFirstOperand)) == PreviousLink &&
1193 "PreviousLink must be the operand other than VecOp");
1194 }
1195
1196 assert(PhiR->getVFScaleFactor() == 1 &&
1197 "inloop reductions must be unscaled");
1198 VPValue *CondOp = cast<VPInstruction>(CurrentLink)->getMask();
1199 auto *RedRecipe = new VPReductionRecipe(
1200 Kind, FMFs, CurrentLinkI, PreviousLink, VecOp, CondOp,
1201 getReductionStyle(/*IsInLoop=*/true, PhiR->isOrdered(), 1),
1202 CurrentLinkI->getDebugLoc());
1203 // Append the recipe to the end of the VPBasicBlock because we need to
1204 // ensure that it comes after all of it's inputs, including CondOp.
1205 // Delete CurrentLink as it will be invalid if its operand is replaced
1206 // with a reduction defined at the bottom of the block in the next link.
1207 if (LinkVPBB->getNumSuccessors() == 0)
1208 RedRecipe->insertBefore(&*std::prev(std::prev(LinkVPBB->end())));
1209 else
1210 LinkVPBB->appendRecipe(RedRecipe);
1211
1212 CurrentLink->replaceAllUsesWith(RedRecipe);
1213 // Move any store recipes using the RedRecipe that appear before it in the
1214 // same block to just after the RedRecipe.
1215 for (VPRecipeBase *UserR : make_early_inc_range(
1216 make_isa_range<VPRecipeBase>(RedRecipe->users()))) {
1217 if (UserR->getParent() != LinkVPBB)
1218 continue;
1220 continue;
1221 UserR->moveAfter(RedRecipe);
1222 }
1223 ToDelete.push_back(CurrentLink);
1224 PreviousLink = RedRecipe;
1225 }
1226 }
1227
1228 for (VPRecipeBase *R : ToDelete)
1229 R->eraseFromParent();
1230}
1231
1233 Loop *TheLoop,
1235 DominatorTree &DT,
1236 AssumptionCache *AC) {
1237 ScalarEvolution &SE = *PSE.getSE();
1238 const DataLayout &DL = TheLoop->getHeader()->getDataLayout();
1239 for (VPBasicBlock *VPBB : vp_rpo_plain_cfg_loop_body(HeaderVPBB)) {
1240 for (VPRecipeBase &R : *VPBB) {
1241 auto *VPI = dyn_cast<VPInstruction>(&R);
1242 if (!VPI || VPI->getOpcode() != Instruction::Load) {
1243 assert(!R.mayReadFromMemory() && "unexpected recipe reading memory");
1244 continue;
1245 }
1246
1247 // Get the pointer SCEV for dereferenceability checking.
1248 VPValue *Ptr = VPI->getOperand(0);
1249 const SCEV *PtrSCEV = vputils::getSCEVExprForVPValue(Ptr, PSE, TheLoop);
1250 if (isa<SCEVCouldNotCompute>(PtrSCEV)) {
1251 LLVM_DEBUG(dbgs() << "LV: Not vectorizing: Found non-dereferenceable "
1252 "load with SCEVCouldNotCompute pointer\n");
1253 return false;
1254 }
1255
1256 // Check dereferenceability using the SCEV-based version.
1257 Type *LoadTy = VPI->getScalarType();
1258 const SCEV *SizeSCEV =
1259 SE.getStoreSizeOfExpr(DL.getIndexType(PtrSCEV->getType()), LoadTy);
1260 auto *Load = cast<LoadInst>(VPI->getUnderlyingValue());
1262 if (isDereferenceableAndAlignedInLoop(PtrSCEV, Load->getAlign(), SizeSCEV,
1263 TheLoop, SE, DT, AC, &Preds))
1264 continue;
1265
1266 return false;
1267 }
1268 }
1269 return true;
1270}
1271
1273 auto *MiddleVPBB = VPBlockUtils::getPlainCFGMiddleBlock(Plan);
1274 // Disconnect countable early exits from the loop, leaving it with a single
1275 // exit from the latch. Countable early exits are left for a scalar epilog.
1276 for (auto [EarlyExitingVPBB, EB] : vputils::getEarlyExits(Plan, MiddleVPBB)) {
1277 // Remove phi operands for the early exiting block.
1278 for (VPRecipeBase &R : EB->phis())
1279 cast<VPIRPhi>(&R)->removeIncomingValueFor(EarlyExitingVPBB);
1280 EarlyExitingVPBB->getTerminator()->eraseFromParent();
1281 VPBlockUtils::disconnectBlocks(EarlyExitingVPBB, EB);
1282 }
1283}
1284
1286 auto *MiddleVPBB = VPBlockUtils::getPlainCFGMiddleBlock(Plan);
1287 // If MiddleVPBB has a single successor then the original loop does not exit
1288 // via the latch and the single successor must be the scalar preheader.
1289 // There's no need to add a runtime check to MiddleVPBB.
1290 if (MiddleVPBB->getNumSuccessors() == 1) {
1291 assert(MiddleVPBB->getSingleSuccessor() == Plan.getScalarPreheader() &&
1292 "must have ScalarPH as single successor");
1293 return;
1294 }
1295
1296 assert(MiddleVPBB->getNumSuccessors() == 2 && "must have 2 successors");
1297
1298 // Add a check in the middle block to see if we have completed all of the
1299 // iterations in the first vector loop.
1300 //
1301 // Three cases:
1302 // 1) If we require a scalar epilogue, the scalar ph must execute. Set the
1303 // condition to false.
1304 // 2) If (N - N%VF) == N, then we *don't* need to run the
1305 // remainder. Thus if tail is to be folded, we know we don't need to run
1306 // the remainder and we can set the condition to true.
1307 // 3) Otherwise, construct a runtime check.
1308
1309 // We use the same DebugLoc as the scalar loop latch terminator instead of
1310 // the corresponding compare because they may have ended up with different
1311 // line numbers and we want to avoid awkward line stepping while debugging.
1312 // E.g., if the compare has got a line number inside the loop.
1313 auto *LatchVPBB = cast<VPBasicBlock>(MiddleVPBB->getSinglePredecessor());
1314 DebugLoc LatchDL = LatchVPBB->getTerminator()->getDebugLoc();
1315 VPBuilder Builder(MiddleVPBB);
1316 VPValue *Cmp =
1317 Builder.createICmp(CmpInst::ICMP_EQ, Plan.getTripCount(),
1318 &Plan.getVectorTripCount(), LatchDL, "cmp.n");
1319 Builder.createNaryOp(VPInstruction::BranchOnCond, {Cmp}, LatchDL);
1320}
1321
1323 VPDominatorTree VPDT(Plan);
1325 Plan.getEntry());
1326 for (VPBlockBase *HeaderVPB : POT)
1327 if (canonicalHeaderAndLatch(HeaderVPB, VPDT))
1328 createLoopRegion(Plan, HeaderVPB, DL);
1329
1330 VPRegionBlock *TopRegion = Plan.getVectorLoopRegion();
1331 TopRegion->setName("vector loop");
1332 TopRegion->getEntryBasicBlock()->setName("vector.body");
1333}
1334
1336 assert(Plan.getExitBlocks().size() == 1 &&
1337 "only a single-exit block is supported currently");
1338 assert(Plan.getExitBlocks().front()->getSinglePredecessor() ==
1339 Plan.getMiddleBlock() &&
1340 "the exit block must have middle block as single predecessor");
1341
1342 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
1343 assert(LoopRegion->getSingleSuccessor() == Plan.getMiddleBlock() &&
1344 "The vector loop region must have the middle block as its single "
1345 "successor for now");
1346 VPBasicBlock *Header = LoopRegion->getEntryBasicBlock();
1347
1348 Header->splitAt(Header->getFirstNonPhi());
1349
1350 // Abstract header mask, materialized into concrete recipes later.
1351 VPValue *HeaderMask = LoopRegion->createHeaderMask();
1352 VPBuilder Builder(Header, Header->getFirstNonPhi());
1353 Builder.createNaryOp(VPInstruction::BranchOnCond, HeaderMask);
1354
1355 VPBasicBlock *OrigLatch = LoopRegion->getExitingBasicBlock();
1356 VPValue *IVInc;
1357 [[maybe_unused]] bool TermBranchOnCount =
1358 match(OrigLatch->getTerminator(),
1360 m_Specific(&Plan.getVectorTripCount())));
1361 assert(TermBranchOnCount &&
1362 match(IVInc, m_Add(m_Specific(LoopRegion->getCanonicalIV()),
1363 m_Specific(&Plan.getVFxUF()))) &&
1364 std::next(IVInc->getDefiningRecipe()->getIterator()) ==
1365 OrigLatch->getTerminator()->getIterator() &&
1366 "Unexpected canonical iv increment");
1367
1368 // Split the latch at the IV update, and branch to it from the header mask.
1369 VPBasicBlock *Latch =
1370 OrigLatch->splitAt(IVInc->getDefiningRecipe()->getIterator());
1371 Latch->setName("vector.latch");
1372 VPBlockUtils::connectBlocks(Header, Latch);
1373
1374 // Collect any values defined in the loop that need a phi. Currently this
1375 // includes header phi backedges and live-outs extracted in the middle block.
1376 // TODO: Handle early exits via Plan.getExitBlocks()
1378 for (VPRecipeBase &R : Header->phis())
1380 NeedsPhi[cast<VPHeaderPHIRecipe>(R).getBackedgeValue()].push_back(&R);
1381
1382 VPValue *V;
1383 for (VPRecipeBase &R : *Plan.getMiddleBlock())
1384 if (match(&R, m_ExtractLastPart(m_VPValue(V))))
1385 NeedsPhi[V].push_back(&R);
1386
1387 // Insert phis for values coming past the end of the tail.
1388 Builder.setInsertPoint(Latch, Latch->begin());
1389 for (const auto &[V, Users] : NeedsPhi) {
1390 if (isa<VPIRValue>(V))
1391 continue;
1392 VPValue *TailVal = Plan.getPoison(V->getScalarType());
1393 std::optional<VPIRFlags> Flags;
1395 "Value used by more than two reduction phis?");
1397 auto *RdxPhi =
1398 RedIt != Users.end() ? cast<VPReductionPHIRecipe>(*RedIt) : nullptr;
1399 if (RdxPhi && !RdxPhi->isInLoop()) {
1400 TailVal = RdxPhi;
1401 Flags = *RdxPhi;
1402 }
1403
1404 VPInstruction *Phi = Builder.createScalarPhi({V, TailVal}, {}, "", Flags);
1405 for (VPUser *U : Users)
1406 U->replaceUsesOfWith(V, Phi);
1407 }
1408
1409 // Any extract of the last element must be updated to extract from the last
1410 // active lane of the header mask instead (i.e., the lane corresponding to the
1411 // last active iteration).
1412 Builder.setInsertPoint(Plan.getMiddleBlock()->getTerminator());
1413 for (VPRecipeBase &R : *Plan.getMiddleBlock()) {
1414 VPValue *Op;
1416 continue;
1417
1418 // Compute the index of the last active lane.
1419 VPValue *LastActiveLane = Builder.createLastActiveLane(HeaderMask);
1420 auto *Ext =
1421 Builder.createNaryOp(VPInstruction::ExtractLane, {LastActiveLane, Op});
1422 R.getVPSingleValue()->replaceAllUsesWith(Ext);
1423 }
1424
1425 // VectorTripCount now equals TripCount so simplify the MiddleVPBB branch.
1429 m_Specific(&Plan.getVectorTripCount())))) &&
1430 "Unexpected MiddleVPBB branch");
1431 Plan.getMiddleBlock()->getTerminator()->setOperand(0, Plan.getTrue());
1432}
1433
1434/// Add an incoming value to all phis in \p VPBB for its just-added last
1435/// predecessor, re-using the value of the previously last one.
1437 for (VPRecipeBase &R : VPBB->phis()) {
1438 auto *Phi = cast<VPPhi>(&R);
1439 assert(Phi->getNumIncoming() == VPBB->getNumPredecessors() - 1 &&
1440 "must have incoming values for all predecessors but the new one");
1441 Phi->addIncoming(Phi->getIncomingValue(Phi->getNumIncoming() - 1));
1442 }
1443}
1444
1445/// Insert \p CheckBlockVPBB on the edge leading to the vector preheader,
1446/// connecting it to both vector and scalar preheaders. Updates scalar
1447/// preheader phis to account for the new predecessor.
1449 VPBasicBlock *CheckBlockVPBB) {
1450 VPBlockBase *VectorPH = Plan.getVectorPreheader();
1451 auto *ScalarPH = cast<VPBasicBlock>(Plan.getScalarPreheader());
1452 VPBlockBase *PreVectorPH = VectorPH->getSinglePredecessor();
1453 VPBlockUtils::insertOnEdge(PreVectorPH, VectorPH, CheckBlockVPBB);
1454 VPBlockUtils::connectBlocks(CheckBlockVPBB, ScalarPH);
1455 CheckBlockVPBB->swapSuccessors();
1457}
1458
1460 VPlan &EpiPlan, VPlan &MainPlan, VPIRBasicBlock *EnteredFrom) {
1461 // Map blocks from MainPlan to new, empty VPIRBasicBlocks in EpiPlan, so the
1462 // skeleton CFG can be modeled explicitly. MainPlan's entry maps to EpiPlan's
1463 // now-disconnected entry and its scalar PH to EnteredFrom.
1464 VPBlockBase *MainEntry = MainPlan.getEntry();
1465 VPBlockBase *MainScalarPH = MainPlan.getScalarPreheader();
1467 MainToEpiVPBB[MainEntry] = EpiPlan.getEntry();
1469 MainEntry);
1471 // Skip entry block and exit blocks/scalar loop header; they are already
1472 // modeled in the epilogue plan.
1473 if (VPBB != MainEntry && VPBB != MainScalarPH && VPBB->hasSuccessors())
1474 MainToEpiVPBB[VPBB] =
1475 EpiPlan.createEmptyVPIRBasicBlock(VPBB->getIRBasicBlock());
1476 MainToEpiVPBB[MainScalarPH] = EnteredFrom;
1477
1478 // First, connect the edges from the bypass blocks (minimum iteration checks,
1479 // runtime checks) to the scalar preheader, in reverse order, to preserve the
1480 // predecessor order of the generated IR.
1481 VPBasicBlock *EpiScalarPH = EpiPlan.getScalarPreheader();
1482 for (VPBlockBase *MainVPBB :
1483 reverse(drop_end(drop_begin(MainScalarPH->predecessors())))) {
1484 VPBlockUtils::connectBlocks(MainToEpiVPBB.lookup(MainVPBB), EpiScalarPH);
1485 addIncomingForLastPredecessor(EpiScalarPH);
1486 }
1487
1488 // Mirror MainPlan's CFG, skipping the bypass edges connected above, which
1489 // come first, and edges to blocks not modeled in EpiPlan.
1490 for (auto &[MainVPBB, EpiVPBB] : drop_end(MainToEpiVPBB))
1491 for (VPBlockBase *Succ :
1492 drop_begin(MainVPBB->getSuccessors(), EpiVPBB->getNumSuccessors()))
1493 if (auto *SuccVPBB = MainToEpiVPBB.lookup(Succ))
1494 VPBlockUtils::connectBlocks(EpiVPBB, SuccVPBB);
1495
1496 // EnteredFrom is the only modeled block with phis; re-use the incoming values
1497 // its IR phis already have for the new predecessors.
1498 for (VPRecipeBase &R : EnteredFrom->phis()) {
1499 auto *PhiR = cast<VPIRPhi>(&R);
1500 for (VPIRBasicBlock *Pred :
1502 PhiR->addIncoming(EpiPlan.getOrAddLiveIn(
1503 PhiR->getIRPhi().getIncomingValueForBlock(Pred->getIRBasicBlock())));
1504 }
1505}
1506
1507// Likelyhood of bypassing the vectorized loop due to a runtime check block,
1508// including memory overlap checks block and wrapping/unit-stride checks block.
1509static constexpr uint32_t CheckBypassWeights[] = {1, 127};
1510
1511/// Create a BranchOnCond terminator in \p CheckBlockVPBB. Optionally adds
1512/// branch weights.
1513static void addBypassBranch(VPlan &Plan, VPBasicBlock *CheckBlockVPBB,
1514 VPValue *Cond, bool AddBranchWeights) {
1516 auto *Term = VPBuilder(CheckBlockVPBB)
1518 if (AddBranchWeights) {
1519 MDBuilder MDB(Plan.getContext());
1520 MDNode *BranchWeights =
1521 MDB.createBranchWeights(CheckBypassWeights, /*IsExpected=*/false);
1522 Term->setMetadata(LLVMContext::MD_prof, BranchWeights);
1523 }
1524}
1525
1527 VPBasicBlock *CheckBlock,
1528 bool AddBranchWeights) {
1529 insertCheckBlockBeforeVectorLoop(Plan, CheckBlock);
1530 addBypassBranch(Plan, CheckBlock, Cond, AddBranchWeights);
1531}
1532
1534 BasicBlock *CheckBlock,
1535 bool AddBranchWeights) {
1536 VPValue *CondVPV = Plan.getOrAddLiveIn(Cond);
1537 VPBasicBlock *CheckBlockVPBB = Plan.createVPIRBasicBlock(CheckBlock);
1538 attachVPCheckBlock(Plan, CondVPV, CheckBlockVPBB, AddBranchWeights);
1539}
1540
1542 VPlan &Plan, ElementCount VF, unsigned UF,
1543 ElementCount MinProfitableTripCount, bool RequiresScalarEpilogue,
1544 bool TailFolded, Loop *OrigLoop, const uint32_t *MinItersBypassWeights,
1546 // Generate code to check if the loop's trip count is less than VF * UF, or
1547 // equal to it in case a scalar epilogue is required; this implies that the
1548 // vector trip count is zero. This check also covers the case where adding one
1549 // to the backedge-taken count overflowed leading to an incorrect trip count
1550 // of zero. In this case we will also jump to the scalar loop.
1551 CmpInst::Predicate CmpPred =
1552 RequiresScalarEpilogue ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT;
1553 // If tail is to be folded, vector loop takes care of all iterations.
1554 VPValue *TripCountVPV = Plan.getTripCount();
1555 const SCEV *TripCount = vputils::getSCEVExprForVPValue(TripCountVPV, PSE);
1556 Type *TripCountTy = TripCount->getType();
1557 ScalarEvolution &SE = *PSE.getSE();
1558 auto GetMinTripCount = [&]() -> const SCEV * {
1559 // Compute max(MinProfitableTripCount, UF * VF) and return it.
1560 const SCEV *VFxUF =
1561 SE.getElementCount(TripCountTy, (VF * UF), SCEV::FlagNUW);
1562 if (UF * VF.getKnownMinValue() >=
1563 MinProfitableTripCount.getKnownMinValue()) {
1564 // TODO: SCEV should be able to simplify test.
1565 return VFxUF;
1566 }
1567 const SCEV *MinProfitableTripCountSCEV =
1568 SE.getElementCount(TripCountTy, MinProfitableTripCount, SCEV::FlagNUW);
1569 return SE.getUMaxExpr(MinProfitableTripCountSCEV, VFxUF);
1570 };
1571
1572 VPBuilder Builder(CheckBlock);
1573 VPValue *TripCountCheck = Plan.getFalse();
1574 const SCEV *Step = GetMinTripCount();
1575 // TripCountCheck = false, folding tail implies positive vector trip
1576 // count.
1577 if (!TailFolded) {
1578 // TODO: Emit unconditional branch to vector preheader instead of
1579 // conditional branch with known condition.
1580 TripCount = SE.applyLoopGuards(TripCount, OrigLoop);
1581 // Check if the trip count is < the step.
1582 if (SE.isKnownPredicate(CmpPred, TripCount, Step)) {
1583 // TODO: Ensure step is at most the trip count when determining max VF and
1584 // UF, w/o tail folding.
1585 TripCountCheck = Plan.getTrue();
1586 } else if (!SE.isKnownPredicate(CmpInst::getInversePredicate(CmpPred),
1587 TripCount, Step)) {
1588 // Generate the minimum iteration check only if we cannot prove the
1589 // check is known to be true, or known to be false.
1590 VPValue *MinTripCountVPV =
1591 VPSCEVExpander(Builder, *PSE.getSE(), DL).expand(Step);
1592 TripCountCheck = Builder.createICmp(
1593 CmpPred, TripCountVPV, MinTripCountVPV, DL, "min.iters.check");
1594 } // else step known to be < trip count, use TripCountCheck preset to false.
1595 }
1596 VPInstruction *Term =
1597 Builder.createNaryOp(VPInstruction::BranchOnCond, {TripCountCheck}, DL);
1599 MDBuilder MDB(Plan.getContext());
1600 MDNode *BranchWeights = MDB.createBranchWeights(
1601 ArrayRef(MinItersBypassWeights, 2), /*IsExpected=*/false);
1602 Term->setMetadata(LLVMContext::MD_prof, BranchWeights);
1603 }
1604}
1605
1607 VPlan &Plan, ElementCount VF, unsigned UF, bool RequiresScalarEpilogue,
1608 Loop *OrigLoop, const uint32_t *MinItersBypassWeights, DebugLoc DL,
1610 auto *CheckBlock = Plan.createVPBasicBlock("vector.main.loop.iter.check");
1611 insertCheckBlockBeforeVectorLoop(Plan, CheckBlock);
1613 RequiresScalarEpilogue, /*TailFolded=*/false,
1614 OrigLoop, MinItersBypassWeights, DL, PSE,
1615 CheckBlock);
1616}
1617
1619 VPlan &Plan, Value *VectorTripCount, bool RequiresScalarEpilogue,
1620 ElementCount EpilogueVF, unsigned EpilogueUF, unsigned MainLoopStep,
1621 unsigned EpilogueLoopStep, ScalarEvolution &SE) {
1622 // Add the minimum iteration check for the epilogue vector loop.
1623 VPValue *TC = Plan.getTripCount();
1624 Value *TripCount = TC->getLiveInIRValue();
1625 VPBuilder Builder(cast<VPBasicBlock>(Plan.getEntry()));
1626 VPValue *VFxUF = Builder.createExpandSCEV(SE.getElementCount(
1627 TripCount->getType(), (EpilogueVF * EpilogueUF), SCEV::FlagNUW));
1628 VPValue *Count = Builder.createSub(TC, Plan.getOrAddLiveIn(VectorTripCount),
1629 DebugLoc::getUnknown(), "n.vec.remaining");
1630
1631 // Generate code to check if the loop's trip count is less than VF * UF of
1632 // the vector epilogue loop.
1633 auto P = RequiresScalarEpilogue ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT;
1634 auto *CheckMinIters = Builder.createICmp(
1635 P, Count, VFxUF, DebugLoc::getUnknown(), "min.epilog.iters.check");
1636 VPInstruction *Branch =
1637 Builder.createNaryOp(VPInstruction::BranchOnCond, CheckMinIters);
1638
1639 // We assume the remaining `Count` is equally distributed in
1640 // [0, MainLoopStep)
1641 // So the probability for `Count < EpilogueLoopStep` should be
1642 // min(MainLoopStep, EpilogueLoopStep) / MainLoopStep
1643 // TODO: Improve the estimate by taking the estimated trip count into
1644 // consideration.
1645 unsigned EstimatedSkipCount = std::min(MainLoopStep, EpilogueLoopStep);
1646 const uint32_t Weights[] = {EstimatedSkipCount,
1647 MainLoopStep - EstimatedSkipCount};
1648 MDBuilder MDB(Plan.getContext());
1649 MDNode *BranchWeights =
1650 MDB.createBranchWeights(Weights, /*IsExpected=*/false);
1651 Branch->setMetadata(LLVMContext::MD_prof, BranchWeights);
1652}
1653
1654/// Find and return the final select instruction of the FindIV result pattern
1655/// for the given \p BackedgeVal:
1656/// select(icmp ne ComputeReductionResult(ReducedIV), Sentinel),
1657/// ComputeReductionResult(ReducedIV), Start.
1659 return cast<VPInstruction>(
1660 vputils::findRecipe(BackedgeVal, [BackedgeVal](VPRecipeBase *R) {
1661 auto *VPI = dyn_cast<VPInstruction>(R);
1662 return VPI &&
1663 matchFindIVResult(VPI, m_Specific(BackedgeVal), m_VPValue());
1664 }));
1665}
1666
1668 auto GetMinOrMaxCompareValue =
1669 [](VPReductionPHIRecipe *RedPhiR) -> VPValue * {
1670 auto *MinOrMaxR =
1671 dyn_cast_or_null<VPRecipeWithIRFlags>(RedPhiR->getBackedgeValue());
1672 if (!MinOrMaxR)
1673 return nullptr;
1674
1675 // Check that MinOrMaxR is a VPWidenIntrinsicRecipe or VPReplicateRecipe
1676 // with an intrinsic that matches the reduction kind.
1677 Intrinsic::ID ExpectedIntrinsicID =
1678 getMinMaxReductionIntrinsicOp(RedPhiR->getRecurrenceKind());
1679 if (!match(MinOrMaxR, m_Intrinsic(ExpectedIntrinsicID)))
1680 return nullptr;
1681
1682 // MinOrMaxR must combine RedPhiR directly with the new element, as the NaN
1683 // check added below only covers the other operand.
1684 // TODO: Support multi-step min/max chains (e.g. maxnum(l, maxnum(k, phi)))
1685 // by checking all operands feeding the chain for NaNs.
1686 if (MinOrMaxR->getOperand(0) == RedPhiR)
1687 return MinOrMaxR->getOperand(1);
1688 if (MinOrMaxR->getOperand(1) == RedPhiR)
1689 return MinOrMaxR->getOperand(0);
1690 return nullptr;
1691 };
1692
1693 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
1695 MinOrMaxNumReductionsToHandle;
1696 bool HasUnsupportedPhi = false;
1697 for (auto &R : LoopRegion->getEntryBasicBlock()->phis()) {
1699 continue;
1700 auto *Cur = dyn_cast<VPReductionPHIRecipe>(&R);
1701 if (!Cur) {
1702 // TODO: Also support fixed-order recurrence phis.
1703 HasUnsupportedPhi = true;
1704 continue;
1705 }
1707 Cur->getRecurrenceKind())) {
1708 HasUnsupportedPhi = true;
1709 continue;
1710 }
1711
1712 VPValue *MinOrMaxOp = GetMinOrMaxCompareValue(Cur);
1713 if (!MinOrMaxOp)
1714 return false;
1715
1716 MinOrMaxNumReductionsToHandle.emplace_back(Cur, MinOrMaxOp);
1717 }
1718
1719 if (MinOrMaxNumReductionsToHandle.empty())
1720 return true;
1721
1722 // We won't be able to resume execution in the scalar tail, if there are
1723 // unsupported header phis or there is no scalar tail at all, due to
1724 // tail-folding.
1725 if (HasUnsupportedPhi || !Plan.hasScalarTail())
1726 return false;
1727
1728 /// Check if the vector loop of \p Plan can early exit and restart
1729 /// execution of last vector iteration in the scalar loop. This requires all
1730 /// recipes up to early exit point be side-effect free as they are
1731 /// re-executed. Currently we check that the loop is free of any recipe that
1732 /// may write to memory. Expected to operate on an early VPlan w/o nested
1733 /// regions.
1736 auto *VPBB = cast<VPBasicBlock>(VPB);
1737 for (auto &R : *VPBB) {
1738 if (R.mayWriteToMemory() && !match(&R, m_BranchOnCount()))
1739 return false;
1740 }
1741 }
1742
1743 // Freeze MinOrMaxOps since:
1744 // * multiple uses are introduced and the value may be undef
1745 // * they feed into a branch condition, so block poison propagation to
1746 // prevent immediate UB
1747 for (auto &[Phi, MinOrMaxOp] : MinOrMaxNumReductionsToHandle) {
1748 VPRecipeBase *MinOrMaxR = Phi->getBackedgeValue()->getDefiningRecipe();
1749 VPInstruction *Freeze = VPBuilder(MinOrMaxR).createFreeze(MinOrMaxOp);
1750 MinOrMaxR->replaceUsesOfWith(MinOrMaxOp, Freeze);
1751 MinOrMaxOp = Freeze;
1752 }
1753
1754 VPBasicBlock *LatchVPBB = LoopRegion->getExitingBasicBlock();
1755 VPBuilder LatchBuilder(LatchVPBB->getTerminator());
1756 VPValue *AllNaNLanes = nullptr;
1757 SmallPtrSet<VPValue *, 2> RdxResults;
1758 for (const auto &[_, MinOrMaxOp] : MinOrMaxNumReductionsToHandle) {
1759 VPValue *RedNaNLanes =
1760 LatchBuilder.createFCmp(CmpInst::FCMP_UNO, MinOrMaxOp, MinOrMaxOp);
1761 AllNaNLanes = AllNaNLanes ? LatchBuilder.createOr(AllNaNLanes, RedNaNLanes)
1762 : RedNaNLanes;
1763 }
1764
1765 VPValue *AnyNaNLane =
1766 LatchBuilder.createNaryOp(VPInstruction::AnyOf, {AllNaNLanes});
1767 VPBasicBlock *MiddleVPBB = Plan.getMiddleBlock();
1768 VPBuilder MiddleBuilder(MiddleVPBB, MiddleVPBB->begin());
1769 for (const auto &[RedPhiR, _] : MinOrMaxNumReductionsToHandle) {
1771 RedPhiR->getRecurrenceKind()) &&
1772 "unsupported reduction");
1773
1774 // If we exit early due to NaNs, compute the final reduction result based on
1775 // the reduction phi at the beginning of the last vector iteration.
1776 auto *RdxResult = vputils::findComputeReductionResult(RedPhiR);
1777 assert(RdxResult && "must find a ComputeReductionResult");
1778
1779 auto *NewSel = MiddleBuilder.createSelect(AnyNaNLane, RedPhiR,
1780 RdxResult->getOperand(0));
1781 RdxResult->setOperand(0, NewSel);
1782 assert(!RdxResults.contains(RdxResult) && "RdxResult already used");
1783 RdxResults.insert(RdxResult);
1784 }
1785
1786 auto *LatchExitingBranch = LatchVPBB->getTerminator();
1787 assert(match(LatchExitingBranch, m_BranchOnCount(m_VPValue(), m_VPValue())) &&
1788 "Unexpected terminator");
1789 auto *IsLatchExitTaken = LatchBuilder.createICmp(
1790 CmpInst::ICMP_EQ, LatchExitingBranch->getOperand(0),
1791 LatchExitingBranch->getOperand(1));
1792 auto *AnyExitTaken = LatchBuilder.createOr(AnyNaNLane, IsLatchExitTaken);
1793 LatchBuilder.createNaryOp(VPInstruction::BranchOnCond, AnyExitTaken);
1794 LatchExitingBranch->eraseFromParent();
1795
1796 // Update resume phis for inductions in the scalar preheader. If AnyNaNLane is
1797 // true, the resume from the start of the last vector iteration via the
1798 // canonical IV, otherwise from the original value.
1799 auto IsTC = [&Plan](VPValue *V) {
1800 return V == &Plan.getVectorTripCount() || V == Plan.getTripCount();
1801 };
1802 for (auto &R : Plan.getScalarPreheader()->phis()) {
1803 auto *ResumeR = cast<VPPhi>(&R);
1804 VPValue *VecV = ResumeR->getOperand(0);
1805 if (RdxResults.contains(VecV))
1806 continue;
1807 if (auto *DerivedIV = dyn_cast<VPDerivedIVRecipe>(VecV)) {
1808 VPValue *DIVTC = DerivedIV->getOperand(1);
1809 if (DerivedIV->hasOneUse() && IsTC(DIVTC)) {
1810 auto *NewSel = MiddleBuilder.createSelect(
1811 AnyNaNLane, LoopRegion->getCanonicalIV(), DIVTC);
1812 DerivedIV->moveAfter(MiddleBuilder.getRecipeAtInsertPoint());
1813 DerivedIV->setOperand(1, NewSel);
1814 continue;
1815 }
1816 }
1817 // Bail out and abandon the current, partially modified, VPlan if we
1818 // encounter resume phi that cannot be updated yet.
1819 if (!IsTC(VecV)) {
1820 LLVM_DEBUG(dbgs() << "Found resume phi we cannot update for VPlan with "
1821 "FMaxNum/FMinNum reduction.\n");
1822 return false;
1823 }
1824 auto *NewSel = MiddleBuilder.createSelect(
1825 AnyNaNLane, LoopRegion->getCanonicalIV(), VecV);
1826 ResumeR->setOperand(0, NewSel);
1827 }
1828
1829 auto *MiddleTerm = MiddleVPBB->getTerminator();
1830 MiddleBuilder.setInsertPoint(MiddleTerm);
1831 VPValue *MiddleCond = MiddleTerm->getOperand(0);
1832 VPValue *NewCond =
1833 MiddleBuilder.createAnd(MiddleCond, MiddleBuilder.createNot(AnyNaNLane));
1834 MiddleTerm->setOperand(0, NewCond);
1835 return true;
1836}
1837
1839 if (Plan.hasScalarVFOnly())
1840 return false;
1841
1842 // We want to create the following nodes:
1843 // vector.body:
1844 // ...new WidenPHI recipe introduced to keep the mask value for the latest
1845 // iteration where any lane was active.
1846 // mask.phi = phi [ ir<false>, vector.ph ], [ vp<new.mask>, vector.body ]
1847 // ...data.phi (a VPReductionPHIRecipe for a FindLast reduction) already
1848 // exists, but needs updating to use 'new.data' for the backedge value.
1849 // data.phi = phi ir<default.val>, vp<new.data>
1850 //
1851 // ...'data' and 'compare' created by existing nodes...
1852 //
1853 // ...new recipes introduced to determine whether to update the reduction
1854 // values or keep the current one.
1855 // any.active = i1 any-of ir<compare>
1856 // new.mask = select vp<any.active>, ir<compare>, vp<mask.phi>
1857 // new.data = select vp<any.active>, ir<data>, ir<data.phi>
1858 //
1859 // middle.block:
1860 // ...extract-last-active replaces compute-reduction-result.
1861 // result = extract-last-active vp<new.data>, vp<new.mask>, ir<default.val>
1862
1867 PhiR.getRecurrenceKind()))
1868 Phis.push_back(&PhiR);
1869 }
1870
1871 if (Phis.empty())
1872 return true;
1873
1874 VPValue *HeaderMask = Plan.getVectorLoopRegion()->getHeaderMask();
1875 for (VPReductionPHIRecipe *PhiR : Phis) {
1876 // Find the condition for the select/blend.
1877 VPValue *BackedgeSelect = PhiR->getBackedgeValue();
1878 VPValue *CondSelect = BackedgeSelect;
1879
1880 // If there's a header mask, the backedge select will not be the find-last
1881 // select.
1882 if (HeaderMask &&
1883 !match(BackedgeSelect,
1884 m_SelectLike(m_Specific(HeaderMask), m_VPValue(CondSelect),
1885 m_Specific(PhiR))))
1886 return false;
1887
1888 VPValue *Cond = nullptr, *Op1 = nullptr, *Op2 = nullptr;
1889
1890 // If we're matching a blend rather than a select, there should be one
1891 // incoming value which is the data, then all other incoming values should
1892 // be the phi.
1893 auto MatchBlend = [&](VPRecipeBase *R) {
1894 auto *Blend = dyn_cast<VPBlendRecipe>(R);
1895 if (!Blend)
1896 return false;
1897 assert(!Blend->isNormalized() && "must run before blend normalizaion");
1898 unsigned NumIncomingDataValues = 0;
1899 for (unsigned I = 0; I < Blend->getNumIncomingValues(); ++I) {
1900 VPValue *Incoming = Blend->getIncomingValue(I);
1901 if (Incoming != PhiR) {
1902 ++NumIncomingDataValues;
1903 Cond = Blend->getMask(I);
1904 Op1 = Incoming;
1905 Op2 = PhiR;
1906 }
1907 }
1908 return NumIncomingDataValues == 1;
1909 };
1910
1911 VPSingleDefRecipe *SelectR =
1913 if (!match(SelectR,
1914 m_Select(m_VPValue(Cond), m_VPValue(Op1), m_VPValue(Op2))) &&
1915 !MatchBlend(SelectR))
1916 return false;
1917
1918 assert(Cond != HeaderMask && "Cond must not be HeaderMask");
1919
1920 // Find final reduction computation and replace it with an
1921 // extract.last.active intrinsic.
1922 auto *RdxResult =
1924 assert(RdxResult && "Could not find reduction result");
1925
1926 // Add mask phi.
1927 VPBuilder Builder = VPBuilder::getToInsertAfter(PhiR);
1928 auto *MaskPHI = Builder.createWidenPhi(Plan.getFalse());
1929
1930 // Add select for mask.
1931 Builder.setInsertPoint(SelectR);
1932
1933 if (Op1 == PhiR) {
1934 // Normalize to selecting the data operand when the condition is true by
1935 // swapping operands and negating the condition.
1936 std::swap(Op1, Op2);
1937 Cond = Builder.createNot(Cond);
1938 }
1939 assert(Op2 == PhiR && "data value must be selected if Cond is true");
1940
1941 if (HeaderMask)
1942 Cond = Builder.createLogicalAnd(HeaderMask, Cond);
1943
1944 VPValue *AnyOf =
1945 Builder.createNaryOp(VPInstruction::AnyOf, Builder.createFreeze(Cond));
1946 // FIXME: The Cond here needs to be frozen too.
1947 VPValue *MaskSelect = Builder.createSelect(AnyOf, Cond, MaskPHI);
1948 MaskPHI->addIncoming(MaskSelect);
1949
1950 // Replace select for data.
1951 VPValue *DataSelect =
1952 Builder.createSelect(AnyOf, Op1, Op2, SelectR->getDebugLoc());
1953 SelectR->replaceAllUsesWith(DataSelect);
1954 PhiR->setBackedgeValue(DataSelect);
1955 SelectR->eraseFromParent();
1956
1957 Builder.setInsertPoint(RdxResult);
1958 auto *ExtractLastActive =
1959 Builder.createNaryOp(VPInstruction::ExtractLastActive,
1960 {PhiR->getStartValue(), DataSelect, MaskSelect},
1961 RdxResult->getDebugLoc());
1962 RdxResult->replaceAllUsesWith(ExtractLastActive);
1963 RdxResult->eraseFromParent();
1964 }
1965
1966 return true;
1967}
1968
1969/// Given a first argmin/argmax pattern with strict predicate consisting of
1970/// 1) a MinOrMax reduction \p MinOrMaxPhiR producing \p MinOrMaxResult,
1971/// 2) a wide induction \p WideIV,
1972/// 3) a FindLastIV reduction \p FindLastIVPhiR using \p WideIV,
1973/// return the smallest index of the FindLastIV reduction result using UMin,
1974/// unless \p MinOrMaxResult equals the start value of its MinOrMax reduction.
1975/// In that case, return the start value of the FindLastIV reduction instead.
1976/// If \p WideIV is not canonical, a new canonical wide IV is added, and the
1977/// final result is scaled back to the non-canonical \p WideIV.
1978/// The final value of the FindLastIV reduction is originally computed using
1979/// \p FindIVSelect, \p FindIVCmp, and \p FindIVRdxResult, which are replaced
1980/// and removed.
1981/// Returns true if the pattern was handled successfully, false otherwise.
1983 VPlan &Plan, VPReductionPHIRecipe *MinOrMaxPhiR,
1984 VPReductionPHIRecipe *FindLastIVPhiR, VPWidenIntOrFpInductionRecipe *WideIV,
1985 VPInstruction *MinOrMaxResult, VPInstruction *FindIVSelect,
1986 VPRecipeBase *FindIVCmp, VPInstruction *FindIVRdxResult) {
1987 assert(!FindLastIVPhiR->isInLoop() && !FindLastIVPhiR->isOrdered() &&
1988 "inloop and ordered reductions not supported");
1989 assert(FindLastIVPhiR->getVFScaleFactor() == 1 &&
1990 "FindIV reduction must not be scaled");
1991
1992 // TODO: support for FP in handleFirstArgMinOrMax
1994 MinOrMaxPhiR->getRecurrenceKind()))
1995 return false;
1996
1998 // TODO: Support non (i.e., narrower than) canonical IV types.
1999 // TODO: Emit remarks for failed transformations.
2000 if (Ty != WideIV->getScalarType())
2001 return false;
2002
2003 auto *FindIVSelectR = cast<VPSingleDefRecipe>(
2004 FindLastIVPhiR->getBackedgeValue()->getDefiningRecipe());
2005 assert(
2006 match(FindIVSelectR, m_Select(m_VPValue(), m_VPValue(), m_VPValue())) &&
2007 "backedge value must be a select");
2008 if (FindIVSelectR->getOperand(1) != WideIV &&
2009 FindIVSelectR->getOperand(2) != WideIV)
2010 return false;
2011
2012 // If the original wide IV is not canonical, create a new one. The canonical
2013 // wide IV is guaranteed to not wrap for all lanes that are active in the
2014 // vector loop.
2015 if (!WideIV->isCanonical()) {
2016 VPIRValue *Zero = Plan.getConstantInt(Ty, 0);
2017 VPIRValue *One = Plan.getConstantInt(Ty, 1);
2018 auto *WidenCanIV = new VPWidenIntOrFpInductionRecipe(
2019 nullptr, Zero, One, WideIV->getVFValue(),
2020 WideIV->getInductionDescriptor(),
2021 VPIRFlags::WrapFlagsTy(/*HasNUW=*/true, /*HasNSW=*/false),
2022 WideIV->getDebugLoc());
2023 WidenCanIV->insertBefore(WideIV);
2024
2025 // Update the select to use the wide canonical IV.
2026 FindIVSelectR->setOperand(FindIVSelectR->getOperand(1) == WideIV ? 1 : 2,
2027 WidenCanIV);
2028 }
2029 FindLastIVPhiR->setOperand(0, Plan.getPoison(Ty));
2030
2031 // The reduction using MinOrMaxPhiR needs adjusting to compute the correct
2032 // result:
2033 // 1. Find the first canonical indices corresponding to partial min/max
2034 // values, using loop reductions.
2035 // 2. Find which of the partial min/max values are equal to the overall
2036 // min/max value.
2037 // 3. Select among the canonical indices those corresponding to the overall
2038 // min/max value.
2039 // 4. Find the first canonical index of overall min/max and scale it back to
2040 // the original IV using VPDerivedIVRecipe.
2041 // 5. If the overall min/max equals the starting min/max, the condition in
2042 // the loop was always false, due to being strict; return the start value
2043 // of FindLastIVPhiR in that case.
2044 //
2045 // For example, we transforms two independent reduction result computations
2046 // for
2047 //
2048 // <x1> vector loop: {
2049 // vector.body:
2050 // ...
2051 // ir<%iv> = WIDEN-INDUCTION nuw nsw ir<10>, ir<1>, vp<%0>
2052 // WIDEN-REDUCTION-PHI ir<%min.idx> = phi ir<sentinel.min.start>,
2053 // ir<%min.idx.next>
2054 // WIDEN-REDUCTION-PHI ir<%min.val> = phi ir<100>, ir<%min.val.next>
2055 // ....
2056 // WIDEN-INTRINSIC ir<%min.val.next> = call llvm.umin(ir<%min.val>, ir<%l>)
2057 // WIDEN ir<%min.idx.next> = select ir<%cmp>, ir<%iv>, ir<%min.idx>
2058 // ...
2059 // }
2060 // Successor(s): middle.block
2061 //
2062 // middle.block:
2063 // vp<%iv.rdx> = compute-reduction-result (smax) vp<%min.idx.next>
2064 // vp<%min.result> = compute-reduction-result (umin) ir<%min.val.next>
2065 // vp<%cmp> = icmp ne vp<%iv.rdx>, ir<sentinel.min.start>
2066 // vp<%find.iv.result> = select vp<%cmp>, vp<%iv.rdx>, ir<10>
2067 //
2068 //
2069 // Into:
2070 //
2071 // vp<%reduced.min> = compute-reduction-result (umin) ir<%min.val.next>
2072 // vp<%reduced.mins.mask> = icmp eq ir<%min.val.next>, vp<%reduced.min>
2073 // vp<%idxs2reduce> = select vp<%reduced.mins.mask>, ir<%min.idx.next>,
2074 // ir<MaxUInt>
2075 // vp<%reduced.idx> = compute-reduction-result (umin) vp<%idxs2reduce>
2076 // vp<%scaled.idx> = DERIVED-IV ir<20> + vp<%reduced.idx> * ir<1>
2077 // vp<%always.false> = icmp eq vp<%reduced.min>, ir<100>
2078 // vp<%final.idx> = select vp<%always.false>, ir<10>,
2079 // vp<%scaled.idx>
2080
2081 VPBuilder Builder(FindIVRdxResult);
2082 VPValue *MinOrMaxExiting = MinOrMaxResult->getOperand(0);
2083 auto *FinalMinOrMaxCmp =
2084 Builder.createICmp(CmpInst::ICMP_EQ, MinOrMaxExiting, MinOrMaxResult);
2085 VPValue *LastIVExiting = FindIVRdxResult->getOperand(0);
2086 VPValue *MaxIV =
2087 Plan.getConstantInt(APInt::getMaxValue(Ty->getIntegerBitWidth()));
2088 auto *FinalIVSelect =
2089 Builder.createSelect(FinalMinOrMaxCmp, LastIVExiting, MaxIV);
2090 VPIRFlags RdxFlags(RecurKind::UMin, false, false, FastMathFlags());
2091 VPSingleDefRecipe *FinalCanIV = Builder.createNaryOp(
2092 VPInstruction::ComputeReductionResult, {FinalIVSelect}, RdxFlags,
2093 FindIVRdxResult->getDebugLoc());
2094
2095 // If we used a new wide canonical IV convert the reduction result back to the
2096 // original IV scale before the final select.
2097 if (!WideIV->isCanonical()) {
2098 auto *DerivedIVRecipe = new VPDerivedIVRecipe(
2100 nullptr, // No FPBinOp for integer induction
2101 WideIV->getStartValue(), FinalCanIV, WideIV->getStepValue());
2102 DerivedIVRecipe->insertBefore(Builder.getRecipeAtInsertPoint());
2103 FinalCanIV = DerivedIVRecipe;
2104 }
2105
2106 // If the final min/max value matches its start value, the condition in the
2107 // loop was always false, i.e. no induction value has been selected. If that's
2108 // the case, set the result of the IV reduction to its start value.
2109 VPValue *AlwaysFalse = Builder.createICmp(CmpInst::ICMP_EQ, MinOrMaxResult,
2110 MinOrMaxPhiR->getStartValue());
2111 VPValue *FinalIV = Builder.createSelect(
2112 AlwaysFalse, FindIVSelect->getOperand(2), FinalCanIV);
2113 FindIVSelect->replaceAllUsesWith(FinalIV);
2114
2115 // Erase the old FindIV result pattern which is now dead.
2116 FindIVSelect->eraseFromParent();
2117 FindIVCmp->eraseFromParent();
2118 FindIVRdxResult->eraseFromParent();
2119 return true;
2120}
2121
2124 Loop *TheLoop) {
2125 for (auto &PhiR : make_early_inc_range(
2127 auto *MinOrMaxPhiR = dyn_cast<VPReductionPHIRecipe>(&PhiR);
2128 // TODO: check for multi-uses in VPlan directly.
2129 if (!MinOrMaxPhiR || !MinOrMaxPhiR->hasUsesOutsideReductionChain())
2130 continue;
2131
2132 // MinOrMaxPhiR has users outside the reduction cycle in the loop. Check if
2133 // the only other user is a FindLastIV reduction. MinOrMaxPhiR must have
2134 // exactly 2 users:
2135 // 1) the min/max operation of the reduction cycle, and
2136 // 2) the compare of a FindLastIV reduction cycle. This compare must match
2137 // the min/max operation - comparing MinOrMaxPhiR with the operand of the
2138 // min/max operation, and be used only by the select of the FindLastIV
2139 // reduction cycle.
2140 RecurKind RdxKind = MinOrMaxPhiR->getRecurrenceKind();
2141 assert(
2143 "only min/max recurrences support users outside the reduction chain");
2144
2145 auto *MinOrMaxOp =
2146 dyn_cast<VPRecipeWithIRFlags>(MinOrMaxPhiR->getBackedgeValue());
2147 if (!MinOrMaxOp)
2148 return false;
2149
2150 // Check that MinOrMaxOp is a VPWidenIntrinsicRecipe or VPReplicateRecipe
2151 // with an intrinsic that matches the reduction kind.
2152 Intrinsic::ID ExpectedIntrinsicID = getMinMaxReductionIntrinsicOp(RdxKind);
2153 if (!match(MinOrMaxOp, m_Intrinsic(ExpectedIntrinsicID)))
2154 return false;
2155
2156 // MinOrMaxOp must have 2 users: 1) MinOrMaxPhiR and 2)
2157 // ComputeReductionResult.
2158 assert(MinOrMaxOp->getNumUsers() == 2 &&
2159 "MinOrMaxOp must have exactly 2 users");
2160 // MinOrMaxOp must combine MinOrMaxPhiR directly with the new element;
2161 // reject multi-step min/max chains (e.g. max(l, max(k, phi))), which
2162 // this transform does not handle.
2163 VPValue *MinOrMaxOpValue;
2164 if (MinOrMaxOp->getOperand(0) == MinOrMaxPhiR)
2165 MinOrMaxOpValue = MinOrMaxOp->getOperand(1);
2166 else if (MinOrMaxOp->getOperand(1) == MinOrMaxPhiR)
2167 MinOrMaxOpValue = MinOrMaxOp->getOperand(0);
2168 else
2169 return false;
2170
2171 VPValue *CmpOpA;
2172 VPValue *CmpOpB;
2173 CmpPredicate Pred;
2175 MinOrMaxPhiR, m_Cmp(Pred, m_VPValue(CmpOpA), m_VPValue(CmpOpB))));
2176 if (!Cmp || Cmp->getNumUsers() != 1 ||
2177 (CmpOpA != MinOrMaxOpValue && CmpOpB != MinOrMaxOpValue))
2178 return false;
2179
2180 if (MinOrMaxOpValue != CmpOpB)
2181 Pred = CmpInst::getSwappedPredicate(Pred);
2182
2183 // MinOrMaxPhiR must have exactly 2 users:
2184 // * MinOrMaxOp,
2185 // * Cmp (that's part of a FindLastIV chain).
2186 if (MinOrMaxPhiR->getNumUsers() != 2)
2187 return false;
2188
2189 VPInstruction *MinOrMaxResult =
2191 assert(MinOrMaxResult && "MinOrMaxResult must be a user of MinOrMaxOp");
2192
2193 // Cmp must be used by the select of a FindLastIV chain.
2194 VPValue *Sel = dyn_cast<VPSingleDefRecipe>(Cmp->getSingleUser());
2195 VPValue *IVOp, *FindIV;
2196 if (!Sel || Sel->getNumUsers() != 2 ||
2197 !match(Sel,
2199 return false;
2200
2202 std::swap(FindIV, IVOp);
2203 Pred = CmpInst::getInversePredicate(Pred);
2204 }
2205
2206 auto *FindIVPhiR = dyn_cast<VPReductionPHIRecipe>(FindIV);
2208 FindIVPhiR->getRecurrenceKind()))
2209 return false;
2210
2211 assert(!FindIVPhiR->isInLoop() && !FindIVPhiR->isOrdered() &&
2212 "cannot handle inloop/ordered reductions yet");
2213
2214 // Check if FindIVPhiR is a FindLast pattern by checking the MinMaxKind
2215 // on its ComputeReductionResult. SMax/UMax indicates FindLast.
2216 VPInstruction *FindIVResult =
2218 FindIVPhiR->getBackedgeValue());
2219 assert(FindIVResult &&
2220 "must be able to retrieve the FindIVResult VPInstruction");
2221 RecurKind FindIVMinMaxKind = FindIVResult->getRecurKind();
2222 if (FindIVMinMaxKind != RecurKind::SMax &&
2223 FindIVMinMaxKind != RecurKind::UMax)
2224 return false;
2225
2226 // TODO: Support cases where IVOp is the IV increment.
2227 if (!match(IVOp, m_TruncOrSelf(m_VPValue(IVOp))) ||
2229 return false;
2230
2231 // Check if the predicate is compatible with the reduction kind.
2232 bool IsValidKindPred = [RdxKind, Pred]() {
2233 switch (RdxKind) {
2234 case RecurKind::UMin:
2235 return Pred == CmpInst::ICMP_UGE || Pred == CmpInst::ICMP_UGT;
2236 case RecurKind::UMax:
2237 return Pred == CmpInst::ICMP_ULE || Pred == CmpInst::ICMP_ULT;
2238 case RecurKind::SMax:
2239 return Pred == CmpInst::ICMP_SLE || Pred == CmpInst::ICMP_SLT;
2240 case RecurKind::SMin:
2241 return Pred == CmpInst::ICMP_SGE || Pred == CmpInst::ICMP_SGT;
2242 case RecurKind::FMax:
2244 return Pred == CmpInst::FCMP_OLE || Pred == CmpInst::FCMP_OLT;
2245 case RecurKind::FMin:
2247 return Pred == CmpInst::FCMP_OGE || Pred == CmpInst::FCMP_OGT;
2248 // minnum and maxnum need special handling due to expected sNaN behaviour
2249 // minimum and maximum return NaN if either input is a NAN
2250 case RecurKind::FMinNum:
2251 case RecurKind::FMaxNum:
2254 return false;
2255 default:
2256 llvm_unreachable("unhandled recurrence kind");
2257 }
2258 }();
2259 if (!IsValidKindPred) {
2260 ORE->emit([&]() {
2262 DEBUG_TYPE, "VectorizationMultiUseReductionPredicate",
2263 TheLoop->getStartLoc(), TheLoop->getHeader())
2264 << "Multi-use reduction with predicate "
2266 << " incompatible with reduction kind";
2267 });
2268 return false;
2269 }
2270
2271 if (RdxKind == RecurKind::FMaximumNum ||
2272 RdxKind == RecurKind::FMinimumNum) {
2273 auto *StartC = dyn_cast<VPConstant>(MinOrMaxPhiR->getStartValue());
2274 if (!StartC || StartC->getConstant()->isNaN())
2275 return false;
2276 }
2277
2278 auto *FindIVSelect = findFindIVSelect(FindIVPhiR->getBackedgeValue());
2279 auto *FindIVCmp = FindIVSelect->getOperand(0)->getDefiningRecipe();
2280 auto *FindIVRdxResult = cast<VPInstruction>(FindIVCmp->getOperand(0));
2281 assert(FindIVSelect->getParent() == MinOrMaxResult->getParent() &&
2282 "both results must be computed in the same block");
2283 // Reducing to a scalar min or max value is placed right before reducing to
2284 // its scalar iteration, in order to generate instructions that use both
2285 // their operands.
2286 MinOrMaxResult->moveBefore(*FindIVRdxResult->getParent(),
2287 FindIVRdxResult->getIterator());
2288
2289 bool IsStrictPredicate = CmpInst::isStrictPredicate(Pred);
2290 if (IsStrictPredicate) {
2291 if (!handleFirstArgMinOrMax(Plan, MinOrMaxPhiR, FindIVPhiR,
2293 MinOrMaxResult, FindIVSelect, FindIVCmp,
2294 FindIVRdxResult))
2295 return false;
2296 continue;
2297 }
2298
2299 // The reduction using MinOrMaxPhiR needs adjusting to compute the correct
2300 // result:
2301 // 1. We need to find the last IV for which the condition based on the
2302 // min/max recurrence is true,
2303 // 2. Compare the partial min/max reduction result to its final value and,
2304 // 3. Select the lanes of the partial FindLastIV reductions which
2305 // correspond to the lanes matching the min/max reduction result.
2306 //
2307 // For example, this transforms
2308 // vp<%min.result> = compute-reduction-result ir<%min.val.next>
2309 // vp<%iv.rdx> = compute-reduction-result (smax) vp<%min.idx.next>
2310 // vp<%cmp> = icmp ne vp<%iv.rdx>, SENTINEL
2311 // vp<%find.iv.result> = select vp<%cmp>, vp<%iv.rdx>, ir<0>
2312 //
2313 // into:
2314 //
2315 // vp<min.result> = compute-reduction-result ir<%min.val.next>
2316 // vp<%final.min.cmp> = icmp eq ir<%min.val.next>, vp<min.result>
2317 // vp<%final.iv> = select vp<%final.min.cmp>, vp<%min.idx.next>, SENTINEL
2318 // vp<%iv.rdx> = compute-reduction-result (smax) vp<%final.iv>
2319 // vp<%cmp> = icmp ne vp<%iv.rdx>, SENTINEL
2320 // vp<%find.iv.result> = select vp<%cmp>, vp<%iv.rdx>, ir<0>
2321 //
2322 VPBuilder B(FindIVRdxResult);
2323 VPValue *MinOrMaxExiting = MinOrMaxResult->getOperand(0);
2324 auto *FinalMinOrMaxCmp =
2326 ? B.createICmp(CmpInst::ICMP_EQ, MinOrMaxExiting, MinOrMaxResult)
2327 : B.createFCmp(CmpInst::FCMP_OEQ, MinOrMaxExiting, MinOrMaxResult);
2328 VPValue *Sentinel = FindIVCmp->getOperand(1);
2329 VPValue *LastIVExiting = FindIVRdxResult->getOperand(0);
2330 auto *FinalIVSelect =
2331 B.createSelect(FinalMinOrMaxCmp, LastIVExiting, Sentinel);
2332 FindIVRdxResult->setOperand(0, FinalIVSelect);
2333 }
2334 return true;
2335}
2336
2338 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
2339 VPValue *HeaderMask = LoopRegion->getHeaderMask();
2340 Type *I1Ty = IntegerType::getInt1Ty(Plan.getContext());
2341
2342 VPBuilder Builder(Plan.getVectorPreheader());
2343 auto *AliasMask = Builder.createNaryOp(
2344 VPInstruction::IncomingAliasMask, {}, nullptr, {}, {},
2345 DebugLoc::getUnknown(), "incoming.alias.mask", I1Ty);
2346
2347 VPBasicBlock *Header = LoopRegion->getEntryBasicBlock();
2348 Builder = VPBuilder(Header, Header->getFirstNonPhi());
2349
2350 // Update all existing users of the header mask to "HeaderMask & AliasMask".
2351 auto *ClampedHeaderMask = Builder.createAnd(HeaderMask, AliasMask);
2352 HeaderMask->replaceUsesWithIf(ClampedHeaderMask, [&](VPUser &U, unsigned) {
2353 return &U != ClampedHeaderMask;
2354 });
2355}
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 DEBUG_TYPE
#define _
iv Induction Variable Users
Definition IVUsers.cpp:48
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file provides a LoopVectorizationPlanner class.
static constexpr uint32_t MinItersBypassWeights[]
#define I(x, y, z)
Definition MD5.cpp:57
#define P(N)
const SmallVectorImpl< MachineOperand > & Cond
Provides some synthesis utilities to produce sequences of values.
This file defines less commonly used SmallVector utilities.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
static bool isHeaderBB(BasicBlock *BB, Loop *L)
static bool handleFirstArgMinOrMax(VPlan &Plan, VPReductionPHIRecipe *MinOrMaxPhiR, VPReductionPHIRecipe *FindLastIVPhiR, VPWidenIntOrFpInductionRecipe *WideIV, VPInstruction *MinOrMaxResult, VPInstruction *FindIVSelect, VPRecipeBase *FindIVCmp, VPInstruction *FindIVRdxResult)
Given a first argmin/argmax pattern with strict predicate consisting of 1) a MinOrMax reduction MinOr...
static VPHeaderPHIRecipe * createWidenInductionRecipe(PHINode *Phi, VPPhi *PhiR, VPIRValue *Start, const InductionDescriptor &IndDesc, VPlan &Plan, PredicatedScalarEvolution &PSE, Loop &OrigLoop, DebugLoc DL)
Creates a VPWidenIntOrFpInductionRecipe or VPWidenPointerInductionRecipe for Phi based on IndDesc.
static void addIncomingForLastPredecessor(VPBasicBlock *VPBB)
Add an incoming value to all phis in VPBB for its just-added last predecessor, re-using the value of ...
static void insertCheckBlockBeforeVectorLoop(VPlan &Plan, VPBasicBlock *CheckBlockVPBB)
Insert CheckBlockVPBB on the edge leading to the vector preheader, connecting it to both vector and s...
static void addBypassBranch(VPlan &Plan, VPBasicBlock *CheckBlockVPBB, VPValue *Cond, bool AddBranchWeights)
Create a BranchOnCond terminator in CheckBlockVPBB.
static bool sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR, VPRecipeBase *Previous, const VPDominatorTree &VPDT)
Try to sink users of FOR after Previous.
static bool canonicalHeaderAndLatch(VPBlockBase *HeaderVPB, const VPDominatorTree &VPDT)
Checks if HeaderVPB is a loop header block in the plain CFG; that is, it has exactly 2 predecessors (...
static void addInitialSkeleton(VPlan &Plan, Type *InductionTy, PredicatedScalarEvolution &PSE, Loop *TheLoop)
static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR, VPRecipeBase *Previous, const VPDominatorTree &VPDT)
Try to hoist Previous and its operands before all users of FOR.
static void createLoopRegion(VPlan &Plan, VPBlockBase *HeaderVPB, DebugLoc DL)
Create a new VPRegionBlock for the loop starting at HeaderVPB.
static VPInstruction * findFindIVSelect(VPValue *BackedgeVal)
Find and return the final select instruction of the FindIV result pattern for the given BackedgeVal: ...
static bool tryToSinkOrHoistRecurrenceUsers(VPBasicBlock *HeaderVPBB, const VPDominatorTree &VPDT)
Sink users of fixed-order recurrences past or hoist before the recipe defining the previous value,...
static constexpr uint32_t CheckBypassWeights[]
static void printAfterInitialConstruction(VPlan &)
To make RUN_VPLAN_PASS print initial VPlan.
static void createExtractsForLiveOuts(VPlan &Plan, VPBasicBlock *MiddleVPBB)
Creates extracts for values in Plan defined in a loop region and used outside a loop region.
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
This file contains the declarations of different VPlan-related auxiliary helpers.
This file provides utility VPlan to VPlan transformations.
#define RUN_VPLAN_PASS_NO_VERIFY(PASS,...)
This file contains the declarations of the Vectorization Plan base classes:
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
Definition APInt.h:202
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Analysis providing branch probability information.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Definition InstrTypes.h:743
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ FCMP_OLT
0 1 0 0 True if ordered and less than
Definition InstrTypes.h:746
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition InstrTypes.h:744
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
Definition InstrTypes.h:745
@ ICMP_UGE
unsigned greater or equal
Definition InstrTypes.h:764
@ ICMP_UGT
unsigned greater than
Definition InstrTypes.h:763
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_ULT
unsigned less than
Definition InstrTypes.h:765
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
Definition InstrTypes.h:747
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
@ ICMP_ULE
unsigned less or equal
Definition InstrTypes.h:766
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
Definition InstrTypes.h:750
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition InstrTypes.h:890
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
static LLVM_ABI StringRef getPredicateName(Predicate P)
bool isStrictPredicate() const
Definition InstrTypes.h:906
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
static DebugLoc getUnknown()
Definition DebugLoc.h:153
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:285
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:305
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:316
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
static FastMathFlags getFast()
Definition FMF.h:50
A struct for saving information about induction variables.
InductionKind getKind() const
const SCEV * getStep() const
@ IK_FpInduction
Floating point induction variable.
@ IK_PtrInduction
Pointer induction var. Step = C.
@ IK_IntInduction
Integer induction variable. Step = C.
Value * getStartValue() const
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
BlockT * getHeader() const
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
This class emits a version of the loop where run-time checks ensure that may-alias pointers can't ove...
LLVM_ABI std::pair< MDNode *, MDNode * > getNoAliasMetadataFor(const Instruction *OrigInst) const
Returns a pair containing the alias_scope and noalias metadata nodes for OrigInst,...
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
Definition LoopInfo.cpp:695
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
Definition MDBuilder.cpp:38
Metadata node.
Definition Metadata.h:1081
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
ValueT lookup(const KeyT &Key) const
Definition MapVector.h:110
iterator find(const KeyT &Key)
Definition MapVector.h:156
iterator end()
Definition MapVector.h:69
The optimization diagnostic interface.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
Diagnostic information for missed-optimization remarks.
Post-order traversal of a graph.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
LLVM_ABI void addPredicate(const SCEVPredicate &Pred)
Adds a new predicate.
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEVPredicate & getPredicate() const
LLVM_ABI const SCEV * getSymbolicMaxBackedgeTakenCount()
Get the (predicated) symbolic max backedge count for the analyzed loop.
LLVM_ABI const SCEV * getSCEV(Value *V)
Returns the SCEV expression of V, in the context of the current SCEV predicate.
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
static bool isFMulAddIntrinsic(Instruction *I)
Returns true if the instruction is a call to the llvm.fmuladd intrinsic.
FastMathFlags getFastMathFlags() const
static bool isFPMinMaxNumRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating-point minnum/maxnum kind.
bool hasUsesOutsideReductionChain() const
Returns true if the reduction PHI has any uses outside the reduction chain.
static bool isFindLastRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
TrackingVH< Value > getRecurrenceStartValue() const
static bool isAnyOfRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
RecurKind getRecurrenceKind() const
bool isOrdered() const
Expose an ordered FP reduction to the instance users.
static LLVM_ABI bool isFloatingPointRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is a floating point kind.
static bool isFindIVRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is of the form select(cmp(),x,y) where one of (x,...
static LLVM_ABI bool isIntegerRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is an integer kind.
static bool isMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is any min/max kind.
virtual unsigned getComplexity() const
Returns the estimated complexity of this predicate.
This class represents an analyzed expression in the program.
static constexpr auto FlagNUW
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getTripCountFromExitCount(const SCEV *ExitCount)
A version of getTripCountFromExitCount below which always picks an evaluation type which can not resu...
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getUMaxExpr(SCEVUse LHS, SCEVUse RHS)
LLVM_ABI const SCEV * getStoreSizeOfExpr(Type *IntTy, Type *StoreTy)
Return an expression for the store size of StoreTy that is type IntTy.
LLVM_ABI bool isKnownPredicate(CmpPredicate Pred, SCEVUse LHS, SCEVUse RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
LLVM_ABI const SCEV * applyLoopGuards(const SCEV *Expr, const Loop *L)
Try to apply information from loop guards for L to Expr.
LLVM_ABI const SCEV * getElementCount(Type *Ty, ElementCount EC, SCEV::NoWrapFlags Flags=SCEV::FlagNone)
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
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.
Definition Type.h:46
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
op_range operands()
Definition User.h:267
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4427
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition VPlan.h:4502
RecipeListTy::iterator iterator
Instruction iterators...
Definition VPlan.h:4454
iterator end()
Definition VPlan.h:4464
iterator begin()
Recipe iterator methods.
Definition VPlan.h:4462
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4515
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:233
VPBasicBlock * splitAt(iterator SplitAt)
Split current block at SplitAt by inserting a new block between the current block and its successors ...
Definition VPlan.cpp:540
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:619
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4493
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:95
void setSuccessors(ArrayRef< VPBlockBase * > NewSuccs)
Set each VPBasicBlock in NewSuccss as successor of this VPBlockBase.
Definition VPlan.h:315
VPRegionBlock * getParent()
Definition VPlan.h:193
iterator_range< VPBlockBase ** > predecessors()
Definition VPlan.h:226
const VPBasicBlock * getExitingBasicBlock() const
Definition VPlan.cpp:203
void setName(const Twine &newName)
Definition VPlan.h:186
size_t getNumSuccessors() const
Definition VPlan.h:243
void swapSuccessors()
Swap successors of the block. The block must have exactly 2 successors.
Definition VPlan.h:337
size_t getNumPredecessors() const
Definition VPlan.h:244
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
Definition VPlan.h:306
bool hasSuccessors() const
Returns true if this block has any successors.
Definition VPlan.h:221
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:228
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
Definition VPlan.h:297
VPBlockBase * getSinglePredecessor() const
Definition VPlan.h:239
void swapPredecessors()
Swap predecessors of the block.
Definition VPlan.h:329
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:188
void setOneSuccessor(VPBlockBase *Successor)
Set a given VPBlockBase Successor as the single successor of this VPBlockBase.
Definition VPlan.h:286
void setParent(VPRegionBlock *P)
Definition VPlan.h:203
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:233
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:217
static auto blocksAs(T &&Range)
Return an iterator range over Range with each block cast to BlockTy.
Definition VPlanUtils.h:438
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBase NewBlock after BlockPtr.
Definition VPlanUtils.h:320
static void insertOnEdge(VPBlockBase *From, VPBlockBase *To, VPBlockBase *BlockPtr)
Inserts BlockPtr on the edge between From and To.
Definition VPlanUtils.h:457
static VPBasicBlock * getPlainCFGMiddleBlock(const VPlan &Plan)
Returns the middle block of Plan in plain CFG form (before regions are formed).
static void connectBlocks(VPBlockBase *From, VPBlockBase *To, unsigned PredIdx=-1u, unsigned SuccIdx=-1u)
Connect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:365
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:383
static std::pair< VPBasicBlock *, VPBasicBlock * > getPlainCFGHeaderAndLatch(const VPlan &Plan)
Returns the header and latch of the outermost loop of Plan in plain CFG form (before regions are form...
static void transferSuccessors(VPBlockBase *Old, VPBlockBase *New)
Transfer successors from Old to New. New must have no successors.
Definition VPlanUtils.h:415
VPlan-based builder utility analogous to IRBuilder.
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt, Type *ResultTy=nullptr)
Create a phi with IncomingValues, using the default flags for the result type, unless Flags is set.
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
void setInsertPoint(const VPInsertPoint &IP)
Set the current insert point.
VPInstruction * createFCmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new FCmp VPInstruction with predicate Pred and operands A and B.
VPRecipeBase * getRecipeAtInsertPoint() const
Get the recipe at the current insert point or nullptr if the insert point is the end of the block.
VPInstruction * createFreeze(VPValue *Op, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
static VPBuilder getToInsertAfter(VPRecipeBase *R)
Create a VPBuilder to insert after R.
VPInstruction * createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new ICmp VPInstruction with predicate Pred and operands A and B.
VPInstruction * createAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
VPInstruction * createSelect(VPValue *Cond, VPValue *TrueVal, VPValue *FalseVal, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt)
Create a select of TrueVal and FalseVal based on Cond, using the default flags for the result type,...
VPInstruction * createNaryOp(unsigned Opcode, ArrayRef< VPValue * > Operands, Instruction *Inst=nullptr, const VPIRFlags &Flags={}, const VPIRMetadata &MD={}, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", Type *ResultTy=nullptr)
Create an N-ary operation with Opcode, Operands and set Inst as its underlying Instruction.
unsigned getNumDefinedValues() const
Returns the number of values defined by the VPDef.
Definition VPlanValue.h:579
VPValue * getVPSingleValue()
Returns the only VPValue defined by the VPDef.
Definition VPlanValue.h:552
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4208
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
bool properlyDominates(const VPRecipeBase *A, const VPRecipeBase *B) const
A pure virtual base class for all recipes modeling header phis, including phis for first order recurr...
Definition VPlan.h:2455
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2502
VPValue * getStartValue()
Returns the start value of the phi, if one is set.
Definition VPlan.h:2491
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4580
Class to record and manage LLVM IR flags.
Definition VPlan.h:704
RecurKind getRecurKind() const
Definition VPlan.h:1065
Helper to manage IR metadata for recipes.
Definition VPlan.h:1193
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1306
@ ExtractLastActive
Extracts the last active lane from a set of vectors.
Definition VPlan.h:1415
@ ExtractLane
Extracts a single lane (first operand) from a set of vector operands.
Definition VPlan.h:1406
@ ExitingIVValue
Compute the exiting value of a wide induction after vectorization, that is the value of the last lane...
Definition VPlan.h:1419
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
Definition VPlan.h:1360
void addIncoming(VPValue *IncomingV)
Append IncomingV as an incoming value to the phi-like recipe.
Definition VPlan.h:1671
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:411
bool isPhi() const
Returns true for PHI-like recipes.
VPBasicBlock * getParent()
Definition VPlan.h:483
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition VPlan.h:561
void moveBefore(VPBasicBlock &BB, iplist< VPRecipeBase >::iterator I)
Unlink this recipe and insert into BB before I.
void insertBefore(VPRecipeBase *InsertPos)
Insert an unlinked recipe into a basic block immediately before the specified recipe.
iplist< VPRecipeBase >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void moveAfter(VPRecipeBase *MovePos)
Unlink this recipe from its current VPBasicBlock and insert it into the VPBasicBlock that MovePos liv...
Type * getScalarType() const
Returns the scalar type of this VPRecipeValue.
Definition VPlanValue.h:354
A recipe for handling reduction phis.
Definition VPlan.h:2873
bool isOrdered() const
Returns true, if the phi is part of an ordered reduction.
Definition VPlan.h:2933
unsigned getVFScaleFactor() const
Get the factor that the VF of this recipe's output should be scaled by, or 1 if it isn't scaled.
Definition VPlan.h:2917
bool isInLoop() const
Returns true if the phi is part of an in-loop reduction.
Definition VPlan.h:2936
RecurKind getRecurrenceKind() const
Returns the recurrence kind of the reduction.
Definition VPlan.h:2930
A recipe to represent inloop, ordered or partial reduction operations.
Definition VPlan.h:3243
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4652
VPRegionValue * createHeaderMask()
Create the header mask for the region and return it.
Definition VPlan.h:4799
Type * getCanonicalIVType() const
Return the type of the canonical IV for loop regions.
Definition VPlan.h:4780
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4772
VPRegionValue * getHeaderMask() const
Return the header mask of the region, or null if not set.
Definition VPlan.h:4785
DebugLoc getDebugLoc() const
Returns the debug location of the VPRegionValue.
Definition VPlanValue.h:267
Lightweight SCEV-to-VPlan expander.
Definition VPlanUtils.h:285
VPValue * expand(const SCEV *S)
Expand S into recipes and live-ins using the builder.
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:619
Type * getType() const
Returns the scalar type of this symbolic value.
Definition VPlanValue.h:232
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:401
void replaceUsesOfWith(VPValue *From, VPValue *To)
Replaces all uses of From in the VPUser with To.
Definition VPlan.cpp:1498
operand_range operands()
Definition VPlanValue.h:474
void setOperand(unsigned I, VPValue *New)
Definition VPlanValue.h:447
VPValue * getOperand(unsigned N) const
Definition VPlanValue.h:442
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Value * getLiveInIRValue() const
Return the underlying IR value for a VPIRValue.
Definition VPlan.cpp:141
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:128
void setUnderlyingValue(Value *Val)
Definition VPlanValue.h:209
void replaceAllUsesWith(VPValue *New)
Definition VPlan.cpp:1464
unsigned getNumUsers() const
Definition VPlanValue.h:115
void replaceUsesWithIf(VPValue *New, llvm::function_ref< bool(VPUser &U, unsigned Idx)> ShouldReplace)
Go through the uses list for this VPValue and make each use point to New if the callback ShouldReplac...
Definition VPlan.cpp:1470
user_range users()
Definition VPlanValue.h:157
Base class for widened induction (VPWidenIntOrFpInductionRecipe and VPWidenPointerInductionRecipe),...
Definition VPlan.h:2527
VPValue * getStepValue()
Returns the step value of the induction.
Definition VPlan.h:2575
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
Definition VPlan.h:2595
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2624
bool isCanonical() const
Returns true if the induction is canonical, i.e.
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4839
VPIRValue * getLiveIn(Value *V) const
Return the live-in VPIRValue for V, if there is one or nullptr otherwise.
Definition VPlan.h:5178
LLVMContext & getContext() const
Definition VPlan.h:5049
VPBasicBlock * getEntry()
Definition VPlan.h:4935
VPValue * getTripCount() const
The trip count of the original loop.
Definition VPlan.h:5007
VPIRValue * getFalse()
Return a VPIRValue wrapping i1 false.
Definition VPlan.h:5144
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5047
VPIRBasicBlock * createEmptyVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock wrapping IRBB, but do not create VPIRInstructions wrapping the instructions i...
Definition VPlan.cpp:1300
VPIRValue * getPoison(Type *Ty)
Return a VPIRValue wrapping a poison value of type Ty.
Definition VPlan.h:5172
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:5001
VPSymbolicValue & getVectorTripCount()
The vector trip count.
Definition VPlan.h:5037
VPIRValue * getOrAddLiveIn(Value *V)
Gets the live-in VPIRValue for V or adds a new live-in (if none exists yet) for V.
Definition VPlan.h:5121
VPRegionBlock * createLoopRegion(Type *CanIVTy, DebugLoc DL, const std::string &Name="", VPBlockBase *Entry=nullptr, VPBlockBase *Exiting=nullptr)
Create a new loop region with a canonical IV using CanIVTy and DL.
Definition VPlan.h:5217
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1042
void setTripCount(VPValue *NewTripCount)
Set the trip count assuming it is currently null; if it is not - use resetTripCount().
Definition VPlan.h:5014
VPBasicBlock * getMiddleBlock()
Returns the 'middle' block of the plan, that is the block that selects whether to execute the scalar ...
Definition VPlan.h:4977
VPBasicBlock * createVPBasicBlock(const Twine &Name, VPRecipeBase *Recipe=nullptr)
Create a new VPBasicBlock with Name and containing Recipe if present.
Definition VPlan.h:5204
LLVM_ABI_FOR_TEST VPIRBasicBlock * createVPIRBasicBlock(BasicBlock *IRBB)
Create a VPIRBasicBlock from IRBB containing VPIRInstructions for all instructions in IRBB,...
Definition VPlan.cpp:1308
VPIRValue * getTrue()
Return a VPIRValue wrapping i1 true.
Definition VPlan.h:5141
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4940
bool hasScalarVFOnly() const
Definition VPlan.h:5089
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4991
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
Definition VPlan.h:4997
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5040
bool hasScalarTail() const
Returns true if the scalar tail may execute after the vector loop, i.e.
Definition VPlan.h:5277
VPIRValue * getConstantInt(Type *Ty, uint64_t Val, bool IsSigned=false)
Return a VPIRValue wrapping a ConstantInt with the given type and value.
Definition VPlan.h:5155
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
Definition ilist_node.h:123
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Entry
Definition COFF.h:862
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
void reportVectorizationFailure(const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag, OptimizationRemarkEmitter *ORE, const Loop *TheLoop, Instruction *I=nullptr)
Reports a vectorization failure: print DebugMsg for debugging purposes along with the corresponding o...
auto m_Cmp()
Matches any compare instruction and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
SelectLike_match< CondTy, LTy, RTy > m_SelectLike(const CondTy &C, const LTy &TrueC, const RTy &FalseC)
Matches a value that behaves like a boolean-controlled select, i.e.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
VPInstruction_match< VPInstruction::ExtractLastLane, VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > > m_ExtractLastLaneOfLastPart(const Op0_t &Op0)
bool matchFindIVResult(VPInstruction *VPI, Op0_t ReducedIV, Op1_t Start)
Match FindIV result pattern: select(icmp ne ComputeReductionResult(ReducedIV), Sentinel),...
VPInstruction_match< VPInstruction::BranchOnTwoConds > m_BranchOnTwoConds()
VPInstruction_match< VPInstruction::ExtractLastLane, Op0_t > m_ExtractLastLane(const Op0_t &Op0)
VPInstruction_match< VPInstruction::BranchOnCount > m_BranchOnCount()
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > m_ExtractLastPart(const Op0_t &Op0)
VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr)
Get or create a VPValue that corresponds to the expansion of Expr.
bool cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking=false)
Return true if we do not know how to (mechanically) hoist or sink R.
VPInstruction * findComputeReductionResult(VPReductionPHIRecipe *PhiR)
Find the ComputeReductionResult recipe for PhiR, looking through selects inserted for predicated redu...
SmallVector< std::pair< VPBasicBlock *, VPIRBasicBlock * > > getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB)
Returns the (early exiting block, exit block) pairs of Plan, i.e.
VPIRFlags getFlagsFromIndDesc(const InductionDescriptor &ID)
Extracts and returns NoWrap and FastMath flags from the induction binop in ID.
Definition VPlanUtils.h:141
DenseMap< const VPBasicBlock *, std::optional< VPExecutionFrequency > > computeExecutionFrequencies(ArrayRef< VPBasicBlock * > Blocks)
Computes for each block in Blocks, which must be in reverse post-order, the frequency with which it e...
VPRecipeBase * findRecipe(VPValue *Start, PredT Pred)
Search Start's users for a recipe satisfying Pred, looking through recipes with definitions.
Definition VPlanUtils.h:158
LLVM_ABI_FOR_TEST const SCEV * getSCEVExprForVPValue(const VPValue *V, PredicatedScalarEvolution &PSE, const Loop *L=nullptr)
Return the SCEV expression for V.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
SmallVector< VPBasicBlock * > vp_rpo_plain_cfg_loop_body(VPBasicBlock *Header)
Returns the VPBasicBlocks forming the loop body of a plain (pre-region) VPlan in reverse post-order s...
Definition VPlanCFG.h:262
LLVM_ABI Intrinsic::ID getMinMaxReductionIntrinsicOp(Intrinsic::ID RdxID)
Returns the min/max intrinsic used when expanding a min/max reduction.
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition STLExtras.h:856
ReductionStyle getReductionStyle(bool InLoop, bool Ordered, unsigned ScaleFactor)
Definition VPlan.h:2860
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
auto map_to_vector(ContainerTy &&C, FuncTy &&F)
Map a range to a SmallVector with element types deduced from the mapping.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
iterator_range< df_iterator< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_depth_first_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order.
Definition VPlanCFG.h:250
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
constexpr size_t range_size(R &&Range)
Returns the size of the Range, i.e., the number of elements.
Definition STLExtras.h:1710
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:552
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
Definition STLExtras.h:323
RecurKind
These are the kinds of recurrences that we support.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ FMinimumNum
FP min with llvm.minimumnum semantics.
@ FindIV
FindIV reduction with select(icmp(),x,y) where one of (x,y) is a loop induction variable (increasing ...
@ FMinimum
FP min with llvm.minimum semantics.
@ FMaxNum
FP max with llvm.maxnum semantics including NaNs.
@ AnyOf
AnyOf reduction with select(cmp(),x,y) where one of (x,y) is loop invariant, and both x and y are int...
@ FMax
FP max implemented in terms of select(cmp()).
@ FMaximum
FP max with llvm.maximum semantics.
@ FMulAdd
Sum of float products with llvm.fmuladd(a * b + sum).
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ FMin
FP min implemented in terms of select(cmp()).
@ FMinNum
FP min with llvm.minnum semantics including NaNs.
@ Sub
Subtraction of integers.
@ AddChainWithSubs
A chain of adds and subs.
@ FMaximumNum
FP max with llvm.maximumnum semantics.
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2035
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
Definition STLExtras.h:2162
LLVM_ABI bool isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L, ScalarEvolution &SE, DominatorTree &DT, AssumptionCache *AC=nullptr, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Return true if we can prove that the given load (which is assumed to be within the specified loop) wo...
Definition Loads.cpp:304
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342
A recipe for handling first-order recurrence phis.
Definition VPlan.h:2811
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:279
static void simplifyLiveInsWithSCEV(VPlan &Plan, PredicatedScalarEvolution &PSE)
Check Plan's live-ins and replace them with constants, if they can be simplified via SCEV.
static void foldTailByMasking(VPlan &Plan)
Adapts the vector loop region for tail folding by introducing a header mask and conditionally executi...
static void addMinimumVectorEpilogueIterationCheck(VPlan &Plan, Value *VectorTripCount, bool RequiresScalarEpilogue, ElementCount EpilogueVF, unsigned EpilogueUF, unsigned MainLoopStep, unsigned EpilogueLoopStep, ScalarEvolution &SE)
Add a check to Plan to see if the epilogue vector loop should be executed.
static bool handleMultiUseReductions(VPlan &Plan, OptimizationRemarkEmitter *ORE, Loop *TheLoop)
Try to legalize reductions with multiple in-loop uses.
static void recordExecutionFrequencies(VPlan &Plan)
Add execution frequencies to each recipe in the loop body of Plan.
static bool handleFindLastReductions(VPlan &Plan)
Check if Plan contains any FindLast reductions.
static void createInLoopReductionRecipes(VPlan &Plan, ElementCount MinVF)
Create VPReductionRecipes for in-loop reductions.
static void modelGeneratedMainLoopBlocks(VPlan &EpiPlan, VPlan &MainPlan, VPIRBasicBlock *EnteredFrom)
Model the blocks the executed MainPlan generated for the main vector loop in EpiPlan during epilogue ...
static LLVM_ABI_FOR_TEST void createLoopRegions(VPlan &Plan, DebugLoc DL)
Replace loops in Plan's flat CFG with VPRegionBlocks, turning Plan's flat CFG into a hierarchical CFG...
static LLVM_ABI_FOR_TEST void addMiddleCheck(VPlan &Plan)
If a check is needed to guard executing the scalar epilogue loop, it will be added to the middle bloc...
static LLVM_ABI_FOR_TEST bool createHeaderPhiRecipes(VPlan &Plan, PredicatedScalarEvolution &PSE, Loop &OrigLoop, const VPDominatorTree &VPDT, const MapVector< PHINode *, InductionDescriptor > &Inductions, const MapVector< PHINode *, RecurrenceDescriptor > &Reductions, const SmallPtrSetImpl< const PHINode * > &FixedOrderRecurrences, const SmallPtrSetImpl< PHINode * > &InLoopReductions, bool AllowReordering)
Replace VPPhi recipes in Plan's header with corresponding VPHeaderPHIRecipe subclasses for inductions...
static void attachAliasMaskToHeaderMask(VPlan &Plan)
Attaches the alias-mask to the existing header-mask.
static bool areAllLoadsDereferenceable(VPBasicBlock *HeaderVPBB, Loop *TheLoop, PredicatedScalarEvolution &PSE, DominatorTree &DT, AssumptionCache *AC)
Check if all loads in the loop are dereferenceable.
static LLVM_ABI_FOR_TEST std::unique_ptr< VPlan > buildVPlan0(Loop *TheLoop, LoopInfo &LI, Type *InductionTy, PredicatedScalarEvolution &PSE, LoopVersioning *LVer=nullptr, function_ref< const BranchProbabilityInfo &()> GetBPI=nullptr)
Create a base VPlan0, serving as the common starting point for all later candidates.
static bool handleMaxMinNumReductions(VPlan &Plan)
Check if Plan contains any FMaxNum or FMinNum reductions.
static void attachCheckBlock(VPlan &Plan, Value *Cond, BasicBlock *CheckBlock, bool AddBranchWeights)
static LLVM_ABI_FOR_TEST void handleCountableEarlyExits(VPlan &Plan)
Disconnect countable early exits from the loop.
static bool finalizeSCEVPredicates(VPlan &Plan, PredicatedScalarEvolution &PSE, bool OptForSize, unsigned SCEVCheckThreshold, OptimizationRemarkEmitter *ORE, Loop *TheLoop)
Finalize SCEV predicates by adding induction predicates from Plan to PSE and checking constraints.
static void addIterationCountCheckBlock(VPlan &Plan, ElementCount VF, unsigned UF, bool RequiresScalarEpilogue, Loop *OrigLoop, const uint32_t *MinItersBypassWeights, DebugLoc DL, PredicatedScalarEvolution &PSE)
Add a new check block before the vector preheader to Plan to check if the main vector loop should be ...
static void addMinimumIterationCheck(VPlan &Plan, ElementCount VF, unsigned UF, ElementCount MinProfitableTripCount, bool RequiresScalarEpilogue, bool TailFolded, Loop *OrigLoop, const uint32_t *MinItersBypassWeights, DebugLoc DL, PredicatedScalarEvolution &PSE, VPBasicBlock *CheckBlock)
static void attachVPCheckBlock(VPlan &Plan, VPValue *Cond, VPBasicBlock *CheckBlock, bool AddBranchWeights)
Wrap runtime check block CheckBlock in a VPIRBB and Cond in a VPValue and connect the block to Plan,...