LLVM 22.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 of a VPBlockBase node. This includes the
29/// entry node of VPRegionBlocks. Exit blocks of a region implicitly have their
30/// parent region's successors. This ensures all blocks in a region are visited
31/// before any blocks in a successor region when doing a reverse post-order
32// traversal of the graph. Region blocks themselves traverse only their entries
33// directly and not their successors. Those will be traversed when a region's
34// exiting block is traversed
35template <typename BlockPtrTy>
37 : public iterator_facade_base<VPAllSuccessorsIterator<BlockPtrTy>,
38 std::bidirectional_iterator_tag,
39 VPBlockBase> {
40 BlockPtrTy Block;
41 /// Index of the current successor. For VPBasicBlock nodes, this simply is the
42 /// index for the successor array. For VPRegionBlock, SuccessorIdx == 0 is
43 /// used for the region's entry block, and SuccessorIdx - 1 are the indices
44 /// for the successor array.
45 size_t SuccessorIdx;
46
47 static BlockPtrTy getBlockWithSuccs(BlockPtrTy Current) {
48 while (Current && Current->getNumSuccessors() == 0)
49 Current = Current->getParent();
50 return Current;
51 }
52
53 /// Templated helper to dereference successor \p SuccIdx of \p Block. Used by
54 /// both the const and non-const operator* implementations.
55 template <typename T1> static T1 deref(T1 Block, unsigned SuccIdx) {
56 if (auto *R = dyn_cast<VPRegionBlock>(Block)) {
57 assert(SuccIdx == 0);
58 return R->getEntry();
59 }
60
61 // For exit blocks, use the next parent region with successors.
62 return getBlockWithSuccs(Block)->getSuccessors()[SuccIdx];
63 }
64
65public:
66 /// Used by iterator_facade_base with bidirectional_iterator_tag.
67 using reference = BlockPtrTy;
68
69 VPAllSuccessorsIterator(BlockPtrTy Block, size_t Idx = 0)
70 : Block(Block), SuccessorIdx(Idx) {}
72 : Block(Other.Block), SuccessorIdx(Other.SuccessorIdx) {}
73
75 Block = R.Block;
76 SuccessorIdx = R.SuccessorIdx;
77 return *this;
78 }
79
80 static VPAllSuccessorsIterator end(BlockPtrTy Block) {
81 if (auto *R = dyn_cast<VPRegionBlock>(Block)) {
82 // Traverse through the region's entry node.
83 return {R, 1};
84 }
85 BlockPtrTy ParentWithSuccs = getBlockWithSuccs(Block);
86 unsigned NumSuccessors =
87 ParentWithSuccs ? ParentWithSuccs->getNumSuccessors() : 0;
88 return {Block, NumSuccessors};
89 }
90
91 bool operator==(const VPAllSuccessorsIterator &R) const {
92 return Block == R.Block && SuccessorIdx == R.SuccessorIdx;
93 }
94
95 const VPBlockBase *operator*() const { return deref(Block, SuccessorIdx); }
96
97 BlockPtrTy operator*() { return deref(Block, SuccessorIdx); }
98
100 SuccessorIdx++;
101 return *this;
102 }
103
105 SuccessorIdx--;
106 return *this;
107 }
108
110 VPAllSuccessorsIterator Orig = *this;
111 SuccessorIdx++;
112 return Orig;
113 }
114};
115
116/// Helper for GraphTraits specialization that traverses through VPRegionBlocks.
117template <typename BlockTy> class VPBlockDeepTraversalWrapper {
118 BlockTy Entry;
119
120public:
121 VPBlockDeepTraversalWrapper(BlockTy Entry) : Entry(Entry) {}
122 BlockTy getEntry() { return Entry; }
123};
124
125/// GraphTraits specialization to recursively traverse VPBlockBase nodes,
126/// including traversing through VPRegionBlocks. Exit blocks of a region
127/// implicitly have their parent region's successors. This ensures all blocks in
128/// a region are visited before any blocks in a successor region when doing a
129/// reverse post-order traversal of the graph.
133
135 return N.getEntry();
136 }
137
139 return ChildIteratorType(N);
140 }
141
143 return ChildIteratorType::end(N);
144 }
145};
146
147template <>
149 using NodeRef = const VPBlockBase *;
151
152 static NodeRef
154 return N.getEntry();
155 }
156
158 return ChildIteratorType(N);
159 }
160
162 return ChildIteratorType::end(N);
163 }
164};
165
166/// Helper for GraphTraits specialization that does not traverses through
167/// VPRegionBlocks.
168template <typename BlockTy> class VPBlockShallowTraversalWrapper {
169 BlockTy Entry;
170
171public:
173 BlockTy getEntry() { return Entry; }
174};
175
179
181 return N.getEntry();
182 }
183
185 return N->getSuccessors().begin();
186 }
187
189 return N->getSuccessors().end();
190 }
191};
192
193template <>
195 using NodeRef = const VPBlockBase *;
197
198 static NodeRef
200 return N.getEntry();
201 }
202
204 return N->getSuccessors().begin();
205 }
206
208 return N->getSuccessors().end();
209 }
210};
211
212/// Returns an iterator range to traverse the graph starting at \p G in
213/// depth-first order. The iterator won't traverse through region blocks.
214inline iterator_range<
215 df_iterator<VPBlockShallowTraversalWrapper<VPBlockBase *>>>
218}
219inline iterator_range<
220 df_iterator<VPBlockShallowTraversalWrapper<const VPBlockBase *>>>
223}
224
225/// Returns an iterator range to traverse the graph starting at \p G in
226/// post order. The iterator won't traverse through region blocks.
227inline iterator_range<
228 po_iterator<VPBlockShallowTraversalWrapper<VPBlockBase *>>>
231}
232
233/// Returns an iterator range to traverse the graph starting at \p G in
234/// post order while traversing through region blocks.
235inline iterator_range<po_iterator<VPBlockDeepTraversalWrapper<VPBlockBase *>>>
238}
239
240/// Returns an iterator range to traverse the graph starting at \p G in
241/// depth-first order while traversing through region blocks.
242inline iterator_range<df_iterator<VPBlockDeepTraversalWrapper<VPBlockBase *>>>
245}
246inline iterator_range<
247 df_iterator<VPBlockDeepTraversalWrapper<const VPBlockBase *>>>
250}
251
252// The following set of template specializations implement GraphTraits to treat
253// any VPBlockBase as a node in a graph of VPBlockBases. It's important to note
254// that VPBlockBase traits don't recurse into VPRegioBlocks, i.e., if the
255// VPBlockBase is a VPRegionBlock, this specialization provides access to its
256// successors/predecessors but not to the blocks inside the region.
257
258template <> struct GraphTraits<VPBlockBase *> {
261
262 static NodeRef getEntryNode(NodeRef N) { return N; }
263
265 return ChildIteratorType(N);
266 }
267
269 return ChildIteratorType::end(N);
270 }
271};
272
273template <> struct GraphTraits<const VPBlockBase *> {
274 using NodeRef = const VPBlockBase *;
276
277 static NodeRef getEntryNode(NodeRef N) { return N; }
278
280 return ChildIteratorType(N);
281 }
282
284 return ChildIteratorType::end(N);
285 }
286};
287
288/// Inverse graph traits are not implemented yet.
289/// TODO: Implement a version of VPBlockNonRecursiveTraversalWrapper to traverse
290/// predecessors recursively through regions.
291template <> struct GraphTraits<Inverse<VPBlockBase *>> {
294
296 llvm_unreachable("not implemented");
297 }
298
300 llvm_unreachable("not implemented");
301 }
302
304 llvm_unreachable("not implemented");
305 }
306};
307
308template <> struct GraphTraits<VPlan *> {
309 using GraphRef = VPlan *;
312
313 static NodeRef getEntryNode(GraphRef N) { return N->getEntry(); }
314
316 return nodes_iterator::begin(N->getEntry());
317 }
318
320 // df_iterator::end() returns an empty iterator so the node used doesn't
321 // matter.
322 return nodes_iterator::end(N->getEntry());
323 }
324};
325
326} // namespace llvm
327
328#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")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
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:56
#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.
This file contains the declarations of the Vectorization Plan base classes:
typename SuperClass::const_iterator const_iterator
Definition: SmallVector.h:579
typename SuperClass::iterator iterator
Definition: SmallVector.h:578
Iterator to traverse all successors of a VPBlockBase node.
Definition: VPlanCFG.h:39
const VPBlockBase * operator*() const
Definition: VPlanCFG.h:95
VPAllSuccessorsIterator & operator++()
Definition: VPlanCFG.h:99
bool operator==(const VPAllSuccessorsIterator &R) const
Definition: VPlanCFG.h:91
VPAllSuccessorsIterator(BlockPtrTy Block, size_t Idx=0)
Definition: VPlanCFG.h:69
VPAllSuccessorsIterator operator++(int X)
Definition: VPlanCFG.h:109
VPAllSuccessorsIterator(const VPAllSuccessorsIterator &Other)
Definition: VPlanCFG.h:71
VPAllSuccessorsIterator & operator--()
Definition: VPlanCFG.h:104
BlockPtrTy reference
Used by iterator_facade_base with bidirectional_iterator_tag.
Definition: VPlanCFG.h:67
VPAllSuccessorsIterator & operator=(const VPAllSuccessorsIterator &R)
Definition: VPlanCFG.h:74
static VPAllSuccessorsIterator end(BlockPtrTy Block)
Definition: VPlanCFG.h:80
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition: VPlan.h:81
Helper for GraphTraits specialization that traverses through VPRegionBlocks.
Definition: VPlanCFG.h:117
VPBlockDeepTraversalWrapper(BlockTy Entry)
Definition: VPlanCFG.h:121
Helper for GraphTraits specialization that does not traverses through VPRegionBlocks.
Definition: VPlanCFG.h:168
VPBlockShallowTraversalWrapper(BlockTy Entry)
Definition: VPlanCFG.h:172
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition: VPlan.h:3930
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition: iterator.h:80
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:216
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:243
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:236
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:229
@ Other
Any other memory.
iterator_range< df_iterator< T > > depth_first(const T &G)
#define N
SmallVectorImpl< VPBlockBase * >::iterator ChildIteratorType
Definition: VPlanCFG.h:293
static NodeRef getEntryNode(Inverse< NodeRef > B)
Definition: VPlanCFG.h:295
static ChildIteratorType child_end(NodeRef N)
Definition: VPlanCFG.h:303
static ChildIteratorType child_begin(NodeRef N)
Definition: VPlanCFG.h:299
static NodeRef getEntryNode(NodeRef N)
Definition: VPlanCFG.h:262
static ChildIteratorType child_begin(NodeRef N)
Definition: VPlanCFG.h:264
static ChildIteratorType child_end(NodeRef N)
Definition: VPlanCFG.h:268
static NodeRef getEntryNode(VPBlockDeepTraversalWrapper< VPBlockBase * > N)
Definition: VPlanCFG.h:134
static NodeRef getEntryNode(VPBlockDeepTraversalWrapper< const VPBlockBase * > N)
Definition: VPlanCFG.h:153
static NodeRef getEntryNode(VPBlockShallowTraversalWrapper< VPBlockBase * > N)
Definition: VPlanCFG.h:180
SmallVectorImpl< VPBlockBase * >::iterator ChildIteratorType
Definition: VPlanCFG.h:178
SmallVectorImpl< VPBlockBase * >::const_iterator ChildIteratorType
Definition: VPlanCFG.h:196
static NodeRef getEntryNode(VPBlockShallowTraversalWrapper< const VPBlockBase * > N)
Definition: VPlanCFG.h:199
static nodes_iterator nodes_end(GraphRef N)
Definition: VPlanCFG.h:319
static NodeRef getEntryNode(GraphRef N)
Definition: VPlanCFG.h:313
static nodes_iterator nodes_begin(GraphRef N)
Definition: VPlanCFG.h:315
static ChildIteratorType child_end(NodeRef N)
Definition: VPlanCFG.h:283
static ChildIteratorType child_begin(NodeRef N)
Definition: VPlanCFG.h:279
static NodeRef getEntryNode(NodeRef N)
Definition: VPlanCFG.h:277
Binary functor that adapts to any other binary functor after dereferencing operands.
Definition: STLExtras.h:2279