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