Skip to content

[mlir][vector] Standarise operand naming #131602

@banach-space

Description

@banach-space

Task

Standarise operand naming for Vector dialect operations.

Context

Below is a list of vector dialect operations that move values from an abstract source to an abstract destination, i.e. "read"/"write" operations:

  • vector.load, vector.store, vector.transfer_read,
    vector.transfer_write, vector.gather, vector.scatter,
    vector.compressstore, vector.expandload, vector.maskedload,
    vector.maskedstore, vector.extract, vector.insert,
    vector.scalable_extract, vector.scalable_insert,
    vector.extract_strided_slice, vector.insert_strided_slice.
| **Vector Dialect Op**          | **Operand Names**        | **Operand Types**             | **Result Name**  | **Result Type**      |
|--------------------------------|--------------------------|-------------------------------|------------------|----------------------|
| `vector.load`                  | `base`                   | `memref`                      | `result`         | `vector`             |
| `vector.store`                 | `valueToStore`, `base`   | `vector`, `memref`            | -                | -                    |
| `vector.transfer_read`         | `source`                 | `memref` / `tensor`           | `vector`         | `vector`             |
| `vector.transfer_write`        | `vector`, `source`       | `vector`, `memref`/ `tensor`  | `result`         | `vector`             |
| `vector.gather`                | `base`                   | `memref` / `tensor`           | `result`         | `vector`             |
| `vector.scatter`               | `valueToStore`, `base`   | `vector`, `memref`            | -                | -                    |
| `vector.expandload`            | `base`                   | `memref`                      | `result`         | `vector`             |
| `vector.compressstore`         | `valueToStore`,`base`    | `vector`, `memref`            | -                | -                    |
| `vector.maskedload`            | `base`                   | `memref`                      | `result`         | `vector`             |
| `vector.maskedstore`           | `valueToStore`, `base`   | `vector`, `memref`            | -                | -                    |
| `vector.extract`               | `vector`                 | `vector`                      | `result`         | `scalar` / `vector`  |
| `vector.insert`                | `source`, `dest`         | `scalar` / `vector`, `vector` | `result`         | `vector`             |
| `vector.scalable_extract`      | `source`                 | `vector`                      | `res`            | `scalar` / `vector`  |
| `vector.scalable_insert`       | `source`, `dest`         | `scalar` / `vector`, `vector` | `res`            | `vector`             |
| `vector.extract_strided_slice` | `vector`                 | `vector`                      | (missing name)   | `vector`             |
| `vector.insert_strided_slice`  | `source`, `dest`         | `vector`                      | `res`            | `vector`             |

Note that "read" operations take one operand ("from"), whereas "write"
operations require two ("value-to-store" and "to").

Observations

Each "read" operation has a "from" argument, while each "write" operation has a
"to" and a "value-to-store" operand. However, the naming conventions are
inconsistent, making it difficult to extract common patterns or determine
operand roles. Here are some inconsistencies:

  • getBase() in vector.load refers to the "from" operand (source).
  • getBase() in vector.store refers to the "to" operand (destination).
  • vector.transfer_read and vector.transfer_write use getSource(), which:
    • Conflicts with the vector.load / vector.store naming pattern.
    • Does not clearly indicate whether the operand represents a source
      or destination.
  • vector.insert defines getSource() and getDest(), making the distinction
    between "to" and "from" operands clear. However, its sibling operation,
    vector.extract, only defines getVector(), making it unclear whether it
    represents a source or destination.
  • vector.store uses getValueToStore(), whereas
    vector.insert_strided_slice does not.

There is no consistent way to identify:

  • "from" (read operand)
  • "to" (write operand)
  • "value-to-store" (written value)

Proposed re-naming

To address these inconsistencies, we propose adopting the following standardised naming conventions:

| **Vector Dialect Op**          | **Operand Names**        | **Operand Types**             | **Result Name**  | **Result Type**      |
|--------------------------------|--------------------------|-------------------------------|------------------|----------------------|
| `vector.load`                  | `base`                   | `memref`                      | `result`         | `vector`             |
| `vector.store`                 | `valueToStore`, `base`   | `vector`, `memref`            | -                | -                    |
| `vector.transfer_read`         | `base`                   | `memref` / `tensor`           | `result`         | `vector`             |
| `vector.transfer_write`        | `valueToStore`, `base`   | `vector`, `memref`/ `tensor`  | `result`         | `vector`             |
| `vector.gather`                | `base`                   | `memref` / `tensor`           | `result`         | `vector`             |
| `vector.scatter`               | `valueToStore`, `base`   | `vector`, `memref`            | -                | -                    |
| `vector.expandload`            | `base`                   | `memref`                      | `result`         | `vector`             |
| `vector.compressstore`         | `valueToStore`, `base`   | `vector`, `memref`            | -                | -                    |
| `vector.maskedload`            | `base`                   | `memref`                      | `result`         | `vector`             |
| `vector.maskedstore`           | `valueToStore`, `base`   | `vector`, `memref`            | -                | -                    |
| `vector.extract`               | `source`                 | `vector`                      | `result`         | `scalar` / `vector`  |
| `vector.insert`                | `valueToStore`, `dest`   | `scalar` / `vector`, `vector` | `result`         | `vector`             |
| `vector.scalable_extract`      | `source`                 | `vector`                      | `result`         | `scalar` / `vector`  |
| `vector.scalable_insert`       | `valueToStore`, `dest`   | `scalar` / `vector`, `vector` | `result`         | `vector`             |
| `vector.extract_strided_slice` | `source`                 | `vector`                      | `result`         | `vector`             |
| `vector.insert_strided_slice`  | `valueToStore`, `dest`   | `vector`                      | `result`         | `vector`             |

Next steps

I will leave this open for 1-2 weeks to gather feedback. If there is broad support, I will prepare a patch to implement these changes.

LAST UPDATE: 12/9/24

List of PRs that implement this (updated whenever a new PR is sent):

TODOs

  • Remove all the newly [[deprecated]] hooks before LLVM 21 release.
  • Remove all the newly [[deprecated]] hooks before LLVM 22 release (this refers to the hooks added post LLVM 21 release).

Thanks!

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions