1 //===-- mlir-c/Rewrite.h - Helpers for C API to Rewrites ----------*- C -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 // This header declares the registration and creation method for
13 //===----------------------------------------------------------------------===//
15 #ifndef MLIR_C_REWRITE_H
16 #define MLIR_C_REWRITE_H
18 #include "mlir-c/IR.h"
19 #include "mlir-c/Support.h"
20 #include "mlir/Config/mlir-config.h"
26 //===----------------------------------------------------------------------===//
27 /// Opaque type declarations (see mlir-c/IR.h for more details).
28 //===----------------------------------------------------------------------===//
30 #define DEFINE_C_API_STRUCT(name, storage) \
34 typedef struct name name
36 DEFINE_C_API_STRUCT(MlirRewriterBase
, void);
37 DEFINE_C_API_STRUCT(MlirFrozenRewritePatternSet
, void);
38 DEFINE_C_API_STRUCT(MlirGreedyRewriteDriverConfig
, void);
39 DEFINE_C_API_STRUCT(MlirRewritePatternSet
, void);
41 //===----------------------------------------------------------------------===//
42 /// RewriterBase API inherited from OpBuilder
43 //===----------------------------------------------------------------------===//
45 /// Get the MLIR context referenced by the rewriter.
46 MLIR_CAPI_EXPORTED MlirContext
47 mlirRewriterBaseGetContext(MlirRewriterBase rewriter
);
49 //===----------------------------------------------------------------------===//
50 /// Insertion points methods
52 // These do not include functions using Block::iterator or Region::iterator, as
53 // they are not exposed by the C API yet. Similarly for methods using
54 // `InsertPoint` directly.
56 /// Reset the insertion point to no location. Creating an operation without a
57 /// set insertion point is an error, but this can still be useful when the
58 /// current insertion point a builder refers to is being removed.
59 MLIR_CAPI_EXPORTED
void
60 mlirRewriterBaseClearInsertionPoint(MlirRewriterBase rewriter
);
62 /// Sets the insertion point to the specified operation, which will cause
63 /// subsequent insertions to go right before it.
64 MLIR_CAPI_EXPORTED
void
65 mlirRewriterBaseSetInsertionPointBefore(MlirRewriterBase rewriter
,
68 /// Sets the insertion point to the node after the specified operation, which
69 /// will cause subsequent insertions to go right after it.
70 MLIR_CAPI_EXPORTED
void
71 mlirRewriterBaseSetInsertionPointAfter(MlirRewriterBase rewriter
,
74 /// Sets the insertion point to the node after the specified value. If value
75 /// has a defining operation, sets the insertion point to the node after such
76 /// defining operation. This will cause subsequent insertions to go right
77 /// after it. Otherwise, value is a BlockArgument. Sets the insertion point to
78 /// the start of its block.
79 MLIR_CAPI_EXPORTED
void
80 mlirRewriterBaseSetInsertionPointAfterValue(MlirRewriterBase rewriter
,
83 /// Sets the insertion point to the start of the specified block.
84 MLIR_CAPI_EXPORTED
void
85 mlirRewriterBaseSetInsertionPointToStart(MlirRewriterBase rewriter
,
88 /// Sets the insertion point to the end of the specified block.
89 MLIR_CAPI_EXPORTED
void
90 mlirRewriterBaseSetInsertionPointToEnd(MlirRewriterBase rewriter
,
93 /// Return the block the current insertion point belongs to. Note that the
94 /// insertion point is not necessarily the end of the block.
95 MLIR_CAPI_EXPORTED MlirBlock
96 mlirRewriterBaseGetInsertionBlock(MlirRewriterBase rewriter
);
98 /// Returns the current block of the rewriter.
99 MLIR_CAPI_EXPORTED MlirBlock
100 mlirRewriterBaseGetBlock(MlirRewriterBase rewriter
);
102 //===----------------------------------------------------------------------===//
103 /// Block and operation creation/insertion/cloning
105 // These functions do not include the IRMapper, as it is not yet exposed by the
108 /// Add new block with 'argTypes' arguments and set the insertion point to the
109 /// end of it. The block is placed before 'insertBefore'. `locs` contains the
110 /// locations of the inserted arguments, and should match the size of
112 MLIR_CAPI_EXPORTED MlirBlock
mlirRewriterBaseCreateBlockBefore(
113 MlirRewriterBase rewriter
, MlirBlock insertBefore
, intptr_t nArgTypes
,
114 MlirType
const *argTypes
, MlirLocation
const *locations
);
116 /// Insert the given operation at the current insertion point and return it.
117 MLIR_CAPI_EXPORTED MlirOperation
118 mlirRewriterBaseInsert(MlirRewriterBase rewriter
, MlirOperation op
);
120 /// Creates a deep copy of the specified operation.
121 MLIR_CAPI_EXPORTED MlirOperation
122 mlirRewriterBaseClone(MlirRewriterBase rewriter
, MlirOperation op
);
124 /// Creates a deep copy of this operation but keep the operation regions
126 MLIR_CAPI_EXPORTED MlirOperation
mlirRewriterBaseCloneWithoutRegions(
127 MlirRewriterBase rewriter
, MlirOperation op
);
129 /// Clone the blocks that belong to "region" before the given position in
130 /// another region "parent".
131 MLIR_CAPI_EXPORTED
void
132 mlirRewriterBaseCloneRegionBefore(MlirRewriterBase rewriter
, MlirRegion region
,
135 //===----------------------------------------------------------------------===//
137 //===----------------------------------------------------------------------===//
139 /// Move the blocks that belong to "region" before the given position in
140 /// another region "parent". The two regions must be different. The caller
141 /// is responsible for creating or updating the operation transferring flow
142 /// of control to the region and passing it the correct block arguments.
143 MLIR_CAPI_EXPORTED
void
144 mlirRewriterBaseInlineRegionBefore(MlirRewriterBase rewriter
, MlirRegion region
,
147 /// Replace the results of the given (original) operation with the specified
148 /// list of values (replacements). The result types of the given op and the
149 /// replacements must match. The original op is erased.
150 MLIR_CAPI_EXPORTED
void
151 mlirRewriterBaseReplaceOpWithValues(MlirRewriterBase rewriter
, MlirOperation op
,
152 intptr_t nValues
, MlirValue
const *values
);
154 /// Replace the results of the given (original) operation with the specified
155 /// new op (replacement). The result types of the two ops must match. The
156 /// original op is erased.
157 MLIR_CAPI_EXPORTED
void
158 mlirRewriterBaseReplaceOpWithOperation(MlirRewriterBase rewriter
,
159 MlirOperation op
, MlirOperation newOp
);
161 /// Erases an operation that is known to have no uses.
162 MLIR_CAPI_EXPORTED
void mlirRewriterBaseEraseOp(MlirRewriterBase rewriter
,
165 /// Erases a block along with all operations inside it.
166 MLIR_CAPI_EXPORTED
void mlirRewriterBaseEraseBlock(MlirRewriterBase rewriter
,
169 /// Inline the operations of block 'source' before the operation 'op'. The
170 /// source block will be deleted and must have no uses. 'argValues' is used to
171 /// replace the block arguments of 'source'
173 /// The source block must have no successors. Otherwise, the resulting IR
174 /// would have unreachable operations.
175 MLIR_CAPI_EXPORTED
void
176 mlirRewriterBaseInlineBlockBefore(MlirRewriterBase rewriter
, MlirBlock source
,
177 MlirOperation op
, intptr_t nArgValues
,
178 MlirValue
const *argValues
);
180 /// Inline the operations of block 'source' into the end of block 'dest'. The
181 /// source block will be deleted and must have no uses. 'argValues' is used to
182 /// replace the block arguments of 'source'
184 /// The dest block must have no successors. Otherwise, the resulting IR would
185 /// have unreachable operation.
186 MLIR_CAPI_EXPORTED
void mlirRewriterBaseMergeBlocks(MlirRewriterBase rewriter
,
190 MlirValue
const *argValues
);
192 /// Unlink this operation from its current block and insert it right before
193 /// `existingOp` which may be in the same or another block in the same
195 MLIR_CAPI_EXPORTED
void mlirRewriterBaseMoveOpBefore(MlirRewriterBase rewriter
,
197 MlirOperation existingOp
);
199 /// Unlink this operation from its current block and insert it right after
200 /// `existingOp` which may be in the same or another block in the same
202 MLIR_CAPI_EXPORTED
void mlirRewriterBaseMoveOpAfter(MlirRewriterBase rewriter
,
204 MlirOperation existingOp
);
206 /// Unlink this block and insert it right before `existingBlock`.
207 MLIR_CAPI_EXPORTED
void
208 mlirRewriterBaseMoveBlockBefore(MlirRewriterBase rewriter
, MlirBlock block
,
209 MlirBlock existingBlock
);
211 /// This method is used to notify the rewriter that an in-place operation
212 /// modification is about to happen. A call to this function *must* be
213 /// followed by a call to either `finalizeOpModification` or
214 /// `cancelOpModification`. This is a minor efficiency win (it avoids creating
215 /// a new operation and removing the old one) but also often allows simpler
216 /// code in the client.
217 MLIR_CAPI_EXPORTED
void
218 mlirRewriterBaseStartOpModification(MlirRewriterBase rewriter
,
221 /// This method is used to signal the end of an in-place modification of the
222 /// given operation. This can only be called on operations that were provided
223 /// to a call to `startOpModification`.
224 MLIR_CAPI_EXPORTED
void
225 mlirRewriterBaseFinalizeOpModification(MlirRewriterBase rewriter
,
228 /// This method cancels a pending in-place modification. This can only be
229 /// called on operations that were provided to a call to
230 /// `startOpModification`.
231 MLIR_CAPI_EXPORTED
void
232 mlirRewriterBaseCancelOpModification(MlirRewriterBase rewriter
,
235 /// Find uses of `from` and replace them with `to`. Also notify the listener
236 /// about every in-place op modification (for every use that was replaced).
237 MLIR_CAPI_EXPORTED
void
238 mlirRewriterBaseReplaceAllUsesWith(MlirRewriterBase rewriter
, MlirValue from
,
241 /// Find uses of `from` and replace them with `to`. Also notify the listener
242 /// about every in-place op modification (for every use that was replaced).
243 MLIR_CAPI_EXPORTED
void mlirRewriterBaseReplaceAllValueRangeUsesWith(
244 MlirRewriterBase rewriter
, intptr_t nValues
, MlirValue
const *from
,
245 MlirValue
const *to
);
247 /// Find uses of `from` and replace them with `to`. Also notify the listener
248 /// about every in-place op modification (for every use that was replaced)
249 /// and that the `from` operation is about to be replaced.
250 MLIR_CAPI_EXPORTED
void
251 mlirRewriterBaseReplaceAllOpUsesWithValueRange(MlirRewriterBase rewriter
,
252 MlirOperation from
, intptr_t nTo
,
253 MlirValue
const *to
);
255 /// Find uses of `from` and replace them with `to`. Also notify the listener
256 /// about every in-place op modification (for every use that was replaced)
257 /// and that the `from` operation is about to be replaced.
258 MLIR_CAPI_EXPORTED
void mlirRewriterBaseReplaceAllOpUsesWithOperation(
259 MlirRewriterBase rewriter
, MlirOperation from
, MlirOperation to
);
261 /// Find uses of `from` within `block` and replace them with `to`. Also notify
262 /// the listener about every in-place op modification (for every use that was
263 /// replaced). The optional `allUsesReplaced` flag is set to "true" if all
264 /// uses were replaced.
265 MLIR_CAPI_EXPORTED
void mlirRewriterBaseReplaceOpUsesWithinBlock(
266 MlirRewriterBase rewriter
, MlirOperation op
, intptr_t nNewValues
,
267 MlirValue
const *newValues
, MlirBlock block
);
269 /// Find uses of `from` and replace them with `to` except if the user is
270 /// `exceptedUser`. Also notify the listener about every in-place op
271 /// modification (for every use that was replaced).
272 MLIR_CAPI_EXPORTED
void
273 mlirRewriterBaseReplaceAllUsesExcept(MlirRewriterBase rewriter
, MlirValue from
,
274 MlirValue to
, MlirOperation exceptedUser
);
276 //===----------------------------------------------------------------------===//
278 //===----------------------------------------------------------------------===//
280 /// Create an IRRewriter and transfer ownership to the caller.
281 MLIR_CAPI_EXPORTED MlirRewriterBase
mlirIRRewriterCreate(MlirContext context
);
283 /// Create an IRRewriter and transfer ownership to the caller. Additionally
284 /// set the insertion point before the operation.
285 MLIR_CAPI_EXPORTED MlirRewriterBase
286 mlirIRRewriterCreateFromOp(MlirOperation op
);
288 /// Takes an IRRewriter owned by the caller and destroys it. It is the
289 /// responsibility of the user to only pass an IRRewriter class.
290 MLIR_CAPI_EXPORTED
void mlirIRRewriterDestroy(MlirRewriterBase rewriter
);
292 //===----------------------------------------------------------------------===//
293 /// FrozenRewritePatternSet API
294 //===----------------------------------------------------------------------===//
296 MLIR_CAPI_EXPORTED MlirFrozenRewritePatternSet
297 mlirFreezeRewritePattern(MlirRewritePatternSet op
);
299 MLIR_CAPI_EXPORTED
void
300 mlirFrozenRewritePatternSetDestroy(MlirFrozenRewritePatternSet op
);
302 MLIR_CAPI_EXPORTED MlirLogicalResult
mlirApplyPatternsAndFoldGreedily(
303 MlirModule op
, MlirFrozenRewritePatternSet patterns
,
304 MlirGreedyRewriteDriverConfig
);
306 //===----------------------------------------------------------------------===//
307 /// PDLPatternModule API
308 //===----------------------------------------------------------------------===//
310 #if MLIR_ENABLE_PDL_IN_PATTERNMATCH
311 DEFINE_C_API_STRUCT(MlirPDLPatternModule
, void);
313 MLIR_CAPI_EXPORTED MlirPDLPatternModule
314 mlirPDLPatternModuleFromModule(MlirModule op
);
316 MLIR_CAPI_EXPORTED
void mlirPDLPatternModuleDestroy(MlirPDLPatternModule op
);
318 MLIR_CAPI_EXPORTED MlirRewritePatternSet
319 mlirRewritePatternSetFromPDLPatternModule(MlirPDLPatternModule op
);
320 #endif // MLIR_ENABLE_PDL_IN_PATTERNMATCH
322 #undef DEFINE_C_API_STRUCT
328 #endif // MLIR_C_REWRITE_H