xref: /llvm-project/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp (revision 71ede8d83159e70e74848a03bfc7c007dbf61203)
1 //===- VPlanUtils.cpp - VPlan-related utilities ---------------------------===//
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 #include "VPlanUtils.h"
10 #include "VPlanPatternMatch.h"
11 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
12 
13 using namespace llvm;
14 
15 bool vputils::onlyFirstLaneUsed(const VPValue *Def) {
16   return all_of(Def->users(),
17                 [Def](const VPUser *U) { return U->onlyFirstLaneUsed(Def); });
18 }
19 
20 bool vputils::onlyFirstPartUsed(const VPValue *Def) {
21   return all_of(Def->users(),
22                 [Def](const VPUser *U) { return U->onlyFirstPartUsed(Def); });
23 }
24 
25 VPValue *vputils::getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
26                                                 ScalarEvolution &SE) {
27   if (auto *Expanded = Plan.getSCEVExpansion(Expr))
28     return Expanded;
29   VPValue *Expanded = nullptr;
30   if (auto *E = dyn_cast<SCEVConstant>(Expr))
31     Expanded = Plan.getOrAddLiveIn(E->getValue());
32   else if (auto *E = dyn_cast<SCEVUnknown>(Expr))
33     Expanded = Plan.getOrAddLiveIn(E->getValue());
34   else {
35     Expanded = new VPExpandSCEVRecipe(Expr, SE);
36     Plan.getPreheader()->appendRecipe(Expanded->getDefiningRecipe());
37   }
38   Plan.addSCEVExpansion(Expr, Expanded);
39   return Expanded;
40 }
41 
42 bool vputils::isHeaderMask(const VPValue *V, VPlan &Plan) {
43   if (isa<VPActiveLaneMaskPHIRecipe>(V))
44     return true;
45 
46   auto IsWideCanonicalIV = [](VPValue *A) {
47     return isa<VPWidenCanonicalIVRecipe>(A) ||
48            (isa<VPWidenIntOrFpInductionRecipe>(A) &&
49             cast<VPWidenIntOrFpInductionRecipe>(A)->isCanonical());
50   };
51 
52   VPValue *A, *B;
53   using namespace VPlanPatternMatch;
54 
55   if (match(V, m_ActiveLaneMask(m_VPValue(A), m_VPValue(B))))
56     return B == Plan.getTripCount() &&
57            (match(A, m_ScalarIVSteps(m_CanonicalIV(), m_SpecificInt(1))) ||
58             IsWideCanonicalIV(A));
59 
60   return match(V, m_Binary<Instruction::ICmp>(m_VPValue(A), m_VPValue(B))) &&
61          IsWideCanonicalIV(A) && B == Plan.getOrCreateBackedgeTakenCount();
62 }
63