]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Transforms/Vectorize/VPlanHCFGTransforms.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Transforms / Vectorize / VPlanHCFGTransforms.cpp
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
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   for (VPBlockBase *Base : RPOT) {
28     // Do not widen instructions in pre-header and exit blocks.
29     if (Base->getNumPredecessors() == 0 || Base->getNumSuccessors() == 0)
30       continue;
31
32     VPBasicBlock *VPBB = Base->getEntryBasicBlock();
33     VPRecipeBase *LastRecipe = nullptr;
34     // Introduce each ingredient into VPlan.
35     for (auto I = VPBB->begin(), E = VPBB->end(); I != E;) {
36       VPRecipeBase *Ingredient = &*I++;
37       // Can only handle VPInstructions.
38       VPInstruction *VPInst = cast<VPInstruction>(Ingredient);
39       Instruction *Inst = cast<Instruction>(VPInst->getUnderlyingValue());
40       if (DeadInstructions.count(Inst)) {
41         Ingredient->eraseFromParent();
42         continue;
43       }
44
45       VPRecipeBase *NewRecipe = nullptr;
46       // Create VPWidenMemoryInstructionRecipe for loads and stores.
47       if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst))
48         NewRecipe = new VPWidenMemoryInstructionRecipe(*Inst, nullptr /*Mask*/);
49       else if (PHINode *Phi = dyn_cast<PHINode>(Inst)) {
50         InductionDescriptor II = Inductions->lookup(Phi);
51         if (II.getKind() == InductionDescriptor::IK_IntInduction ||
52             II.getKind() == InductionDescriptor::IK_FpInduction) {
53           NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi);
54         } else
55           NewRecipe = new VPWidenPHIRecipe(Phi);
56       } else {
57         // If the last recipe is a VPWidenRecipe, add Inst to it instead of
58         // creating a new recipe.
59         if (VPWidenRecipe *WidenRecipe =
60                 dyn_cast_or_null<VPWidenRecipe>(LastRecipe)) {
61           WidenRecipe->appendInstruction(Inst);
62           Ingredient->eraseFromParent();
63           continue;
64         }
65         NewRecipe = new VPWidenRecipe(Inst);
66       }
67
68       NewRecipe->insertBefore(Ingredient);
69       LastRecipe = NewRecipe;
70       Ingredient->eraseFromParent();
71     }
72   }
73 }