//===- VPlanCFG.h - GraphTraits for VP blocks -------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// Specializations of GraphTraits that allow VPBlockBase graphs to be /// treated as proper graphs for generic algorithms; //===----------------------------------------------------------------------===// #ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANCFG_H #define LLVM_TRANSFORMS_VECTORIZE_VPLANCFG_H #include "VPlan.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/ADT/SmallVector.h" namespace llvm { //===----------------------------------------------------------------------===// // GraphTraits specializations for VPlan Hierarchical Control-Flow Graphs // //===----------------------------------------------------------------------===// /// Iterator to traverse all successors of a VPBlockBase node. This includes the /// entry node of VPRegionBlocks. Exit blocks of a region implicitly have their /// parent region's successors. This ensures all blocks in a region are visited /// before any blocks in a successor region when doing a reverse post-order // traversal of the graph. Region blocks themselves traverse only their entries // directly and not their successors. Those will be traversed when a region's // exiting block is traversed template <typename BlockPtrTy> class VPAllSuccessorsIterator : public iterator_facade_base<VPAllSuccessorsIterator<BlockPtrTy>, std::bidirectional_iterator_tag, VPBlockBase> { … }; /// Helper for GraphTraits specialization that traverses through VPRegionBlocks. template <typename BlockTy> class VPBlockDeepTraversalWrapper { … }; /// GraphTraits specialization to recursively traverse VPBlockBase nodes, /// including traversing through VPRegionBlocks. Exit blocks of a region /// implicitly have their parent region's successors. This ensures all blocks in /// a region are visited before any blocks in a successor region when doing a /// reverse post-order traversal of the graph. template <> struct GraphTraits<VPBlockDeepTraversalWrapper<VPBlockBase *>> { … }; template <> struct GraphTraits<VPBlockDeepTraversalWrapper<const VPBlockBase *>> { … }; /// Helper for GraphTraits specialization that does not traverses through /// VPRegionBlocks. template <typename BlockTy> class VPBlockShallowTraversalWrapper { … }; template <> struct GraphTraits<VPBlockShallowTraversalWrapper<VPBlockBase *>> { … }; template <> struct GraphTraits<VPBlockShallowTraversalWrapper<const VPBlockBase *>> { … }; /// Returns an iterator range to traverse the graph starting at \p G in /// depth-first order. The iterator won't traverse through region blocks. inline iterator_range< df_iterator<VPBlockShallowTraversalWrapper<VPBlockBase *>>> vp_depth_first_shallow(VPBlockBase *G) { … } inline iterator_range< df_iterator<VPBlockShallowTraversalWrapper<const VPBlockBase *>>> vp_depth_first_shallow(const VPBlockBase *G) { … } /// Returns an iterator range to traverse the graph starting at \p G in /// depth-first order while traversing through region blocks. inline iterator_range<df_iterator<VPBlockDeepTraversalWrapper<VPBlockBase *>>> vp_depth_first_deep(VPBlockBase *G) { … } inline iterator_range< df_iterator<VPBlockDeepTraversalWrapper<const VPBlockBase *>>> vp_depth_first_deep(const VPBlockBase *G) { … } // The following set of template specializations implement GraphTraits to treat // any VPBlockBase as a node in a graph of VPBlockBases. It's important to note // that VPBlockBase traits don't recurse into VPRegioBlocks, i.e., if the // VPBlockBase is a VPRegionBlock, this specialization provides access to its // successors/predecessors but not to the blocks inside the region. template <> struct GraphTraits<VPBlockBase *> { … }; template <> struct GraphTraits<const VPBlockBase *> { … }; /// Inverse graph traits are not implemented yet. /// TODO: Implement a version of VPBlockNonRecursiveTraversalWrapper to traverse /// predecessors recursively through regions. template <> struct GraphTraits<Inverse<VPBlockBase *>> { … }; template <> struct GraphTraits<VPlan *> { … }; } // namespace llvm #endif // LLVM_TRANSFORMS_VECTORIZE_VPLANCFG_H