Emit reduction during op vectorization instead of doing it when creating the transfer write. This allow us to not broadcast output arguments for reduction initial value.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
| mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp | ||
|---|---|---|
| 389 | This "fused" loop structure feels quite unnatural. I'd rather structure the code like: SmallVector<Value> reducedValues, operands;
for (Value operand : ...) {
...
if (reducedValue) {
reducedValues.push_back(reducedValue);
operands.push_back(operand);
}
}
assert(reducedValues.size() <= 1);
... etc | |
| 403 | "reduce only if needed" sounds exactly like reduceIfNeeded. | |
| 405 | is this check only for avoid interfering with the specific path of contraction vectorization? | |
| mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp | ||
|---|---|---|
| 397 | reductionOps may contain multiple ops. Actually, I think we are not even using reductionOps anywhere here? I think this is bringing back the problem I was trying to solve with the matchReduction utility: detecting reductions with multiple ops. | |
| mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp | ||
|---|---|---|
| 397 | Right, we currently check that there is only a single op in matchReduction otherwise it fails. This wouldn't work otherwise indeed, maybe we need an assert. Here op will be the same as reductionOps[0], probably worth an assert too. | |
This "fused" loop structure feels quite unnatural.
Maybe they are not possible in practice but it looks like there is a possible path where one operand passes all the checks and then we hit return; that would def. sound fishy.
I'd rather structure the code like:
SmallVector<Value> reducedValues, operands; for (Value operand : ...) { ... if (reducedValue) { reducedValues.push_back(reducedValue); operands.push_back(operand); } } assert(reducedValues.size() <= 1); ... etc