diff options
Diffstat (limited to 'llvm/lib/Transforms/Vectorize')
-rw-r--r-- | llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp | 53 | ||||
-rw-r--r-- | llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp | 24 | ||||
-rw-r--r-- | llvm/lib/Transforms/Vectorize/VPlan.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/Transforms/Vectorize/VPlan.h | 145 |
4 files changed, 146 insertions, 94 deletions
diff --git a/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp b/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp index 9cf66382b58..2ec4f6ca9e7 100644 --- a/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/LoadStoreVectorizer.cpp @@ -1,4 +1,4 @@ -//===----- LoadStoreVectorizer.cpp - GPU Load & Store Vectorizer ----------===// +//===- LoadStoreVectorizer.cpp - GPU Load & Store Vectorizer --------------===// // // The LLVM Compiler Infrastructure // @@ -6,47 +6,66 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -//===----------------------------------------------------------------------===// +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/PostOrderIterator.h" -#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" -#include "llvm/ADT/Triple.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/OrderedBasicBlock.h" #include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/VectorUtils.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/IR/User.h" #include "llvm/IR/Value.h" -#include "llvm/Support/CommandLine.h" +#include "llvm/Pass.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" #include "llvm/Support/KnownBits.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Vectorize.h" +#include <algorithm> +#include <cassert> +#include <cstdlib> +#include <tuple> +#include <utility> using namespace llvm; #define DEBUG_TYPE "load-store-vectorizer" + STATISTIC(NumVectorInstructions, "Number of vector accesses generated"); STATISTIC(NumScalarsVectorized, "Number of scalar accesses vectorized"); -namespace { - // FIXME: Assuming stack alignment of 4 is always good enough static const unsigned StackAdjustedAlignment = 4; -typedef SmallVector<Instruction *, 8> InstrList; -typedef MapVector<Value *, InstrList> InstrListMap; + +namespace { + +using InstrList = SmallVector<Instruction *, 8>; +using InstrListMap = MapVector<Value *, InstrList>; class Vectorizer { Function &F; @@ -163,7 +182,10 @@ public: AU.setPreservesCFG(); } }; -} + +} // end anonymous namespace + +char LoadStoreVectorizer::ID = 0; INITIALIZE_PASS_BEGIN(LoadStoreVectorizer, DEBUG_TYPE, "Vectorize load and Store instructions", false, false) @@ -175,8 +197,6 @@ INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_END(LoadStoreVectorizer, DEBUG_TYPE, "Vectorize load and store instructions", false, false) -char LoadStoreVectorizer::ID = 0; - Pass *llvm::createLoadStoreVectorizerPass() { return new LoadStoreVectorizer(); } @@ -605,7 +625,7 @@ Vectorizer::collectInstructions(BasicBlock *BB) { continue; // Make sure all the users of a vector are constant-index extracts. - if (isa<VectorType>(Ty) && !all_of(LI->users(), [](const User *U) { + if (isa<VectorType>(Ty) && !llvm::all_of(LI->users(), [](const User *U) { const ExtractElementInst *EEI = dyn_cast<ExtractElementInst>(U); return EEI && isa<ConstantInt>(EEI->getOperand(1)); })) @@ -614,7 +634,6 @@ Vectorizer::collectInstructions(BasicBlock *BB) { // Save the load locations. Value *ObjPtr = GetUnderlyingObject(Ptr, DL); LoadRefs[ObjPtr].push_back(LI); - } else if (StoreInst *SI = dyn_cast<StoreInst>(&I)) { if (!SI->isSimple()) continue; @@ -639,7 +658,7 @@ Vectorizer::collectInstructions(BasicBlock *BB) { if (TySize > VecRegSize / 2) continue; - if (isa<VectorType>(Ty) && !all_of(SI->users(), [](const User *U) { + if (isa<VectorType>(Ty) && !llvm::all_of(SI->users(), [](const User *U) { const ExtractElementInst *EEI = dyn_cast<ExtractElementInst>(U); return EEI && isa<ConstantInt>(EEI->getOperand(1)); })) diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp index 6055aff8b9b..5dcf5528ac9 100644 --- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp +++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp @@ -6,6 +6,7 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// // This pass implements the Bottom Up SLP vectorizer. It detects consecutive // stores that can be put together into vector-stores. Next, it attempts to // construct vectorizable tree using the use-def chains. If a profitable tree @@ -361,14 +362,17 @@ static Value *isOneOf(Value *OpValue, Value *Op) { } namespace { + /// Contains data for the instructions going to be vectorized. struct RawInstructionsData { /// Main Opcode of the instructions going to be vectorized. unsigned Opcode = 0; + /// The list of instructions have some instructions with alternate opcodes. bool HasAltOpcodes = false; }; -} // namespace + +} // end anonymous namespace /// Checks the list of the vectorized instructions \p VL and returns info about /// this list. @@ -392,19 +396,24 @@ static RawInstructionsData getMainOpcode(ArrayRef<Value *> VL) { } namespace { + /// Main data required for vectorization of instructions. struct InstructionsState { /// The very first instruction in the list with the main opcode. Value *OpValue = nullptr; + /// The main opcode for the list of instructions. unsigned Opcode = 0; + /// Some of the instructions in the list have alternate opcodes. bool IsAltShuffle = false; + InstructionsState() = default; InstructionsState(Value *OpValue, unsigned Opcode, bool IsAltShuffle) : OpValue(OpValue), Opcode(Opcode), IsAltShuffle(IsAltShuffle) {} }; -} // namespace + +} // end anonymous namespace /// \returns analysis of the Instructions in \p VL described in /// InstructionsState, the Opcode that we suppose the whole list @@ -973,6 +982,7 @@ private: return os; } #endif + friend struct GraphTraits<BoUpSLP *>; friend struct DOTGraphTraits<BoUpSLP *>; @@ -1176,9 +1186,9 @@ private: /// The ID of the scheduling region. For a new vectorization iteration this /// is incremented which "removes" all ScheduleData from the region. - int SchedulingRegionID = 1; // Make sure that the initial SchedulingRegionID is greater than the // initial SchedulingRegionID in ScheduleData (which is 0). + int SchedulingRegionID = 1; }; /// Attaches the BlockScheduling structures to basic blocks. @@ -1212,6 +1222,7 @@ private: unsigned MaxVecRegSize; // This is set by TTI or overridden by cl::opt. unsigned MinVecRegSize; // Set by cl::opt (default: 128). + /// Instruction builder to construct the vectorized tree. IRBuilder<> Builder; @@ -4662,6 +4673,7 @@ class HorizontalReduction { RK_Max, /// Maximum reduction data. RK_UMax, /// Unsigned maximum reduction data. }; + /// Contains info about operation, like its opcode, left and right operands. class OperationData { /// Opcode of the instruction. @@ -4672,8 +4684,10 @@ class HorizontalReduction { /// Right operand of the reduction operation. Value *RHS = nullptr; + /// Kind of the reduction operation. ReductionKind Kind = RK_None; + /// True if float point min/max reduction has no NaNs. bool NoNaN = false; @@ -4725,7 +4739,7 @@ class HorizontalReduction { /// Construction for reduced values. They are identified by opcode only and /// don't have associated LHS/RHS values. - explicit OperationData(Value *V) : Kind(RK_None) { + explicit OperationData(Value *V) { if (auto *I = dyn_cast<Instruction>(V)) Opcode = I->getOpcode(); } @@ -4737,6 +4751,7 @@ class HorizontalReduction { : Opcode(Opcode), LHS(LHS), RHS(RHS), Kind(Kind), NoNaN(NoNaN) { assert(Kind != RK_None && "One of the reduction operations is expected."); } + explicit operator bool() const { return Opcode; } /// Get the index of the first operand. @@ -5421,7 +5436,6 @@ private: /// starting from the last insertelement instruction. /// /// Returns true if it matches -/// static bool findBuildVector(InsertElementInst *LastInsertElem, SmallVectorImpl<Value *> &BuildVector, SmallVectorImpl<Value *> &BuildVectorOpds) { diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp index 498f4c4f7f3..f74426e5f30 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -18,12 +18,29 @@ //===----------------------------------------------------------------------===// #include "VPlan.h" +#include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/PostOrderIterator.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Twine.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/IR/BasicBlock.h" +#include "llvm/IR/CFG.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/GraphWriter.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include <cassert> +#include <iterator> +#include <string> +#include <vector> using namespace llvm; @@ -138,7 +155,6 @@ void VPBasicBlock::execute(VPTransformState *State) { SingleHPred->getExitBasicBlock() == PrevVPBB && PrevVPBB->getSingleHierarchicalSuccessor()) && /* B */ !(Replica && getPredecessors().empty())) { /* C */ - NewBB = createEmptyBasicBlock(State->CFG); State->Builder.SetInsertPoint(NewBB); // Temporarily terminate with unreachable until CFG is rewired. diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index 3c11fdeb076..d43774dd36e 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1,4 +1,4 @@ -//===- VPlan.h - Represent A Vectorizer Plan ------------------------------===// +//===- VPlan.h - Represent A Vectorizer Plan --------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,7 +6,7 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// This file contains the declarations of the Vectorization Plan base classes: /// 1. VPBasicBlock and VPRegionBlock that inherit from a common pure virtual @@ -18,34 +18,37 @@ /// 4. The VPlan class holding a candidate for vectorization; /// 5. The VPlanPrinter class providing a way to print a plan in dot format. /// These are documented in docs/VectorizationPlan.rst. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_TRANSFORMS_VECTORIZE_VPLAN_H #define LLVM_TRANSFORMS_VECTORIZE_VPLAN_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Twine.h" #include "llvm/ADT/ilist.h" #include "llvm/ADT/ilist_node.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/Support/raw_ostream.h" - -// The (re)use of existing LoopVectorize classes is subject to future VPlan -// refactoring. -namespace { -// Forward declarations. -//class InnerLoopVectorizer; -class LoopVectorizationLegality; -class LoopVectorizationCostModel; -} // namespace +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <map> +#include <string> namespace llvm { -// Forward declarations. class BasicBlock; +class DominatorTree; class InnerLoopVectorizer; +class LoopInfo; +class raw_ostream; +class Value; class VPBasicBlock; +class VPRegionBlock; /// In what follows, the term "input IR" refers to code that is fed into the /// vectorizer whereas the term "output IR" refers to code that is generated by @@ -54,8 +57,11 @@ class VPBasicBlock; /// VPIteration represents a single point in the iteration space of the output /// (vectorized and/or unrolled) IR loop. struct VPIteration { - unsigned Part; ///< in [0..UF) - unsigned Lane; ///< in [0..VF) + /// in [0..UF) + unsigned Part; + + /// in [0..VF) + unsigned Lane; }; /// This is a helper struct for maintaining vectorization state. It's used for @@ -75,7 +81,6 @@ struct VPIteration { /// /// Entries from either map can be retrieved using the getVectorValue and /// getScalarValue functions, which assert that the desired value exists. - struct VectorizerValueMap { private: /// The unroll factor. Each entry in the vector map contains UF vector values. @@ -87,8 +92,8 @@ private: /// The vector and scalar map storage. We use std::map and not DenseMap /// because insertions to DenseMap invalidate its iterators. - typedef SmallVector<Value *, 2> VectorParts; - typedef SmallVector<SmallVector<Value *, 4>, 2> ScalarParts; + using VectorParts = SmallVector<Value *, 2>; + using ScalarParts = SmallVector<SmallVector<Value *, 4>, 2>; std::map<Value *, VectorParts> VectorMapStorage; std::map<Value *, ScalarParts> ScalarMapStorage; @@ -193,12 +198,11 @@ public: /// VPTransformState holds information passed down when "executing" a VPlan, /// needed for generating the output IR. struct VPTransformState { - - VPTransformState(unsigned VF, unsigned UF, class LoopInfo *LI, - class DominatorTree *DT, IRBuilder<> &Builder, - VectorizerValueMap &ValueMap, InnerLoopVectorizer *ILV) - : VF(VF), UF(UF), Instance(), LI(LI), DT(DT), Builder(Builder), - ValueMap(ValueMap), ILV(ILV) {} + VPTransformState(unsigned VF, unsigned UF, LoopInfo *LI, DominatorTree *DT, + IRBuilder<> &Builder, VectorizerValueMap &ValueMap, + InnerLoopVectorizer *ILV) + : VF(VF), UF(UF), LI(LI), DT(DT), Builder(Builder), ValueMap(ValueMap), + ILV(ILV) {} /// The chosen Vectorization and Unroll Factors of the loop being vectorized. unsigned VF; @@ -213,25 +217,28 @@ struct VPTransformState { /// traversing the VPBasicBlocks and generating corresponding IR BasicBlocks. struct CFGState { /// The previous VPBasicBlock visited. Initially set to null. - VPBasicBlock *PrevVPBB; + VPBasicBlock *PrevVPBB = nullptr; + /// The previous IR BasicBlock created or used. Initially set to the new /// header BasicBlock. - BasicBlock *PrevBB; + BasicBlock *PrevBB = nullptr; + /// The last IR BasicBlock in the output IR. Set to the new latch /// BasicBlock, used for placing the newly created BasicBlocks. - BasicBlock *LastBB; + BasicBlock *LastBB = nullptr; + /// A mapping of each VPBasicBlock to the corresponding BasicBlock. In case /// of replication, maps the BasicBlock of the last replica created. SmallDenseMap<VPBasicBlock *, BasicBlock *> VPBB2IRBB; - CFGState() : PrevVPBB(nullptr), PrevBB(nullptr), LastBB(nullptr) {} + CFGState() = default; } CFG; /// Hold a pointer to LoopInfo to register new basic blocks in the loop. - class LoopInfo *LI; + LoopInfo *LI; /// Hold a pointer to Dominator Tree to register new basic blocks in the loop. - class DominatorTree *DT; + DominatorTree *DT; /// Hold a reference to the IRBuilder used to generate output IR code. IRBuilder<> &Builder; @@ -241,7 +248,7 @@ struct VPTransformState { VectorizerValueMap &ValueMap; /// Hold a pointer to InnerLoopVectorizer to reuse its IR generation methods. - class InnerLoopVectorizer *ILV; + InnerLoopVectorizer *ILV; }; /// VPBlockBase is the building block of the Hierarchical Control-Flow Graph. @@ -255,7 +262,7 @@ private: /// The immediate VPRegionBlock which this VPBlockBase belongs to, or null if /// it is a topmost VPBlockBase. - class VPRegionBlock *Parent; + VPRegionBlock *Parent = nullptr; /// List of predecessor blocks. SmallVector<VPBlockBase *, 1> Predecessors; @@ -291,18 +298,18 @@ private: protected: VPBlockBase(const unsigned char SC, const std::string &N) - : SubclassID(SC), Name(N), Parent(nullptr) {} + : SubclassID(SC), Name(N) {} public: /// An enumeration for keeping track of the concrete subclass of VPBlockBase /// that are actually instantiated. Values of this enumeration are kept in the /// SubclassID field of the VPBlockBase objects. They are used for concrete /// type identification. - typedef enum { VPBasicBlockSC, VPRegionBlockSC } VPBlockTy; + using VPBlockTy = enum { VPBasicBlockSC, VPRegionBlockSC }; - typedef SmallVectorImpl<VPBlockBase *> VPBlocksTy; + using VPBlocksTy = SmallVectorImpl<VPBlockBase *>; - virtual ~VPBlockBase() {} + virtual ~VPBlockBase() = default; const std::string &getName() const { return Name; } @@ -437,14 +444,14 @@ private: const unsigned char SubclassID; ///< Subclass identifier (for isa/dyn_cast). /// Each VPRecipe belongs to a single VPBasicBlock. - VPBasicBlock *Parent; + VPBasicBlock *Parent = nullptr; public: /// An enumeration for keeping track of the concrete subclass of VPRecipeBase /// that is actually instantiated. Values of this enumeration are kept in the /// SubclassID field of the VPRecipeBase objects. They are used for concrete /// type identification. - typedef enum { + using VPRecipeTy = enum { VPBranchOnMaskSC, VPInterleaveSC, VPPredInstPHISC, @@ -452,11 +459,10 @@ public: VPWidenIntOrFpInductionSC, VPWidenPHISC, VPWidenSC, - } VPRecipeTy; - - VPRecipeBase(const unsigned char SC) : SubclassID(SC), Parent(nullptr) {} + }; - virtual ~VPRecipeBase() {} + VPRecipeBase(const unsigned char SC) : SubclassID(SC) {} + virtual ~VPRecipeBase() = default; /// \return an ID for the concrete type of this object. /// This is used to implement the classof checks. This should not be used @@ -480,18 +486,26 @@ public: /// output IR instructions. class VPBasicBlock : public VPBlockBase { public: - typedef iplist<VPRecipeBase> RecipeListTy; + using RecipeListTy = iplist<VPRecipeBase>; private: /// The VPRecipes held in the order of output instructions to generate. RecipeListTy Recipes; public: + VPBasicBlock(const Twine &Name = "", VPRecipeBase *Recipe = nullptr) + : VPBlockBase(VPBasicBlockSC, Name.str()) { + if (Recipe) + appendRecipe(Recipe); + } + + ~VPBasicBlock() override { Recipes.clear(); } + /// Instruction iterators... - typedef RecipeListTy::iterator iterator; - typedef RecipeListTy::const_iterator const_iterator; - typedef RecipeListTy::reverse_iterator reverse_iterator; - typedef RecipeListTy::const_reverse_iterator const_reverse_iterator; + using iterator = RecipeListTy::iterator; + using const_iterator = RecipeListTy::const_iterator; + using reverse_iterator = RecipeListTy::reverse_iterator; + using const_reverse_iterator = RecipeListTy::const_reverse_iterator; //===--------------------------------------------------------------------===// /// Recipe iterator methods @@ -518,14 +532,6 @@ public: return &VPBasicBlock::Recipes; } - VPBasicBlock(const Twine &Name = "", VPRecipeBase *Recipe = nullptr) - : VPBlockBase(VPBasicBlockSC, Name.str()) { - if (Recipe) - appendRecipe(Recipe); - } - - ~VPBasicBlock() { Recipes.clear(); } - /// Method to support type inquiry through isa, cast, and dyn_cast. static inline bool classof(const VPBlockBase *V) { return V->getVPBlockID() == VPBlockBase::VPBasicBlockSC; @@ -581,7 +587,7 @@ public: Exit->setParent(this); } - ~VPRegionBlock() { + ~VPRegionBlock() override { if (Entry) deleteCFG(Entry); } @@ -649,7 +655,7 @@ public: private: /// Add to the given dominator tree the header block and every new basic block /// that was created between it and the latch block, inclusive. - static void updateDominatorTree(class DominatorTree *DT, + static void updateDominatorTree(DominatorTree *DT, BasicBlock *LoopPreHeaderBB, BasicBlock *LoopLatchBB); }; @@ -667,11 +673,11 @@ private: unsigned Depth; unsigned TabWidth = 2; std::string Indent; - unsigned BID = 0; - SmallDenseMap<const VPBlockBase *, unsigned> BlockID; + VPlanPrinter(raw_ostream &O, VPlan &P) : OS(O), Plan(P) {} + /// Handle indentation. void bumpIndent(int b) { Indent = std::string((Depth += b) * TabWidth, ' '); } @@ -701,8 +707,6 @@ private: void drawEdge(const VPBlockBase *From, const VPBlockBase *To, bool Hidden, const Twine &Label); - VPlanPrinter(raw_ostream &O, VPlan &P) : OS(O), Plan(P) {} - void dump(); static void printAsIngredient(raw_ostream &O, Value *V); @@ -710,6 +714,7 @@ private: struct VPlanIngredient { Value *V; + VPlanIngredient(Value *V) : V(V) {} }; @@ -732,8 +737,8 @@ inline raw_ostream &operator<<(raw_ostream &OS, VPlan &Plan) { // graph of VPBlockBase nodes... template <> struct GraphTraits<VPBlockBase *> { - typedef VPBlockBase *NodeRef; - typedef SmallVectorImpl<VPBlockBase *>::iterator ChildIteratorType; + using NodeRef = VPBlockBase *; + using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::iterator; static NodeRef getEntryNode(NodeRef N) { return N; } @@ -747,8 +752,8 @@ template <> struct GraphTraits<VPBlockBase *> { }; template <> struct GraphTraits<const VPBlockBase *> { - typedef const VPBlockBase *NodeRef; - typedef SmallVectorImpl<VPBlockBase *>::const_iterator ChildIteratorType; + using NodeRef = const VPBlockBase *; + using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::const_iterator; static NodeRef getEntryNode(NodeRef N) { return N; } @@ -765,11 +770,9 @@ template <> struct GraphTraits<const VPBlockBase *> { // graph of VPBlockBase nodes... and to walk it in inverse order. Inverse order // for a VPBlockBase is considered to be when traversing the predecessors of a // VPBlockBase instead of its successors. -// - template <> struct GraphTraits<Inverse<VPBlockBase *>> { - typedef VPBlockBase *NodeRef; - typedef SmallVectorImpl<VPBlockBase *>::iterator ChildIteratorType; + using NodeRef = VPBlockBase *; + using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::iterator; static Inverse<VPBlockBase *> getEntryNode(Inverse<VPBlockBase *> B) { return B; @@ -784,6 +787,6 @@ template <> struct GraphTraits<Inverse<VPBlockBase *>> { } }; -} // namespace llvm +} // end namespace llvm #endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H |