[VPlan] Add & use VPValue operands for VPReplicateRecipe (NFC).

This patch adds VPValue version of the instruction operands to
VPReplicateRecipe and uses them during code-generation.

Reviewers: Ayal, gilr, rengolin

Reviewed By: gilr

Differential Revision: https://reviews.llvm.org/D80114
This commit is contained in:
Florian Hahn 2020-05-19 15:04:48 +01:00
parent 7ebf7d91e6
commit f828d75b46
2 changed files with 24 additions and 13 deletions

View File

@ -441,9 +441,11 @@ public:
/// A helper function to scalarize a single Instruction in the innermost loop. /// A helper function to scalarize a single Instruction in the innermost loop.
/// Generates a sequence of scalar instances for each lane between \p MinLane /// Generates a sequence of scalar instances for each lane between \p MinLane
/// and \p MaxLane, times each part between \p MinPart and \p MaxPart, /// and \p MaxLane, times each part between \p MinPart and \p MaxPart,
/// inclusive.. /// inclusive. Uses the VPValue operands from \p Operands instead of \p
void scalarizeInstruction(Instruction *Instr, const VPIteration &Instance, /// Instr's operands.
bool IfPredicateInstr); void scalarizeInstruction(Instruction *Instr, VPUser &Operands,
const VPIteration &Instance, bool IfPredicateInstr,
VPTransformState &State);
/// Widen an integer or floating-point induction variable \p IV. If \p Trunc /// Widen an integer or floating-point induction variable \p IV. If \p Trunc
/// is provided, the integer induction variable will first be truncated to /// is provided, the integer induction variable will first be truncated to
@ -2496,9 +2498,10 @@ void InnerLoopVectorizer::vectorizeMemoryInstruction(Instruction *Instr,
} }
} }
void InnerLoopVectorizer::scalarizeInstruction(Instruction *Instr, void InnerLoopVectorizer::scalarizeInstruction(Instruction *Instr, VPUser &User,
const VPIteration &Instance, const VPIteration &Instance,
bool IfPredicateInstr) { bool IfPredicateInstr,
VPTransformState &State) {
assert(!Instr->getType()->isAggregateType() && "Can't handle vectors"); assert(!Instr->getType()->isAggregateType() && "Can't handle vectors");
setDebugLocFromInst(Builder, Instr); setDebugLocFromInst(Builder, Instr);
@ -2512,8 +2515,8 @@ void InnerLoopVectorizer::scalarizeInstruction(Instruction *Instr,
// Replace the operands of the cloned instructions with their scalar // Replace the operands of the cloned instructions with their scalar
// equivalents in the new loop. // equivalents in the new loop.
for (unsigned op = 0, e = Instr->getNumOperands(); op != e; ++op) { for (unsigned op = 0, e = User.getNumOperands(); op != e; ++op) {
auto *NewOp = getOrCreateScalarValue(Instr->getOperand(op), Instance); auto *NewOp = State.get(User.getOperand(op), Instance);
Cloned->setOperand(op, NewOp); Cloned->setOperand(op, NewOp);
} }
addNewMetadata(Cloned, Instr); addNewMetadata(Cloned, Instr);
@ -7045,7 +7048,8 @@ VPBasicBlock *VPRecipeBuilder::handleReplication(
bool IsPredicated = LoopVectorizationPlanner::getDecisionAndClampRange( bool IsPredicated = LoopVectorizationPlanner::getDecisionAndClampRange(
[&](unsigned VF) { return CM.isScalarWithPredication(I, VF); }, Range); [&](unsigned VF) { return CM.isScalarWithPredication(I, VF); }, Range);
auto *Recipe = new VPReplicateRecipe(I, IsUniform, IsPredicated); auto *Recipe = new VPReplicateRecipe(I, Plan->mapToVPValues(I->operands()),
IsUniform, IsPredicated);
setRecipe(I, Recipe); setRecipe(I, Recipe);
// Find if I uses a predicated instruction. If so, it will use its scalar // Find if I uses a predicated instruction. If so, it will use its scalar
@ -7498,7 +7502,8 @@ void VPInterleaveRecipe::execute(VPTransformState &State) {
void VPReplicateRecipe::execute(VPTransformState &State) { void VPReplicateRecipe::execute(VPTransformState &State) {
if (State.Instance) { // Generate a single instance. if (State.Instance) { // Generate a single instance.
State.ILV->scalarizeInstruction(Ingredient, *State.Instance, IsPredicated); State.ILV->scalarizeInstruction(Ingredient, User, *State.Instance,
IsPredicated, State);
// Insert scalar instance packing it into a vector. // Insert scalar instance packing it into a vector.
if (AlsoPack && State.VF > 1) { if (AlsoPack && State.VF > 1) {
// If we're constructing lane 0, initialize to start from undef. // If we're constructing lane 0, initialize to start from undef.
@ -7518,7 +7523,8 @@ void VPReplicateRecipe::execute(VPTransformState &State) {
unsigned EndLane = IsUniform ? 1 : State.VF; unsigned EndLane = IsUniform ? 1 : State.VF;
for (unsigned Part = 0; Part < State.UF; ++Part) for (unsigned Part = 0; Part < State.UF; ++Part)
for (unsigned Lane = 0; Lane < EndLane; ++Lane) for (unsigned Lane = 0; Lane < EndLane; ++Lane)
State.ILV->scalarizeInstruction(Ingredient, {Part, Lane}, IsPredicated); State.ILV->scalarizeInstruction(Ingredient, User, {Part, Lane},
IsPredicated, State);
} }
void VPBranchOnMaskRecipe::execute(VPTransformState &State) { void VPBranchOnMaskRecipe::execute(VPTransformState &State) {

View File

@ -1021,6 +1021,9 @@ class VPReplicateRecipe : public VPRecipeBase {
/// The instruction being replicated. /// The instruction being replicated.
Instruction *Ingredient; Instruction *Ingredient;
/// Hold VPValues for the operands of the ingredient.
VPUser User;
/// Indicator if only a single replica per lane is needed. /// Indicator if only a single replica per lane is needed.
bool IsUniform; bool IsUniform;
@ -1031,9 +1034,11 @@ class VPReplicateRecipe : public VPRecipeBase {
bool AlsoPack; bool AlsoPack;
public: public:
VPReplicateRecipe(Instruction *I, bool IsUniform, bool IsPredicated = false) template <typename IterT>
: VPRecipeBase(VPReplicateSC), Ingredient(I), IsUniform(IsUniform), VPReplicateRecipe(Instruction *I, iterator_range<IterT> Operands,
IsPredicated(IsPredicated) { bool IsUniform, bool IsPredicated = false)
: VPRecipeBase(VPReplicateSC), Ingredient(I), User(Operands),
IsUniform(IsUniform), IsPredicated(IsPredicated) {
// Retain the previous behavior of predicateInstructions(), where an // Retain the previous behavior of predicateInstructions(), where an
// insert-element of a predicated instruction got hoisted into the // insert-element of a predicated instruction got hoisted into the
// predicated basic block iff it was its only user. This is achieved by // predicated basic block iff it was its only user. This is achieved by