LLVM 23.0.0git
VPlanCFG.h
Go to the documentation of this file.
1//===- VPlanCFG.h - GraphTraits for VP blocks -------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8/// Specializations of GraphTraits that allow VPBlockBase graphs to be
9/// treated as proper graphs for generic algorithms;
10//===----------------------------------------------------------------------===//
11
12#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANCFG_H
13#define LLVM_TRANSFORMS_VECTORIZE_VPLANCFG_H
14
15#include "VPlan.h"
16#include "VPlanUtils.h"
21
22namespace llvm {
23
24//===----------------------------------------------------------------------===//
25// GraphTraits specializations for VPlan Hierarchical Control-Flow Graphs //
26//===----------------------------------------------------------------------===//
27
28/// Iterator to traverse all successors/predecessors of a VPBlockBase node,
29/// including its hierarchical successors/predecessors:
30///
31/// A
32/// |
33/// +-----+ <- Region R
34/// | b |
35/// | |
36/// | ... |
37/// | |
38/// | e |
39/// +-----+
40/// |
41/// B
42///
43/// Forward == true:
44/// Region blocks themselves traverse only their entries directly.
45/// Region's successor is implictly traversed when processing its exiting
46/// block.
47/// children(A) == {R}
48/// children(R) == {b}
49/// children(e) == {B}
50///
51/// Forward == false:
52/// Region blocks themselves traverse only their exiting blocks directly.
53/// Region's predecessor is implicitly traversed when processing its entry
54/// block.
55/// children(B) == {R}
56/// children(R) == {e}
57/// children(b) == {A}
58///
59/// The scheme described above ensures that all blocks of the region are visited
60/// before continuing traversal outside the region when doing a reverse
61/// post-order traversal of the VPlan.
62template <typename BlockPtrTy, bool Forward = true>
64 : public iterator_facade_base<
65 VPHierarchicalChildrenIterator<BlockPtrTy, Forward>,
66 std::bidirectional_iterator_tag, VPBlockBase> {
67 BlockPtrTy Block;
68 /// Index of the current successor/predecessor. For VPBasicBlock nodes, this
69 /// simply is the index for the successors/predecessors array. For
70 /// VPRegionBlock, EdgeIdx == 0 is used for the region's entry/exiting block,
71 /// and EdgeIdx - 1 are the indices for the successors/predecessors array.
72 size_t EdgeIdx;
73
74 static size_t getNumOutgoingEdges(BlockPtrTy Current) {
75 if constexpr (Forward)
76 return Current->getNumSuccessors();
77 else
78 return Current->getNumPredecessors();
79 }
80
81 static ArrayRef<BlockPtrTy> getOutgoingEdges(BlockPtrTy Current) {
82 if constexpr (Forward)
83 return Current->getSuccessors();
84 else
85 return Current->getPredecessors();
86 }
87
88 static BlockPtrTy getBlockWithOutgoingEdges(BlockPtrTy Current) {
89 while (Current && getNumOutgoingEdges(Current) == 0)
90 Current = Current->getParent();
91 return Current;
92 }
93
94 /// Templated helper to dereference successor/predecessor \p EdgeIdx of \p
95 /// Block. Used by both the const and non-const operator* implementations.
96 template <typename T1> static T1 deref(T1 Block, unsigned EdgeIdx) {
97 if (auto *R = dyn_cast<VPRegionBlock>(Block)) {
98 assert(EdgeIdx == 0);
99 if constexpr (Forward)
100 return R->getEntry();
101 else
102 return R->getExiting();
103 }
104
105 // For exit blocks, use the next parent region with successors.
106 return getOutgoingEdges(getBlockWithOutgoingEdges(Block))[EdgeIdx];
107 }
108
109public:
110 /// Used by iterator_facade_base with bidirectional_iterator_tag.
111 using reference = BlockPtrTy;
112
113 VPHierarchicalChildrenIterator(BlockPtrTy Block, size_t Idx = 0)
114 : Block(Block), EdgeIdx(Idx) {}
115
116 static VPHierarchicalChildrenIterator end(BlockPtrTy Block) {
117 if (auto *R = dyn_cast<VPRegionBlock>(Block)) {
118 // Traverse through the region's entry/exiting (based on Forward) node.
119 return {R, 1};
120 }
121 BlockPtrTy ParentWithOutgoingEdges = getBlockWithOutgoingEdges(Block);
122 unsigned NumOutgoingEdges =
123 ParentWithOutgoingEdges ? getNumOutgoingEdges(ParentWithOutgoingEdges)
124 : 0;
125 return {Block, NumOutgoingEdges};
126 }
127
129 return Block == R.Block && EdgeIdx == R.EdgeIdx;
130 }
131
132 const VPBlockBase *operator*() const { return deref(Block, EdgeIdx); }
133
134 BlockPtrTy operator*() { return deref(Block, EdgeIdx); }
135
137 EdgeIdx++;
138 return *this;
139 }
140
142 EdgeIdx--;
143 return *this;
144 }
145
148 EdgeIdx++;
149 return Orig;
150 }
151};
152
153/// Helper for GraphTraits specialization that traverses through VPRegionBlocks.
154template <typename BlockTy> class VPBlockDeepTraversalWrapper {
155 BlockTy Entry;
156
157public:
158 VPBlockDeepTraversalWrapper(BlockTy Entry) : Entry(Entry) {}
159 BlockTy getEntry() { return Entry; }
160};
161
162/// GraphTraits specialization to recursively traverse VPBlockBase nodes,
163/// including traversing through VPRegionBlocks. Exit blocks of a region
164/// implicitly have their parent region's successors. This ensures all blocks in
165/// a region are visited before any blocks in a successor region when doing a
166/// reverse post-order traversal of the graph.
183
184template <>
202
203/// Helper for GraphTraits specialization that does not traverses through
204/// VPRegionBlocks.
205template <typename BlockTy> class VPBlockShallowTraversalWrapper {
206 BlockTy Entry;
207
208public:
210 BlockTy getEntry() { return Entry; }
211};
212
216
220
222 return N->getSuccessors().begin();
223 }
224
226 return N->getSuccessors().end();
227 }
228};
229
230template <>
232 using NodeRef = const VPBlockBase *;
234
235 static NodeRef
239
241 return N->getSuccessors().begin();
242 }
243
245 return N->getSuccessors().end();
246 }
247};
248
249/// Returns an iterator range to traverse the graph starting at \p G in
250/// depth-first order. The iterator won't traverse through region blocks.
251inline iterator_range<
252 df_iterator<VPBlockShallowTraversalWrapper<VPBlockBase *>>>
256inline iterator_range<
257 df_iterator<VPBlockShallowTraversalWrapper<const VPBlockBase *>>>
261
262/// Returns an iterator range to traverse the graph starting at \p G in
263/// post order. The iterator won't traverse through region blocks.
264inline iterator_range<
265 po_iterator<VPBlockShallowTraversalWrapper<VPBlockBase *>>>
269
270/// Returns an iterator range to traverse the graph starting at \p G in
271/// post order while traversing through region blocks.
276
277/// Returns an iterator range to traverse the graph starting at \p G in
278/// depth-first order while traversing through region blocks.
283inline iterator_range<
284 df_iterator<VPBlockDeepTraversalWrapper<const VPBlockBase *>>>
288
289// The following set of template specializations implement GraphTraits to treat
290// any VPBlockBase as a node in a graph of VPBlockBases. It's important to note
291// that VPBlockBase traits don't recurse into VPRegioBlocks, i.e., if the
292// VPBlockBase is a VPRegionBlock, this specialization provides access to its
293// successors/predecessors but not to the blocks inside the region.
294
295template <> struct GraphTraits<VPBlockBase *> {
298
299 static NodeRef getEntryNode(NodeRef N) { return N; }
300
302 return ChildIteratorType(N);
303 }
304
307 }
308};
309
310template <> struct GraphTraits<const VPBlockBase *> {
311 using NodeRef = const VPBlockBase *;
313
314 static NodeRef getEntryNode(NodeRef N) { return N; }
315
317 return ChildIteratorType(N);
318 }
319
322 }
323};
324
325template <> struct GraphTraits<Inverse<VPBlockBase *>> {
328 VPHierarchicalChildrenIterator<VPBlockBase *, /*Forward=*/false>;
329
330 static NodeRef getEntryNode(Inverse<NodeRef> B) { return B.Graph; }
331
333 return ChildIteratorType(N);
334 }
335
338 }
339};
340
341template <> struct GraphTraits<VPlan *> {
342 using GraphRef = VPlan *;
345
346 static NodeRef getEntryNode(GraphRef N) { return N->getEntry(); }
347
349 return nodes_iterator::begin(N->getEntry());
350 }
351
353 // df_iterator::end() returns an empty iterator so the node used doesn't
354 // matter.
355 return nodes_iterator::end(N->getEntry());
356 }
357};
358
359} // namespace llvm
360
361#endif // LLVM_TRANSFORMS_VECTORIZE_VPLANCFG_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
std::pair< BasicBlock *, unsigned > BlockTy
A pair of (basic block, score).
#define G(x, y, z)
Definition MD5.cpp:55
#define T1
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file defines the SmallVector class.
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This file contains the declarations of the Vectorization Plan base classes:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
typename SuperClass::const_iterator const_iterator
typename SuperClass::iterator iterator
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:82
Helper for GraphTraits specialization that traverses through VPRegionBlocks.
Definition VPlanCFG.h:154
VPBlockDeepTraversalWrapper(BlockTy Entry)
Definition VPlanCFG.h:158
Helper for GraphTraits specialization that does not traverses through VPRegionBlocks.
Definition VPlanCFG.h:205
VPBlockShallowTraversalWrapper(BlockTy Entry)
Definition VPlanCFG.h:209
Iterator to traverse all successors/predecessors of a VPBlockBase node, including its hierarchical su...
Definition VPlanCFG.h:66
const VPBlockBase * operator*() const
Definition VPlanCFG.h:132
VPHierarchicalChildrenIterator & operator++()
Definition VPlanCFG.h:136
VPHierarchicalChildrenIterator(BlockPtrTy Block, size_t Idx=0)
Definition VPlanCFG.h:113
BlockPtrTy reference
Used by iterator_facade_base with bidirectional_iterator_tag.
Definition VPlanCFG.h:111
static VPHierarchicalChildrenIterator end(BlockPtrTy Block)
Definition VPlanCFG.h:116
VPHierarchicalChildrenIterator operator++(int X)
Definition VPlanCFG.h:146
bool operator==(const VPHierarchicalChildrenIterator &R) const
Definition VPlanCFG.h:128
VPHierarchicalChildrenIterator & operator--()
Definition VPlanCFG.h:141
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4514
static df_iterator begin(const NodeRef &G)
static df_iterator end(const NodeRef &G)
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterator.h:80
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
iterator_range< po_iterator< T > > post_order(const T &G)
iterator_range< df_iterator< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_depth_first_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order.
Definition VPlanCFG.h:253
iterator_range< df_iterator< VPBlockDeepTraversalWrapper< VPBlockBase * > > > vp_depth_first_deep(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order while traversing t...
Definition VPlanCFG.h:280
iterator_range< po_iterator< VPBlockDeepTraversalWrapper< VPBlockBase * > > > vp_post_order_deep(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in post order while traversing through ...
Definition VPlanCFG.h:273
iterator_range< po_iterator< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_post_order_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in post order.
Definition VPlanCFG.h:266
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
iterator_range< df_iterator< T > > depth_first(const T &G)
#define N
VPHierarchicalChildrenIterator< VPBlockBase *, false > ChildIteratorType
Definition VPlanCFG.h:327
static NodeRef getEntryNode(Inverse< NodeRef > B)
Definition VPlanCFG.h:330
static ChildIteratorType child_end(NodeRef N)
Definition VPlanCFG.h:336
static ChildIteratorType child_begin(NodeRef N)
Definition VPlanCFG.h:332
VPHierarchicalChildrenIterator< VPBlockBase * > ChildIteratorType
Definition VPlanCFG.h:297
static NodeRef getEntryNode(NodeRef N)
Definition VPlanCFG.h:299
static ChildIteratorType child_begin(NodeRef N)
Definition VPlanCFG.h:301
static ChildIteratorType child_end(NodeRef N)
Definition VPlanCFG.h:305
static NodeRef getEntryNode(VPBlockDeepTraversalWrapper< VPBlockBase * > N)
Definition VPlanCFG.h:171
VPHierarchicalChildrenIterator< VPBlockBase * > ChildIteratorType
Definition VPlanCFG.h:169
VPHierarchicalChildrenIterator< const VPBlockBase * > ChildIteratorType
Definition VPlanCFG.h:187
static NodeRef getEntryNode(VPBlockDeepTraversalWrapper< const VPBlockBase * > N)
Definition VPlanCFG.h:190
static NodeRef getEntryNode(VPBlockShallowTraversalWrapper< VPBlockBase * > N)
Definition VPlanCFG.h:217
SmallVectorImpl< VPBlockBase * >::iterator ChildIteratorType
Definition VPlanCFG.h:215
SmallVectorImpl< VPBlockBase * >::const_iterator ChildIteratorType
Definition VPlanCFG.h:233
static NodeRef getEntryNode(VPBlockShallowTraversalWrapper< const VPBlockBase * > N)
Definition VPlanCFG.h:236
static nodes_iterator nodes_end(GraphRef N)
Definition VPlanCFG.h:352
static NodeRef getEntryNode(GraphRef N)
Definition VPlanCFG.h:346
df_iterator< NodeRef > nodes_iterator
Definition VPlanCFG.h:344
static nodes_iterator nodes_begin(GraphRef N)
Definition VPlanCFG.h:348
VPHierarchicalChildrenIterator< const VPBlockBase * > ChildIteratorType
Definition VPlanCFG.h:312
static ChildIteratorType child_end(NodeRef N)
Definition VPlanCFG.h:320
static ChildIteratorType child_begin(NodeRef N)
Definition VPlanCFG.h:316
static NodeRef getEntryNode(NodeRef N)
Definition VPlanCFG.h:314