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 // 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. 55 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); 61 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, 66 MlirOperation op); 67 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, 72 MlirOperation op); 73 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, 81 MlirValue value); 82 83 /// Sets the insertion point to the start of the specified block. 84 MLIR_CAPI_EXPORTED void 85 mlirRewriterBaseSetInsertionPointToStart(MlirRewriterBase rewriter, 86 MlirBlock block); 87 88 /// Sets the insertion point to the end of the specified block. 89 MLIR_CAPI_EXPORTED void 90 mlirRewriterBaseSetInsertionPointToEnd(MlirRewriterBase rewriter, 91 MlirBlock block); 92 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); 97 98 /// Returns the current block of the rewriter. 99 MLIR_CAPI_EXPORTED MlirBlock 100 mlirRewriterBaseGetBlock(MlirRewriterBase rewriter); 101 102 //===----------------------------------------------------------------------===// 103 /// Block and operation creation/insertion/cloning 104 105 // These functions do not include the IRMapper, as it is not yet exposed by the 106 // C API. 107 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 111 /// `argTypes`. 112 MLIR_CAPI_EXPORTED MlirBlock mlirRewriterBaseCreateBlockBefore( 113 MlirRewriterBase rewriter, MlirBlock insertBefore, intptr_t nArgTypes, 114 MlirType const *argTypes, MlirLocation const *locations); 115 116 /// Insert the given operation at the current insertion point and return it. 117 MLIR_CAPI_EXPORTED MlirOperation 118 mlirRewriterBaseInsert(MlirRewriterBase rewriter, MlirOperation op); 119 120 /// Creates a deep copy of the specified operation. 121 MLIR_CAPI_EXPORTED MlirOperation 122 mlirRewriterBaseClone(MlirRewriterBase rewriter, MlirOperation op); 123 124 /// Creates a deep copy of this operation but keep the operation regions 125 /// empty. 126 MLIR_CAPI_EXPORTED MlirOperation mlirRewriterBaseCloneWithoutRegions( 127 MlirRewriterBase rewriter, MlirOperation op); 128 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, 133 MlirBlock before); 134 135 //===----------------------------------------------------------------------===// 136 /// RewriterBase API 137 //===----------------------------------------------------------------------===// 138 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, 145 MlirBlock before); 146 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); 153 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); 160 161 /// Erases an operation that is known to have no uses. 162 MLIR_CAPI_EXPORTED void mlirRewriterBaseEraseOp(MlirRewriterBase rewriter, 163 MlirOperation op); 164 165 /// Erases a block along with all operations inside it. 166 MLIR_CAPI_EXPORTED void mlirRewriterBaseEraseBlock(MlirRewriterBase rewriter, 167 MlirBlock block); 168 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' 172 /// 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); 179 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' 183 /// 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, 187 MlirBlock source, 188 MlirBlock dest, 189 intptr_t nArgValues, 190 MlirValue const *argValues); 191 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 194 /// function. 195 MLIR_CAPI_EXPORTED void mlirRewriterBaseMoveOpBefore(MlirRewriterBase rewriter, 196 MlirOperation op, 197 MlirOperation existingOp); 198 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 201 /// function. 202 MLIR_CAPI_EXPORTED void mlirRewriterBaseMoveOpAfter(MlirRewriterBase rewriter, 203 MlirOperation op, 204 MlirOperation existingOp); 205 206 /// Unlink this block and insert it right before `existingBlock`. 207 MLIR_CAPI_EXPORTED void 208 mlirRewriterBaseMoveBlockBefore(MlirRewriterBase rewriter, MlirBlock block, 209 MlirBlock existingBlock); 210 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, 219 MlirOperation op); 220 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, 226 MlirOperation op); 227 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, 233 MlirOperation op); 234 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, 239 MlirValue to); 240 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); 246 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); 254 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); 260 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); 268 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); 275 276 //===----------------------------------------------------------------------===// 277 /// IRRewriter API 278 //===----------------------------------------------------------------------===// 279 280 /// Create an IRRewriter and transfer ownership to the caller. 281 MLIR_CAPI_EXPORTED MlirRewriterBase mlirIRRewriterCreate(MlirContext context); 282 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); 287 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); 291 292 //===----------------------------------------------------------------------===// 293 /// FrozenRewritePatternSet API 294 //===----------------------------------------------------------------------===// 295 296 MLIR_CAPI_EXPORTED MlirFrozenRewritePatternSet 297 mlirFreezeRewritePattern(MlirRewritePatternSet op); 298 299 MLIR_CAPI_EXPORTED void 300 mlirFrozenRewritePatternSetDestroy(MlirFrozenRewritePatternSet op); 301 302 MLIR_CAPI_EXPORTED MlirLogicalResult mlirApplyPatternsAndFoldGreedily( 303 MlirModule op, MlirFrozenRewritePatternSet patterns, 304 MlirGreedyRewriteDriverConfig); 305 306 //===----------------------------------------------------------------------===// 307 /// PDLPatternModule API 308 //===----------------------------------------------------------------------===// 309 310 #if MLIR_ENABLE_PDL_IN_PATTERNMATCH 311 DEFINE_C_API_STRUCT(MlirPDLPatternModule, void); 312 313 MLIR_CAPI_EXPORTED MlirPDLPatternModule 314 mlirPDLPatternModuleFromModule(MlirModule op); 315 316 MLIR_CAPI_EXPORTED void mlirPDLPatternModuleDestroy(MlirPDLPatternModule op); 317 318 MLIR_CAPI_EXPORTED MlirRewritePatternSet 319 mlirRewritePatternSetFromPDLPatternModule(MlirPDLPatternModule op); 320 #endif // MLIR_ENABLE_PDL_IN_PATTERNMATCH 321 322 #undef DEFINE_C_API_STRUCT 323 324 #ifdef __cplusplus 325 } 326 #endif 327 328 #endif // MLIR_C_REWRITE_H 329