From e60b36cf92e1570284482eddb2eac3652e28c2eb Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sat, 7 Dec 2019 08:52:36 +0000 Subject: [VPlan] Rename VPlanHCFGTransforms to VPlanTransforms (NFC). The file is intended to gather various VPlan transformations, not only CFG related transforms. Actually, the only transformation there is not CFG related. Reviewers: Ayal, gilr, hsaito, rengolin Reviewed By: gilr Differential Revision: https://reviews.llvm.org/D70732 --- llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp | 86 +++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp (limited to 'llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp') diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp new file mode 100644 index 00000000000..fb81a396bbb --- /dev/null +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -0,0 +1,86 @@ +//===-- VPlanTransforms.cpp - Utility VPlan to VPlan transforms -----------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file implements a set of utility VPlan to VPlan transformations. +/// +//===----------------------------------------------------------------------===// + +#include "VPlanTransforms.h" +#include "llvm/ADT/PostOrderIterator.h" + +using namespace llvm; + +void VPlanTransforms::VPInstructionsToVPRecipes( + Loop *OrigLoop, VPlanPtr &Plan, + LoopVectorizationLegality::InductionList *Inductions, + SmallPtrSetImpl &DeadInstructions) { + + auto *TopRegion = cast(Plan->getEntry()); + ReversePostOrderTraversal RPOT(TopRegion->getEntry()); + + // Condition bit VPValues get deleted during transformation to VPRecipes. + // Create new VPValues and save away as condition bits. These will be deleted + // after finalizing the vector IR basic blocks. + for (VPBlockBase *Base : RPOT) { + VPBasicBlock *VPBB = Base->getEntryBasicBlock(); + if (auto *CondBit = VPBB->getCondBit()) { + auto *NCondBit = new VPValue(CondBit->getUnderlyingValue()); + VPBB->setCondBit(NCondBit); + Plan->addCBV(NCondBit); + } + } + 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(Ingredient); + Instruction *Inst = cast(VPInst->getUnderlyingValue()); + if (DeadInstructions.count(Inst)) { + Ingredient->eraseFromParent(); + continue; + } + + VPRecipeBase *NewRecipe = nullptr; + // Create VPWidenMemoryInstructionRecipe for loads and stores. + if (isa(Inst) || isa(Inst)) + NewRecipe = new VPWidenMemoryInstructionRecipe(*Inst, nullptr /*Mask*/); + else if (PHINode *Phi = dyn_cast(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 (GetElementPtrInst *GEP = dyn_cast(Inst)) { + NewRecipe = new VPWidenGEPRecipe(GEP, OrigLoop); + } 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(LastRecipe)) { + WidenRecipe->appendInstruction(Inst); + Ingredient->eraseFromParent(); + continue; + } + NewRecipe = new VPWidenRecipe(Inst); + } + + NewRecipe->insertBefore(Ingredient); + LastRecipe = NewRecipe; + Ingredient->eraseFromParent(); + } + } +} -- cgit v1.2.3