forked from OSchip/llvm-project
[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:
parent
7ebf7d91e6
commit
f828d75b46
|
@ -441,9 +441,11 @@ public:
|
|||
/// A helper function to scalarize a single Instruction in the innermost loop.
|
||||
/// Generates a sequence of scalar instances for each lane between \p MinLane
|
||||
/// and \p MaxLane, times each part between \p MinPart and \p MaxPart,
|
||||
/// inclusive..
|
||||
void scalarizeInstruction(Instruction *Instr, const VPIteration &Instance,
|
||||
bool IfPredicateInstr);
|
||||
/// inclusive. Uses the VPValue operands from \p Operands instead of \p
|
||||
/// Instr's operands.
|
||||
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
|
||||
/// 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,
|
||||
bool IfPredicateInstr) {
|
||||
bool IfPredicateInstr,
|
||||
VPTransformState &State) {
|
||||
assert(!Instr->getType()->isAggregateType() && "Can't handle vectors");
|
||||
|
||||
setDebugLocFromInst(Builder, Instr);
|
||||
|
@ -2512,8 +2515,8 @@ void InnerLoopVectorizer::scalarizeInstruction(Instruction *Instr,
|
|||
|
||||
// Replace the operands of the cloned instructions with their scalar
|
||||
// equivalents in the new loop.
|
||||
for (unsigned op = 0, e = Instr->getNumOperands(); op != e; ++op) {
|
||||
auto *NewOp = getOrCreateScalarValue(Instr->getOperand(op), Instance);
|
||||
for (unsigned op = 0, e = User.getNumOperands(); op != e; ++op) {
|
||||
auto *NewOp = State.get(User.getOperand(op), Instance);
|
||||
Cloned->setOperand(op, NewOp);
|
||||
}
|
||||
addNewMetadata(Cloned, Instr);
|
||||
|
@ -7045,7 +7048,8 @@ VPBasicBlock *VPRecipeBuilder::handleReplication(
|
|||
bool IsPredicated = LoopVectorizationPlanner::getDecisionAndClampRange(
|
||||
[&](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);
|
||||
|
||||
// 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) {
|
||||
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.
|
||||
if (AlsoPack && State.VF > 1) {
|
||||
// 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;
|
||||
for (unsigned Part = 0; Part < State.UF; ++Part)
|
||||
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) {
|
||||
|
|
|
@ -1021,6 +1021,9 @@ class VPReplicateRecipe : public VPRecipeBase {
|
|||
/// The instruction being replicated.
|
||||
Instruction *Ingredient;
|
||||
|
||||
/// Hold VPValues for the operands of the ingredient.
|
||||
VPUser User;
|
||||
|
||||
/// Indicator if only a single replica per lane is needed.
|
||||
bool IsUniform;
|
||||
|
||||
|
@ -1031,9 +1034,11 @@ class VPReplicateRecipe : public VPRecipeBase {
|
|||
bool AlsoPack;
|
||||
|
||||
public:
|
||||
VPReplicateRecipe(Instruction *I, bool IsUniform, bool IsPredicated = false)
|
||||
: VPRecipeBase(VPReplicateSC), Ingredient(I), IsUniform(IsUniform),
|
||||
IsPredicated(IsPredicated) {
|
||||
template <typename IterT>
|
||||
VPReplicateRecipe(Instruction *I, iterator_range<IterT> Operands,
|
||||
bool IsUniform, bool IsPredicated = false)
|
||||
: VPRecipeBase(VPReplicateSC), Ingredient(I), User(Operands),
|
||||
IsUniform(IsUniform), IsPredicated(IsPredicated) {
|
||||
// Retain the previous behavior of predicateInstructions(), where an
|
||||
// insert-element of a predicated instruction got hoisted into the
|
||||
// predicated basic block iff it was its only user. This is achieved by
|
||||
|
|
Loading…
Reference in New Issue