/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|*                                                                            *|
|* Dialect Declarations                                                       *|
|*                                                                            *|
|* Automatically generated file, do not edit!                                 *|
|* From: IndexOps.td                                                          *|
|*                                                                            *|
\*===----------------------------------------------------------------------===*/

namespace mlir::index {

/// The Index dialect
/// The Index dialect contains operations for manipulating values of the builtin
/// `index` type. The index type models target-specific values of pointer width,
/// like `intptr_t`. Index values are typically used as loop bounds, array
/// subscripts, tensor dimensions, etc.
/// 
/// The operations in this dialect operate exclusively on scalar index types.
/// The dialect and its operations treat the index type as signless and contains
/// signed and unsigned versions of certain operations where the distinction is
/// meaningful. In particular, the operations and transformations are careful to
/// be aware of the target-independent-ness of the index type, such as when
/// folding.
/// 
/// The folding semantics of the Index dialect operations ensure that folding
/// produces the same results irrespective of the eventual target pointer width.
/// All index constants are stored in `APInt`s of maximum index bitwidth: 64.
/// Operations are folded using 64-bit integer arithmetic.
/// 
/// For operations where the values of the upper 32 bits don't impact the values
/// of the lower 32 bits, no additional handling is required because if the
/// target is 32-bit, the truncated folded result will be the same as if the
/// operation were computed with 32-bit arithmetic, and if the target is 64-bit,
/// the fold result is valid by default.
/// 
/// Consider addition: an overflow in 32-bit is the same as truncating the
/// result computed in 64-bit. For example, `add(0x800000008, 0x800000008)` is
/// `0x1000000010` in 64-bit, which truncates to `0x10`, the same result as
/// truncating the operands first: `add(0x08, 0x08)`. Specifically, an operation
/// `f` can always be folded if it satisfies the following for all 64-bit values
/// of `a` and `b`:
/// 
/// ```
/// trunc(f(a, b)) = f(trunc(a), trunc(b))
/// ```
/// 
/// When materializing target-specific code, constants just need to be truncated
/// as appropriate.
/// 
/// Operations where the values of the upper 32 bits do impact the values of the
/// lower 32 bits are not folded if the results would be different in 32-bit.
/// These are operations that right shift -- division, remainder, etc. These
/// operations are only folded for subsets of `a` and `b` for which the above
/// property is satisfied. This is checked per fold attempt.
/// 
/// Consider division: the 32-bit computation will differ from 64-bit if the
/// latter results in a high bit shifted into the lower 32 bits. For example,
/// `div(0x100000002, 2)` is `0x80000001` in 64-bit but `0x01` in 32-bit; it
/// cannot be folded. However, `div(0x200000002, 2)` can be folded. The 64-bit
/// result is `0x100000001`, which truncated to 32 bits is `0x01`. The 32-bit
/// result of the operation with truncated operands `div(0x02, 2)` which is
/// `0x01`, the same as truncating the 64-bit result.
class IndexDialect : public ::mlir::Dialect {
  explicit IndexDialect(::mlir::MLIRContext *context);

  void initialize();
  friend class ::mlir::MLIRContext;
public:
  ~IndexDialect() override;
  static constexpr ::llvm::StringLiteral getDialectNamespace() {
    return ::llvm::StringLiteral("index");
  }

  /// Parse an attribute registered to this dialect.
  ::mlir::Attribute parseAttribute(::mlir::DialectAsmParser &parser,
                                   ::mlir::Type type) const override;

  /// Print an attribute registered to this dialect.
  void printAttribute(::mlir::Attribute attr,
                      ::mlir::DialectAsmPrinter &os) const override;

  /// Materialize a single constant operation from a given attribute value with
  /// the desired resultant type.
  ::mlir::Operation *materializeConstant(::mlir::OpBuilder &builder,
                                         ::mlir::Attribute value,
                                         ::mlir::Type type,
                                         ::mlir::Location loc) override;

    /// Register all dialect attributes.
    void registerAttributes();
    /// Register all dialect operations.
    void registerOperations();
  };

} // namespace mlir::index
MLIR_DECLARE_EXPLICIT_TYPE_ID(::mlir::index::IndexDialect)
