xref: /llvm-project/llvm/lib/Transforms/Vectorize/VPlanUtils.h (revision 2c87133c6212d4bd02b5e64adbb51f4e66bc2351)
1 //===- VPlanUtils.h - VPlan-related utilities -------------------*- C++ -*-===//
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 #ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANUTILS_H
10 #define LLVM_TRANSFORMS_VECTORIZE_VPLANUTILS_H
11 
12 #include "VPlan.h"
13 
14 namespace llvm {
15 class ScalarEvolution;
16 class SCEV;
17 } // namespace llvm
18 
19 namespace llvm::vputils {
20 /// Returns true if only the first lane of \p Def is used.
21 bool onlyFirstLaneUsed(const VPValue *Def);
22 
23 /// Returns true if only the first part of \p Def is used.
24 bool onlyFirstPartUsed(const VPValue *Def);
25 
26 /// Get or create a VPValue that corresponds to the expansion of \p Expr. If \p
27 /// Expr is a SCEVConstant or SCEVUnknown, return a VPValue wrapping the live-in
28 /// value. Otherwise return a VPExpandSCEVRecipe to expand \p Expr. If \p Plan's
29 /// pre-header already contains a recipe expanding \p Expr, return it. If not,
30 /// create a new one.
31 VPValue *getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
32                                        ScalarEvolution &SE);
33 
34 /// Return the SCEV expression for \p V. Returns SCEVCouldNotCompute if no
35 /// SCEV expression could be constructed.
36 const SCEV *getSCEVExprForVPValue(VPValue *V, ScalarEvolution &SE);
37 
38 /// Returns true if \p VPV is uniform after vectorization.
39 inline bool isUniformAfterVectorization(const VPValue *VPV) {
40   // A value defined outside the vector region must be uniform after
41   // vectorization inside a vector region.
42   if (VPV->isDefinedOutsideLoopRegions())
43     return true;
44   const VPRecipeBase *Def = VPV->getDefiningRecipe();
45   assert(Def && "Must have definition for value defined inside vector region");
46   if (auto *Rep = dyn_cast<VPReplicateRecipe>(Def))
47     return Rep->isUniform();
48   if (isa<VPWidenGEPRecipe, VPDerivedIVRecipe>(Def))
49     return all_of(Def->operands(), isUniformAfterVectorization);
50   if (auto *VPI = dyn_cast<VPInstruction>(Def))
51     return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
52            ((Instruction::isBinaryOp(VPI->getOpcode()) ||
53              VPI->getOpcode() == VPInstruction::PtrAdd) &&
54             all_of(VPI->operands(), isUniformAfterVectorization));
55   if (auto *IV = dyn_cast<VPDerivedIVRecipe>(Def))
56     return all_of(IV->operands(), isUniformAfterVectorization);
57 
58   // VPExpandSCEVRecipes must be placed in the entry and are alway uniform.
59   return isa<VPExpandSCEVRecipe>(Def);
60 }
61 
62 /// Return true if \p V is a header mask in \p Plan.
63 bool isHeaderMask(const VPValue *V, VPlan &Plan);
64 
65 /// Checks if \p V is uniform across all VF lanes and UF parts. It is considered
66 /// as such if it is either loop invariant (defined outside the vector region)
67 /// or its operand is known to be uniform across all VFs and UFs (e.g.
68 /// VPDerivedIV or VPCanonicalIVPHI).
69 bool isUniformAcrossVFsAndUFs(VPValue *V);
70 
71 } // end namespace llvm::vputils
72 
73 #endif
74