1 //===-- VPlanHCFGTransforms.cpp - Utility VPlan to VPlan transforms -------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file implements a set of utility VPlan to VPlan transformations.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "VPlanHCFGTransforms.h"
16 #include "llvm/ADT/PostOrderIterator.h"
17 
18 using namespace llvm;
19 
VPInstructionsToVPRecipes(VPlanPtr & Plan,LoopVectorizationLegality::InductionList * Inductions,SmallPtrSetImpl<Instruction * > & DeadInstructions)20 void VPlanHCFGTransforms::VPInstructionsToVPRecipes(
21     VPlanPtr &Plan,
22     LoopVectorizationLegality::InductionList *Inductions,
23     SmallPtrSetImpl<Instruction *> &DeadInstructions) {
24 
25   VPRegionBlock *TopRegion = dyn_cast<VPRegionBlock>(Plan->getEntry());
26   ReversePostOrderTraversal<VPBlockBase *> RPOT(TopRegion->getEntry());
27 
28   // Condition bit VPValues get deleted during transformation to VPRecipes.
29   // Create new VPValues and save away as condition bits. These will be deleted
30   // after finalizing the vector IR basic blocks.
31   for (VPBlockBase *Base : RPOT) {
32     VPBasicBlock *VPBB = Base->getEntryBasicBlock();
33     if (auto *CondBit = VPBB->getCondBit()) {
34       auto *NCondBit = new VPValue(CondBit->getUnderlyingValue());
35       VPBB->setCondBit(NCondBit);
36       Plan->addCBV(NCondBit);
37     }
38   }
39   for (VPBlockBase *Base : RPOT) {
40     // Do not widen instructions in pre-header and exit blocks.
41     if (Base->getNumPredecessors() == 0 || Base->getNumSuccessors() == 0)
42       continue;
43 
44     VPBasicBlock *VPBB = Base->getEntryBasicBlock();
45     VPRecipeBase *LastRecipe = nullptr;
46     // Introduce each ingredient into VPlan.
47     for (auto I = VPBB->begin(), E = VPBB->end(); I != E;) {
48       VPRecipeBase *Ingredient = &*I++;
49       // Can only handle VPInstructions.
50       VPInstruction *VPInst = cast<VPInstruction>(Ingredient);
51       Instruction *Inst = cast<Instruction>(VPInst->getUnderlyingValue());
52       if (DeadInstructions.count(Inst)) {
53         Ingredient->eraseFromParent();
54         continue;
55       }
56 
57       VPRecipeBase *NewRecipe = nullptr;
58       // Create VPWidenMemoryInstructionRecipe for loads and stores.
59       if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst))
60         NewRecipe = new VPWidenMemoryInstructionRecipe(*Inst, nullptr /*Mask*/);
61       else if (PHINode *Phi = dyn_cast<PHINode>(Inst)) {
62         InductionDescriptor II = Inductions->lookup(Phi);
63         if (II.getKind() == InductionDescriptor::IK_IntInduction ||
64             II.getKind() == InductionDescriptor::IK_FpInduction) {
65           NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi);
66         } else
67           NewRecipe = new VPWidenPHIRecipe(Phi);
68       } else {
69         // If the last recipe is a VPWidenRecipe, add Inst to it instead of
70         // creating a new recipe.
71         if (VPWidenRecipe *WidenRecipe =
72                 dyn_cast_or_null<VPWidenRecipe>(LastRecipe)) {
73           WidenRecipe->appendInstruction(Inst);
74           Ingredient->eraseFromParent();
75           continue;
76         }
77         NewRecipe = new VPWidenRecipe(Inst);
78       }
79 
80       NewRecipe->insertBefore(Ingredient);
81       LastRecipe = NewRecipe;
82       Ingredient->eraseFromParent();
83     }
84   }
85 }
86