| //===- VPlanUtils.cpp - VPlan-related utilities ---------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "VPlanUtils.h" |
| #include "VPlanPatternMatch.h" |
| #include "llvm/Analysis/ScalarEvolutionExpressions.h" |
| |
| using namespace llvm; |
| |
| bool vputils::onlyFirstLaneUsed(const VPValue *Def) { |
| return all_of(Def->users(), |
| [Def](const VPUser *U) { return U->onlyFirstLaneUsed(Def); }); |
| } |
| |
| bool vputils::onlyFirstPartUsed(const VPValue *Def) { |
| return all_of(Def->users(), |
| [Def](const VPUser *U) { return U->onlyFirstPartUsed(Def); }); |
| } |
| |
| VPValue *vputils::getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr, |
| ScalarEvolution &SE) { |
| if (auto *Expanded = Plan.getSCEVExpansion(Expr)) |
| return Expanded; |
| VPValue *Expanded = nullptr; |
| if (auto *E = dyn_cast<SCEVConstant>(Expr)) |
| Expanded = Plan.getOrAddLiveIn(E->getValue()); |
| else if (auto *E = dyn_cast<SCEVUnknown>(Expr)) |
| Expanded = Plan.getOrAddLiveIn(E->getValue()); |
| else { |
| Expanded = new VPExpandSCEVRecipe(Expr, SE); |
| Plan.getPreheader()->appendRecipe(Expanded->getDefiningRecipe()); |
| } |
| Plan.addSCEVExpansion(Expr, Expanded); |
| return Expanded; |
| } |
| |
| bool vputils::isHeaderMask(const VPValue *V, VPlan &Plan) { |
| if (isa<VPActiveLaneMaskPHIRecipe>(V)) |
| return true; |
| |
| auto IsWideCanonicalIV = [](VPValue *A) { |
| return isa<VPWidenCanonicalIVRecipe>(A) || |
| (isa<VPWidenIntOrFpInductionRecipe>(A) && |
| cast<VPWidenIntOrFpInductionRecipe>(A)->isCanonical()); |
| }; |
| |
| VPValue *A, *B; |
| using namespace VPlanPatternMatch; |
| |
| if (match(V, m_ActiveLaneMask(m_VPValue(A), m_VPValue(B)))) |
| return B == Plan.getTripCount() && |
| (match(A, m_ScalarIVSteps(m_CanonicalIV(), m_SpecificInt(1))) || |
| IsWideCanonicalIV(A)); |
| |
| return match(V, m_Binary<Instruction::ICmp>(m_VPValue(A), m_VPValue(B))) && |
| IsWideCanonicalIV(A) && B == Plan.getOrCreateBackedgeTakenCount(); |
| } |