Skip to content

Commit 30c49b0

Browse files
author
git apple-llvm automerger
committed
Merge commit '1c49f5eb0c5d' from apple/main into swift/next
2 parents d063e01 + 1c49f5e commit 30c49b0

File tree

2 files changed

+36
-27
lines changed

2 files changed

+36
-27
lines changed

mlir/lib/Dialect/StandardOps/Transforms/Bufferize.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "mlir/Dialect/SCF/SCF.h"
1616
#include "mlir/Dialect/StandardOps/IR/Ops.h"
1717
#include "mlir/Dialect/StandardOps/Transforms/Passes.h"
18-
#include "mlir/Dialect/Tensor/IR/Tensor.h"
1918
#include "mlir/IR/BlockAndValueMapping.h"
2019
#include "mlir/Transforms/DialectConversion.h"
2120

@@ -70,18 +69,29 @@ class BufferizeDynamicTensorFromElementsOp
7069
upperBounds.push_back(upperBound);
7170
}
7271

73-
// Generate tensor elements with a parallel loop.
74-
rewriter.create<scf::ParallelOp>(
75-
loc, lowerBounds, upperBounds, steps,
76-
[&](OpBuilder &b, Location loc, ValueRange ivs) {
77-
BlockAndValueMapping mapping;
78-
mapping.map(op.body().getArguments(), ivs);
79-
for (auto &nestedOp : op.getBody()->without_terminator())
80-
b.clone(nestedOp, mapping);
81-
auto yieldOp = cast<YieldOp>(op.getBody()->getTerminator());
82-
b.create<StoreOp>(loc, mapping.lookup(yieldOp.value()), result, ivs);
83-
b.create<scf::YieldOp>(loc);
84-
});
72+
// Generate tensor elements with a parallel loop that stores into
73+
// each element of the resulting memref.
74+
//
75+
// This is a bit tricky. We cannot simply clone the ops because when an op
76+
// is cloned, it must be legalized. However, we want to allow arbitrary ops
77+
// in the body that we don't necessarily have legalization patterns for as
78+
// part of this dialect conversion invocation.
79+
//
80+
// To accomplish this, we use mergeBlockBefore to "move" this op's body
81+
// into the scf.parallel's body.
82+
auto parallel =
83+
rewriter.create<scf::ParallelOp>(loc, lowerBounds, upperBounds, steps);
84+
Block *parallelBody = parallel.getBody();
85+
rewriter.mergeBlockBefore(op.getBody(), parallelBody->getTerminator(),
86+
parallelBody->getArguments());
87+
// Replace the inlined yield op with a store op. The scf.parallel's builder
88+
// already populated an scf.yield at the end, so we don't need to worry
89+
// about creating that.
90+
Operation *elementYield = parallelBody->getTerminator()->getPrevNode();
91+
rewriter.setInsertionPointAfter(elementYield);
92+
rewriter.replaceOpWithNewOp<StoreOp>(elementYield,
93+
elementYield->getOperands()[0], result,
94+
parallelBody->getArguments());
8595

8696
rewriter.replaceOp(op, {result});
8797
return success();
@@ -168,7 +178,6 @@ struct StdBufferizePass : public StdBufferizeBase<StdBufferizePass> {
168178

169179
target.addLegalDialect<StandardOpsDialect>();
170180
target.addLegalDialect<scf::SCFDialect>();
171-
target.addLegalDialect<tensor::TensorDialect>();
172181

173182
populateStdBufferizePatterns(context, typeConverter, patterns);
174183
target.addIllegalOp<DynamicTensorFromElementsOp, TensorCastOp,

mlir/test/Dialect/Standard/bufferize.mlir

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,20 +123,20 @@ func @tensor_from_elements(%arg0: index, %arg1: index) -> tensor<2xindex> {
123123
return %0 : tensor<2xindex>
124124
}
125125

126-
// The dynamic_tensor_from_elements op clones each op in its body.
127-
// Make sure that regions nested within such ops are recursively converted.
128-
// CHECK-LABEL: func @recursively_convert_cloned_regions
129-
func @recursively_convert_cloned_regions(%arg0: tensor<*xf32>, %arg1: index, %arg2: i1) -> tensor<?xindex> {
130-
%tensor = dynamic_tensor_from_elements %arg1 {
126+
// The dynamic_tensor_from_elements op needs to put its body into the
127+
// resulting scf.parallel. To handle unknown ops in the body, it cannot clone
128+
// the body because that would require the cloned ops to be legalized
129+
// immediately, which is usually not possible since they might be from various
130+
// other dialects.
131+
//
132+
// CHECK-LABEL: func @unknown_ops_in_body
133+
func @unknown_ops_in_body(%arg0: index) -> tensor<?xindex> {
134+
// CHECK-NOT: dynamic_tensor_from_elements
135+
%tensor = dynamic_tensor_from_elements %arg0 {
131136
^bb0(%iv: index):
132-
%48 = scf.if %arg2 -> (index) {
133-
scf.yield %iv : index
134-
} else {
135-
// CHECK-NOT: dim{{.*}}tensor
136-
%50 = dim %arg0, %iv : tensor<*xf32>
137-
scf.yield %50 : index
138-
}
139-
yield %48 : index
137+
// CHECK: test.source
138+
%0 = "test.source"() : () -> index
139+
yield %0 : index
140140
} : tensor<?xindex>
141141
return %tensor : tensor<?xindex>
142142
}

0 commit comments

Comments
 (0)