|
10 | 10 | /// This file contains the declarations of the Vectorization Plan base classes:
|
11 | 11 | /// 1. VPBasicBlock and VPRegionBlock that inherit from a common pure virtual
|
12 | 12 | /// VPBlockBase, together implementing a Hierarchical CFG;
|
13 |
| -/// 2. Specializations of GraphTraits that allow VPBlockBase graphs to be |
14 |
| -/// treated as proper graphs for generic algorithms; |
15 |
| -/// 3. Pure virtual VPRecipeBase serving as the base class for recipes contained |
| 13 | +/// 2. Pure virtual VPRecipeBase serving as the base class for recipes contained |
16 | 14 | /// within VPBasicBlocks;
|
17 |
| -/// 4. VPInstruction, a concrete Recipe and VPUser modeling a single planned |
| 15 | +/// 3. VPInstruction, a concrete Recipe and VPUser modeling a single planned |
18 | 16 | /// instruction;
|
19 |
| -/// 5. The VPlan class holding a candidate for vectorization; |
20 |
| -/// 6. The VPlanPrinter class providing a way to print a plan in dot format; |
| 17 | +/// 4. The VPlan class holding a candidate for vectorization; |
| 18 | +/// 5. The VPlanPrinter class providing a way to print a plan in dot format; |
21 | 19 | /// These are documented in docs/VectorizationPlan.rst.
|
22 | 20 | //
|
23 | 21 | //===----------------------------------------------------------------------===//
|
|
28 | 26 | #include "VPlanValue.h"
|
29 | 27 | #include "llvm/ADT/DenseMap.h"
|
30 | 28 | #include "llvm/ADT/DepthFirstIterator.h"
|
31 |
| -#include "llvm/ADT/GraphTraits.h" |
32 | 29 | #include "llvm/ADT/MapVector.h"
|
33 | 30 | #include "llvm/ADT/SmallBitVector.h"
|
34 | 31 | #include "llvm/ADT/SmallPtrSet.h"
|
@@ -2231,258 +2228,6 @@ class VPRegionBlock : public VPBlockBase {
|
2231 | 2228 | #endif
|
2232 | 2229 | };
|
2233 | 2230 |
|
2234 |
| -//===----------------------------------------------------------------------===// |
2235 |
| -// GraphTraits specializations for VPlan Hierarchical Control-Flow Graphs // |
2236 |
| -//===----------------------------------------------------------------------===// |
2237 |
| - |
2238 |
| -// The following set of template specializations implement GraphTraits to treat |
2239 |
| -// any VPBlockBase as a node in a graph of VPBlockBases. It's important to note |
2240 |
| -// that VPBlockBase traits don't recurse into VPRegioBlocks, i.e., if the |
2241 |
| -// VPBlockBase is a VPRegionBlock, this specialization provides access to its |
2242 |
| -// successors/predecessors but not to the blocks inside the region. |
2243 |
| - |
2244 |
| -template <> struct GraphTraits<VPBlockBase *> { |
2245 |
| - using NodeRef = VPBlockBase *; |
2246 |
| - using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::iterator; |
2247 |
| - |
2248 |
| - static NodeRef getEntryNode(NodeRef N) { return N; } |
2249 |
| - |
2250 |
| - static inline ChildIteratorType child_begin(NodeRef N) { |
2251 |
| - return N->getSuccessors().begin(); |
2252 |
| - } |
2253 |
| - |
2254 |
| - static inline ChildIteratorType child_end(NodeRef N) { |
2255 |
| - return N->getSuccessors().end(); |
2256 |
| - } |
2257 |
| -}; |
2258 |
| - |
2259 |
| -template <> struct GraphTraits<const VPBlockBase *> { |
2260 |
| - using NodeRef = const VPBlockBase *; |
2261 |
| - using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::const_iterator; |
2262 |
| - |
2263 |
| - static NodeRef getEntryNode(NodeRef N) { return N; } |
2264 |
| - |
2265 |
| - static inline ChildIteratorType child_begin(NodeRef N) { |
2266 |
| - return N->getSuccessors().begin(); |
2267 |
| - } |
2268 |
| - |
2269 |
| - static inline ChildIteratorType child_end(NodeRef N) { |
2270 |
| - return N->getSuccessors().end(); |
2271 |
| - } |
2272 |
| -}; |
2273 |
| - |
2274 |
| -// Inverse order specialization for VPBasicBlocks. Predecessors are used instead |
2275 |
| -// of successors for the inverse traversal. |
2276 |
| -template <> struct GraphTraits<Inverse<VPBlockBase *>> { |
2277 |
| - using NodeRef = VPBlockBase *; |
2278 |
| - using ChildIteratorType = SmallVectorImpl<VPBlockBase *>::iterator; |
2279 |
| - |
2280 |
| - static NodeRef getEntryNode(Inverse<NodeRef> B) { return B.Graph; } |
2281 |
| - |
2282 |
| - static inline ChildIteratorType child_begin(NodeRef N) { |
2283 |
| - return N->getPredecessors().begin(); |
2284 |
| - } |
2285 |
| - |
2286 |
| - static inline ChildIteratorType child_end(NodeRef N) { |
2287 |
| - return N->getPredecessors().end(); |
2288 |
| - } |
2289 |
| -}; |
2290 |
| - |
2291 |
| -// The following set of template specializations implement GraphTraits to |
2292 |
| -// treat VPRegionBlock as a graph and recurse inside its nodes. It's important |
2293 |
| -// to note that the blocks inside the VPRegionBlock are treated as VPBlockBases |
2294 |
| -// (i.e., no dyn_cast is performed, VPBlockBases specialization is used), so |
2295 |
| -// there won't be automatic recursion into other VPBlockBases that turn to be |
2296 |
| -// VPRegionBlocks. |
2297 |
| - |
2298 |
| -template <> |
2299 |
| -struct GraphTraits<VPRegionBlock *> : public GraphTraits<VPBlockBase *> { |
2300 |
| - using GraphRef = VPRegionBlock *; |
2301 |
| - using nodes_iterator = df_iterator<NodeRef>; |
2302 |
| - |
2303 |
| - static NodeRef getEntryNode(GraphRef N) { return N->getEntry(); } |
2304 |
| - |
2305 |
| - static nodes_iterator nodes_begin(GraphRef N) { |
2306 |
| - return nodes_iterator::begin(N->getEntry()); |
2307 |
| - } |
2308 |
| - |
2309 |
| - static nodes_iterator nodes_end(GraphRef N) { |
2310 |
| - // df_iterator::end() returns an empty iterator so the node used doesn't |
2311 |
| - // matter. |
2312 |
| - return nodes_iterator::end(N); |
2313 |
| - } |
2314 |
| -}; |
2315 |
| - |
2316 |
| -template <> |
2317 |
| -struct GraphTraits<const VPRegionBlock *> |
2318 |
| - : public GraphTraits<const VPBlockBase *> { |
2319 |
| - using GraphRef = const VPRegionBlock *; |
2320 |
| - using nodes_iterator = df_iterator<NodeRef>; |
2321 |
| - |
2322 |
| - static NodeRef getEntryNode(GraphRef N) { return N->getEntry(); } |
2323 |
| - |
2324 |
| - static nodes_iterator nodes_begin(GraphRef N) { |
2325 |
| - return nodes_iterator::begin(N->getEntry()); |
2326 |
| - } |
2327 |
| - |
2328 |
| - static nodes_iterator nodes_end(GraphRef N) { |
2329 |
| - // df_iterator::end() returns an empty iterator so the node used doesn't |
2330 |
| - // matter. |
2331 |
| - return nodes_iterator::end(N); |
2332 |
| - } |
2333 |
| -}; |
2334 |
| - |
2335 |
| -template <> |
2336 |
| -struct GraphTraits<Inverse<VPRegionBlock *>> |
2337 |
| - : public GraphTraits<Inverse<VPBlockBase *>> { |
2338 |
| - using GraphRef = VPRegionBlock *; |
2339 |
| - using nodes_iterator = df_iterator<NodeRef>; |
2340 |
| - |
2341 |
| - static NodeRef getEntryNode(Inverse<GraphRef> N) { |
2342 |
| - return N.Graph->getExiting(); |
2343 |
| - } |
2344 |
| - |
2345 |
| - static nodes_iterator nodes_begin(GraphRef N) { |
2346 |
| - return nodes_iterator::begin(N->getExiting()); |
2347 |
| - } |
2348 |
| - |
2349 |
| - static nodes_iterator nodes_end(GraphRef N) { |
2350 |
| - // df_iterator::end() returns an empty iterator so the node used doesn't |
2351 |
| - // matter. |
2352 |
| - return nodes_iterator::end(N); |
2353 |
| - } |
2354 |
| -}; |
2355 |
| - |
2356 |
| -/// Iterator to traverse all successors of a VPBlockBase node. This includes the |
2357 |
| -/// entry node of VPRegionBlocks. Exit blocks of a region implicitly have their |
2358 |
| -/// parent region's successors. This ensures all blocks in a region are visited |
2359 |
| -/// before any blocks in a successor region when doing a reverse post-order |
2360 |
| -// traversal of the graph. |
2361 |
| -template <typename BlockPtrTy> |
2362 |
| -class VPAllSuccessorsIterator |
2363 |
| - : public iterator_facade_base<VPAllSuccessorsIterator<BlockPtrTy>, |
2364 |
| - std::forward_iterator_tag, VPBlockBase> { |
2365 |
| - BlockPtrTy Block; |
2366 |
| - /// Index of the current successor. For VPBasicBlock nodes, this simply is the |
2367 |
| - /// index for the successor array. For VPRegionBlock, SuccessorIdx == 0 is |
2368 |
| - /// used for the region's entry block, and SuccessorIdx - 1 are the indices |
2369 |
| - /// for the successor array. |
2370 |
| - size_t SuccessorIdx; |
2371 |
| - |
2372 |
| - static BlockPtrTy getBlockWithSuccs(BlockPtrTy Current) { |
2373 |
| - while (Current && Current->getNumSuccessors() == 0) |
2374 |
| - Current = Current->getParent(); |
2375 |
| - return Current; |
2376 |
| - } |
2377 |
| - |
2378 |
| - /// Templated helper to dereference successor \p SuccIdx of \p Block. Used by |
2379 |
| - /// both the const and non-const operator* implementations. |
2380 |
| - template <typename T1> static T1 deref(T1 Block, unsigned SuccIdx) { |
2381 |
| - if (auto *R = dyn_cast<VPRegionBlock>(Block)) { |
2382 |
| - if (SuccIdx == 0) |
2383 |
| - return R->getEntry(); |
2384 |
| - SuccIdx--; |
2385 |
| - } |
2386 |
| - |
2387 |
| - // For exit blocks, use the next parent region with successors. |
2388 |
| - return getBlockWithSuccs(Block)->getSuccessors()[SuccIdx]; |
2389 |
| - } |
2390 |
| - |
2391 |
| -public: |
2392 |
| - VPAllSuccessorsIterator(BlockPtrTy Block, size_t Idx = 0) |
2393 |
| - : Block(Block), SuccessorIdx(Idx) {} |
2394 |
| - VPAllSuccessorsIterator(const VPAllSuccessorsIterator &Other) |
2395 |
| - : Block(Other.Block), SuccessorIdx(Other.SuccessorIdx) {} |
2396 |
| - |
2397 |
| - VPAllSuccessorsIterator &operator=(const VPAllSuccessorsIterator &R) { |
2398 |
| - Block = R.Block; |
2399 |
| - SuccessorIdx = R.SuccessorIdx; |
2400 |
| - return *this; |
2401 |
| - } |
2402 |
| - |
2403 |
| - static VPAllSuccessorsIterator end(BlockPtrTy Block) { |
2404 |
| - BlockPtrTy ParentWithSuccs = getBlockWithSuccs(Block); |
2405 |
| - unsigned NumSuccessors = ParentWithSuccs |
2406 |
| - ? ParentWithSuccs->getNumSuccessors() |
2407 |
| - : Block->getNumSuccessors(); |
2408 |
| - |
2409 |
| - if (auto *R = dyn_cast<VPRegionBlock>(Block)) |
2410 |
| - return {R, NumSuccessors + 1}; |
2411 |
| - return {Block, NumSuccessors}; |
2412 |
| - } |
2413 |
| - |
2414 |
| - bool operator==(const VPAllSuccessorsIterator &R) const { |
2415 |
| - return Block == R.Block && SuccessorIdx == R.SuccessorIdx; |
2416 |
| - } |
2417 |
| - |
2418 |
| - const VPBlockBase *operator*() const { return deref(Block, SuccessorIdx); } |
2419 |
| - |
2420 |
| - BlockPtrTy operator*() { return deref(Block, SuccessorIdx); } |
2421 |
| - |
2422 |
| - VPAllSuccessorsIterator &operator++() { |
2423 |
| - SuccessorIdx++; |
2424 |
| - return *this; |
2425 |
| - } |
2426 |
| - |
2427 |
| - VPAllSuccessorsIterator operator++(int X) { |
2428 |
| - VPAllSuccessorsIterator Orig = *this; |
2429 |
| - SuccessorIdx++; |
2430 |
| - return Orig; |
2431 |
| - } |
2432 |
| -}; |
2433 |
| - |
2434 |
| -/// Helper for GraphTraits specialization that traverses through VPRegionBlocks. |
2435 |
| -template <typename BlockTy> class VPBlockRecursiveTraversalWrapper { |
2436 |
| - BlockTy Entry; |
2437 |
| - |
2438 |
| -public: |
2439 |
| - VPBlockRecursiveTraversalWrapper(BlockTy Entry) : Entry(Entry) {} |
2440 |
| - BlockTy getEntry() { return Entry; } |
2441 |
| -}; |
2442 |
| - |
2443 |
| -/// GraphTraits specialization to recursively traverse VPBlockBase nodes, |
2444 |
| -/// including traversing through VPRegionBlocks. Exit blocks of a region |
2445 |
| -/// implicitly have their parent region's successors. This ensures all blocks in |
2446 |
| -/// a region are visited before any blocks in a successor region when doing a |
2447 |
| -/// reverse post-order traversal of the graph. |
2448 |
| -template <> |
2449 |
| -struct GraphTraits<VPBlockRecursiveTraversalWrapper<VPBlockBase *>> { |
2450 |
| - using NodeRef = VPBlockBase *; |
2451 |
| - using ChildIteratorType = VPAllSuccessorsIterator<VPBlockBase *>; |
2452 |
| - |
2453 |
| - static NodeRef |
2454 |
| - getEntryNode(VPBlockRecursiveTraversalWrapper<VPBlockBase *> N) { |
2455 |
| - return N.getEntry(); |
2456 |
| - } |
2457 |
| - |
2458 |
| - static inline ChildIteratorType child_begin(NodeRef N) { |
2459 |
| - return ChildIteratorType(N); |
2460 |
| - } |
2461 |
| - |
2462 |
| - static inline ChildIteratorType child_end(NodeRef N) { |
2463 |
| - return ChildIteratorType::end(N); |
2464 |
| - } |
2465 |
| -}; |
2466 |
| - |
2467 |
| -template <> |
2468 |
| -struct GraphTraits<VPBlockRecursiveTraversalWrapper<const VPBlockBase *>> { |
2469 |
| - using NodeRef = const VPBlockBase *; |
2470 |
| - using ChildIteratorType = VPAllSuccessorsIterator<const VPBlockBase *>; |
2471 |
| - |
2472 |
| - static NodeRef |
2473 |
| - getEntryNode(VPBlockRecursiveTraversalWrapper<const VPBlockBase *> N) { |
2474 |
| - return N.getEntry(); |
2475 |
| - } |
2476 |
| - |
2477 |
| - static inline ChildIteratorType child_begin(NodeRef N) { |
2478 |
| - return ChildIteratorType(N); |
2479 |
| - } |
2480 |
| - |
2481 |
| - static inline ChildIteratorType child_end(NodeRef N) { |
2482 |
| - return ChildIteratorType::end(N); |
2483 |
| - } |
2484 |
| -}; |
2485 |
| - |
2486 | 2231 | /// VPlan models a candidate for vectorization, encoding various decisions take
|
2487 | 2232 | /// to produce efficient output IR, including which branches, basic-blocks and
|
2488 | 2233 | /// output IR instructions to generate, and their cost. VPlan holds a
|
@@ -2541,25 +2286,7 @@ class VPlan {
|
2541 | 2286 | Entry->setPlan(this);
|
2542 | 2287 | }
|
2543 | 2288 |
|
2544 |
| - ~VPlan() { |
2545 |
| - clearLiveOuts(); |
2546 |
| - |
2547 |
| - if (Entry) { |
2548 |
| - VPValue DummyValue; |
2549 |
| - for (VPBlockBase *Block : depth_first(Entry)) |
2550 |
| - Block->dropAllReferences(&DummyValue); |
2551 |
| - |
2552 |
| - VPBlockBase::deleteCFG(Entry); |
2553 |
| - } |
2554 |
| - for (VPValue *VPV : VPValuesToFree) |
2555 |
| - delete VPV; |
2556 |
| - if (TripCount) |
2557 |
| - delete TripCount; |
2558 |
| - if (BackedgeTakenCount) |
2559 |
| - delete BackedgeTakenCount; |
2560 |
| - for (auto &P : VPExternalDefs) |
2561 |
| - delete P.second; |
2562 |
| - } |
| 2289 | + ~VPlan(); |
2563 | 2290 |
|
2564 | 2291 | /// Prepare the plan for execution, setting up the required live-in values.
|
2565 | 2292 | void prepareToExecute(Value *TripCount, Value *VectorTripCount,
|
|
0 commit comments