/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* Dialect Interface Declarations                                             *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

namespace mlir {

/// This is the interface that must be implemented by the dialects of operations
///     to be inlined. This interface should only handle the operations of the
///     given dialect.
class DialectInlinerInterface : public ::mlir::DialectInterface::Base<DialectInlinerInterface> {
public:
  DialectInlinerInterface(::mlir::Dialect *dialect) : Base(dialect) {}
  
  /// Returns true if the given operation 'callable', that implements the
  /// 'CallableOpInterface', can be inlined into the position given call
  /// operation 'call', that is registered to the current dialect and implements
  /// the `CallOpInterface`. 'wouldBeCloned' is set to true if the region of the
  /// given 'callable' is set to be cloned during the inlining process, or false
  /// if the region is set to be moved in-place(i.e. no duplicates would be
  /// created).
  virtual bool isLegalToInline(::mlir::Operation * call, ::mlir::Operation * callable, bool wouldBeCloned) const {
    return false;
  }

  /// Returns true if the given region 'src' can be inlined into the region
  /// 'dest' that is attached to an operation registered to the current dialect.
  /// 'wouldBeCloned' is set to true if the given 'src' region is set to be
  /// cloned during the inlining process, or false if the region is set to be
  /// moved in-place (i.e. no duplicates would be created). 'valueMapping'
  /// contains any remapped values from within the 'src' region. This can be
  /// used to examine what values will replace entry arguments into the 'src'
  /// region for example.
  virtual bool isLegalToInline(::mlir::Region * dest, ::mlir::Region * src, bool wouldBeCloned, ::mlir::IRMapping & valueMapping) const {
    return false;
  }

  /// Returns true if the given region 'src' can be inlined into the region
  /// 'dest' that is attached to an operation registered to the current dialect.
  /// 'wouldBeCloned' is set to true if the given 'src' region is set to be
  /// cloned during the inlining process, or false if the region is set to be
  /// moved in-place(i.e. no duplicates would be created). 'valueMapping'
  /// contains any remapped values from within the 'src' region. This can be
  /// used to examine what values will replace entry arguments into the 'src'
  /// region for example.
  virtual bool isLegalToInline(::mlir::Operation * op, ::mlir::Region * dest, bool wouldBeCloned, ::mlir::IRMapping & valueMapping) const {
    return false;
  }

  /// This hook is invoked on an operation that contains regions. It should
  /// return true if the analyzer should recurse within the regions of this
  /// operation when computing legality and cost, false otherwise. The default
  /// implementation returns true.
  virtual bool shouldAnalyzeRecursively(::mlir::Operation * op) const {
    return true;
  }

  /// Handle the given inlined terminator by replacing it with a new operation
  /// as necessary. This overload is called when the inlined region has more
  /// than one block. The 'newDest' block represents the new final branching
  /// destination of blocks within this region, i.e. operations that release
  /// control to the parent operation will likely now branch to this block.
  /// Its block arguments correspond to any values that need to be replaced by
  /// terminators within the inlined region.
  virtual void handleTerminator(::mlir::Operation * op, ::mlir::Block * newDest) const {
    llvm_unreachable("must implement handleTerminator in the case of multiple "
                             "inlined blocks");
  }

  /// Handle the given inlined terminator by replacing it with a new operation
  /// as necessary. This overload is called when the inlined region only
  /// contains one block. 'valuesToReplace' contains the previously returned
  /// values of the call site before inlining. These values must be replaced by
  /// this callback if they had any users (for example for traditional function
  /// calls, these are directly replaced with the operands of the `return`
  /// operation). The given 'op' will be removed by the caller, after this
  /// function has been called.
  virtual void handleTerminator(::mlir::Operation * op, ::mlir::ValueRange valuesToReplace) const {
    llvm_unreachable(
                "must implement handleTerminator in the case of one inlined block");
  }

  /// Attempt to materialize a conversion for a type mismatch between a call
  /// from this dialect, and a callable region. This method should generate an
  /// operation that takes 'input' as the only operand, and produces a single
  /// result of 'resultType'. If a conversion can not be generated, nullptr
  /// should be returned. For example, this hook may be invoked in the following
  /// scenarios:
  /// 
  ///   ```mlir
  ///   func @foo(i32) -> i32 { ... }
  /// 
  ///   // Mismatched input operand ... = foo.call @foo(%input : i16) -> i32
  /// 
  ///   // Mismatched result type.
  ///   ... = foo.call @foo(%input : i32) -> i16
  ///   ```
  /// 
  /// NOTE: This hook may be invoked before the 'isLegal' checks above.
  virtual ::mlir::Operation *materializeCallConversion(::mlir::OpBuilder & builder, ::mlir::Value input, ::mlir::Type resultType, ::mlir::Location conversionLoc) const {
    return nullptr;
  }

  /// Hook to transform the call arguments before using them to replace the
  /// callee arguments. Returns a value of the same type or the `argument`
  /// itself if nothing changed. The `argumentAttrs` dictionary is non-null even
  /// if no attribute is present. The hook is called after converting the
  /// callsite argument types using the materializeCallConversion callback, and
  /// right before inlining the callee region. Any operations created using the
  /// provided `builder` are inserted right before the inlined callee region. An
  /// example use case is the insertion of copies for by value arguments.
  virtual ::mlir::Value handleArgument(::mlir::OpBuilder & builder, ::mlir::Operation * call, ::mlir::Operation * callable, ::mlir::Value argument, ::mlir::DictionaryAttr argumentAttrs) const {
    return argument;
  }

  /// Hook to transform the callee results before using them to replace the call
  /// results. Returns a value of the same type or the `result` itself if
  /// nothing changed. The `resultAttrs` dictionary is non-null even if no
  /// attribute is present. The hook is called right before handling
  /// terminators, and obtains the callee result before converting its type
  /// using the `materializeCallConversion` callback. Any operations created
  /// using the provided `builder` are inserted right after the inlined callee
  /// region. An example use case is the insertion of copies for by value
  /// results. NOTE: This hook is invoked after inlining the `callable` region.
  virtual ::mlir::Value handleResult(::mlir::OpBuilder & builder, ::mlir::Operation * call, ::mlir::Operation * callable, ::mlir::Value result, ::mlir::DictionaryAttr resultAttrs) const {
    return result;
  }

  /// Process a set of blocks that have been inlined for a call. This callback
  /// is invoked before inlined terminator operations have been processed.
  virtual void processInlinedCallBlocks(::mlir::Operation * call, ::mlir::iterator_range<::mlir::Region::iterator> inlinedBlocks) const {}

  /// Returns true if the inliner can assume a fast path of not creating a new
  /// block, if there is only one block.
  virtual bool allowSingleBlockOptimization(::mlir::iterator_range<::mlir::Region::iterator> inlinedBlocks) const {
    return true;
  }
};

} // namespace mlir
