MLIR  16.0.0git
DialectConversion.h
Go to the documentation of this file.
1 //===- DialectConversion.h - MLIR dialect conversion pass -------*- 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 declares a generic pass for converting between MLIR dialects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_TRANSFORMS_DIALECTCONVERSION_H_
14 #define MLIR_TRANSFORMS_DIALECTCONVERSION_H_
15 
17 #include "llvm/ADT/MapVector.h"
18 #include "llvm/ADT/StringMap.h"
19 #include <type_traits>
20 
21 namespace mlir {
22 
23 // Forward declarations.
24 class Block;
25 class ConversionPatternRewriter;
26 class MLIRContext;
27 class Operation;
28 class Type;
29 class Value;
30 
31 //===----------------------------------------------------------------------===//
32 // Type Conversion
33 //===----------------------------------------------------------------------===//
34 
35 /// Type conversion class. Specific conversions and materializations can be
36 /// registered using addConversion and addMaterialization, respectively.
38 public:
39  /// This class provides all of the information necessary to convert a type
40  /// signature.
42  public:
43  SignatureConversion(unsigned numOrigInputs)
44  : remappedInputs(numOrigInputs) {}
45 
46  /// This struct represents a range of new types or a single value that
47  /// remaps an existing signature input.
48  struct InputMapping {
49  size_t inputNo, size;
51  };
52 
53  /// Return the argument types for the new signature.
54  ArrayRef<Type> getConvertedTypes() const { return argTypes; }
55 
56  /// Get the input mapping for the given argument.
57  Optional<InputMapping> getInputMapping(unsigned input) const {
58  return remappedInputs[input];
59  }
60 
61  //===------------------------------------------------------------------===//
62  // Conversion Hooks
63  //===------------------------------------------------------------------===//
64 
65  /// Remap an input of the original signature with a new set of types. The
66  /// new types are appended to the new signature conversion.
67  void addInputs(unsigned origInputNo, ArrayRef<Type> types);
68 
69  /// Append new input types to the signature conversion, this should only be
70  /// used if the new types are not intended to remap an existing input.
71  void addInputs(ArrayRef<Type> types);
72 
73  /// Remap an input of the original signature to another `replacement`
74  /// value. This drops the original argument.
75  void remapInput(unsigned origInputNo, Value replacement);
76 
77  private:
78  /// Remap an input of the original signature with a range of types in the
79  /// new signature.
80  void remapInput(unsigned origInputNo, unsigned newInputNo,
81  unsigned newInputCount = 1);
82 
83  /// The remapping information for each of the original arguments.
84  SmallVector<Optional<InputMapping>, 4> remappedInputs;
85 
86  /// The set of new argument types.
87  SmallVector<Type, 4> argTypes;
88  };
89 
90  /// Register a conversion function. A conversion function must be convertible
91  /// to any of the following forms(where `T` is a class derived from `Type`:
92  /// * Optional<Type>(T)
93  /// - This form represents a 1-1 type conversion. It should return nullptr
94  /// or `llvm::None` to signify failure. If `llvm::None` is returned, the
95  /// converter is allowed to try another conversion function to perform
96  /// the conversion.
97  /// * Optional<LogicalResult>(T, SmallVectorImpl<Type> &)
98  /// - This form represents a 1-N type conversion. It should return
99  /// `failure` or `llvm::None` to signify a failed conversion. If the new
100  /// set of types is empty, the type is removed and any usages of the
101  /// existing value are expected to be removed during conversion. If
102  /// `llvm::None` is returned, the converter is allowed to try another
103  /// conversion function to perform the conversion.
104  /// * Optional<LogicalResult>(T, SmallVectorImpl<Type> &, ArrayRef<Type>)
105  /// - This form represents a 1-N type conversion supporting recursive
106  /// types. The first two arguments and the return value are the same as
107  /// for the regular 1-N form. The third argument is contains is the
108  /// "call stack" of the recursive conversion: it contains the list of
109  /// types currently being converted, with the current type being the
110  /// last one. If it is present more than once in the list, the
111  /// conversion concerns a recursive type.
112  /// Note: When attempting to convert a type, e.g. via 'convertType', the
113  /// mostly recently added conversions will be invoked first.
114  template <typename FnT, typename T = typename llvm::function_traits<
115  std::decay_t<FnT>>::template arg_t<0>>
116  void addConversion(FnT &&callback) {
117  registerConversion(wrapCallback<T>(std::forward<FnT>(callback)));
118  }
119 
120  /// Register a materialization function, which must be convertible to the
121  /// following form:
122  /// `Optional<Value>(OpBuilder &, T, ValueRange, Location)`,
123  /// where `T` is any subclass of `Type`. This function is responsible for
124  /// creating an operation, using the OpBuilder and Location provided, that
125  /// "casts" a range of values into a single value of the given type `T`. It
126  /// must return a Value of the converted type on success, an `llvm::None` if
127  /// it failed but other materialization can be attempted, and `nullptr` on
128  /// unrecoverable failure. It will only be called for (sub)types of `T`.
129  /// Materialization functions must be provided when a type conversion may
130  /// persist after the conversion has finished.
131  ///
132  /// This method registers a materialization that will be called when
133  /// converting an illegal block argument type, to a legal type.
134  template <typename FnT, typename T = typename llvm::function_traits<
135  std::decay_t<FnT>>::template arg_t<1>>
136  void addArgumentMaterialization(FnT &&callback) {
137  argumentMaterializations.emplace_back(
138  wrapMaterialization<T>(std::forward<FnT>(callback)));
139  }
140  /// This method registers a materialization that will be called when
141  /// converting a legal type to an illegal source type. This is used when
142  /// conversions to an illegal type must persist beyond the main conversion.
143  template <typename FnT, typename T = typename llvm::function_traits<
144  std::decay_t<FnT>>::template arg_t<1>>
145  void addSourceMaterialization(FnT &&callback) {
146  sourceMaterializations.emplace_back(
147  wrapMaterialization<T>(std::forward<FnT>(callback)));
148  }
149  /// This method registers a materialization that will be called when
150  /// converting type from an illegal, or source, type to a legal type.
151  template <typename FnT, typename T = typename llvm::function_traits<
152  std::decay_t<FnT>>::template arg_t<1>>
153  void addTargetMaterialization(FnT &&callback) {
154  targetMaterializations.emplace_back(
155  wrapMaterialization<T>(std::forward<FnT>(callback)));
156  }
157 
158  /// Convert the given type. This function should return failure if no valid
159  /// conversion exists, success otherwise. If the new set of types is empty,
160  /// the type is removed and any usages of the existing value are expected to
161  /// be removed during conversion.
163 
164  /// This hook simplifies defining 1-1 type conversions. This function returns
165  /// the type to convert to on success, and a null type on failure.
166  Type convertType(Type t);
167 
168  /// Convert the given set of types, filling 'results' as necessary. This
169  /// returns failure if the conversion of any of the types fails, success
170  /// otherwise.
172 
173  /// Return true if the given type is legal for this type converter, i.e. the
174  /// type converts to itself.
175  bool isLegal(Type type);
176  /// Return true if all of the given types are legal for this type converter.
177  template <typename RangeT>
180  bool>
181  isLegal(RangeT &&range) {
182  return llvm::all_of(range, [this](Type type) { return isLegal(type); });
183  }
184  /// Return true if the given operation has legal operand and result types.
185  bool isLegal(Operation *op);
186 
187  /// Return true if the types of block arguments within the region are legal.
188  bool isLegal(Region *region);
189 
190  /// Return true if the inputs and outputs of the given function type are
191  /// legal.
192  bool isSignatureLegal(FunctionType ty);
193 
194  /// This method allows for converting a specific argument of a signature. It
195  /// takes as inputs the original argument input number, type.
196  /// On success, it populates 'result' with any new mappings.
197  LogicalResult convertSignatureArg(unsigned inputNo, Type type,
198  SignatureConversion &result);
200  SignatureConversion &result,
201  unsigned origInputOffset = 0);
202 
203  /// This function converts the type signature of the given block, by invoking
204  /// 'convertSignatureArg' for each argument. This function should return a
205  /// valid conversion for the signature on success, None otherwise.
207 
208  /// Materialize a conversion from a set of types into one result type by
209  /// generating a cast sequence of some kind. See the respective
210  /// `add*Materialization` for more information on the context for these
211  /// methods.
213  Type resultType, ValueRange inputs) {
214  return materializeConversion(argumentMaterializations, builder, loc,
215  resultType, inputs);
216  }
218  Type resultType, ValueRange inputs) {
219  return materializeConversion(sourceMaterializations, builder, loc,
220  resultType, inputs);
221  }
223  Type resultType, ValueRange inputs) {
224  return materializeConversion(targetMaterializations, builder, loc,
225  resultType, inputs);
226  }
227 
228 private:
229  /// The signature of the callback used to convert a type. If the new set of
230  /// types is empty, the type is removed and any usages of the existing value
231  /// are expected to be removed during conversion.
232  using ConversionCallbackFn = std::function<Optional<LogicalResult>(
234 
235  /// The signature of the callback used to materialize a conversion.
236  using MaterializationCallbackFn =
237  std::function<Optional<Value>(OpBuilder &, Type, ValueRange, Location)>;
238 
239  /// Attempt to materialize a conversion using one of the provided
240  /// materialization functions.
241  Value materializeConversion(
243  OpBuilder &builder, Location loc, Type resultType, ValueRange inputs);
244 
245  /// Generate a wrapper for the given callback. This allows for accepting
246  /// different callback forms, that all compose into a single version.
247  /// With callback of form: `Optional<Type>(T)`
248  template <typename T, typename FnT>
249  std::enable_if_t<std::is_invocable_v<FnT, T>, ConversionCallbackFn>
250  wrapCallback(FnT &&callback) {
251  return wrapCallback<T>(
252  [callback = std::forward<FnT>(callback)](
253  T type, SmallVectorImpl<Type> &results, ArrayRef<Type>) {
254  if (Optional<Type> resultOpt = callback(type)) {
255  bool wasSuccess = static_cast<bool>(resultOpt.value());
256  if (wasSuccess)
257  results.push_back(resultOpt.value());
258  return Optional<LogicalResult>(success(wasSuccess));
259  }
260  return Optional<LogicalResult>();
261  });
262  }
263  /// With callback of form: `Optional<LogicalResult>(T, SmallVectorImpl<Type>
264  /// &)`
265  template <typename T, typename FnT>
266  std::enable_if_t<std::is_invocable_v<FnT, T, SmallVectorImpl<Type> &>,
267  ConversionCallbackFn>
268  wrapCallback(FnT &&callback) {
269  return wrapCallback<T>(
270  [callback = std::forward<FnT>(callback)](
271  T type, SmallVectorImpl<Type> &results, ArrayRef<Type>) {
272  return callback(type, results);
273  });
274  }
275  /// With callback of form: `Optional<LogicalResult>(T, SmallVectorImpl<Type>
276  /// &, ArrayRef<Type>)`.
277  template <typename T, typename FnT>
278  std::enable_if_t<
279  std::is_invocable_v<FnT, T, SmallVectorImpl<Type> &, ArrayRef<Type>>,
280  ConversionCallbackFn>
281  wrapCallback(FnT &&callback) {
282  return [callback = std::forward<FnT>(callback)](
283  Type type, SmallVectorImpl<Type> &results,
284  ArrayRef<Type> callStack) -> Optional<LogicalResult> {
285  T derivedType = type.dyn_cast<T>();
286  if (!derivedType)
287  return llvm::None;
288  return callback(derivedType, results, callStack);
289  };
290  }
291 
292  /// Register a type conversion.
293  void registerConversion(ConversionCallbackFn callback) {
294  conversions.emplace_back(std::move(callback));
295  cachedDirectConversions.clear();
296  cachedMultiConversions.clear();
297  }
298 
299  /// Generate a wrapper for the given materialization callback. The callback
300  /// may take any subclass of `Type` and the wrapper will check for the target
301  /// type to be of the expected class before calling the callback.
302  template <typename T, typename FnT>
303  MaterializationCallbackFn wrapMaterialization(FnT &&callback) {
304  return [callback = std::forward<FnT>(callback)](
305  OpBuilder &builder, Type resultType, ValueRange inputs,
306  Location loc) -> Optional<Value> {
307  if (T derivedType = resultType.dyn_cast<T>())
308  return callback(builder, derivedType, inputs, loc);
309  return llvm::None;
310  };
311  }
312 
313  /// The set of registered conversion functions.
314  SmallVector<ConversionCallbackFn, 4> conversions;
315 
316  /// The list of registered materialization functions.
317  SmallVector<MaterializationCallbackFn, 2> argumentMaterializations;
318  SmallVector<MaterializationCallbackFn, 2> sourceMaterializations;
319  SmallVector<MaterializationCallbackFn, 2> targetMaterializations;
320 
321  /// A set of cached conversions to avoid recomputing in the common case.
322  /// Direct 1-1 conversions are the most common, so this cache stores the
323  /// successful 1-1 conversions as well as all failed conversions.
324  DenseMap<Type, Type> cachedDirectConversions;
325  /// This cache stores the successful 1->N conversions, where N != 1.
326  DenseMap<Type, SmallVector<Type, 2>> cachedMultiConversions;
327 
328  /// Stores the types that are being converted in the case when convertType
329  /// is being called recursively to convert nested types.
330  SmallVector<Type, 2> conversionCallStack;
331 };
332 
333 //===----------------------------------------------------------------------===//
334 // Conversion Patterns
335 //===----------------------------------------------------------------------===//
336 
337 /// Base class for the conversion patterns. This pattern class enables type
338 /// conversions, and other uses specific to the conversion framework. As such,
339 /// patterns of this type can only be used with the 'apply*' methods below.
341 public:
342  /// Hook for derived classes to implement rewriting. `op` is the (first)
343  /// operation matched by the pattern, `operands` is a list of the rewritten
344  /// operand values that are passed to `op`, `rewriter` can be used to emit the
345  /// new operations. This function should not fail. If some specific cases of
346  /// the operation are not supported, these cases should not be matched.
347  virtual void rewrite(Operation *op, ArrayRef<Value> operands,
348  ConversionPatternRewriter &rewriter) const {
349  llvm_unreachable("unimplemented rewrite");
350  }
351 
352  /// Hook for derived classes to implement combined matching and rewriting.
353  virtual LogicalResult
355  ConversionPatternRewriter &rewriter) const {
356  if (failed(match(op)))
357  return failure();
358  rewrite(op, operands, rewriter);
359  return success();
360  }
361 
362  /// Attempt to match and rewrite the IR root at the specified operation.
364  PatternRewriter &rewriter) const final;
365 
366  /// Return the type converter held by this pattern, or nullptr if the pattern
367  /// does not require type conversion.
369 
370  template <typename ConverterTy>
372  ConverterTy *>
374  return static_cast<ConverterTy *>(typeConverter);
375  }
376 
377 protected:
378  /// See `RewritePattern::RewritePattern` for information on the other
379  /// available constructors.
380  using RewritePattern::RewritePattern;
381  /// Construct a conversion pattern with the given converter, and forward the
382  /// remaining arguments to RewritePattern.
383  template <typename... Args>
385  : RewritePattern(std::forward<Args>(args)...),
387 
388 protected:
389  /// An optional type converter for use by this pattern.
391 
392 private:
394 };
395 
396 /// OpConversionPattern is a wrapper around ConversionPattern that allows for
397 /// matching and rewriting against an instance of a derived operation class as
398 /// opposed to a raw Operation.
399 template <typename SourceOp>
401 public:
402  using OpAdaptor = typename SourceOp::Adaptor;
403 
405  : ConversionPattern(SourceOp::getOperationName(), benefit, context) {}
407  PatternBenefit benefit = 1)
408  : ConversionPattern(typeConverter, SourceOp::getOperationName(), benefit,
409  context) {}
410 
411  /// Wrappers around the ConversionPattern methods that pass the derived op
412  /// type.
413  LogicalResult match(Operation *op) const final {
414  return match(cast<SourceOp>(op));
415  }
416  void rewrite(Operation *op, ArrayRef<Value> operands,
417  ConversionPatternRewriter &rewriter) const final {
418  rewrite(cast<SourceOp>(op), OpAdaptor(operands, op->getAttrDictionary()),
419  rewriter);
420  }
423  ConversionPatternRewriter &rewriter) const final {
424  return matchAndRewrite(cast<SourceOp>(op),
425  OpAdaptor(operands, op->getAttrDictionary()),
426  rewriter);
427  }
428 
429  /// Rewrite and Match methods that operate on the SourceOp type. These must be
430  /// overridden by the derived pattern class.
431  virtual LogicalResult match(SourceOp op) const {
432  llvm_unreachable("must override match or matchAndRewrite");
433  }
434  virtual void rewrite(SourceOp op, OpAdaptor adaptor,
435  ConversionPatternRewriter &rewriter) const {
436  llvm_unreachable("must override matchAndRewrite or a rewrite method");
437  }
438  virtual LogicalResult
439  matchAndRewrite(SourceOp op, OpAdaptor adaptor,
440  ConversionPatternRewriter &rewriter) const {
441  if (failed(match(op)))
442  return failure();
443  rewrite(op, adaptor, rewriter);
444  return success();
445  }
446 
447 private:
449 };
450 
451 /// OpInterfaceConversionPattern is a wrapper around ConversionPattern that
452 /// allows for matching and rewriting against an instance of an OpInterface
453 /// class as opposed to a raw Operation.
454 template <typename SourceOp>
456 public:
459  SourceOp::getInterfaceID(), benefit, context) {}
461  MLIRContext *context, PatternBenefit benefit = 1)
463  SourceOp::getInterfaceID(), benefit, context) {}
464 
465  /// Wrappers around the ConversionPattern methods that pass the derived op
466  /// type.
467  void rewrite(Operation *op, ArrayRef<Value> operands,
468  ConversionPatternRewriter &rewriter) const final {
469  rewrite(cast<SourceOp>(op), operands, rewriter);
470  }
473  ConversionPatternRewriter &rewriter) const final {
474  return matchAndRewrite(cast<SourceOp>(op), operands, rewriter);
475  }
476 
477  /// Rewrite and Match methods that operate on the SourceOp type. These must be
478  /// overridden by the derived pattern class.
479  virtual void rewrite(SourceOp op, ArrayRef<Value> operands,
480  ConversionPatternRewriter &rewriter) const {
481  llvm_unreachable("must override matchAndRewrite or a rewrite method");
482  }
483  virtual LogicalResult
484  matchAndRewrite(SourceOp op, ArrayRef<Value> operands,
485  ConversionPatternRewriter &rewriter) const {
486  if (failed(match(op)))
487  return failure();
488  rewrite(op, operands, rewriter);
489  return success();
490  }
491 
492 private:
494 };
495 
496 /// Add a pattern to the given pattern list to convert the signature of a
497 /// FunctionOpInterface op with the given type converter. This only supports
498 /// ops which use FunctionType to represent their type.
500  StringRef functionLikeOpName, RewritePatternSet &patterns,
501  TypeConverter &converter);
502 
503 template <typename FuncOpT>
505  RewritePatternSet &patterns, TypeConverter &converter) {
506  populateFunctionOpInterfaceTypeConversionPattern(FuncOpT::getOperationName(),
507  patterns, converter);
508 }
509 
511  RewritePatternSet &patterns, TypeConverter &converter);
512 
513 //===----------------------------------------------------------------------===//
514 // Conversion PatternRewriter
515 //===----------------------------------------------------------------------===//
516 
517 namespace detail {
518 struct ConversionPatternRewriterImpl;
519 } // namespace detail
520 
521 /// This class implements a pattern rewriter for use with ConversionPatterns. It
522 /// extends the base PatternRewriter and provides special conversion specific
523 /// hooks.
525 public:
526  explicit ConversionPatternRewriter(MLIRContext *ctx);
528 
529  /// Apply a signature conversion to the entry block of the given region. This
530  /// replaces the entry block with a new block containing the updated
531  /// signature. The new entry block to the region is returned for convenience.
532  ///
533  /// If provided, `converter` will be used for any materializations.
534  Block *
537  TypeConverter *converter = nullptr);
538 
539  /// Convert the types of block arguments within the given region. This
540  /// replaces each block with a new block containing the updated signature. The
541  /// entry block may have a special conversion if `entryConversion` is
542  /// provided. On success, the new entry block to the region is returned for
543  /// convenience. Otherwise, failure is returned.
545  Region *region, TypeConverter &converter,
546  TypeConverter::SignatureConversion *entryConversion = nullptr);
547 
548  /// Convert the types of block arguments within the given region except for
549  /// the entry region. This replaces each non-entry block with a new block
550  /// containing the updated signature.
551  ///
552  /// If special conversion behavior is needed for the non-entry blocks (for
553  /// example, we need to convert only a subset of a BB arguments), such
554  /// behavior can be specified in blockConversions.
556  Region *region, TypeConverter &converter,
558 
559  /// Replace all the uses of the block argument `from` with value `to`.
561 
562  /// Return the converted value of 'key' with a type defined by the type
563  /// converter of the currently executing pattern. Return nullptr in the case
564  /// of failure, the remapped value otherwise.
566 
567  /// Return the converted values that replace 'keys' with types defined by the
568  /// type converter of the currently executing pattern. Returns failure if the
569  /// remap failed, success otherwise.
571  SmallVectorImpl<Value> &results);
572 
573  //===--------------------------------------------------------------------===//
574  // PatternRewriter Hooks
575  //===--------------------------------------------------------------------===//
576 
577  /// Indicate that the conversion rewriter can recover from rewrite failure.
578  /// Recovery is supported via rollback, allowing for continued processing of
579  /// patterns even if a failure is encountered during the rewrite step.
580  bool canRecoverFromRewriteFailure() const override { return true; }
581 
582  /// PatternRewriter hook for replacing the results of an operation when the
583  /// given functor returns true.
584  void replaceOpWithIf(
585  Operation *op, ValueRange newValues, bool *allUsesReplaced,
586  llvm::unique_function<bool(OpOperand &) const> functor) override;
587 
588  /// PatternRewriter hook for replacing the results of an operation.
589  void replaceOp(Operation *op, ValueRange newValues) override;
591 
592  /// PatternRewriter hook for erasing a dead operation. The uses of this
593  /// operation *must* be made dead by the end of the conversion process,
594  /// otherwise an assert will be issued.
595  void eraseOp(Operation *op) override;
596 
597  /// PatternRewriter hook for erase all operations in a block. This is not yet
598  /// implemented for dialect conversion.
599  void eraseBlock(Block *block) override;
600 
601  /// PatternRewriter hook creating a new block.
602  void notifyBlockCreated(Block *block) override;
603 
604  /// PatternRewriter hook for splitting a block into two parts.
605  Block *splitBlock(Block *block, Block::iterator before) override;
606 
607  /// PatternRewriter hook for merging a block into another.
608  void mergeBlocks(Block *source, Block *dest, ValueRange argValues) override;
609 
610  /// PatternRewriter hook for moving blocks out of a region.
611  void inlineRegionBefore(Region &region, Region &parent,
612  Region::iterator before) override;
614 
615  /// PatternRewriter hook for cloning blocks of one region into another. The
616  /// given region to clone *must* not have been modified as part of conversion
617  /// yet, i.e. it must be within an operation that is either in the process of
618  /// conversion, or has not yet been converted.
619  void cloneRegionBefore(Region &region, Region &parent,
620  Region::iterator before,
621  BlockAndValueMapping &mapping) override;
623 
624  /// PatternRewriter hook for inserting a new operation.
625  void notifyOperationInserted(Operation *op) override;
626 
627  /// PatternRewriter hook for updating the root operation in-place.
628  /// Note: These methods only track updates to the top-level operation itself,
629  /// and not nested regions. Updates to regions will still require notification
630  /// through other more specific hooks above.
631  void startRootUpdate(Operation *op) override;
632 
633  /// PatternRewriter hook for updating the root operation in-place.
634  void finalizeRootUpdate(Operation *op) override;
635 
636  /// PatternRewriter hook for updating the root operation in-place.
637  void cancelRootUpdate(Operation *op) override;
638 
639  /// PatternRewriter hook for notifying match failure reasons.
642  function_ref<void(Diagnostic &)> reasonCallback) override;
644 
645  /// Return a reference to the internal implementation.
647 
648 private:
649  std::unique_ptr<detail::ConversionPatternRewriterImpl> impl;
650 };
651 
652 //===----------------------------------------------------------------------===//
653 // ConversionTarget
654 //===----------------------------------------------------------------------===//
655 
656 /// This class describes a specific conversion target.
658 public:
659  /// This enumeration corresponds to the specific action to take when
660  /// considering an operation legal for this conversion target.
661  enum class LegalizationAction {
662  /// The target supports this operation.
663  Legal,
664 
665  /// This operation has dynamic legalization constraints that must be checked
666  /// by the target.
667  Dynamic,
668 
669  /// The target explicitly does not support this operation.
670  Illegal,
671  };
672 
673  /// A structure containing additional information describing a specific legal
674  /// operation instance.
675  struct LegalOpDetails {
676  /// A flag that indicates if this operation is 'recursively' legal. This
677  /// means that if an operation is legal, either statically or dynamically,
678  /// all of the operations nested within are also considered legal.
679  bool isRecursivelyLegal = false;
680  };
681 
682  /// The signature of the callback used to determine if an operation is
683  /// dynamically legal on the target.
684  using DynamicLegalityCallbackFn = std::function<Optional<bool>(Operation *)>;
685 
686  ConversionTarget(MLIRContext &ctx) : ctx(ctx) {}
687  virtual ~ConversionTarget() = default;
688 
689  //===--------------------------------------------------------------------===//
690  // Legality Registration
691  //===--------------------------------------------------------------------===//
692 
693  /// Register a legality action for the given operation.
695  template <typename OpT>
697  setOpAction(OperationName(OpT::getOperationName(), &ctx), action);
698  }
699 
700  /// Register the given operations as legal.
703  }
704  template <typename OpT>
705  void addLegalOp() {
706  addLegalOp(OperationName(OpT::getOperationName(), &ctx));
707  }
708  template <typename OpT, typename OpT2, typename... OpTs>
709  void addLegalOp() {
710  addLegalOp<OpT>();
711  addLegalOp<OpT2, OpTs...>();
712  }
713 
714  /// Register the given operation as dynamically legal and set the dynamic
715  /// legalization callback to the one provided.
717  const DynamicLegalityCallbackFn &callback) {
719  setLegalityCallback(op, callback);
720  }
721  template <typename OpT>
723  addDynamicallyLegalOp(OperationName(OpT::getOperationName(), &ctx),
724  callback);
725  }
726  template <typename OpT, typename OpT2, typename... OpTs>
728  addDynamicallyLegalOp<OpT>(callback);
729  addDynamicallyLegalOp<OpT2, OpTs...>(callback);
730  }
731  template <typename OpT, class Callable>
732  std::enable_if_t<!std::is_invocable_v<Callable, Operation *>>
733  addDynamicallyLegalOp(Callable &&callback) {
734  addDynamicallyLegalOp<OpT>(
735  [=](Operation *op) { return callback(cast<OpT>(op)); });
736  }
737 
738  /// Register the given operation as illegal, i.e. this operation is known to
739  /// not be supported by this target.
742  }
743  template <typename OpT>
744  void addIllegalOp() {
745  addIllegalOp(OperationName(OpT::getOperationName(), &ctx));
746  }
747  template <typename OpT, typename OpT2, typename... OpTs>
748  void addIllegalOp() {
749  addIllegalOp<OpT>();
750  addIllegalOp<OpT2, OpTs...>();
751  }
752 
753  /// Mark an operation, that *must* have either been set as `Legal` or
754  /// `DynamicallyLegal`, as being recursively legal. This means that in
755  /// addition to the operation itself, all of the operations nested within are
756  /// also considered legal. An optional dynamic legality callback may be
757  /// provided to mark subsets of legal instances as recursively legal.
759  const DynamicLegalityCallbackFn &callback);
760  template <typename OpT>
762  OperationName opName(OpT::getOperationName(), &ctx);
763  markOpRecursivelyLegal(opName, callback);
764  }
765  template <typename OpT, typename OpT2, typename... OpTs>
767  markOpRecursivelyLegal<OpT>(callback);
768  markOpRecursivelyLegal<OpT2, OpTs...>(callback);
769  }
770  template <typename OpT, class Callable>
771  std::enable_if_t<!std::is_invocable_v<Callable, Operation *>>
772  markOpRecursivelyLegal(Callable &&callback) {
773  markOpRecursivelyLegal<OpT>(
774  [=](Operation *op) { return callback(cast<OpT>(op)); });
775  }
776 
777  /// Register a legality action for the given dialects.
778  void setDialectAction(ArrayRef<StringRef> dialectNames,
779  LegalizationAction action);
780 
781  /// Register the operations of the given dialects as legal.
782  template <typename... Names>
783  void addLegalDialect(StringRef name, Names... names) {
784  SmallVector<StringRef, 2> dialectNames({name, names...});
786  }
787  template <typename... Args>
789  SmallVector<StringRef, 2> dialectNames({Args::getDialectNamespace()...});
791  }
792 
793  /// Register the operations of the given dialects as dynamically legal, i.e.
794  /// requiring custom handling by the callback.
795  template <typename... Names>
797  StringRef name, Names... names) {
798  SmallVector<StringRef, 2> dialectNames({name, names...});
800  setLegalityCallback(dialectNames, callback);
801  }
802  template <typename... Args>
804  addDynamicallyLegalDialect(std::move(callback),
805  Args::getDialectNamespace()...);
806  }
807 
808  /// Register unknown operations as dynamically legal. For operations(and
809  /// dialects) that do not have a set legalization action, treat them as
810  /// dynamically legal and invoke the given callback.
812  setLegalityCallback(fn);
813  }
814 
815  /// Register the operations of the given dialects as illegal, i.e.
816  /// operations of this dialect are not supported by the target.
817  template <typename... Names>
818  void addIllegalDialect(StringRef name, Names... names) {
819  SmallVector<StringRef, 2> dialectNames({name, names...});
821  }
822  template <typename... Args>
824  SmallVector<StringRef, 2> dialectNames({Args::getDialectNamespace()...});
826  }
827 
828  //===--------------------------------------------------------------------===//
829  // Legality Querying
830  //===--------------------------------------------------------------------===//
831 
832  /// Get the legality action for the given operation.
834 
835  /// If the given operation instance is legal on this target, a structure
836  /// containing legality information is returned. If the operation is not
837  /// legal, None is returned. Also returns None is operation legality wasn't
838  /// registered by user or dynamic legality callbacks returned None.
839  ///
840  /// Note: Legality is actually a 4-state: Legal(recursive=true),
841  /// Legal(recursive=false), Illegal or Unknown, where Unknown is treated
842  /// either as Legal or Illegal depending on context.
844 
845  /// Returns true is operation instance is illegal on this target. Returns
846  /// false if operation is legal, operation legality wasn't registered by user
847  /// or dynamic legality callbacks returned None.
848  bool isIllegal(Operation *op) const;
849 
850 private:
851  /// Set the dynamic legality callback for the given operation.
852  void setLegalityCallback(OperationName name,
853  const DynamicLegalityCallbackFn &callback);
854 
855  /// Set the dynamic legality callback for the given dialects.
856  void setLegalityCallback(ArrayRef<StringRef> dialects,
857  const DynamicLegalityCallbackFn &callback);
858 
859  /// Set the dynamic legality callback for the unknown ops.
860  void setLegalityCallback(const DynamicLegalityCallbackFn &callback);
861 
862  /// The set of information that configures the legalization of an operation.
863  struct LegalizationInfo {
864  /// The legality action this operation was given.
866 
867  /// If some legal instances of this operation may also be recursively legal.
868  bool isRecursivelyLegal = false;
869 
870  /// The legality callback if this operation is dynamically legal.
871  DynamicLegalityCallbackFn legalityFn;
872  };
873 
874  /// Get the legalization information for the given operation.
875  Optional<LegalizationInfo> getOpInfo(OperationName op) const;
876 
877  /// A deterministic mapping of operation name and its respective legality
878  /// information.
879  llvm::MapVector<OperationName, LegalizationInfo> legalOperations;
880 
881  /// A set of legality callbacks for given operation names that are used to
882  /// check if an operation instance is recursively legal.
883  DenseMap<OperationName, DynamicLegalityCallbackFn> opRecursiveLegalityFns;
884 
885  /// A deterministic mapping of dialect name to the specific legality action to
886  /// take.
887  llvm::StringMap<LegalizationAction> legalDialects;
888 
889  /// A set of dynamic legality callbacks for given dialect names.
890  llvm::StringMap<DynamicLegalityCallbackFn> dialectLegalityFns;
891 
892  /// An optional legality callback for unknown operations.
893  DynamicLegalityCallbackFn unknownLegalityFn;
894 
895  /// The current context this target applies to.
896  MLIRContext &ctx;
897 };
898 
899 //===----------------------------------------------------------------------===//
900 // PDL Configuration
901 //===----------------------------------------------------------------------===//
902 
903 /// A PDL configuration that is used to supported dialect conversion
904 /// functionality.
906  : public PDLPatternConfigBase<PDLConversionConfig> {
907 public:
908  PDLConversionConfig(TypeConverter *converter) : converter(converter) {}
909  ~PDLConversionConfig() final = default;
910 
911  /// Return the type converter used by this configuration, which may be nullptr
912  /// if no type conversions are expected.
913  TypeConverter *getTypeConverter() const { return converter; }
914 
915  /// Hooks that are invoked at the beginning and end of a rewrite of a matched
916  /// pattern.
917  void notifyRewriteBegin(PatternRewriter &rewriter) final;
918  void notifyRewriteEnd(PatternRewriter &rewriter) final;
919 
920 private:
921  /// An optional type converter to use for the pattern.
922  TypeConverter *converter;
923 };
924 
925 /// Register the dialect conversion PDL functions with the given pattern set.
926 void registerConversionPDLFunctions(RewritePatternSet &patterns);
927 
928 //===----------------------------------------------------------------------===//
929 // Op Conversion Entry Points
930 //===----------------------------------------------------------------------===//
931 
932 /// Below we define several entry points for operation conversion. It is
933 /// important to note that the patterns provided to the conversion framework may
934 /// have additional constraints. See the `PatternRewriter Hooks` section of the
935 /// ConversionPatternRewriter, to see what additional constraints are imposed on
936 /// the use of the PatternRewriter.
937 
938 /// Apply a partial conversion on the given operations and all nested
939 /// operations. This method converts as many operations to the target as
940 /// possible, ignoring operations that failed to legalize. This method only
941 /// returns failure if there ops explicitly marked as illegal. If an
942 /// `unconvertedOps` set is provided, all operations that are found not to be
943 /// legalizable to the given `target` are placed within that set. (Note that if
944 /// there is an op explicitly marked as illegal, the conversion terminates and
945 /// the `unconvertedOps` set will not necessarily be complete.)
946 LogicalResult
947 applyPartialConversion(ArrayRef<Operation *> ops, ConversionTarget &target,
948  const FrozenRewritePatternSet &patterns,
949  DenseSet<Operation *> *unconvertedOps = nullptr);
950 LogicalResult
951 applyPartialConversion(Operation *op, ConversionTarget &target,
952  const FrozenRewritePatternSet &patterns,
953  DenseSet<Operation *> *unconvertedOps = nullptr);
954 
955 /// Apply a complete conversion on the given operations, and all nested
956 /// operations. This method returns failure if the conversion of any operation
957 /// fails, or if there are unreachable blocks in any of the regions nested
958 /// within 'ops'.
959 LogicalResult applyFullConversion(ArrayRef<Operation *> ops,
960  ConversionTarget &target,
961  const FrozenRewritePatternSet &patterns);
962 LogicalResult applyFullConversion(Operation *op, ConversionTarget &target,
963  const FrozenRewritePatternSet &patterns);
964 
965 /// Apply an analysis conversion on the given operations, and all nested
966 /// operations. This method analyzes which operations would be successfully
967 /// converted to the target if a conversion was applied. All operations that
968 /// were found to be legalizable to the given 'target' are placed within the
969 /// provided 'convertedOps' set; note that no actual rewrites are applied to the
970 /// operations on success and only pre-existing operations are added to the set.
971 /// This method only returns failure if there are unreachable blocks in any of
972 /// the regions nested within 'ops'. There's an additional argument
973 /// `notifyCallback` which is used for collecting match failure diagnostics
974 /// generated during the conversion. Diagnostics are only reported to this
975 /// callback may only be available in debug mode.
976 LogicalResult applyAnalysisConversion(
977  ArrayRef<Operation *> ops, ConversionTarget &target,
978  const FrozenRewritePatternSet &patterns,
979  DenseSet<Operation *> &convertedOps,
980  function_ref<void(Diagnostic &)> notifyCallback = nullptr);
981 LogicalResult applyAnalysisConversion(
982  Operation *op, ConversionTarget &target,
983  const FrozenRewritePatternSet &patterns,
984  DenseSet<Operation *> &convertedOps,
985  function_ref<void(Diagnostic &)> notifyCallback = nullptr);
986 } // namespace mlir
987 
988 #endif // MLIR_TRANSFORMS_DIALECTCONVERSION_H_
static constexpr const bool value
This class represents an argument of a Block.
Definition: Value.h:296
Block represents an ordered list of Operations.
Definition: Block.h:30
OpListType::iterator iterator
Definition: Block.h:129
This class implements a pattern rewriter for use with ConversionPatterns.
Block * applySignatureConversion(Region *region, TypeConverter::SignatureConversion &conversion, TypeConverter *converter=nullptr)
Apply a signature conversion to the entry block of the given region.
void replaceOp(Operation *op, ValueRange newValues) override
PatternRewriter hook for replacing the results of an operation.
LogicalResult convertNonEntryRegionTypes(Region *region, TypeConverter &converter, ArrayRef< TypeConverter::SignatureConversion > blockConversions)
Convert the types of block arguments within the given region except for the entry region.
LogicalResult getRemappedValues(ValueRange keys, SmallVectorImpl< Value > &results)
Return the converted values that replace 'keys' with types defined by the type converter of the curre...
LogicalResult notifyMatchFailure(Location loc, function_ref< void(Diagnostic &)> reasonCallback) override
PatternRewriter hook for notifying match failure reasons.
void inlineRegionBefore(Region &region, Region &parent, Region::iterator before) override
PatternRewriter hook for moving blocks out of a region.
void finalizeRootUpdate(Operation *op) override
PatternRewriter hook for updating the root operation in-place.
void eraseOp(Operation *op) override
PatternRewriter hook for erasing a dead operation.
void replaceOpWithIf(Operation *op, ValueRange newValues, bool *allUsesReplaced, llvm::unique_function< bool(OpOperand &) const > functor) override
PatternRewriter hook for replacing the results of an operation when the given functor returns true.
void notifyBlockCreated(Block *block) override
PatternRewriter hook creating a new block.
FailureOr< Block * > convertRegionTypes(Region *region, TypeConverter &converter, TypeConverter::SignatureConversion *entryConversion=nullptr)
Convert the types of block arguments within the given region.
Block * splitBlock(Block *block, Block::iterator before) override
PatternRewriter hook for splitting a block into two parts.
void mergeBlocks(Block *source, Block *dest, ValueRange argValues) override
PatternRewriter hook for merging a block into another.
detail::ConversionPatternRewriterImpl & getImpl()
Return a reference to the internal implementation.
void cloneRegionBefore(Region &region, Region &parent, Region::iterator before, BlockAndValueMapping &mapping) override
PatternRewriter hook for cloning blocks of one region into another.
void notifyOperationInserted(Operation *op) override
PatternRewriter hook for inserting a new operation.
void cancelRootUpdate(Operation *op) override
PatternRewriter hook for updating the root operation in-place.
void eraseBlock(Block *block) override
PatternRewriter hook for erase all operations in a block.
bool canRecoverFromRewriteFailure() const override
Indicate that the conversion rewriter can recover from rewrite failure.
Value getRemappedValue(Value key)
Return the converted value of 'key' with a type defined by the type converter of the currently execut...
void replaceUsesOfBlockArgument(BlockArgument from, Value to)
Replace all the uses of the block argument from with value to.
void startRootUpdate(Operation *op) override
PatternRewriter hook for updating the root operation in-place.
Base class for the conversion patterns.
std::enable_if_t< std::is_base_of< TypeConverter, ConverterTy >::value, ConverterTy * > getTypeConverter() const
TypeConverter * typeConverter
An optional type converter for use by this pattern.
TypeConverter * getTypeConverter() const
Return the type converter held by this pattern, or nullptr if the pattern does not require type conve...
ConversionPattern(TypeConverter &typeConverter, Args &&...args)
Construct a conversion pattern with the given converter, and forward the remaining arguments to Rewri...
virtual void rewrite(Operation *op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const
Hook for derived classes to implement rewriting.
virtual LogicalResult matchAndRewrite(Operation *op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const
Hook for derived classes to implement combined matching and rewriting.
This class describes a specific conversion target.
void setDialectAction(ArrayRef< StringRef > dialectNames, LegalizationAction action)
Register a legality action for the given dialects.
void setOpAction(LegalizationAction action)
void addLegalOp(OperationName op)
Register the given operations as legal.
void addDynamicallyLegalDialect(DynamicLegalityCallbackFn callback)
void setOpAction(OperationName op, LegalizationAction action)
Register a legality action for the given operation.
void addDynamicallyLegalDialect(const DynamicLegalityCallbackFn &callback, StringRef name, Names... names)
Register the operations of the given dialects as dynamically legal, i.e.
void addDynamicallyLegalOp(const DynamicLegalityCallbackFn &callback)
std::function< Optional< bool >(Operation *)> DynamicLegalityCallbackFn
The signature of the callback used to determine if an operation is dynamically legal on the target.
void addLegalDialect(StringRef name, Names... names)
Register the operations of the given dialects as legal.
Optional< LegalOpDetails > isLegal(Operation *op) const
If the given operation instance is legal on this target, a structure containing legality information ...
std::enable_if_t<!std::is_invocable_v< Callable, Operation * > > markOpRecursivelyLegal(Callable &&callback)
void markUnknownOpDynamicallyLegal(const DynamicLegalityCallbackFn &fn)
Register unknown operations as dynamically legal.
Optional< LegalizationAction > getOpAction(OperationName op) const
Get the legality action for the given operation.
void addDynamicallyLegalOp(OperationName op, const DynamicLegalityCallbackFn &callback)
Register the given operation as dynamically legal and set the dynamic legalization callback to the on...
void addIllegalDialect(StringRef name, Names... names)
Register the operations of the given dialects as illegal, i.e.
std::enable_if_t<!std::is_invocable_v< Callable, Operation * > > addDynamicallyLegalOp(Callable &&callback)
void addDynamicallyLegalOp(const DynamicLegalityCallbackFn &callback)
void markOpRecursivelyLegal(const DynamicLegalityCallbackFn &callback={})
void addIllegalOp(OperationName op)
Register the given operation as illegal, i.e.
LegalizationAction
This enumeration corresponds to the specific action to take when considering an operation legal for t...
@ Illegal
The target explicitly does not support this operation.
@ Dynamic
This operation has dynamic legalization constraints that must be checked by the target.
@ Legal
The target supports this operation.
ConversionTarget(MLIRContext &ctx)
void markOpRecursivelyLegal(OperationName name, const DynamicLegalityCallbackFn &callback)
Mark an operation, that must have either been set as Legal or DynamicallyLegal, as being recursively ...
void markOpRecursivelyLegal(const DynamicLegalityCallbackFn &callback={})
bool isIllegal(Operation *op) const
Returns true is operation instance is illegal on this target.
virtual ~ConversionTarget()=default
This class contains all of the information necessary to report a diagnostic to the DiagnosticEngine.
Definition: Diagnostics.h:155
This class provides support for representing a failure result, or a valid value of type T.
Definition: LogicalResult.h:78
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:64
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:56
This class helps build Operations.
Definition: Builders.h:198
OpConversionPattern is a wrapper around ConversionPattern that allows for matching and rewriting agai...
void rewrite(Operation *op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const final
Hook for derived classes to implement rewriting.
LogicalResult match(Operation *op) const final
Wrappers around the ConversionPattern methods that pass the derived op type.
typename SourceOp::Adaptor OpAdaptor
OpConversionPattern(MLIRContext *context, PatternBenefit benefit=1)
virtual LogicalResult match(SourceOp op) const
Rewrite and Match methods that operate on the SourceOp type.
OpConversionPattern(TypeConverter &typeConverter, MLIRContext *context, PatternBenefit benefit=1)
virtual LogicalResult matchAndRewrite(SourceOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const
virtual void rewrite(SourceOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const
LogicalResult matchAndRewrite(Operation *op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const final
Hook for derived classes to implement combined matching and rewriting.
OpInterfaceConversionPattern is a wrapper around ConversionPattern that allows for matching and rewri...
void rewrite(Operation *op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const final
Wrappers around the ConversionPattern methods that pass the derived op type.
LogicalResult matchAndRewrite(Operation *op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const final
Hook for derived classes to implement combined matching and rewriting.
OpInterfaceConversionPattern(MLIRContext *context, PatternBenefit benefit=1)
OpInterfaceConversionPattern(TypeConverter &typeConverter, MLIRContext *context, PatternBenefit benefit=1)
virtual void rewrite(SourceOp op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const
Rewrite and Match methods that operate on the SourceOp type.
virtual LogicalResult matchAndRewrite(SourceOp op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const
This class represents an operand of an operation.
Definition: Value.h:247
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:31
A PDL configuration that is used to supported dialect conversion functionality.
void notifyRewriteEnd(PatternRewriter &rewriter) final
void notifyRewriteBegin(PatternRewriter &rewriter) final
Hooks that are invoked at the beginning and end of a rewrite of a matched pattern.
PDLConversionConfig(TypeConverter *converter)
TypeConverter * getTypeConverter() const
Return the type converter used by this configuration, which may be nullptr if no type conversions are...
~PDLConversionConfig() final=default
This class provides a base class for users implementing a type of pattern configuration.
Definition: PatternMatch.h:840
This class represents the benefit of a pattern match in a unitless scheme that ranges from 0 (very li...
Definition: PatternMatch.h:32
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
Definition: PatternMatch.h:605
This class contains all of the data related to a pattern, but does not contain any methods or logic f...
Definition: PatternMatch.h:71
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition: Region.h:26
BlockListType::iterator iterator
Definition: Region.h:52
RewritePattern is the common base class for all DAG to DAG replacements.
Definition: PatternMatch.h:244
virtual LogicalResult match(Operation *op) const
Attempt to match against code rooted at the specified operation, which is the same operation code as ...
virtual void rewrite(Operation *op, PatternRewriter &rewriter) const
Rewrite the IR rooted at the specified operation with the result of this pattern, generating any new ...
std::enable_if_t<!std::is_convertible< CallbackT, Twine >::value, LogicalResult > notifyMatchFailure(Location loc, CallbackT &&reasonCallback)
Used to notify the rewriter that the IR failed to be rewritten because of a match failure,...
Definition: PatternMatch.h:517
virtual void cloneRegionBefore(Region &region, Region &parent, Region::iterator before, BlockAndValueMapping &mapping)
Clone the blocks that belong to "region" before the given position in another region "parent".
virtual void replaceOp(Operation *op, ValueRange newValues)
This method replaces the results of the operation with the specified list of values.
virtual void inlineRegionBefore(Region &region, Region &parent, Region::iterator before)
Move the blocks that belong to "region" before the given position in another region "parent".
This class provides all of the information necessary to convert a type signature.
void addInputs(unsigned origInputNo, ArrayRef< Type > types)
Remap an input of the original signature with a new set of types.
Optional< InputMapping > getInputMapping(unsigned input) const
Get the input mapping for the given argument.
ArrayRef< Type > getConvertedTypes() const
Return the argument types for the new signature.
void remapInput(unsigned origInputNo, Value replacement)
Remap an input of the original signature to another replacement value.
Type conversion class.
std::enable_if_t<!std::is_convertible< RangeT, Type >::value &&!std::is_convertible< RangeT, Operation * >::value, bool > isLegal(RangeT &&range)
Return true if all of the given types are legal for this type converter.
void addConversion(FnT &&callback)
Register a conversion function.
bool isSignatureLegal(FunctionType ty)
Return true if the inputs and outputs of the given function type are legal.
LogicalResult convertSignatureArg(unsigned inputNo, Type type, SignatureConversion &result)
This method allows for converting a specific argument of a signature.
void addArgumentMaterialization(FnT &&callback)
Register a materialization function, which must be convertible to the following form: Optional<Value>...
LogicalResult convertTypes(TypeRange types, SmallVectorImpl< Type > &results)
Convert the given set of types, filling 'results' as necessary.
LogicalResult convertSignatureArgs(TypeRange types, SignatureConversion &result, unsigned origInputOffset=0)
bool isLegal(Type type)
Return true if the given type is legal for this type converter, i.e.
LogicalResult convertType(Type t, SmallVectorImpl< Type > &results)
Convert the given type.
Optional< SignatureConversion > convertBlockSignature(Block *block)
This function converts the type signature of the given block, by invoking 'convertSignatureArg' for e...
void addSourceMaterialization(FnT &&callback)
This method registers a materialization that will be called when converting a legal type to an illega...
Value materializeArgumentConversion(OpBuilder &builder, Location loc, Type resultType, ValueRange inputs)
Materialize a conversion from a set of types into one result type by generating a cast sequence of so...
void addTargetMaterialization(FnT &&callback)
This method registers a materialization that will be called when converting type from an illegal,...
Value materializeSourceConversion(OpBuilder &builder, Location loc, Type resultType, ValueRange inputs)
Value materializeTargetConversion(OpBuilder &builder, Location loc, Type resultType, ValueRange inputs)
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:36
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:349
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
@ Type
An inlay hint that for a type annotation.
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
llvm::function_ref< Fn > function_ref
Definition: LLVM.h:150
void populateFunctionOpInterfaceTypeConversionPattern(StringRef functionLikeOpName, RewritePatternSet &patterns, TypeConverter &converter)
Add a pattern to the given pattern list to convert the signature of a FunctionOpInterface op with the...
LogicalResult applyPartialConversion(ArrayRef< Operation * > ops, ConversionTarget &target, const FrozenRewritePatternSet &patterns, DenseSet< Operation * > *unconvertedOps=nullptr)
Below we define several entry points for operation conversion.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
LogicalResult applyFullConversion(ArrayRef< Operation * > ops, ConversionTarget &target, const FrozenRewritePatternSet &patterns)
Apply a complete conversion on the given operations, and all nested operations.
void populateAnyFunctionOpInterfaceTypeConversionPattern(RewritePatternSet &patterns, TypeConverter &converter)
void registerConversionPDLFunctions(RewritePatternSet &patterns)
Register the dialect conversion PDL functions with the given pattern set.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
Definition: LogicalResult.h:72
LogicalResult applyAnalysisConversion(ArrayRef< Operation * > ops, ConversionTarget &target, const FrozenRewritePatternSet &patterns, DenseSet< Operation * > &convertedOps, function_ref< void(Diagnostic &)> notifyCallback=nullptr)
Apply an analysis conversion on the given operations, and all nested operations.
A structure containing additional information describing a specific legal operation instance.
bool isRecursivelyLegal
A flag that indicates if this operation is 'recursively' legal.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
This class acts as a special tag that makes the desire to match any operation that implements a given...
Definition: PatternMatch.h:162
This struct represents a range of new types or a single value that remaps an existing signature input...