MLIR  14.0.0git
BufferUtils.h
Go to the documentation of this file.
1 //===- BufferUtils.h - Buffer optimization utilities ------------*- 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 //
9 // This file provides utilities for passes optimizing code that has already
10 // been converted to buffers.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_TRANSFORMS_BUFFERUTILS_H
15 #define MLIR_TRANSFORMS_BUFFERUTILS_H
16 
18 #include "mlir/Analysis/Liveness.h"
21 #include "mlir/IR/Builders.h"
22 #include "mlir/IR/BuiltinOps.h"
23 #include "mlir/IR/Dominance.h"
24 #include "mlir/IR/Operation.h"
26 
27 namespace mlir {
28 
29 /// A simple analysis that detects allocation operations.
31 public:
32  /// Represents a tuple of allocValue and deallocOperation.
33  using AllocEntry = std::tuple<Value, Operation *>;
34 
35  /// Represents a list containing all alloc entries.
37 
38  /// Get the start operation to place the given alloc value within the
39  /// specified placement block.
40  static Operation *getStartOperation(Value allocValue, Block *placementBlock,
41  const Liveness &liveness);
42 
43 public:
44  /// Initializes the internal list by discovering all supported allocation
45  /// nodes.
47 
48  /// Returns the begin iterator to iterate over all allocations.
49  AllocEntryList::const_iterator begin() const { return allocs.begin(); }
50 
51  /// Returns the end iterator that can be used in combination with begin.
52  AllocEntryList::const_iterator end() const { return allocs.end(); }
53 
54  /// Returns the begin iterator to iterate over all allocations.
55  AllocEntryList::iterator begin() { return allocs.begin(); }
56 
57  /// Returns the end iterator that can be used in combination with begin.
58  AllocEntryList::iterator end() { return allocs.end(); }
59 
60  /// Registers a new allocation entry.
61  void registerAlloc(const AllocEntry &entry) { allocs.push_back(entry); }
62 
63 private:
64  /// Searches for and registers all supported allocation entries.
65  void build(Operation *op);
66 
67 private:
68  /// Maps allocation nodes to their associated blocks.
69  AllocEntryList allocs;
70 };
71 
72 /// The base class for all BufferPlacement transformations.
74 public:
76 
77  /// Finds a common dominator for the given value while taking the positions
78  /// of the values in the value set into account. It supports dominator and
79  /// post-dominator analyses via template arguments.
80  template <typename DominatorT>
81  static Block *findCommonDominator(Value value, const ValueSetT &values,
82  const DominatorT &doms) {
83  // Start with the current block the value is defined in.
84  Block *dom = value.getParentBlock();
85  // Iterate over all aliases and their uses to find a safe placement block
86  // according to the given dominator information.
87  for (Value childValue : values) {
88  for (Operation *user : childValue.getUsers()) {
89  // Move upwards in the dominator tree to find an appropriate
90  // dominator block that takes the current use into account.
91  dom = doms.findNearestCommonDominator(dom, user->getBlock());
92  }
93  // Take values without any users into account.
94  dom = doms.findNearestCommonDominator(dom, childValue.getParentBlock());
95  }
96  return dom;
97  }
98 
99  /// Returns true if the given operation represents a loop by testing whether
100  /// it implements the `LoopLikeOpInterface` or the `RegionBranchOpInterface`.
101  /// In the case of a `RegionBranchOpInterface`, it checks all region-based
102  /// control-flow edges for cycles.
103  static bool isLoop(Operation *op);
104 
105  /// Constructs a new operation base using the given root operation.
107 
108 protected:
109  /// Alias information that can be updated during the insertion of copies.
111 
112  /// Stores all internally managed allocations.
114 
115  /// The underlying liveness analysis to compute fine grained information
116  /// about alloc and dealloc positions.
118 };
119 
120 namespace memref {
121 class GlobalOp;
122 } // namespace memref
123 
124 // Support class to create global ops for tensor-valued constants in the
125 // program. Globals are created lazily at the top of the `moduleOp` with pretty
126 // names. Duplicates are avoided.
128 public:
129  GlobalCreator(ModuleOp module, unsigned alignment = 0)
130  : moduleOp(module), alignment(alignment) {}
131  memref::GlobalOp getGlobalFor(arith::ConstantOp constantOp);
132 
133 private:
134  ModuleOp moduleOp;
135  unsigned alignment;
136  // This could use memref::GlobalOp key but we avoid introducing a new
137  // dependence to the memref dialect for this.
139 };
140 } // namespace mlir
141 
142 #endif // MLIR_TRANSFORMS_BUFFERUTILS_H
SmallPtrSet< Value, 16 > ValueSetT
Include the generated interface declarations.
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
Block represents an ordered list of Operations.
Definition: Block.h:29
AllocEntryList::iterator begin()
Returns the begin iterator to iterate over all allocations.
Definition: BufferUtils.h:55
GlobalCreator(ModuleOp module, unsigned alignment=0)
Definition: BufferUtils.h:129
A straight-forward alias analysis which ensures that all dependencies of all values will be determine...
BufferViewFlowAnalysis aliases
Alias information that can be updated during the insertion of copies.
Definition: BufferUtils.h:110
std::tuple< Value, Operation * > AllocEntry
Represents a tuple of allocValue and deallocOperation.
Definition: BufferUtils.h:33
BufferPlacementAllocs allocs
Stores all internally managed allocations.
Definition: BufferUtils.h:113
The base class for all BufferPlacement transformations.
Definition: BufferUtils.h:73
static constexpr const bool value
A simple analysis that detects allocation operations.
Definition: BufferUtils.h:30
Block * getParentBlock()
Return the Block in which this Value is defined.
Definition: Value.cpp:48
Represents an analysis for computing liveness information from a given top-level operation.
Definition: Liveness.h:47
static Operation * getStartOperation(Value allocValue, Block *placementBlock, const Liveness &liveness)
Get the start operation to place the given alloc value within the specified placement block...
Definition: BufferUtils.cpp:32
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:84
void registerAlloc(const AllocEntry &entry)
Registers a new allocation entry.
Definition: BufferUtils.h:61
static Block * findCommonDominator(Value value, const ValueSetT &values, const DominatorT &doms)
Finds a common dominator for the given value while taking the positions of the values in the value se...
Definition: BufferUtils.h:81
BufferPlacementAllocs(Operation *op)
Initializes the internal list by discovering all supported allocation nodes.
Definition: BufferUtils.cpp:54
Liveness liveness
The underlying liveness analysis to compute fine grained information about alloc and dealloc position...
Definition: BufferUtils.h:117
AllocEntryList::const_iterator end() const
Returns the end iterator that can be used in combination with begin.
Definition: BufferUtils.h:52
AllocEntryList::const_iterator begin() const
Returns the begin iterator to iterate over all allocations.
Definition: BufferUtils.h:49
user_range getUsers()
Returns a range of all users.
Definition: Operation.h:591
AllocEntryList::iterator end()
Returns the end iterator that can be used in combination with begin.
Definition: BufferUtils.h:58