32  using EdgeMaskCacheTy =
 
   33      DenseMap<std::pair<const VPBasicBlock *, const VPBasicBlock *>,
 
   35  using BlockMaskCacheTy = DenseMap<VPBasicBlock *, VPValue *>;
 
   36  EdgeMaskCacheTy EdgeMaskCache;
 
   38  BlockMaskCacheTy BlockMaskCache;
 
   41  void createSwitchEdgeMasks(VPInstruction *SI);
 
   45  VPValue *createEdgeMask(VPBasicBlock *Src, VPBasicBlock *Dst);
 
   48  VPValue *getBlockInMask(VPBasicBlock *VPBB)
 const {
 
   49    return BlockMaskCache.
lookup(VPBB);
 
   54  void setBlockInMask(VPBasicBlock *VPBB, VPValue *Mask) {
 
   57    assert(!getBlockInMask(VPBB) && 
"Mask already set");
 
   58    BlockMaskCache[VPBB] = 
Mask;
 
   63  VPValue *setEdgeMask(
const VPBasicBlock *Src, 
const VPBasicBlock *Dst,
 
   65    assert(Src != Dst && 
"Src and Dst must be different");
 
   66    assert(!getEdgeMask(Src, Dst) && 
"Mask already set");
 
   67    return EdgeMaskCache[{Src, Dst}] = 
Mask;
 
   72  VPValue *getEdgeMask(
const VPBasicBlock *Src, 
const VPBasicBlock *Dst)
 const {
 
   73    return EdgeMaskCache.
lookup({Src, Dst});
 
   77  void createHeaderMask(VPBasicBlock *HeaderVPBB, 
bool FoldTail);
 
   81  VPValue *createBlockInMask(VPBasicBlock *VPBB);
 
   84  void convertPhisToBlends(VPBasicBlock *VPBB);
 
   86  const BlockMaskCacheTy getBlockMaskCache()
 const { 
return BlockMaskCache; }
 
   94  VPValue *EdgeMask = getEdgeMask(Src, Dst);
 
   98  VPValue *SrcMask = getBlockInMask(Src);
 
  101  if (Src->getNumSuccessors() == 1)
 
  102    return setEdgeMask(Src, Dst, SrcMask);
 
  105  if (
Term->getOpcode() == Instruction::Switch) {
 
  106    createSwitchEdgeMasks(Term);
 
  107    return getEdgeMask(Src, Dst);
 
  111         "Unsupported terminator");
 
  112  if (Src->getSuccessors()[0] == Src->getSuccessors()[1])
 
  113    return setEdgeMask(Src, Dst, SrcMask);
 
  115  EdgeMask = 
Term->getOperand(0);
 
  116  assert(EdgeMask && 
"No Edge Mask found for condition");
 
  118  if (Src->getSuccessors()[0] != Dst)
 
  128  return setEdgeMask(Src, Dst, EdgeMask);
 
  131VPValue *VPPredicator::createBlockInMask(VPBasicBlock *VPBB) {
 
  136  VPValue *BlockMask = 
nullptr;
 
  138  for (
auto *Predecessor : SetVector<VPBlockBase *>(
 
  143      setBlockInMask(VPBB, EdgeMask);
 
  148      BlockMask = EdgeMask;
 
  152    BlockMask = Builder.
createOr(BlockMask, EdgeMask, {});
 
  155  setBlockInMask(VPBB, BlockMask);
 
  159void VPPredicator::createHeaderMask(VPBasicBlock *HeaderVPBB, 
bool FoldTail) {
 
  161    setBlockInMask(HeaderVPBB, 
nullptr);
 
  170  auto &Plan = *HeaderVPBB->
getPlan();
 
  176  VPValue *BTC = Plan.getOrCreateBackedgeTakenCount();
 
  178  setBlockInMask(HeaderVPBB, BlockMask);
 
  181void VPPredicator::createSwitchEdgeMasks(VPInstruction *SI) {
 
  182  VPBasicBlock *Src = 
SI->getParent();
 
  187  VPValue *
Cond = 
SI->getOperand(0);
 
  189  MapVector<VPBasicBlock *, SmallVector<VPValue *>> Dst2Compares;
 
  192    assert(!getEdgeMask(Src, Dst) && 
"Edge masks already created");
 
  195    if (Dst == DefaultDst)
 
  197    auto &Compares = Dst2Compares[Dst];
 
  198    VPValue *
V = 
SI->getOperand(Idx + 1);
 
  204  VPValue *SrcMask = getBlockInMask(Src);
 
  205  VPValue *DefaultMask = 
nullptr;
 
  206  for (
const auto &[Dst, Conds] : Dst2Compares) {
 
  210    VPValue *
Mask = Conds[0];
 
  215    setEdgeMask(Src, Dst, Mask);
 
  221    DefaultMask = DefaultMask ? Builder.
createOr(DefaultMask, Mask) : 
Mask;
 
  225    DefaultMask = Builder.
createNot(DefaultMask);
 
  229  setEdgeMask(Src, DefaultDst, DefaultMask);
 
  232void VPPredicator::convertPhisToBlends(VPBasicBlock *VPBB) {
 
  234  for (VPRecipeBase &R : VPBB->
phis())
 
  236  for (VPPhi *PhiR : Phis) {
 
  244    for (
const auto &[InVPV, InVPBB] : PhiR->incoming_values_and_blocks()) {
 
  246      VPValue *EdgeMask = getEdgeMask(InVPBB, VPBB);
 
  249               "Distinct incoming values with one having a full mask");
 
  257        new VPBlendRecipe(IRPhi, OperandsWithMask, PhiR->getDebugLoc());
 
  259    PhiR->replaceAllUsesWith(Blend);
 
  260    PhiR->eraseFromParent();
 
  264DenseMap<VPBasicBlock *, VPValue *>
 
  279    if (VPBB == Header) {
 
  280      Predicator.createHeaderMask(Header, FoldTail);
 
  292    if (Successors.size() > 1)
 
  297    for (
auto *Succ : Successors)
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
 
const SmallVectorImpl< MachineOperand > & Cond
 
This file contains the declarations of the Vectorization Plan base classes:
 
static const uint32_t IV[8]
 
@ ICMP_ULE
unsigned less or equal
 
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
 
void push_back(const T &Elt)
 
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
 
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
 
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
 
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
 
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
 
VPRegionBlock * getParent()
 
const VPBlocksTy & getPredecessors() const
 
const VPBasicBlock * getEntryBasicBlock() const
 
const VPBlocksTy & getSuccessors() const
 
static auto blocksOnly(const T &Range)
Return an iterator range over Range which only includes BlockTy blocks.
 
static void connectBlocks(VPBlockBase *From, VPBlockBase *To, unsigned PredIdx=-1u, unsigned SuccIdx=-1u)
Connect VPBlockBases From and To bi-directionally.
 
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
 
VPInstruction * createOr(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
 
VPInstruction * createNot(VPValue *Operand, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
 
VPInstruction * createLogicalAnd(VPValue *LHS, VPValue *RHS, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
 
void insert(VPRecipeBase *R)
Insert R at the current insertion point.
 
VPInstruction * createICmp(CmpInst::Predicate Pred, VPValue *A, VPValue *B, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="")
Create a new ICmp VPInstruction with predicate Pred and operands A and B.
 
void setInsertPoint(VPBasicBlock *TheBB)
This specifies that created VPInstructions should be appended to the end of the specified block.
 
iplist< VPRecipeBase >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
 
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
 
VPCanonicalIVPHIRecipe * getCanonicalIV()
Returns the canonical induction recipe of the region.
 
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
 
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
 
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
 
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
 
This is an optimization pass for GlobalISel generic memory operations.
 
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
 
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
 
auto cast_or_null(const Y &Val)
 
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
 
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
 
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
 
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.