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