xref: /llvm-project/mlir/include/mlir/Dialect/Index/IR/IndexDialect.td (revision 863c346209e27d22157fad21d0fd730e710a3441)
1//===- IndexDialect.td - Index dialect definition ----------*- tablegen -*-===//
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#ifndef INDEX_DIALECT
10#define INDEX_DIALECT
11
12include "mlir/IR/DialectBase.td"
13
14//===----------------------------------------------------------------------===//
15// IndexDialect
16//===----------------------------------------------------------------------===//
17
18def IndexDialect : Dialect {
19  let name = "index";
20
21  let summary = "The Index dialect";
22  let description = [{
23    The Index dialect contains operations for manipulating values of the builtin
24    `index` type. The index type models target-specific values of pointer width,
25    like `intptr_t`. Index values are typically used as loop bounds, array
26    subscripts, tensor dimensions, etc.
27
28    The operations in this dialect operate exclusively on scalar index types.
29    The dialect and its operations treat the index type as signless and contains
30    signed and unsigned versions of certain operations where the distinction is
31    meaningful. In particular, the operations and transformations are careful to
32    be aware of the target-independent-ness of the index type, such as when
33    folding.
34
35    The folding semantics of the Index dialect operations ensure that folding
36    produces the same results irrespective of the eventual target pointer width.
37    All index constants are stored in `APInt`s of maximum index bitwidth: 64.
38    Operations are folded using 64-bit integer arithmetic.
39
40    For operations where the values of the upper 32 bits don't impact the values
41    of the lower 32 bits, no additional handling is required because if the
42    target is 32-bit, the truncated folded result will be the same as if the
43    operation were computed with 32-bit arithmetic, and if the target is 64-bit,
44    the fold result is valid by default.
45
46    Consider addition: an overflow in 32-bit is the same as truncating the
47    result computed in 64-bit. For example, `add(0x800000008, 0x800000008)` is
48    `0x1000000010` in 64-bit, which truncates to `0x10`, the same result as
49    truncating the operands first: `add(0x08, 0x08)`. Specifically, an operation
50    `f` can always be folded if it satisfies the following for all 64-bit values
51    of `a` and `b`:
52
53    ```
54    trunc(f(a, b)) = f(trunc(a), trunc(b))
55    ```
56
57    When materializing target-specific code, constants just need to be truncated
58    as appropriate.
59
60    Operations where the values of the upper 32 bits do impact the values of the
61    lower 32 bits are not folded if the results would be different in 32-bit.
62    These are operations that right shift -- division, remainder, etc. These
63    operations are only folded for subsets of `a` and `b` for which the above
64    property is satisfied. This is checked per fold attempt.
65
66    Consider division: the 32-bit computation will differ from 64-bit if the
67    latter results in a high bit shifted into the lower 32 bits. For example,
68    `div(0x100000002, 2)` is `0x80000001` in 64-bit but `0x01` in 32-bit; it
69    cannot be folded. However, `div(0x200000002, 2)` can be folded. The 64-bit
70    result is `0x100000001`, which truncated to 32 bits is `0x01`. The 32-bit
71    result of the operation with truncated operands `div(0x02, 2)` which is
72    `0x01`, the same as truncating the 64-bit result.
73  }];
74
75  let cppNamespace = "::mlir::index";
76
77  let extraClassDeclaration = [{
78    /// Register all dialect attributes.
79    void registerAttributes();
80    /// Register all dialect operations.
81    void registerOperations();
82  }];
83
84  let hasConstantMaterializer = 1;
85  let useDefaultAttributePrinterParser = 1;
86}
87
88#endif // INDEX_DIALECT
89