[Mlir-commits] [mlir] [mlir][linalg] Add constant folder for linalg.elementwise ops (PR #203608)
Federico Bruzzone
llvmlistbot at llvm.org
Mon Jun 15 07:04:34 PDT 2026
================
@@ -300,10 +300,95 @@ struct FoldConstantTranspose : public FoldConstantBase<FoldConstantTranspose> {
ControlFusionFn controlFn;
};
+
+/// Folds linalg.elementwise ops with all-constant inputs by interpreting the
+/// region body. Each op in the body is folded using its own fold()
+/// implementation, enabling constant propagation through any elementwise kind
+/// (unary, binary, ternary) without explicit per-kind handling.
+struct FoldConstantElementwise
+ : public FoldConstantBase<FoldConstantElementwise> {
+
+ using FoldConstantBase::FoldConstantBase;
+
+ bool matchIndexingMaps(LinalgOp linalgOp) const {
+ return isa<ElementwiseOp>(linalgOp.getOperation());
+ }
+
+ RegionComputationFn getRegionComputeFn(LinalgOp linalgOp) const {
+ Block &body = linalgOp->getRegion(0).front();
+
+ auto yieldOp = dyn_cast<linalg::YieldOp>(body.getTerminator());
+ if (!yieldOp || yieldOp.getNumOperands() != 1)
+ return nullptr;
+
+ return [&body](const APIntOrFloatArray &inputs) -> APIntOrFloat {
+ // Map Value -> folded constant Attribute.
+ DenseMap<Value, Attribute> valueMap;
----------------
FedericoBruzzone wrote:
`DenseMap<Value, Attribute> valueMap` is rebuilt from scratch on every call to the lambda, which is invoked once per output element. For an op with N elements and a body of K ops this is $O(N \times K)$ map allocations. Since the body structure is constant across all elements, the walk and `op.fold` calls could be structured once outside the lambda, with only the per-element input substitution varying. Am I missing something?
https://github.com/llvm/llvm-project/pull/203608
More information about the Mlir-commits
mailing list