mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[VPlan] Move recipe based VPlan generation to separate function.
This first step separates VPInstruction-based and VPRecipe-based VPlan creation, which should make it easier to migrate to VPInstruction based code-gen step by step. Reviewers: Ayal, rengolin, dcaballe, hsaito, mkuper, mzolotukhin Reviewed By: dcaballe Subscribers: bollu, tschuett, rkruppe, llvm-commits Differential Revision: https://reviews.llvm.org/D47477 llvm-svn: 334284
This commit is contained in:
parent
bfa46b6381
commit
148a435017
@ -345,8 +345,18 @@ private:
|
||||
/// Build a VPlan according to the information gathered by Legal. \return a
|
||||
/// VPlan for vectorization factors \p Range.Start and up to \p Range.End
|
||||
/// exclusive, possibly decreasing \p Range.End.
|
||||
VPlanPtr buildVPlan(VFRange &Range,
|
||||
const SmallPtrSetImpl<Value *> &NeedDef);
|
||||
VPlanPtr buildVPlan(VFRange &Range);
|
||||
|
||||
/// Build a VPlan using VPRecipes according to the information gather by
|
||||
/// Legal. This method is only used for the legacy inner loop vectorizer.
|
||||
VPlanPtr
|
||||
buildVPlanWithVPRecipes(VFRange &Range, SmallPtrSetImpl<Value *> &NeedDef,
|
||||
SmallPtrSetImpl<Instruction *> &DeadInstructions);
|
||||
|
||||
/// Build VPlans for power-of-2 VF's between \p MinVF and \p MaxVF inclusive,
|
||||
/// according to the information gathered by Legal when it checked if it is
|
||||
/// legal to vectorize the loop. This method creates VPlans using VPRecipes.
|
||||
void buildVPlansWithVPRecipes(unsigned MinVF, unsigned MaxVF);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -6316,7 +6316,7 @@ LoopVectorizationPlanner::plan(bool OptForSize, unsigned UserVF) {
|
||||
// Collect the instructions (and their associated costs) that will be more
|
||||
// profitable to scalarize.
|
||||
CM.selectUserVectorizationFactor(UserVF);
|
||||
buildVPlans(UserVF, UserVF);
|
||||
buildVPlansWithVPRecipes(UserVF, UserVF);
|
||||
LLVM_DEBUG(printPlans(dbgs()));
|
||||
return {UserVF, 0};
|
||||
}
|
||||
@ -6334,7 +6334,7 @@ LoopVectorizationPlanner::plan(bool OptForSize, unsigned UserVF) {
|
||||
CM.collectInstsToScalarize(VF);
|
||||
}
|
||||
|
||||
buildVPlans(1, MaxVF);
|
||||
buildVPlansWithVPRecipes(1, MaxVF);
|
||||
LLVM_DEBUG(printPlans(dbgs()));
|
||||
if (MaxVF == 1)
|
||||
return NoVectorization;
|
||||
@ -6495,23 +6495,9 @@ bool LoopVectorizationPlanner::getDecisionAndClampRange(
|
||||
/// vectorization decision can potentially shorten this sub-range during
|
||||
/// buildVPlan().
|
||||
void LoopVectorizationPlanner::buildVPlans(unsigned MinVF, unsigned MaxVF) {
|
||||
|
||||
// Collect conditions feeding internal conditional branches; they need to be
|
||||
// represented in VPlan for it to model masking.
|
||||
SmallPtrSet<Value *, 1> NeedDef;
|
||||
|
||||
auto *Latch = OrigLoop->getLoopLatch();
|
||||
for (BasicBlock *BB : OrigLoop->blocks()) {
|
||||
if (BB == Latch)
|
||||
continue;
|
||||
BranchInst *Branch = dyn_cast<BranchInst>(BB->getTerminator());
|
||||
if (Branch && Branch->isConditional())
|
||||
NeedDef.insert(Branch->getCondition());
|
||||
}
|
||||
|
||||
for (unsigned VF = MinVF; VF < MaxVF + 1;) {
|
||||
VFRange SubRange = {VF, MaxVF + 1};
|
||||
VPlans.push_back(buildVPlan(SubRange, NeedDef));
|
||||
VPlans.push_back(buildVPlan(SubRange));
|
||||
VF = SubRange.End;
|
||||
}
|
||||
}
|
||||
@ -6866,31 +6852,22 @@ LoopVectorizationPlanner::createReplicateRegion(Instruction *Instr,
|
||||
return Region;
|
||||
}
|
||||
|
||||
LoopVectorizationPlanner::VPlanPtr
|
||||
LoopVectorizationPlanner::buildVPlan(VFRange &Range,
|
||||
const SmallPtrSetImpl<Value *> &NeedDef) {
|
||||
// Outer loop handling: They may require CFG and instruction level
|
||||
// transformations before even evaluating whether vectorization is profitable.
|
||||
// Since we cannot modify the incoming IR, we need to build VPlan upfront in
|
||||
// the vectorization pipeline.
|
||||
if (!OrigLoop->empty()) {
|
||||
assert(EnableVPlanNativePath && "VPlan-native path is not enabled.");
|
||||
|
||||
// Create new empty VPlan
|
||||
auto Plan = llvm::make_unique<VPlan>();
|
||||
|
||||
// Build hierarchical CFG
|
||||
VPlanHCFGBuilder HCFGBuilder(OrigLoop, LI);
|
||||
HCFGBuilder.buildHierarchicalCFG(*Plan.get());
|
||||
|
||||
return Plan;
|
||||
}
|
||||
|
||||
void LoopVectorizationPlanner::buildVPlansWithVPRecipes(unsigned MinVF,
|
||||
unsigned MaxVF) {
|
||||
assert(OrigLoop->empty() && "Inner loop expected.");
|
||||
EdgeMaskCache.clear();
|
||||
BlockMaskCache.clear();
|
||||
DenseMap<Instruction *, Instruction *> &SinkAfter = Legal->getSinkAfter();
|
||||
DenseMap<Instruction *, Instruction *> SinkAfterInverse;
|
||||
|
||||
// Collect conditions feeding internal conditional branches; they need to be
|
||||
// represented in VPlan for it to model masking.
|
||||
SmallPtrSet<Value *, 1> NeedDef;
|
||||
|
||||
auto *Latch = OrigLoop->getLoopLatch();
|
||||
for (BasicBlock *BB : OrigLoop->blocks()) {
|
||||
if (BB == Latch)
|
||||
continue;
|
||||
BranchInst *Branch = dyn_cast<BranchInst>(BB->getTerminator());
|
||||
if (Branch && Branch->isConditional())
|
||||
NeedDef.insert(Branch->getCondition());
|
||||
}
|
||||
|
||||
// Collect instructions from the original loop that will become trivially dead
|
||||
// in the vectorized loop. We don't need to vectorize these instructions. For
|
||||
@ -6901,11 +6878,28 @@ LoopVectorizationPlanner::buildVPlan(VFRange &Range,
|
||||
SmallPtrSet<Instruction *, 4> DeadInstructions;
|
||||
collectTriviallyDeadInstructions(DeadInstructions);
|
||||
|
||||
for (unsigned VF = MinVF; VF < MaxVF + 1;) {
|
||||
VFRange SubRange = {VF, MaxVF + 1};
|
||||
VPlans.push_back(
|
||||
buildVPlanWithVPRecipes(SubRange, NeedDef, DeadInstructions));
|
||||
VF = SubRange.End;
|
||||
}
|
||||
}
|
||||
|
||||
LoopVectorizationPlanner::VPlanPtr
|
||||
LoopVectorizationPlanner::buildVPlanWithVPRecipes(
|
||||
VFRange &Range, SmallPtrSetImpl<Value *> &NeedDef,
|
||||
SmallPtrSetImpl<Instruction *> &DeadInstructions) {
|
||||
// Hold a mapping from predicated instructions to their recipes, in order to
|
||||
// fix their AlsoPack behavior if a user is determined to replicate and use a
|
||||
// scalar instead of vector value.
|
||||
DenseMap<Instruction *, VPReplicateRecipe *> PredInst2Recipe;
|
||||
|
||||
EdgeMaskCache.clear();
|
||||
BlockMaskCache.clear();
|
||||
DenseMap<Instruction *, Instruction *> &SinkAfter = Legal->getSinkAfter();
|
||||
DenseMap<Instruction *, Instruction *> SinkAfterInverse;
|
||||
|
||||
// Create a dummy pre-entry VPBasicBlock to start building the VPlan.
|
||||
VPBasicBlock *VPBB = new VPBasicBlock("Pre-Entry");
|
||||
auto Plan = llvm::make_unique<VPlan>(VPBB);
|
||||
@ -7047,6 +7041,25 @@ LoopVectorizationPlanner::buildVPlan(VFRange &Range,
|
||||
return Plan;
|
||||
}
|
||||
|
||||
LoopVectorizationPlanner::VPlanPtr
|
||||
LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
|
||||
// Outer loop handling: They may require CFG and instruction level
|
||||
// transformations before even evaluating whether vectorization is profitable.
|
||||
// Since we cannot modify the incoming IR, we need to build VPlan upfront in
|
||||
// the vectorization pipeline.
|
||||
assert(!OrigLoop->empty());
|
||||
assert(EnableVPlanNativePath && "VPlan-native path is not enabled.");
|
||||
|
||||
// Create new empty VPlan
|
||||
auto Plan = llvm::make_unique<VPlan>();
|
||||
|
||||
// Build hierarchical CFG
|
||||
VPlanHCFGBuilder HCFGBuilder(OrigLoop, LI);
|
||||
HCFGBuilder.buildHierarchicalCFG(*Plan.get());
|
||||
|
||||
return Plan;
|
||||
}
|
||||
|
||||
Value* LoopVectorizationPlanner::VPCallbackILV::
|
||||
getOrCreateVectorValues(Value *V, unsigned Part) {
|
||||
return ILV.getOrCreateVectorValue(V, Part);
|
||||
|
Loading…
x
Reference in New Issue
Block a user