LLVM 20.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"
20
21namespace llvm {
22
23//===----------------------------------------------------------------------===//
24// GraphTraits specializations for VPlan Hierarchical Control-Flow Graphs //
25//===----------------------------------------------------------------------===//
26
27/// Iterator to traverse all successors of a VPBlockBase node. This includes the
28/// entry node of VPRegionBlocks. Exit blocks of a region implicitly have their
29/// parent region's successors. This ensures all blocks in a region are visited
30/// before any blocks in a successor region when doing a reverse post-order
31// traversal of the graph. Region blocks themselves traverse only their entries
32// directly and not their successors. Those will be traversed when a region's
33// exiting block is traversed
34template <typename BlockPtrTy>
36 : public iterator_facade_base<VPAllSuccessorsIterator<BlockPtrTy>,
37 std::bidirectional_iterator_tag,
38 VPBlockBase> {
39 BlockPtrTy Block;
40 /// Index of the current successor. For VPBasicBlock nodes, this simply is the
41 /// index for the successor array. For VPRegionBlock, SuccessorIdx == 0 is
42 /// used for the region's entry block, and SuccessorIdx - 1 are the indices
43 /// for the successor array.
44 size_t SuccessorIdx;
45
46 static BlockPtrTy getBlockWithSuccs(BlockPtrTy Current) {
47 while (Current && Current->getNumSuccessors() == 0)
48 Current = Current->getParent();
49 return Current;
50 }
51
52 /// Templated helper to dereference successor \p SuccIdx of \p Block. Used by
53 /// both the const and non-const operator* implementations.
54 template <typename T1> static T1 deref(T1 Block, unsigned SuccIdx) {
55 if (auto *R = dyn_cast<VPRegionBlock>(Block)) {
56 assert(SuccIdx == 0);
57 return R->getEntry();
58 }
59
60 // For exit blocks, use the next parent region with successors.
61 return getBlockWithSuccs(Block)->getSuccessors()[SuccIdx];
62 }
63
64public:
65 /// Used by iterator_facade_base with bidirectional_iterator_tag.
66 using reference = BlockPtrTy;
67
68 VPAllSuccessorsIterator(BlockPtrTy Block, size_t Idx = 0)
69 : Block(Block), SuccessorIdx(Idx) {}
71 : Block(Other.Block), SuccessorIdx(Other.SuccessorIdx) {}
72
74 Block = R.Block;
75 SuccessorIdx = R.SuccessorIdx;
76 return *this;
77 }
78
79 static VPAllSuccessorsIterator end(BlockPtrTy Block) {
80 if (auto *R = dyn_cast<VPRegionBlock>(Block)) {
81 // Traverse through the region's entry node.
82 return {R, 1};
83 }
84 BlockPtrTy ParentWithSuccs = getBlockWithSuccs(Block);
85 unsigned NumSuccessors =
86 ParentWithSuccs ? ParentWithSuccs->getNumSuccessors() : 0;
87 return {Block, NumSuccessors};
88 }
89
90 bool operator==(const VPAllSuccessorsIterator &R) const {
91 return Block == R.Block && SuccessorIdx == R.SuccessorIdx;
92 }
93
94 const VPBlockBase *operator*() const { return deref(Block, SuccessorIdx); }
95
96 BlockPtrTy operator*() { return deref(Block, SuccessorIdx); }
97
99 SuccessorIdx++;
100 return *this;
101 }
102
104 SuccessorIdx--;
105 return *this;
106 }
107
109 VPAllSuccessorsIterator Orig = *this;
110 SuccessorIdx++;
111 return Orig;
112 }
113};
114
115/// Helper for GraphTraits specialization that traverses through VPRegionBlocks.
116template <typename BlockTy> class VPBlockDeepTraversalWrapper {
117 BlockTy Entry;
118
119public:
120 VPBlockDeepTraversalWrapper(BlockTy Entry) : Entry(Entry) {}
121 BlockTy getEntry() { return Entry; }
122};
123
124/// GraphTraits specialization to recursively traverse VPBlockBase nodes,
125/// including traversing through VPRegionBlocks. Exit blocks of a region
126/// implicitly have their parent region's successors. This ensures all blocks in
127/// a region are visited before any blocks in a successor region when doing a
128/// reverse post-order traversal of the graph.
132
134 return N.getEntry();
135 }
136
138 return ChildIteratorType(N);
139 }
140
142 return ChildIteratorType::end(N);
143 }
144};
145
146template <>
148 using NodeRef = const VPBlockBase *;
150
151 static NodeRef
153 return N.getEntry();
154 }
155
157 return ChildIteratorType(N);
158 }
159
161 return ChildIteratorType::end(N);
162 }
163};
164
165/// Helper for GraphTraits specialization that does not traverses through
166/// VPRegionBlocks.
167template <typename BlockTy> class VPBlockShallowTraversalWrapper {
168 BlockTy Entry;
169
170public:
172 BlockTy getEntry() { return Entry; }
173};
174
178
180 return N.getEntry();
181 }
182
184 return N->getSuccessors().begin();
185 }
186
188 return N->getSuccessors().end();
189 }
190};
191
192template <>
194 using NodeRef = const VPBlockBase *;
196
197 static NodeRef
199 return N.getEntry();
200 }
201
203 return N->getSuccessors().begin();
204 }
205
207 return N->getSuccessors().end();
208 }
209};
210
211/// Returns an iterator range to traverse the graph starting at \p G in
212/// depth-first order. The iterator won't traverse through region blocks.
213inline iterator_range<
214 df_iterator<VPBlockShallowTraversalWrapper<VPBlockBase *>>>
217}
218inline iterator_range<
219 df_iterator<VPBlockShallowTraversalWrapper<const VPBlockBase *>>>
222}
223
224/// Returns an iterator range to traverse the graph starting at \p G in
225/// depth-first order while traversing through region blocks.
226inline iterator_range<df_iterator<VPBlockDeepTraversalWrapper<VPBlockBase *>>>
229}
230inline iterator_range<
231 df_iterator<VPBlockDeepTraversalWrapper<const VPBlockBase *>>>
234}
235
236// The following set of template specializations implement GraphTraits to treat
237// any VPBlockBase as a node in a graph of VPBlockBases. It's important to note
238// that VPBlockBase traits don't recurse into VPRegioBlocks, i.e., if the
239// VPBlockBase is a VPRegionBlock, this specialization provides access to its
240// successors/predecessors but not to the blocks inside the region.
241
242template <> struct GraphTraits<VPBlockBase *> {
245
246 static NodeRef getEntryNode(NodeRef N) { return N; }
247
249 return ChildIteratorType(N);
250 }
251
253 return ChildIteratorType::end(N);
254 }
255};
256
257template <> struct GraphTraits<const VPBlockBase *> {
258 using NodeRef = const VPBlockBase *;
260
261 static NodeRef getEntryNode(NodeRef N) { return N; }
262
264 return ChildIteratorType(N);
265 }
266
268 return ChildIteratorType::end(N);
269 }
270};
271
272/// Inverse graph traits are not implemented yet.
273/// TODO: Implement a version of VPBlockNonRecursiveTraversalWrapper to traverse
274/// predecessors recursively through regions.
275template <> struct GraphTraits<Inverse<VPBlockBase *>> {
278
280 llvm_unreachable("not implemented");
281 }
282
284 llvm_unreachable("not implemented");
285 }
286
288 llvm_unreachable("not implemented");
289 }
290};
291
292template <> struct GraphTraits<VPlan *> {
293 using GraphRef = VPlan *;
296
297 static NodeRef getEntryNode(GraphRef N) { return N->getEntry(); }
298
300 return nodes_iterator::begin(N->getEntry());
301 }
302
304 // df_iterator::end() returns an empty iterator so the node used doesn't
305 // matter.
306 return nodes_iterator::end(N->getEntry());
307 }
308};
309
310inline auto VPlan::getExitBlocks() {
311 VPBlockBase *ScalarHeader = getScalarHeader();
312 return make_filter_range(
313 VPBlockUtils::blocksOnly<VPIRBasicBlock>(
314 vp_depth_first_shallow(getVectorLoopRegion()->getSingleSuccessor())),
315 [ScalarHeader](VPIRBasicBlock *VPIRBB) {
316 return VPIRBB != ScalarHeader && VPIRBB->getNumSuccessors() == 0;
317 });
318}
319} // namespace llvm
320
321#endif // LLVM_TRANSFORMS_VECTORIZE_VPLANCFG_H
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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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:578
typename SuperClass::iterator iterator
Definition: SmallVector.h:577
Iterator to traverse all successors of a VPBlockBase node.
Definition: VPlanCFG.h:38
const VPBlockBase * operator*() const
Definition: VPlanCFG.h:94
VPAllSuccessorsIterator & operator++()
Definition: VPlanCFG.h:98
bool operator==(const VPAllSuccessorsIterator &R) const
Definition: VPlanCFG.h:90
VPAllSuccessorsIterator(BlockPtrTy Block, size_t Idx=0)
Definition: VPlanCFG.h:68
VPAllSuccessorsIterator operator++(int X)
Definition: VPlanCFG.h:108
VPAllSuccessorsIterator(const VPAllSuccessorsIterator &Other)
Definition: VPlanCFG.h:70
VPAllSuccessorsIterator & operator--()
Definition: VPlanCFG.h:103
BlockPtrTy reference
Used by iterator_facade_base with bidirectional_iterator_tag.
Definition: VPlanCFG.h:66
VPAllSuccessorsIterator & operator=(const VPAllSuccessorsIterator &R)
Definition: VPlanCFG.h:73
static VPAllSuccessorsIterator end(BlockPtrTy Block)
Definition: VPlanCFG.h:79
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition: VPlan.h:392
size_t getNumSuccessors() const
Definition: VPlan.h:530
Helper for GraphTraits specialization that traverses through VPRegionBlocks.
Definition: VPlanCFG.h:116
VPBlockDeepTraversalWrapper(BlockTy Entry)
Definition: VPlanCFG.h:120
Helper for GraphTraits specialization that does not traverses through VPRegionBlocks.
Definition: VPlanCFG.h:167
VPBlockShallowTraversalWrapper(BlockTy Entry)
Definition: VPlanCFG.h:171
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition: VPlan.h:3683
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition: VPlan.h:3817
auto getExitBlocks()
Return an iterator range over the VPIRBasicBlock wrapping the exit blocks of the VPlan,...
Definition: VPlanCFG.h:310
VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition: VPlan.cpp:1051
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
Definition: VPlan.h:3962
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< 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:215
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:227
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition: STLExtras.h:573
@ Other
Any other memory.
iterator_range< df_iterator< T > > depth_first(const T &G)
#define N
SmallVectorImpl< VPBlockBase * >::iterator ChildIteratorType
Definition: VPlanCFG.h:277
static NodeRef getEntryNode(Inverse< NodeRef > B)
Definition: VPlanCFG.h:279
static ChildIteratorType child_end(NodeRef N)
Definition: VPlanCFG.h:287
static ChildIteratorType child_begin(NodeRef N)
Definition: VPlanCFG.h:283
static NodeRef getEntryNode(NodeRef N)
Definition: VPlanCFG.h:246
static ChildIteratorType child_begin(NodeRef N)
Definition: VPlanCFG.h:248
static ChildIteratorType child_end(NodeRef N)
Definition: VPlanCFG.h:252
static NodeRef getEntryNode(VPBlockDeepTraversalWrapper< VPBlockBase * > N)
Definition: VPlanCFG.h:133
static NodeRef getEntryNode(VPBlockDeepTraversalWrapper< const VPBlockBase * > N)
Definition: VPlanCFG.h:152
static NodeRef getEntryNode(VPBlockShallowTraversalWrapper< VPBlockBase * > N)
Definition: VPlanCFG.h:179
SmallVectorImpl< VPBlockBase * >::iterator ChildIteratorType
Definition: VPlanCFG.h:177
SmallVectorImpl< VPBlockBase * >::const_iterator ChildIteratorType
Definition: VPlanCFG.h:195
static NodeRef getEntryNode(VPBlockShallowTraversalWrapper< const VPBlockBase * > N)
Definition: VPlanCFG.h:198
static nodes_iterator nodes_end(GraphRef N)
Definition: VPlanCFG.h:303
static NodeRef getEntryNode(GraphRef N)
Definition: VPlanCFG.h:297
static nodes_iterator nodes_begin(GraphRef N)
Definition: VPlanCFG.h:299
static ChildIteratorType child_end(NodeRef N)
Definition: VPlanCFG.h:267
static ChildIteratorType child_begin(NodeRef N)
Definition: VPlanCFG.h:263
static NodeRef getEntryNode(NodeRef N)
Definition: VPlanCFG.h:261
Binary functor that adapts to any other binary functor after dereferencing operands.
Definition: STLExtras.h:2236