Skip to content

Commit 5f8c46b

Browse files
authored
[mlir] Add RewriterBase to the C API (#98962)
This exposes most of the `RewriterBase` methods to the C API. This allows to manipulate both the `IRRewriter` and the `PatternRewriter`. The `IRRewriter` can be created from the C API, while the `PatternRewriter` cannot. The missing operations are the ones taking `Block::iterator` and `Region::iterator` as parameters, as they are not exposed by the C API yet AFAIK. The Python bindings for these methods and classes are not implemented.
1 parent 81704f6 commit 5f8c46b

File tree

7 files changed

+1088
-0
lines changed

7 files changed

+1088
-0
lines changed

mlir/include/mlir-c/Rewrite.h

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,266 @@ extern "C" {
3333
}; \
3434
typedef struct name name
3535

36+
DEFINE_C_API_STRUCT(MlirRewriterBase, void);
3637
DEFINE_C_API_STRUCT(MlirFrozenRewritePatternSet, void);
3738
DEFINE_C_API_STRUCT(MlirGreedyRewriteDriverConfig, void);
3839
DEFINE_C_API_STRUCT(MlirRewritePatternSet, void);
3940

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+
40296
MLIR_CAPI_EXPORTED MlirFrozenRewritePatternSet
41297
mlirFreezeRewritePattern(MlirRewritePatternSet op);
42298

@@ -47,6 +303,10 @@ MLIR_CAPI_EXPORTED MlirLogicalResult mlirApplyPatternsAndFoldGreedily(
47303
MlirModule op, MlirFrozenRewritePatternSet patterns,
48304
MlirGreedyRewriteDriverConfig);
49305

306+
//===----------------------------------------------------------------------===//
307+
/// PDLPatternModule API
308+
//===----------------------------------------------------------------------===//
309+
50310
#if MLIR_ENABLE_PDL_IN_PATTERNMATCH
51311
DEFINE_C_API_STRUCT(MlirPDLPatternModule, void);
52312

mlir/include/mlir/CAPI/Rewrite.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===- Rewrite.h - C API Utils for Core MLIR classes ------------*- 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 contains declarations of implementation details of the C API for
10+
// rewrite patterns. This file should not be included from C++ code other than
11+
// C API implementation nor from C code.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef MLIR_CAPI_REWRITE_H
16+
#define MLIR_CAPI_REWRITE_H
17+
18+
#include "mlir/CAPI/Wrap.h"
19+
#include "mlir/IR/PatternMatch.h"
20+
21+
DEFINE_C_API_PTR_METHODS(MlirRewriterBase, mlir::RewriterBase);
22+
23+
#endif // MLIR_CAPIREWRITER_H

0 commit comments

Comments
 (0)