2018-06-19 02:28:49 +08:00
|
|
|
//===-- VPlanHCFGTransforms.cpp - Utility VPlan to VPlan transforms -------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2018-06-19 02:28:49 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
///
|
|
|
|
/// \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());
|
[VPlan] Implement initial vector code generation support for simple outer loops.
Summary:
[VPlan] Implement vector code generation support for simple outer loops.
Context: Patch Series #1 for outer loop vectorization support in LV using VPlan. (RFC: http://lists.llvm.org/pipermail/llvm-dev/2017-December/119523.html).
This patch introduces vector code generation support for simple outer loops that are currently supported in the VPlanNativePath. Changes here essentially do the following:
- force vector code generation using explicit vectorize_width
- add conservative early returns in cost model and other places for VPlanNativePath
- add code for setting up outer loop inductions
- support for widening non-induction PHIs that can result from inner loops and uniform conditional branches
- support for generating uniform inner branches
We plan to add a handful C outer loop executable tests once the initial code generation support is committed. This patch is expected to be NFC for the inner loop vectorizer path. Since we are moving in the direction of supporting outer loop vectorization in LV, it may also be time to rename classes such as InnerLoopVectorizer.
Reviewers: fhahn, rengolin, hsaito, dcaballe, mkuper, hfinkel, Ayal
Reviewed By: fhahn, hsaito
Subscribers: dmgreen, bollu, tschuett, rkruppe, rogfer01, llvm-commits
Differential Revision: https://reviews.llvm.org/D50820
llvm-svn: 342197
2018-09-14 08:36:00 +08:00
|
|
|
|
|
|
|
// 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);
|
2018-09-14 10:02:57 +08:00
|
|
|
Plan->addCBV(NCondBit);
|
[VPlan] Implement initial vector code generation support for simple outer loops.
Summary:
[VPlan] Implement vector code generation support for simple outer loops.
Context: Patch Series #1 for outer loop vectorization support in LV using VPlan. (RFC: http://lists.llvm.org/pipermail/llvm-dev/2017-December/119523.html).
This patch introduces vector code generation support for simple outer loops that are currently supported in the VPlanNativePath. Changes here essentially do the following:
- force vector code generation using explicit vectorize_width
- add conservative early returns in cost model and other places for VPlanNativePath
- add code for setting up outer loop inductions
- support for widening non-induction PHIs that can result from inner loops and uniform conditional branches
- support for generating uniform inner branches
We plan to add a handful C outer loop executable tests once the initial code generation support is committed. This patch is expected to be NFC for the inner loop vectorizer path. Since we are moving in the direction of supporting outer loop vectorization in LV, it may also be time to rename classes such as InnerLoopVectorizer.
Reviewers: fhahn, rengolin, hsaito, dcaballe, mkuper, hfinkel, Ayal
Reviewed By: fhahn, hsaito
Subscribers: dmgreen, bollu, tschuett, rkruppe, rogfer01, llvm-commits
Differential Revision: https://reviews.llvm.org/D50820
llvm-svn: 342197
2018-09-14 08:36:00 +08:00
|
|
|
}
|
|
|
|
}
|
2018-06-19 02:28:49 +08:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|