//===- 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(Expr)) Expanded = Plan.getOrAddLiveIn(E->getValue()); else if (auto *E = dyn_cast(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(V)) return true; auto IsWideCanonicalIV = [](VPValue *A) { return isa(A) || (isa(A) && cast(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(m_VPValue(A), m_VPValue(B))) && IsWideCanonicalIV(A) && B == Plan.getOrCreateBackedgeTakenCount(); }