annotate mlir/docs/DialectConversion.md @ 220:42394fc6a535

Added tag llvm12 for changeset 0572611fdcc8
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 15 Jun 2021 19:13:43 +0900
parents 0572611fdcc8
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 # Dialect Conversion
anatofuz
parents:
diff changeset
2
anatofuz
parents:
diff changeset
3 This document describes a framework in MLIR in which to perform operation
anatofuz
parents:
diff changeset
4 conversions between, and within dialects. This framework allows for transforming
anatofuz
parents:
diff changeset
5 illegal operations to those supported by a provided conversion target, via a set
anatofuz
parents:
diff changeset
6 of pattern-based operation rewriting patterns.
anatofuz
parents:
diff changeset
7
anatofuz
parents:
diff changeset
8 [TOC]
anatofuz
parents:
diff changeset
9
anatofuz
parents:
diff changeset
10 To utilize the framework, a few things must be provided:
anatofuz
parents:
diff changeset
11
anatofuz
parents:
diff changeset
12 * A [Conversion Target](#conversion-target)
anatofuz
parents:
diff changeset
13 * A set of [Rewrite Patterns](#rewrite-pattern-specification)
anatofuz
parents:
diff changeset
14 * A [Type Converter](#type-conversion) (Optional)
anatofuz
parents:
diff changeset
15
anatofuz
parents:
diff changeset
16 ## Modes of Conversion
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 When applying a conversion to a set of operations, there are several conversion
anatofuz
parents:
diff changeset
19 modes that can be selected from:
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 * Partial Conversion
anatofuz
parents:
diff changeset
22
anatofuz
parents:
diff changeset
23 - A partial conversion will legalize as many operations to the target as
anatofuz
parents:
diff changeset
24 possible, but will allow pre-existing operations that were not
anatofuz
parents:
diff changeset
25 explicitly marked as `illegal` to remain unconverted. This allows for
anatofuz
parents:
diff changeset
26 partially lowering parts of the module in the presence of unknown
anatofuz
parents:
diff changeset
27 operations.
anatofuz
parents:
diff changeset
28 - A partial conversion can be applied via `applyPartialConversion`.
anatofuz
parents:
diff changeset
29
anatofuz
parents:
diff changeset
30 * Full Conversion
anatofuz
parents:
diff changeset
31
anatofuz
parents:
diff changeset
32 - A full conversion is only successful if all operations are properly
anatofuz
parents:
diff changeset
33 legalized to the given conversion target. This ensures that only known
anatofuz
parents:
diff changeset
34 operations will exist after the conversion process.
anatofuz
parents:
diff changeset
35 - A full conversion can be applied via `applyFullConversion`.
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 * Analysis Conversion
anatofuz
parents:
diff changeset
38
anatofuz
parents:
diff changeset
39 - An analysis conversion will analyze which operations are legalizable to
anatofuz
parents:
diff changeset
40 the given conversion target if a conversion were to be applied. Note
anatofuz
parents:
diff changeset
41 that no rewrites, or transformations, are actually applied to the input
anatofuz
parents:
diff changeset
42 operations.
anatofuz
parents:
diff changeset
43 - An analysis conversion can be applied via `applyAnalysisConversion`.
anatofuz
parents:
diff changeset
44
anatofuz
parents:
diff changeset
45 ## Conversion Target
anatofuz
parents:
diff changeset
46
anatofuz
parents:
diff changeset
47 The conversion target is the formal definition of what is considered to be legal
anatofuz
parents:
diff changeset
48 during the conversion process. The final operations generated by the conversion
anatofuz
parents:
diff changeset
49 framework must be marked as legal on the `ConversionTarget` for the rewrite to
anatofuz
parents:
diff changeset
50 be a success. Existing operations need not always be legal, though; see the
anatofuz
parents:
diff changeset
51 different conversion modes for why. Operations and dialects may be marked with
anatofuz
parents:
diff changeset
52 any of the provided legality actions below:
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54 * Legal
anatofuz
parents:
diff changeset
55
anatofuz
parents:
diff changeset
56 - This action signals that every instance of a given operation is legal,
anatofuz
parents:
diff changeset
57 i.e. any combination of attributes, operands, types, etc. are valid.
anatofuz
parents:
diff changeset
58
anatofuz
parents:
diff changeset
59 * Dynamic
anatofuz
parents:
diff changeset
60
anatofuz
parents:
diff changeset
61 - This action signals that only some instances of a given operation are
anatofuz
parents:
diff changeset
62 legal. This allows for defining fine-tune constraints, e.g. saying that
anatofuz
parents:
diff changeset
63 `addi` is only legal when operating on 32-bit integers.
anatofuz
parents:
diff changeset
64 - If a specific handler is not provided when setting the action, the
anatofuz
parents:
diff changeset
65 target must override the `isDynamicallyLegal` hook provided by
anatofuz
parents:
diff changeset
66 `ConversionTarget`.
anatofuz
parents:
diff changeset
67
anatofuz
parents:
diff changeset
68 * Illegal
anatofuz
parents:
diff changeset
69
anatofuz
parents:
diff changeset
70 - This action signals that no instance of a given operation is legal.
anatofuz
parents:
diff changeset
71 Operations marked as `illegal` must always be converted for the
anatofuz
parents:
diff changeset
72 conversion to be successful. This action also allows for selectively
anatofuz
parents:
diff changeset
73 marking specific operations as illegal in an otherwise legal dialect.
anatofuz
parents:
diff changeset
74
anatofuz
parents:
diff changeset
75 An example conversion target is shown below:
anatofuz
parents:
diff changeset
76
anatofuz
parents:
diff changeset
77 ```c++
anatofuz
parents:
diff changeset
78 struct MyTarget : public ConversionTarget {
anatofuz
parents:
diff changeset
79 MyTarget(MLIRContext &ctx) : ConversionTarget(ctx) {
anatofuz
parents:
diff changeset
80 //--------------------------------------------------------------------------
anatofuz
parents:
diff changeset
81 // Marking an operation as Legal:
anatofuz
parents:
diff changeset
82
anatofuz
parents:
diff changeset
83 /// Mark all operations within the LLVM dialect are legal.
anatofuz
parents:
diff changeset
84 addLegalDialects<LLVMDialect>();
anatofuz
parents:
diff changeset
85
anatofuz
parents:
diff changeset
86 /// Mark `std.constant` op is always legal on this target.
anatofuz
parents:
diff changeset
87 addLegalOps<ConstantOp>();
anatofuz
parents:
diff changeset
88
anatofuz
parents:
diff changeset
89 //--------------------------------------------------------------------------
anatofuz
parents:
diff changeset
90 // Marking an operation as dynamically legal.
anatofuz
parents:
diff changeset
91
anatofuz
parents:
diff changeset
92 /// Mark all operations within Affine dialect have dynamic legality
anatofuz
parents:
diff changeset
93 /// constraints.
anatofuz
parents:
diff changeset
94 addDynamicallyLegalDialects<AffineDialect>();
anatofuz
parents:
diff changeset
95
anatofuz
parents:
diff changeset
96 /// Mark `std.return` as dynamically legal.
anatofuz
parents:
diff changeset
97 addDynamicallyLegalOp<ReturnOp>();
anatofuz
parents:
diff changeset
98
anatofuz
parents:
diff changeset
99 /// Mark `std.return` as dynamically legal, but provide a specific legality
anatofuz
parents:
diff changeset
100 /// callback.
anatofuz
parents:
diff changeset
101 addDynamicallyLegalOp<ReturnOp>([](ReturnOp op) { ... });
anatofuz
parents:
diff changeset
102
anatofuz
parents:
diff changeset
103 /// Treat unknown operations, i.e. those without a legalization action
anatofuz
parents:
diff changeset
104 /// directly set, as dynamically legal.
anatofuz
parents:
diff changeset
105 markUnknownOpDynamicallyLegal();
anatofuz
parents:
diff changeset
106 markUnknownOpDynamicallyLegal([](Operation *op) { ... });
anatofuz
parents:
diff changeset
107
anatofuz
parents:
diff changeset
108 //--------------------------------------------------------------------------
anatofuz
parents:
diff changeset
109 // Marking an operation as illegal.
anatofuz
parents:
diff changeset
110
anatofuz
parents:
diff changeset
111 /// All operations within the GPU dialect are illegal.
anatofuz
parents:
diff changeset
112 addIllegalDialect<GPUDialect>();
anatofuz
parents:
diff changeset
113
anatofuz
parents:
diff changeset
114 /// Mark `std.br` and `std.cond_br` as illegal.
anatofuz
parents:
diff changeset
115 addIllegalOp<BranchOp, CondBranchOp>();
anatofuz
parents:
diff changeset
116 }
anatofuz
parents:
diff changeset
117
anatofuz
parents:
diff changeset
118 /// Implement the default legalization handler to handle operations marked as
anatofuz
parents:
diff changeset
119 /// dynamically legal that were not provided with an explicit handler.
anatofuz
parents:
diff changeset
120 bool isDynamicallyLegal(Operation *op) override { ... }
anatofuz
parents:
diff changeset
121 };
anatofuz
parents:
diff changeset
122 ```
anatofuz
parents:
diff changeset
123
anatofuz
parents:
diff changeset
124 ### Recursive Legality
anatofuz
parents:
diff changeset
125
anatofuz
parents:
diff changeset
126 In some cases, it may be desirable to mark entire regions of operations as
anatofuz
parents:
diff changeset
127 legal. This provides an additional granularity of context to the concept of
anatofuz
parents:
diff changeset
128 "legal". The `ConversionTarget` supports marking operations, that were
anatofuz
parents:
diff changeset
129 previously added as `Legal` or `Dynamic`, as `recursively` legal. Recursive
anatofuz
parents:
diff changeset
130 legality means that if an operation instance is legal, either statically or
anatofuz
parents:
diff changeset
131 dynamically, all of the operations nested within are also considered legal. An
anatofuz
parents:
diff changeset
132 operation can be marked via `markOpRecursivelyLegal<>`:
anatofuz
parents:
diff changeset
133
anatofuz
parents:
diff changeset
134 ```c++
anatofuz
parents:
diff changeset
135 ConversionTarget &target = ...;
anatofuz
parents:
diff changeset
136
anatofuz
parents:
diff changeset
137 /// The operation must first be marked as `Legal` or `Dynamic`.
anatofuz
parents:
diff changeset
138 target.addLegalOp<MyOp>(...);
anatofuz
parents:
diff changeset
139 target.addDynamicallyLegalOp<MySecondOp>(...);
anatofuz
parents:
diff changeset
140
anatofuz
parents:
diff changeset
141 /// Mark the operation as always recursively legal.
anatofuz
parents:
diff changeset
142 target.markOpRecursivelyLegal<MyOp>();
anatofuz
parents:
diff changeset
143 /// Mark optionally with a callback to allow selective marking.
anatofuz
parents:
diff changeset
144 target.markOpRecursivelyLegal<MyOp, MySecondOp>([](Operation *op) { ... });
anatofuz
parents:
diff changeset
145 /// Mark optionally with a callback to allow selective marking.
anatofuz
parents:
diff changeset
146 target.markOpRecursivelyLegal<MyOp>([](MyOp op) { ... });
anatofuz
parents:
diff changeset
147 ```
anatofuz
parents:
diff changeset
148
anatofuz
parents:
diff changeset
149 ## Rewrite Pattern Specification
anatofuz
parents:
diff changeset
150
anatofuz
parents:
diff changeset
151 After the conversion target has been defined, a set of legalization patterns
anatofuz
parents:
diff changeset
152 must be provided to transform illegal operations into legal ones. The patterns
anatofuz
parents:
diff changeset
153 supplied here, that do not [require type changes](#conversion-patterns), are the
anatofuz
parents:
diff changeset
154 same as those described in the
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
155 [quickstart rewrites guide](Tutorials/QuickstartRewrites.md#adding-patterns), but have a
150
anatofuz
parents:
diff changeset
156 few additional [restrictions](#restrictions). The patterns provided do not need
anatofuz
parents:
diff changeset
157 to generate operations that are directly legal on the target. The framework will
anatofuz
parents:
diff changeset
158 automatically build a graph of conversions to convert non-legal operations into
anatofuz
parents:
diff changeset
159 a set of legal ones.
anatofuz
parents:
diff changeset
160
anatofuz
parents:
diff changeset
161 As an example, say you define a target that supports one operation: `foo.add`.
anatofuz
parents:
diff changeset
162 When providing the following patterns: [`bar.add` -> `baz.add`, `baz.add` ->
anatofuz
parents:
diff changeset
163 `foo.add`], the framework will automatically detect that it can legalize
anatofuz
parents:
diff changeset
164 `baz.add` -> `foo.add` even though a direct conversion does not exist. This
anatofuz
parents:
diff changeset
165 means that you don’t have to define a direct legalization pattern for `bar.add`
anatofuz
parents:
diff changeset
166 -> `foo.add`.
anatofuz
parents:
diff changeset
167
anatofuz
parents:
diff changeset
168 ### Restrictions
anatofuz
parents:
diff changeset
169
anatofuz
parents:
diff changeset
170 The framework processes operations in topological order, trying to legalize them
anatofuz
parents:
diff changeset
171 individually. As such, patterns used in the conversion framework have a few
anatofuz
parents:
diff changeset
172 additional restrictions:
anatofuz
parents:
diff changeset
173
anatofuz
parents:
diff changeset
174 1. If a pattern matches, it must erase or replace the op it matched on.
anatofuz
parents:
diff changeset
175 Operations can *not* be updated in place.
anatofuz
parents:
diff changeset
176 2. Match criteria should not be based on the IR outside of the op itself. The
anatofuz
parents:
diff changeset
177 preceding ops will already have been processed by the framework (although it
anatofuz
parents:
diff changeset
178 may not update uses), and the subsequent IR will not yet be processed. This
anatofuz
parents:
diff changeset
179 can create confusion if a pattern attempts to match against a sequence of
anatofuz
parents:
diff changeset
180 ops (e.g. rewrite A + B -> C). That sort of rewrite should be performed in a
anatofuz
parents:
diff changeset
181 separate pass.
anatofuz
parents:
diff changeset
182
anatofuz
parents:
diff changeset
183 ## Type Conversion
anatofuz
parents:
diff changeset
184
anatofuz
parents:
diff changeset
185 It is sometimes necessary as part of a conversion to convert the set types of
anatofuz
parents:
diff changeset
186 being operated on. In these cases, a `TypeConverter` object may be defined that
anatofuz
parents:
diff changeset
187 details how types should be converted. The `TypeConverter` is used by patterns
anatofuz
parents:
diff changeset
188 and by the general conversion infrastructure to convert the signatures of blocks
anatofuz
parents:
diff changeset
189 and regions.
anatofuz
parents:
diff changeset
190
anatofuz
parents:
diff changeset
191 ### Type Converter
anatofuz
parents:
diff changeset
192
anatofuz
parents:
diff changeset
193 As stated above, the `TypeConverter` contains several hooks for detailing how to
anatofuz
parents:
diff changeset
194 convert types. Several of these hooks are detailed below:
anatofuz
parents:
diff changeset
195
anatofuz
parents:
diff changeset
196 ```c++
anatofuz
parents:
diff changeset
197 class TypeConverter {
anatofuz
parents:
diff changeset
198 public:
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
199 /// Register a conversion function. A conversion function must be convertible
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
200 /// to any of the following forms(where `T` is a class derived from `Type`:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
201 /// * Optional<Type>(T)
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
202 /// - This form represents a 1-1 type conversion. It should return nullptr
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
203 /// or `llvm::None` to signify failure. If `llvm::None` is returned, the
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
204 /// converter is allowed to try another conversion function to perform
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
205 /// the conversion.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
206 /// * Optional<LogicalResult>(T, SmallVectorImpl<Type> &)
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
207 /// - This form represents a 1-N type conversion. It should return
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
208 /// `failure` or `llvm::None` to signify a failed conversion. If the new
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
209 /// set of types is empty, the type is removed and any usages of the
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
210 /// existing value are expected to be removed during conversion. If
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
211 /// `llvm::None` is returned, the converter is allowed to try another
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
212 /// conversion function to perform the conversion.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
213 ///
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
214 /// When attempting to convert a type, e.g. via `convertType`, the
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
215 /// `TypeConverter` will invoke each of the converters starting with the one
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
216 /// most recently registered.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
217 template <typename ConversionFnT>
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
218 void addConversion(ConversionFnT &&callback);
150
anatofuz
parents:
diff changeset
219
anatofuz
parents:
diff changeset
220 /// This hook allows for materializing a conversion from a set of types into
anatofuz
parents:
diff changeset
221 /// one result type by generating a cast operation of some kind. The generated
anatofuz
parents:
diff changeset
222 /// operation should produce one result, of 'resultType', with the provided
anatofuz
parents:
diff changeset
223 /// 'inputs' as operands. This hook must be overridden when a type conversion
anatofuz
parents:
diff changeset
224 /// results in more than one type, or if a type conversion may persist after
anatofuz
parents:
diff changeset
225 /// the conversion has finished.
anatofuz
parents:
diff changeset
226 virtual Operation *materializeConversion(PatternRewriter &rewriter,
anatofuz
parents:
diff changeset
227 Type resultType,
anatofuz
parents:
diff changeset
228 ArrayRef<Value> inputs,
anatofuz
parents:
diff changeset
229 Location loc);
anatofuz
parents:
diff changeset
230 };
anatofuz
parents:
diff changeset
231 ```
anatofuz
parents:
diff changeset
232
anatofuz
parents:
diff changeset
233 ### Conversion Patterns
anatofuz
parents:
diff changeset
234
anatofuz
parents:
diff changeset
235 When type conversion comes into play, the general Rewrite Patterns can no longer
anatofuz
parents:
diff changeset
236 be used. This is due to the fact that the operands of the operation being
anatofuz
parents:
diff changeset
237 matched will not correspond with the operands of the correct type as determined
anatofuz
parents:
diff changeset
238 by `TypeConverter`. The operation rewrites on type boundaries must thus use a
anatofuz
parents:
diff changeset
239 special pattern, the `ConversionPattern`. This pattern provides, as an
anatofuz
parents:
diff changeset
240 additional argument to the `matchAndRewrite` and `rewrite` methods, the set of
anatofuz
parents:
diff changeset
241 remapped operands corresponding to the desired type. These patterns also utilize
anatofuz
parents:
diff changeset
242 a special `PatternRewriter`, `ConversionPatternRewriter`, that provides special
anatofuz
parents:
diff changeset
243 hooks for use with the conversion infrastructure.
anatofuz
parents:
diff changeset
244
anatofuz
parents:
diff changeset
245 ```c++
anatofuz
parents:
diff changeset
246 struct MyConversionPattern : public ConversionPattern {
anatofuz
parents:
diff changeset
247 /// The `matchAndRewrite` hooks on ConversionPatterns take an additional
anatofuz
parents:
diff changeset
248 /// `operands` parameter, containing the remapped operands of the original
anatofuz
parents:
diff changeset
249 /// operation.
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
250 virtual LogicalResult
150
anatofuz
parents:
diff changeset
251 matchAndRewrite(Operation *op, ArrayRef<Value> operands,
anatofuz
parents:
diff changeset
252 ConversionPatternRewriter &rewriter) const;
anatofuz
parents:
diff changeset
253 };
anatofuz
parents:
diff changeset
254 ```
anatofuz
parents:
diff changeset
255
anatofuz
parents:
diff changeset
256 These patterns have the same [restrictions](#restrictions) as the basic rewrite
anatofuz
parents:
diff changeset
257 patterns used in dialect conversion.
anatofuz
parents:
diff changeset
258
anatofuz
parents:
diff changeset
259 ### Region Signature Conversion
anatofuz
parents:
diff changeset
260
anatofuz
parents:
diff changeset
261 From the perspective of type conversion, the entry block to a region is often
anatofuz
parents:
diff changeset
262 special. The types of the entry block arguments are often tied semantically to
anatofuz
parents:
diff changeset
263 details on the operation, e.g. FuncOp, AffineForOp, etc. Given this, the
anatofuz
parents:
diff changeset
264 conversion of the types for this block must be done explicitly via a conversion
anatofuz
parents:
diff changeset
265 pattern. To convert the signature of a region entry block, a custom hook on the
anatofuz
parents:
diff changeset
266 ConversionPatternRewriter must be invoked `applySignatureConversion`. A
anatofuz
parents:
diff changeset
267 signature conversion, `TypeConverter::SignatureConversion`, can be built
anatofuz
parents:
diff changeset
268 programmatically:
anatofuz
parents:
diff changeset
269
anatofuz
parents:
diff changeset
270 ```c++
anatofuz
parents:
diff changeset
271 class SignatureConversion {
anatofuz
parents:
diff changeset
272 public:
anatofuz
parents:
diff changeset
273 /// Remap an input of the original signature with a new set of types. The
anatofuz
parents:
diff changeset
274 /// new types are appended to the new signature conversion.
anatofuz
parents:
diff changeset
275 void addInputs(unsigned origInputNo, ArrayRef<Type> types);
anatofuz
parents:
diff changeset
276
anatofuz
parents:
diff changeset
277 /// Append new input types to the signature conversion, this should only be
anatofuz
parents:
diff changeset
278 /// used if the new types are not intended to remap an existing input.
anatofuz
parents:
diff changeset
279 void addInputs(ArrayRef<Type> types);
anatofuz
parents:
diff changeset
280
anatofuz
parents:
diff changeset
281 /// Remap an input of the original signature with a range of types in the
anatofuz
parents:
diff changeset
282 /// new signature.
anatofuz
parents:
diff changeset
283 void remapInput(unsigned origInputNo, unsigned newInputNo,
anatofuz
parents:
diff changeset
284 unsigned newInputCount = 1);
anatofuz
parents:
diff changeset
285
anatofuz
parents:
diff changeset
286 /// Remap an input of the original signature to another `replacement`
anatofuz
parents:
diff changeset
287 /// value. This drops the original argument.
anatofuz
parents:
diff changeset
288 void remapInput(unsigned origInputNo, Value replacement);
anatofuz
parents:
diff changeset
289 };
anatofuz
parents:
diff changeset
290 ```
anatofuz
parents:
diff changeset
291
anatofuz
parents:
diff changeset
292 The `TypeConverter` provides several default utilities for signature conversion:
anatofuz
parents:
diff changeset
293 `convertSignatureArg`/`convertBlockSignature`.