Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h
35269 views
//===- VPRecipeBuilder.h - Helper class to build recipes --------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLVM_TRANSFORMS_VECTORIZE_VPRECIPEBUILDER_H9#define LLVM_TRANSFORMS_VECTORIZE_VPRECIPEBUILDER_H1011#include "LoopVectorizationPlanner.h"12#include "VPlan.h"13#include "llvm/ADT/DenseMap.h"14#include "llvm/ADT/PointerUnion.h"15#include "llvm/IR/IRBuilder.h"1617namespace llvm {1819class LoopVectorizationLegality;20class LoopVectorizationCostModel;21class TargetLibraryInfo;2223/// Helper class to create VPRecipies from IR instructions.24class VPRecipeBuilder {25/// The VPlan new recipes are added to.26VPlan &Plan;2728/// The loop that we evaluate.29Loop *OrigLoop;3031/// Target Library Info.32const TargetLibraryInfo *TLI;3334/// The legality analysis.35LoopVectorizationLegality *Legal;3637/// The profitablity analysis.38LoopVectorizationCostModel &CM;3940PredicatedScalarEvolution &PSE;4142VPBuilder &Builder;4344/// When we if-convert we need to create edge masks. We have to cache values45/// so that we don't end up with exponential recursion/IR. Note that46/// if-conversion currently takes place during VPlan-construction, so these47/// caches are only used at that stage.48using EdgeMaskCacheTy =49DenseMap<std::pair<BasicBlock *, BasicBlock *>, VPValue *>;50using BlockMaskCacheTy = DenseMap<BasicBlock *, VPValue *>;51EdgeMaskCacheTy EdgeMaskCache;52BlockMaskCacheTy BlockMaskCache;5354// VPlan construction support: Hold a mapping from ingredients to55// their recipe.56DenseMap<Instruction *, VPRecipeBase *> Ingredient2Recipe;5758/// Cross-iteration reduction & first-order recurrence phis for which we need59/// to add the incoming value from the backedge after all recipes have been60/// created.61SmallVector<VPHeaderPHIRecipe *, 4> PhisToFix;6263/// Check if \p I can be widened at the start of \p Range and possibly64/// decrease the range such that the returned value holds for the entire \p65/// Range. The function should not be called for memory instructions or calls.66bool shouldWiden(Instruction *I, VFRange &Range) const;6768/// Check if the load or store instruction \p I should widened for \p69/// Range.Start and potentially masked. Such instructions are handled by a70/// recipe that takes an additional VPInstruction for the mask.71VPWidenMemoryRecipe *tryToWidenMemory(Instruction *I,72ArrayRef<VPValue *> Operands,73VFRange &Range);7475/// Check if an induction recipe should be constructed for \p Phi. If so build76/// and return it. If not, return null.77VPHeaderPHIRecipe *tryToOptimizeInductionPHI(PHINode *Phi,78ArrayRef<VPValue *> Operands,79VFRange &Range);8081/// Optimize the special case where the operand of \p I is a constant integer82/// induction variable.83VPWidenIntOrFpInductionRecipe *84tryToOptimizeInductionTruncate(TruncInst *I, ArrayRef<VPValue *> Operands,85VFRange &Range);8687/// Handle non-loop phi nodes. Return a new VPBlendRecipe otherwise. Currently88/// all such phi nodes are turned into a sequence of select instructions as89/// the vectorizer currently performs full if-conversion.90VPBlendRecipe *tryToBlend(PHINode *Phi, ArrayRef<VPValue *> Operands);9192/// Handle call instructions. If \p CI can be widened for \p Range.Start,93/// return a new VPWidenCallRecipe. Range.End may be decreased to ensure same94/// decision from \p Range.Start to \p Range.End.95VPWidenCallRecipe *tryToWidenCall(CallInst *CI, ArrayRef<VPValue *> Operands,96VFRange &Range);9798/// Check if \p I has an opcode that can be widened and return a VPWidenRecipe99/// if it can. The function should only be called if the cost-model indicates100/// that widening should be performed.101VPWidenRecipe *tryToWiden(Instruction *I, ArrayRef<VPValue *> Operands,102VPBasicBlock *VPBB);103104public:105VPRecipeBuilder(VPlan &Plan, Loop *OrigLoop, const TargetLibraryInfo *TLI,106LoopVectorizationLegality *Legal,107LoopVectorizationCostModel &CM,108PredicatedScalarEvolution &PSE, VPBuilder &Builder)109: Plan(Plan), OrigLoop(OrigLoop), TLI(TLI), Legal(Legal), CM(CM),110PSE(PSE), Builder(Builder) {}111112/// Create and return a widened recipe for \p I if one can be created within113/// the given VF \p Range.114VPRecipeBase *tryToCreateWidenRecipe(Instruction *Instr,115ArrayRef<VPValue *> Operands,116VFRange &Range, VPBasicBlock *VPBB);117118/// Set the recipe created for given ingredient.119void setRecipe(Instruction *I, VPRecipeBase *R) {120assert(!Ingredient2Recipe.contains(I) &&121"Cannot reset recipe for instruction.");122Ingredient2Recipe[I] = R;123}124125/// Create the mask for the vector loop header block.126void createHeaderMask();127128/// A helper function that computes the predicate of the block BB, assuming129/// that the header block of the loop is set to True or the loop mask when130/// tail folding.131void createBlockInMask(BasicBlock *BB);132133/// Returns the *entry* mask for the block \p BB.134VPValue *getBlockInMask(BasicBlock *BB) const;135136/// A helper function that computes the predicate of the edge between SRC137/// and DST.138VPValue *createEdgeMask(BasicBlock *Src, BasicBlock *Dst);139140/// A helper that returns the previously computed predicate of the edge141/// between SRC and DST.142VPValue *getEdgeMask(BasicBlock *Src, BasicBlock *Dst) const;143144/// Return the recipe created for given ingredient.145VPRecipeBase *getRecipe(Instruction *I) {146assert(Ingredient2Recipe.count(I) &&147"Recording this ingredients recipe was not requested");148assert(Ingredient2Recipe[I] != nullptr &&149"Ingredient doesn't have a recipe");150return Ingredient2Recipe[I];151}152153/// Build a VPReplicationRecipe for \p I. If it is predicated, add the mask as154/// last operand. Range.End may be decreased to ensure same recipe behavior155/// from \p Range.Start to \p Range.End.156VPReplicateRecipe *handleReplication(Instruction *I, VFRange &Range);157158/// Add the incoming values from the backedge to reduction & first-order159/// recurrence cross-iteration phis.160void fixHeaderPhis();161162/// Returns a range mapping the values of the range \p Operands to their163/// corresponding VPValues.164iterator_range<mapped_iterator<Use *, std::function<VPValue *(Value *)>>>165mapToVPValues(User::op_range Operands);166167VPValue *getVPValueOrAddLiveIn(Value *V, VPlan &Plan) {168if (auto *I = dyn_cast<Instruction>(V)) {169if (auto *R = Ingredient2Recipe.lookup(I))170return R->getVPSingleValue();171}172return Plan.getOrAddLiveIn(V);173}174};175} // end namespace llvm176177#endif // LLVM_TRANSFORMS_VECTORIZE_VPRECIPEBUILDER_H178179180