Skip to content

Commit

Permalink
[VPlan] Use one VPWidenRecipe per original IR instruction. (NFC).
Browse files Browse the repository at this point in the history
This patch changes VPWidenRecipe to only store a single original IR
instruction. This is the first required step towards modeling it's
operands as VPValues and also towards breaking it up into a
VPInstruction.

Discussed as part of D74695.

Reviewers: Ayal, gilr, rengolin

Reviewed By: gilr

Differential Revision: https://reviews.llvm.org/D76988
  • Loading branch information
fhahn committed Mar 29, 2020
1 parent 6ba6351 commit 49d0082
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 71 deletions.
17 changes: 2 additions & 15 deletions llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
Expand Up @@ -6976,21 +6976,9 @@ bool VPRecipeBuilder::tryToWiden(Instruction *I, VPBasicBlock *VPBB,

if (!LoopVectorizationPlanner::getDecisionAndClampRange(willWiden, Range))
return false;
// If this ingredient's recipe is to be recorded, keep its recipe a singleton
// to avoid having to split recipes later.
bool IsSingleton = Ingredient2Recipe.count(I);

// Success: widen this instruction.

// Use the default widening recipe. We optimize the common case where
// consecutive instructions can be represented by a single recipe.
if (!IsSingleton && !VPBB->empty() && LastExtensibleRecipe == &VPBB->back() &&
LastExtensibleRecipe->appendInstruction(I))
return true;

VPWidenRecipe *WidenRecipe = new VPWidenRecipe(I);
if (!IsSingleton)
LastExtensibleRecipe = WidenRecipe;
VPWidenRecipe *WidenRecipe = new VPWidenRecipe(*I);
setRecipe(I, WidenRecipe);
VPBB->appendRecipe(WidenRecipe);
return true;
Expand Down Expand Up @@ -7385,8 +7373,7 @@ void VPInterleaveRecipe::print(raw_ostream &O, const Twine &Indent,
}

void VPWidenRecipe::execute(VPTransformState &State) {
for (auto &Instr : make_range(Begin, End))
State.ILV->widenInstruction(Instr);
State.ILV->widenInstruction(Ingredient);
}

void VPWidenGEPRecipe::execute(VPTransformState &State) {
Expand Down
5 changes: 1 addition & 4 deletions llvm/lib/Transforms/Vectorize/VPRecipeBuilder.h
Expand Up @@ -49,11 +49,8 @@ class VPRecipeBuilder {

// VPlan-VPlan transformations support: Hold a mapping from ingredients to
// their recipe. To save on memory, only do so for selected ingredients,
// marked by having a nullptr entry in this map. If those ingredients get a
// VPWidenRecipe, also avoid compressing other ingredients into it to avoid
// having to split such recipes later.
// marked by having a nullptr entry in this map.
DenseMap<Instruction *, VPRecipeBase *> Ingredient2Recipe;
VPWidenRecipe *LastExtensibleRecipe = nullptr;

/// Set the recipe created for given ingredient. This operation is a no-op for
/// ingredients that were not marked using a nullptr entry in the map.
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Transforms/Vectorize/VPlan.cpp
Expand Up @@ -715,8 +715,7 @@ void VPlanPrinter::printAsIngredient(raw_ostream &O, Value *V) {
void VPWidenRecipe::print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const {
O << " +\n" << Indent << "\"WIDEN\\l\"";
for (auto &Instr : make_range(Begin, End))
O << " +\n" << Indent << "\" " << VPlanIngredient(&Instr) << "\\l\"";
O << "\" " << VPlanIngredient(&Ingredient) << "\\l\"";
}

void VPWidenIntOrFpInductionRecipe::print(raw_ostream &O, const Twine &Indent,
Expand Down
25 changes: 6 additions & 19 deletions llvm/lib/Transforms/Vectorize/VPlan.h
Expand Up @@ -757,21 +757,16 @@ class VPInstruction : public VPUser, public VPRecipeBase {
}
};

/// VPWidenRecipe is a recipe for producing a copy of vector type for each
/// Instruction in its ingredients independently, in order. This recipe covers
/// most of the traditional vectorization cases where each ingredient transforms
/// into a vectorized version of itself.
/// VPWidenRecipe is a recipe for producing a copy of vector type its
/// ingredient. This recipe covers most of the traditional vectorization cases
/// where each ingredient transforms into a vectorized version of itself.
class VPWidenRecipe : public VPRecipeBase {
private:
/// Hold the ingredients by pointing to their original BasicBlock location.
BasicBlock::iterator Begin;
BasicBlock::iterator End;
/// Hold the instruction to be widened.
Instruction &Ingredient;

public:
VPWidenRecipe(Instruction *I) : VPRecipeBase(VPWidenSC) {
End = I->getIterator();
Begin = End++;
}
VPWidenRecipe(Instruction &I) : VPRecipeBase(VPWidenSC), Ingredient(I) {}

~VPWidenRecipe() override = default;

Expand All @@ -783,14 +778,6 @@ class VPWidenRecipe : public VPRecipeBase {
/// Produce widened copies of all Ingredients.
void execute(VPTransformState &State) override;

/// Augment the recipe to include Instr, if it lies at its End.
bool appendInstruction(Instruction *Instr) {
if (End != Instr->getIterator())
return false;
End++;
return true;
}

/// Print the recipe.
void print(raw_ostream &O, const Twine &Indent,
VPSlotTracker &SlotTracker) const override;
Expand Down
15 changes: 2 additions & 13 deletions llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
Expand Up @@ -41,7 +41,6 @@ void VPlanTransforms::VPInstructionsToVPRecipes(
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++;
Expand Down Expand Up @@ -72,20 +71,10 @@ void VPlanTransforms::VPInstructionsToVPRecipes(
NewRecipe = new VPWidenPHIRecipe(Phi);
} else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(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<VPWidenRecipe>(LastRecipe)) {
WidenRecipe->appendInstruction(Inst);
Ingredient->eraseFromParent();
continue;
}
NewRecipe = new VPWidenRecipe(Inst);
}
} else
NewRecipe = new VPWidenRecipe(*Inst);

NewRecipe->insertBefore(Ingredient);
LastRecipe = NewRecipe;
Ingredient->eraseFromParent();
}
}
Expand Down
26 changes: 8 additions & 18 deletions llvm/unittests/Transforms/Vectorize/VPlanHCFGTest.cpp
Expand Up @@ -169,28 +169,18 @@ TEST_F(VPlanHCFGTest, testVPInstructionToVPRecipesInner) {
EXPECT_EQ(1u, Entry->getNumSuccessors());

VPBasicBlock *VecBB = Entry->getSingleSuccessor()->getEntryBasicBlock();
EXPECT_EQ(6u, VecBB->size());
EXPECT_EQ(7u, VecBB->size());
EXPECT_EQ(2u, VecBB->getNumPredecessors());
EXPECT_EQ(2u, VecBB->getNumSuccessors());

auto Iter = VecBB->begin();
auto *Phi = dyn_cast<VPWidenPHIRecipe>(&*Iter++);
EXPECT_NE(nullptr, Phi);

auto *Idx = dyn_cast<VPWidenGEPRecipe>(&*Iter++);
EXPECT_NE(nullptr, Idx);

auto *Load = dyn_cast<VPWidenMemoryInstructionRecipe>(&*Iter++);
EXPECT_NE(nullptr, Load);

auto *Add = dyn_cast<VPWidenRecipe>(&*Iter++);
EXPECT_NE(nullptr, Add);

auto *Store = dyn_cast<VPWidenMemoryInstructionRecipe>(&*Iter++);
EXPECT_NE(nullptr, Store);

auto *LastWiden = dyn_cast<VPWidenRecipe>(&*Iter++);
EXPECT_NE(nullptr, LastWiden);
EXPECT_NE(nullptr, dyn_cast<VPWidenPHIRecipe>(&*Iter++));
EXPECT_NE(nullptr, dyn_cast<VPWidenGEPRecipe>(&*Iter++));
EXPECT_NE(nullptr, dyn_cast<VPWidenMemoryInstructionRecipe>(&*Iter++));
EXPECT_NE(nullptr, dyn_cast<VPWidenRecipe>(&*Iter++));
EXPECT_NE(nullptr, dyn_cast<VPWidenMemoryInstructionRecipe>(&*Iter++));
EXPECT_NE(nullptr, dyn_cast<VPWidenRecipe>(&*Iter++));
EXPECT_NE(nullptr, dyn_cast<VPWidenRecipe>(&*Iter++));
EXPECT_EQ(VecBB->end(), Iter);
}

Expand Down

0 comments on commit 49d0082

Please sign in to comment.