@@ -257,6 +257,96 @@ expressing `vector`s in the IR directly and simple pattern-rewrites.
257257[ EDSC] ( https://github.com/llvm/llvm-project/blob/main/mlir/docs/EDSC.md ) s
258258provide a simple way of driving such a notional language directly in C++.
259259
260+ ### Taxonomy for "Read"/"Write" Operations
261+
262+ Below is a list of vector dialect operations that move values from an abstract
263+ ** source** to an abstract ** destination** , i.e. "read"/"write" operations:
264+
265+ * ` vector.load ` , ` vector.store ` , ` vector.transfer_read ` ,
266+ ` vector.transfer_write ` , ` vector.gather ` , ` vector.scatter ` ,
267+ ` vector.compressstore ` , ` vector.expandload ` , ` vector.maskedload ` ,
268+ ` vector.maskedstore ` , ` vector.extract ` , ` vector.insert ` ,
269+ ` vector.scalable_extract ` , ` vector.scalable_insert ` ,
270+ ` vector.extract_strided_slice ` , ` vector.insert_strided_slice ` .
271+
272+ #### Current Naming in Vector Dialect
273+ | ** Vector Dialect Op** | ** Operand Names** | ** Operand Types** | ** Result Name** | ** Result Type** |
274+ | --------------------------------| --------------------------| -------------------------------| ------------------| ----------------------|
275+ | ` vector.load ` | ` base ` | ` memref ` | ` result ` | ` vector ` |
276+ | ` vector.store ` | ` valueToStore ` , ` base ` | ` vector ` , ` memref ` | - | - |
277+ | ` vector.transfer_read ` | ` source ` | ` memref ` / ` tensor ` | ` vector ` | ` vector ` |
278+ | ` vector.transfer_write ` | ` vector ` , ` source ` | ` vector ` , ` memref ` / ` tensor ` | ` result ` | ` vector ` |
279+ | ` vector.gather ` | ` base ` | ` memref ` | ` result ` | ` vector ` |
280+ | ` vector.scatter ` | ` valueToStore ` , ` base ` | ` vector ` , ` memref ` | - | - |
281+ | ` vector.expandload ` | ` base ` | ` memref ` | ` result ` | ` vector ` |
282+ | ` vector.compressstore ` | ` valueToStore ` ,` base ` | ` vector ` , ` memref ` | - | - |
283+ | ` vector.maskedload ` | ` base ` | ` memref ` | ` result ` | ` vector ` |
284+ | ` vector.maskedstore ` | ` valueToStore ` , ` base ` | ` vector ` , ` memref ` | - | - |
285+ | ` vector.extract ` | ` vector ` | ` vector ` | ` result ` | ` scalar ` / ` vector ` |
286+ | ` vector.insert ` | ` source ` , ` dest ` | ` scalar ` / ` vector ` , ` vector ` | ` result ` | ` vector ` |
287+ | ` vector.scalable_extract ` | ` source ` | ` vector ` | ` res ` | ` scalar ` / ` vector ` |
288+ | ` vector.scalable_insert ` | ` source ` , ` dest ` | ` scalar ` / ` vector ` , ` vector ` | ` res ` | ` vector ` |
289+ | ` vector.extract_strided_slice ` | ` vector ` | ` vector ` | (missing name) | ` vector ` |
290+ | ` vector.insert_strided_slice ` | ` source ` , ` dest ` | ` vector ` | ` res ` | ` vector ` |
291+
292+ Note that "read" operations take one operand ("from"), whereas "write"
293+ operations require two ("value-to-store" and "to").
294+
295+ ### Observations
296+ Each "read" operation has a "from" argument, while each "write" operation has a
297+ "to" and a "value-to-store" operand. However, the naming conventions are
298+ ** inconsistent** , making it difficult to extract common patterns or determine
299+ operand roles. Here are some inconsistencies:
300+
301+ - ` getBase() ` in ` vector.load ` refers to the ** "from"** operand (source).
302+ - ` getBase() ` in ` vector.store ` refers to the ** "to"** operand (destination).
303+ - ` vector.transfer_read ` and ` vector.transfer_write ` use ` getSource() ` , which:
304+ - ** Conflicts** with the ` vector.load ` / ` vector.store ` naming pattern.
305+ - ** Does not clearly indicate** whether the operand represents a ** source**
306+ or ** destination** .
307+ - ` vector.insert ` defines ` getSource() ` and ` getDest() ` , making the distinction
308+ between "to" and "from" operands ** clear** . However, its sibling operation,
309+ ` vector.extract ` , only defines ` getVector() ` , making it unclear whether it
310+ represents a ** source** or ** destination** .
311+ - ` vector.store ` uses ` getValueToStore() ` , whereas
312+ ` vector.insert_strided_slice ` does not.
313+
314+ There is ** no consistent way** to identify:
315+ - ` "from" ` (read operand)
316+ - ` "to" ` (write operand)
317+ - ` "value-to-store" ` (written value)
318+
319+ ### Indexed vs. Non-Indexed Taxonomy
320+ A more consistent way to classify "to", "from", and "value-to-store" arguments
321+ is by determining whether an operand is _ indexed_ or _ non-indexed_ .
322+
323+ #### ** Example: ` vector.transfer_read ` and ` vector.transfer_write ` **
324+ ``` mlir
325+ Indexed Operand
326+ |
327+ %res = vector.transfer_read %A[%expr1, %expr2, %expr3, %expr4]
328+ { permutation_map : (d0,d1,d2,d3) -> (d2,0,d0) } :
329+ memref<?x?x?x?xf32>, vector<3x4x5xf32>
330+ \
331+ Non-Indexed Result
332+
333+ Non-Indexed Operand Indexed Operand
334+ \ /
335+ vector.transfer_write %4, %arg1[%c3, %c3]
336+ {permutation_map = (d0, d1)->(d0, d1)}
337+ : vector<1x1x4x3xf32>, memref<?x?xvector<4x3xf32>>
338+ ```
339+
340+ Using the "indexed" vs. "non-indexed" classification, we can systematically
341+ differentiate between "to", "from" and "value-to-store" arguments across
342+ operations:
343+ * "to" is always _ indexed_ for "write" operations, "value-to-store" is
344+ _ non-indexed_ ,
345+ * "from" is always _ indexed_ for "read" operations.
346+
347+ In addition, for "read" operations, we can view the "result" as a non-indexed
348+ argument.
349+
260350## Bikeshed Naming Discussion
261351
262352There are arguments against naming an n-D level of abstraction ` vector ` because
0 commit comments