1 //===-- VPlanHCFGTransforms.cpp - Utility VPlan to VPlan transforms -------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file implements a set of utility VPlan to VPlan transformations.
12 //===----------------------------------------------------------------------===//
14 #include "VPlanHCFGTransforms.h"
15 #include "llvm/ADT/PostOrderIterator.h"
19 void VPlanHCFGTransforms::VPInstructionsToVPRecipes(
21 LoopVectorizationLegality::InductionList
*Inductions
,
22 SmallPtrSetImpl
<Instruction
*> &DeadInstructions
) {
24 auto *TopRegion
= cast
<VPRegionBlock
>(Plan
->getEntry());
25 ReversePostOrderTraversal
<VPBlockBase
*> RPOT(TopRegion
->getEntry());
27 // Condition bit VPValues get deleted during transformation to VPRecipes.
28 // Create new VPValues and save away as condition bits. These will be deleted
29 // after finalizing the vector IR basic blocks.
30 for (VPBlockBase
*Base
: RPOT
) {
31 VPBasicBlock
*VPBB
= Base
->getEntryBasicBlock();
32 if (auto *CondBit
= VPBB
->getCondBit()) {
33 auto *NCondBit
= new VPValue(CondBit
->getUnderlyingValue());
34 VPBB
->setCondBit(NCondBit
);
35 Plan
->addCBV(NCondBit
);
38 for (VPBlockBase
*Base
: RPOT
) {
39 // Do not widen instructions in pre-header and exit blocks.
40 if (Base
->getNumPredecessors() == 0 || Base
->getNumSuccessors() == 0)
43 VPBasicBlock
*VPBB
= Base
->getEntryBasicBlock();
44 VPRecipeBase
*LastRecipe
= nullptr;
45 // Introduce each ingredient into VPlan.
46 for (auto I
= VPBB
->begin(), E
= VPBB
->end(); I
!= E
;) {
47 VPRecipeBase
*Ingredient
= &*I
++;
48 // Can only handle VPInstructions.
49 VPInstruction
*VPInst
= cast
<VPInstruction
>(Ingredient
);
50 Instruction
*Inst
= cast
<Instruction
>(VPInst
->getUnderlyingValue());
51 if (DeadInstructions
.count(Inst
)) {
52 Ingredient
->eraseFromParent();
56 VPRecipeBase
*NewRecipe
= nullptr;
57 // Create VPWidenMemoryInstructionRecipe for loads and stores.
58 if (isa
<LoadInst
>(Inst
) || isa
<StoreInst
>(Inst
))
59 NewRecipe
= new VPWidenMemoryInstructionRecipe(*Inst
, nullptr /*Mask*/);
60 else if (PHINode
*Phi
= dyn_cast
<PHINode
>(Inst
)) {
61 InductionDescriptor II
= Inductions
->lookup(Phi
);
62 if (II
.getKind() == InductionDescriptor::IK_IntInduction
||
63 II
.getKind() == InductionDescriptor::IK_FpInduction
) {
64 NewRecipe
= new VPWidenIntOrFpInductionRecipe(Phi
);
66 NewRecipe
= new VPWidenPHIRecipe(Phi
);
68 // If the last recipe is a VPWidenRecipe, add Inst to it instead of
69 // creating a new recipe.
70 if (VPWidenRecipe
*WidenRecipe
=
71 dyn_cast_or_null
<VPWidenRecipe
>(LastRecipe
)) {
72 WidenRecipe
->appendInstruction(Inst
);
73 Ingredient
->eraseFromParent();
76 NewRecipe
= new VPWidenRecipe(Inst
);
79 NewRecipe
->insertBefore(Ingredient
);
80 LastRecipe
= NewRecipe
;
81 Ingredient
->eraseFromParent();