mirror of
https://github.com/RPCS3/llvm.git
synced 2025-05-15 18:06:08 +00:00

to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351636 91177308-0d34-0410-b5e6-96231b3b80d8
132 lines
5.7 KiB
C++
132 lines
5.7 KiB
C++
//===- VPRecipeBuilder.h - Helper class to build recipes --------*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_TRANSFORMS_VECTORIZE_VPRECIPEBUILDER_H
|
|
#define LLVM_TRANSFORMS_VECTORIZE_VPRECIPEBUILDER_H
|
|
|
|
#include "LoopVectorizationPlanner.h"
|
|
#include "VPlan.h"
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include "llvm/IR/IRBuilder.h"
|
|
|
|
namespace llvm {
|
|
|
|
class LoopVectorizationLegality;
|
|
class LoopVectorizationCostModel;
|
|
class TargetTransformInfo;
|
|
class TargetLibraryInfo;
|
|
|
|
/// Helper class to create VPRecipies from IR instructions.
|
|
class VPRecipeBuilder {
|
|
/// The loop that we evaluate.
|
|
Loop *OrigLoop;
|
|
|
|
/// Target Library Info.
|
|
const TargetLibraryInfo *TLI;
|
|
|
|
/// Target Transform Info.
|
|
const TargetTransformInfo *TTI;
|
|
|
|
/// The legality analysis.
|
|
LoopVectorizationLegality *Legal;
|
|
|
|
/// The profitablity analysis.
|
|
LoopVectorizationCostModel &CM;
|
|
|
|
VPBuilder &Builder;
|
|
|
|
/// When we if-convert we need to create edge masks. We have to cache values
|
|
/// so that we don't end up with exponential recursion/IR. Note that
|
|
/// if-conversion currently takes place during VPlan-construction, so these
|
|
/// caches are only used at that stage.
|
|
using EdgeMaskCacheTy =
|
|
DenseMap<std::pair<BasicBlock *, BasicBlock *>, VPValue *>;
|
|
using BlockMaskCacheTy = DenseMap<BasicBlock *, VPValue *>;
|
|
EdgeMaskCacheTy EdgeMaskCache;
|
|
BlockMaskCacheTy BlockMaskCache;
|
|
|
|
public:
|
|
/// A helper function that computes the predicate of the block BB, assuming
|
|
/// that the header block of the loop is set to True. It returns the *entry*
|
|
/// mask for the block BB.
|
|
VPValue *createBlockInMask(BasicBlock *BB, VPlanPtr &Plan);
|
|
|
|
/// A helper function that computes the predicate of the edge between SRC
|
|
/// and DST.
|
|
VPValue *createEdgeMask(BasicBlock *Src, BasicBlock *Dst, VPlanPtr &Plan);
|
|
|
|
/// Check if \I belongs to an Interleave Group within the given VF \p Range,
|
|
/// \return true in the first returned value if so and false otherwise.
|
|
/// Build a new VPInterleaveGroup Recipe if \I is the primary member of an IG
|
|
/// for \p Range.Start, and provide it as the second returned value.
|
|
/// Note that if \I is an adjunct member of an IG for \p Range.Start, the
|
|
/// \return value is <true, nullptr>, as it is handled by another recipe.
|
|
/// \p Range.End may be decreased to ensure same decision from \p Range.Start
|
|
/// to \p Range.End.
|
|
VPInterleaveRecipe *tryToInterleaveMemory(Instruction *I, VFRange &Range,
|
|
VPlanPtr &Plan);
|
|
|
|
/// Check if \I is a memory instruction to be widened for \p Range.Start and
|
|
/// potentially masked. Such instructions are handled by a recipe that takes
|
|
/// an additional VPInstruction for the mask.
|
|
VPWidenMemoryInstructionRecipe *
|
|
tryToWidenMemory(Instruction *I, VFRange &Range, VPlanPtr &Plan);
|
|
|
|
/// Check if an induction recipe should be constructed for \I within the given
|
|
/// VF \p Range. If so build and return it. If not, return null. \p Range.End
|
|
/// may be decreased to ensure same decision from \p Range.Start to
|
|
/// \p Range.End.
|
|
VPWidenIntOrFpInductionRecipe *tryToOptimizeInduction(Instruction *I,
|
|
VFRange &Range);
|
|
|
|
/// Handle non-loop phi nodes. Currently all such phi nodes are turned into
|
|
/// a sequence of select instructions as the vectorizer currently performs
|
|
/// full if-conversion.
|
|
VPBlendRecipe *tryToBlend(Instruction *I, VPlanPtr &Plan);
|
|
|
|
/// Check if \p I can be widened within the given VF \p Range. If \p I can be
|
|
/// widened for \p Range.Start, check if the last recipe of \p VPBB can be
|
|
/// extended to include \p I or else build a new VPWidenRecipe for it and
|
|
/// append it to \p VPBB. Return true if \p I can be widened for Range.Start,
|
|
/// false otherwise. Range.End may be decreased to ensure same decision from
|
|
/// \p Range.Start to \p Range.End.
|
|
bool tryToWiden(Instruction *I, VPBasicBlock *VPBB, VFRange &Range);
|
|
|
|
/// Create a replicating region for instruction \p I that requires
|
|
/// predication. \p PredRecipe is a VPReplicateRecipe holding \p I.
|
|
VPRegionBlock *createReplicateRegion(Instruction *I, VPRecipeBase *PredRecipe,
|
|
VPlanPtr &Plan);
|
|
|
|
public:
|
|
VPRecipeBuilder(Loop *OrigLoop, const TargetLibraryInfo *TLI,
|
|
const TargetTransformInfo *TTI,
|
|
LoopVectorizationLegality *Legal,
|
|
LoopVectorizationCostModel &CM, VPBuilder &Builder)
|
|
: OrigLoop(OrigLoop), TLI(TLI), TTI(TTI), Legal(Legal), CM(CM),
|
|
Builder(Builder) {}
|
|
|
|
/// Check if a recipe can be create for \p I withing the given VF \p Range.
|
|
/// If a recipe can be created, it adds it to \p VPBB.
|
|
bool tryToCreateRecipe(Instruction *Instr, VFRange &Range, VPlanPtr &Plan,
|
|
VPBasicBlock *VPBB);
|
|
|
|
/// Build a VPReplicationRecipe for \p I and enclose it within a Region if it
|
|
/// is predicated. \return \p VPBB augmented with this new recipe if \p I is
|
|
/// not predicated, otherwise \return a new VPBasicBlock that succeeds the new
|
|
/// Region. Update the packing decision of predicated instructions if they
|
|
/// feed \p I. Range.End may be decreased to ensure same recipe behavior from
|
|
/// \p Range.Start to \p Range.End.
|
|
VPBasicBlock *handleReplication(
|
|
Instruction *I, VFRange &Range, VPBasicBlock *VPBB,
|
|
DenseMap<Instruction *, VPReplicateRecipe *> &PredInst2Recipe,
|
|
VPlanPtr &Plan);
|
|
};
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_TRANSFORMS_VECTORIZE_VPRECIPEBUILDER_H
|