The folder `shape_cast(splat constant) -> splat constant` was first introduced [here](36480657d8 (diff-484cea976e0c96459027c951733bf2d22d34c5a0c0de6f577069870ef4588983R2600)) (Nov 2020). In that commit there is a comment to _Only handle splat for now_. Based on that I assume the intention was to, at a later time, support a general `shape_cast(constant) -> constant` folder. That is what this PR does One minor downside: It is possible with this folder end up with, instead of 1 large constant and 1 shape_cast, 2 large constants: ```mlir func.func @foo() -> (vector<4xi32>, vector<2x2xi32>) { %cst = arith.constant dense<[1, 2, 3, 4]> : vector<4xi32> # 'large' constant 1 %0 = vector.shape_cast %cst : vector<4xi32> to vector<2x2xi32> return %cst, %0 : vector<4xi32>, vector<2x2xi32> } ``` gets folded with this new folder to ```mlir func.func @foo() -> (vector<4xi32>, vector<2x2xi32>) { %cst = arith.constant dense<[1, 2, 3, 4]> : vector<4xi32> # 'large' constant 1 %cst_0 = arith.constant dense<[[1, 2], [3, 4]]> : vector<2x2xi32> # 'large' constant 2 return %cst, %cst_0 : vector<4xi32>, vector<2x2xi32> } ``` Notes on the above case: 1) This only effects the textual IR, the actual values share the same context storage (I've verified this by checking pointer values in the `DenseIntOrFPElementsAttrStorage` [constructor](da5c442550/mlir/lib/IR/AttributeDetail.h (L59))) so no compile-time memory overhead to this folding. At the LLVM IR level the constant is shared, too. 2) This only happens when the pre-folded constant cannot be dead code eliminated (i.e. when it has 2+ uses) which I don't think is common.
Multi-Level Intermediate Representation
See https://mlir.llvm.org/ for more information.