diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 10:51:19 +0000 | 
| commit | eb11fae6d08f479c0799db45860a98af528fa6e7 (patch) | |
| tree | 44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /lib/Transforms/Vectorize/VPlanHCFGTransforms.cpp | |
| parent | b8a2042aa938069e862750553db0e4d82d25822c (diff) | |
Notes
Diffstat (limited to 'lib/Transforms/Vectorize/VPlanHCFGTransforms.cpp')
| -rw-r--r-- | lib/Transforms/Vectorize/VPlanHCFGTransforms.cpp | 73 | 
1 files changed, 73 insertions, 0 deletions
diff --git a/lib/Transforms/Vectorize/VPlanHCFGTransforms.cpp b/lib/Transforms/Vectorize/VPlanHCFGTransforms.cpp new file mode 100644 index 000000000000..e3cbab077e61 --- /dev/null +++ b/lib/Transforms/Vectorize/VPlanHCFGTransforms.cpp @@ -0,0 +1,73 @@ +//===-- VPlanHCFGTransforms.cpp - Utility VPlan to VPlan transforms -------===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file implements a set of utility VPlan to VPlan transformations. +/// +//===----------------------------------------------------------------------===// + +#include "VPlanHCFGTransforms.h" +#include "llvm/ADT/PostOrderIterator.h" + +using namespace llvm; + +void VPlanHCFGTransforms::VPInstructionsToVPRecipes( +    VPlanPtr &Plan, +    LoopVectorizationLegality::InductionList *Inductions, +    SmallPtrSetImpl<Instruction *> &DeadInstructions) { + +  VPRegionBlock *TopRegion = dyn_cast<VPRegionBlock>(Plan->getEntry()); +  ReversePostOrderTraversal<VPBlockBase *> RPOT(TopRegion->getEntry()); +  for (VPBlockBase *Base : RPOT) { +    // Do not widen instructions in pre-header and exit blocks. +    if (Base->getNumPredecessors() == 0 || Base->getNumSuccessors() == 0) +      continue; + +    VPBasicBlock *VPBB = Base->getEntryBasicBlock(); +    VPRecipeBase *LastRecipe = nullptr; +    // Introduce each ingredient into VPlan. +    for (auto I = VPBB->begin(), E = VPBB->end(); I != E;) { +      VPRecipeBase *Ingredient = &*I++; +      // Can only handle VPInstructions. +      VPInstruction *VPInst = cast<VPInstruction>(Ingredient); +      Instruction *Inst = cast<Instruction>(VPInst->getUnderlyingValue()); +      if (DeadInstructions.count(Inst)) { +        Ingredient->eraseFromParent(); +        continue; +      } + +      VPRecipeBase *NewRecipe = nullptr; +      // Create VPWidenMemoryInstructionRecipe for loads and stores. +      if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst)) +        NewRecipe = new VPWidenMemoryInstructionRecipe(*Inst, nullptr /*Mask*/); +      else if (PHINode *Phi = dyn_cast<PHINode>(Inst)) { +        InductionDescriptor II = Inductions->lookup(Phi); +        if (II.getKind() == InductionDescriptor::IK_IntInduction || +            II.getKind() == InductionDescriptor::IK_FpInduction) { +          NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi); +        } else +          NewRecipe = new VPWidenPHIRecipe(Phi); +      } else { +        // If the last recipe is a VPWidenRecipe, add Inst to it instead of +        // creating a new recipe. +        if (VPWidenRecipe *WidenRecipe = +                dyn_cast_or_null<VPWidenRecipe>(LastRecipe)) { +          WidenRecipe->appendInstruction(Inst); +          Ingredient->eraseFromParent(); +          continue; +        } +        NewRecipe = new VPWidenRecipe(Inst); +      } + +      NewRecipe->insertBefore(Ingredient); +      LastRecipe = NewRecipe; +      Ingredient->eraseFromParent(); +    } +  } +}  | 
