Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ updateCalls(ModuleOp module, const AllocDynamicSizesMap &map,
}
if (!options.filterFn(&callee))
return;
if (callee.isExternal() || callee.isPublic())
return;

SmallVector<Value, 6> replaceWithNewCallResults;
SmallVector<Value, 6> replaceWithOutParams;
for (OpResult result : op.getResults()) {
Expand Down Expand Up @@ -292,14 +295,14 @@ LogicalResult mlir::bufferization::promoteBufferResultsToOutParams(
// function.
AllocDynamicSizesMap map;
for (auto func : module.getOps<func::FuncOp>()) {
if (func.isExternal() || func.isPublic())
continue;
if (!options.filterFn(&func))
continue;
SmallVector<BlockArgument, 6> appendedEntryArgs;
if (failed(
updateFuncOp(func, appendedEntryArgs, options.addResultAttribute)))
return failure();
if (func.isExternal())
continue;
if (failed(updateReturnOps(func, appendedEntryArgs, map, options))) {
return failure();
}
Expand Down
4 changes: 2 additions & 2 deletions mlir/test/Conversion/ConvertToEmitC/tosa.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// RUN: mlir-opt --pass-pipeline=%{pipeline} %s | FileCheck %s
// -----

// CHECK: emitc.func @main(%[[ARG0:.*]]: !emitc.array<2xf32>, %[[ARG1:.*]]: !emitc.array<2xf32>, %[[RES:.*]]: !emitc.array<2xf32>) {
// CHECK: emitc.func private @main(%[[ARG0:.*]]: !emitc.array<2xf32>, %[[ARG1:.*]]: !emitc.array<2xf32>, %[[RES:.*]]: !emitc.array<2xf32>)
// CHECK-DAG: %[[C0:.*]] = "emitc.constant"() <{value = 0 : index}> : () -> !emitc.size_t
// CHECK-DAG: %[[C1:.*]] = "emitc.constant"() <{value = 1 : index}> : () -> !emitc.size_t
// CHECK-DAG: %[[C2:.*]] = "emitc.constant"() <{value = 2 : index}> : () -> !emitc.size_t
Expand All @@ -35,7 +35,7 @@
// CHECK-NEXT: }
// CHECK-NEXT: return
// CHECK-NEXT: }
func.func @main(%arg0: tensor<2xf32>, %arg1: tensor<2xf32>) -> tensor<2xf32> {
func.func private @main(%arg0: tensor<2xf32>, %arg1: tensor<2xf32>) -> tensor<2xf32> {
%0 = tosa.add %arg0, %arg1 : (tensor<2xf32>, tensor<2xf32>) -> tensor<2xf32>
return %0 : tensor<2xf32>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

// Note: This bufferization is not very efficient yet, but it works.

// CHECK-LABEL: func @callee(
// CHECK-LABEL: func private @callee(
// CHECK-SAME: %[[arg0:.*]]: memref<5xf32, strided<[?], offset: ?>>,
// CHECK-SAME: %[[arg1:.*]]: memref<5xf32, strided<[?], offset: ?>>) {
// This alloc is not needed, but it is inserted due to the out-of-place
Expand All @@ -21,21 +21,21 @@
// CHECK: return
// CHECK: }

// CHECK-NO-LAYOUT-LABEL: func @callee(
// CHECK-NO-LAYOUT-LABEL: func private @callee(
// CHECK-NO-LAYOUT-SAME: %[[arg0:.*]]: memref<5xf32>,
// CHECK-NO-LAYOUT-SAME: %[[arg1:.*]]: memref<5xf32>) {
// CHECK-NO-LAYOUT: %[[alloc:.*]] = memref.alloc() {{.*}} : memref<5xf32>
// CHECK-NO-LAYOUT: memref.copy %[[arg0]], %[[alloc]]
// CHECK-NO-LAYOUT: memref.store {{.*}}, %[[alloc]]
// CHECK-NO-LAYOUT: memref.copy %[[alloc]], %[[arg1]]

// CHECK-BASELINE-LABEL: func @callee(
// CHECK-BASELINE-LABEL: func private @callee(
// CHECK-BASELINE-SAME: %[[arg0:.*]]: memref<5xf32, strided<[?], offset: ?>>) -> memref<5xf32> {
// CHECK-BASELINE: %[[alloc:.*]] = memref.alloc() {{.*}} : memref<5xf32>
// CHECK-BASELINE: memref.copy %[[arg0]], %[[alloc]]
// CHECK-BASELINE: memref.store {{.*}}, %[[alloc]]
// CHECK-BASELINE: return %[[alloc]]
func.func @callee(%t: tensor<5xf32>) -> (tensor<5xf32>, tensor<5xf32>) {
func.func private @callee(%t: tensor<5xf32>) -> (tensor<5xf32>, tensor<5xf32>) {
%c0 = arith.constant 0 : index
%cst = arith.constant 8.0 : f32
// This must bufferize out-of-place.
Expand Down Expand Up @@ -68,15 +68,15 @@ func.func @main(%t: tensor<5xf32>) -> (f32, f32) {

// -----

// CHECK-LABEL: func @callee(
// CHECK-LABEL: func private @callee(
// CHECK-SAME: %{{.*}}: index,
// CHECK-SAME: %[[r:.*]]: memref<2x5xf32, strided<[?, ?], offset: ?>>) {
// CHECK: %[[alloc:.*]] = memref.alloc() {{.*}} : memref<10x20xf32>
// CHECK: %[[subview:.*]] = memref.subview %[[alloc]]{{.*}} : memref<10x20xf32> to memref<2x5xf32, strided<[20, 1], offset: ?>>
// CHECK: %[[casted:.*]] = memref.cast %[[subview]]
// CHECK: memref.copy %[[casted]], %[[r]]

// CHECK-NO-LAYOUT-LABEL: func @callee(
// CHECK-NO-LAYOUT-LABEL: func private @callee(
// CHECK-NO-LAYOUT-SAME: %{{.*}}: index,
// CHECK-NO-LAYOUT-SAME: %[[r:.*]]: memref<2x5xf32>) {
// CHECK-NO-LAYOUT: %[[alloc:.*]] = memref.alloc() {{.*}} : memref<10x20xf32>
Expand All @@ -88,12 +88,12 @@ func.func @main(%t: tensor<5xf32>) -> (f32, f32) {
// CHECK-NO-LAYOUT: memref.copy %[[subview]], %[[alloc2]]
// CHECK-NO-LAYOUT: memref.copy %[[alloc2]], %[[r]]

// CHECK-BASELINE-LABEL: func @callee(
// CHECK-BASELINE-LABEL: func private @callee(
// CHECK-BASELINE-SAME: %{{.*}}: index) -> memref<2x5xf32, strided<[20, 1], offset: ?>> {
// CHECK-BASELINE: %[[alloc:.*]] = memref.alloc() {{.*}} : memref<10x20xf32>
// CHECK-BASELINE: %[[subview:.*]] = memref.subview %[[alloc]]
// CHECK-BASELINE: return %[[subview]]
func.func @callee(%idx: index) -> tensor<2x5xf32> {
func.func private @callee(%idx: index) -> tensor<2x5xf32> {
%0 = bufferization.alloc_tensor() : tensor<10x20xf32>
%1 = tensor.extract_slice %0[%idx, %idx][2, 5][1, 1] : tensor<10x20xf32> to tensor<2x5xf32>
return %1 : tensor<2x5xf32>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: mlir-opt -p 'builtin.module(buffer-results-to-out-params{add-result-attr})' -split-input-file -verify-diagnostics %s | FileCheck %s

// CHECK-LABEL: @basic({{.*}}: memref<f32> {bufferize.result})
func.func @basic() -> (memref<f32>) {
func.func private @basic() -> (memref<f32>) {
%0 = "test.source"() : () -> (memref<f32>)
return %0 : memref<f32>
}
Expand All @@ -11,7 +11,7 @@ func.func @basic() -> (memref<f32>) {
// CHECK-LABEL: multiple_results
// CHECK-SAME: memref<1xf32> {bufferize.result}
// CHECK-SAME: memref<2xf32> {bufferize.result}
func.func @multiple_results() -> (memref<1xf32>, memref<2xf32>) {
func.func private @multiple_results() -> (memref<1xf32>, memref<2xf32>) {
%0, %1 = "test.source"() : () -> (memref<1xf32>, memref<2xf32>)
return %0, %1 : memref<1xf32>, memref<2xf32>
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
// RUN: mlir-opt -allow-unregistered-dialect -p 'builtin.module(buffer-results-to-out-params{hoist-static-allocs})' %s | FileCheck %s

// CHECK-LABEL: func @basic(
// CHECK-LABEL: func private @basic(
// CHECK-SAME: %[[ARG:.*]]: memref<8x64xf32>) {
// CHECK-NOT: memref.alloc()
// CHECK: "test.source"(%[[ARG]]) : (memref<8x64xf32>) -> ()
// CHECK: return
// CHECK: }
func.func @basic() -> (memref<8x64xf32>) {
func.func private @basic() -> (memref<8x64xf32>) {
%b = memref.alloc() : memref<8x64xf32>
"test.source"(%b) : (memref<8x64xf32>) -> ()
return %b : memref<8x64xf32>
}

// CHECK-LABEL: func @basic_no_change(
// CHECK-LABEL: func private @basic_no_change(
// CHECK-SAME: %[[ARG:.*]]: memref<f32>) {
// CHECK: %[[RESULT:.*]] = "test.source"() : () -> memref<f32>
// CHECK: memref.copy %[[RESULT]], %[[ARG]] : memref<f32> to memref<f32>
// CHECK: return
// CHECK: }
func.func @basic_no_change() -> (memref<f32>) {
func.func private @basic_no_change() -> (memref<f32>) {
%0 = "test.source"() : () -> (memref<f32>)
return %0 : memref<f32>
}

// CHECK-LABEL: func @basic_dynamic(
// CHECK-LABEL: func private @basic_dynamic(
// CHECK-SAME: %[[D:.*]]: index, %[[ARG:.*]]: memref<?xf32>) {
// CHECK: %[[RESULT:.*]] = memref.alloc(%[[D]]) : memref<?xf32>
// CHECK: "test.source"(%[[RESULT]]) : (memref<?xf32>) -> ()
// CHECK: memref.copy %[[RESULT]], %[[ARG]]
// CHECK: return
// CHECK: }
func.func @basic_dynamic(%d: index) -> (memref<?xf32>) {
func.func private @basic_dynamic(%d: index) -> (memref<?xf32>) {
%b = memref.alloc(%d) : memref<?xf32>
"test.source"(%b) : (memref<?xf32>) -> ()
return %b : memref<?xf32>
Expand All @@ -39,13 +39,13 @@ func.func @basic_dynamic(%d: index) -> (memref<?xf32>) {
// -----

// no change due to writing to func args
// CHECK-LABEL: func @return_arg(
// CHECK-LABEL: func private @return_arg(
// CHECK-SAME: %[[ARG0:.*]]: memref<128x256xf32>, %[[ARG1:.*]]: memref<128x256xf32>, %[[ARG2:.*]]: memref<128x256xf32>) {
// CHECK: "test.source"(%[[ARG0]], %[[ARG1]])
// CHECK: memref.copy
// CHECK: return
// CHECK: }
func.func @return_arg(%arg0: memref<128x256xf32>, %arg1: memref<128x256xf32>) -> memref<128x256xf32> {
func.func private @return_arg(%arg0: memref<128x256xf32>, %arg1: memref<128x256xf32>) -> memref<128x256xf32> {
"test.source"(%arg0, %arg1) : (memref<128x256xf32>, memref<128x256xf32>) -> ()
return %arg0 : memref<128x256xf32>
}
51 changes: 25 additions & 26 deletions mlir/test/Transforms/buffer-results-to-out-params.mlir
Original file line number Diff line number Diff line change
@@ -1,67 +1,66 @@
// RUN: mlir-opt -buffer-results-to-out-params -split-input-file -verify-diagnostics %s | FileCheck %s

// CHECK-LABEL: func @basic(
// CHECK-LABEL: func private @basic(
// CHECK-SAME: %[[ARG:.*]]: memref<f32>) {
// CHECK: %[[RESULT:.*]] = "test.source"() : () -> memref<f32>
// CHECK: memref.copy %[[RESULT]], %[[ARG]] : memref<f32> to memref<f32>
// CHECK: return
// CHECK: }
func.func @basic() -> (memref<f32>) {
func.func private @basic() -> (memref<f32>) {
%0 = "test.source"() : () -> (memref<f32>)
return %0 : memref<f32>
}

// CHECK-LABEL: func @presence_of_existing_arguments(
// CHECK-LABEL: func private @presence_of_existing_arguments(
// CHECK-SAME: %[[ARG0:.*]]: memref<1xf32>,
// CHECK-SAME: %[[ARG1:.*]]: memref<2xf32>) {
// CHECK: %[[RESULT:.*]] = "test.source"() : () -> memref<2xf32>
// CHECK: memref.copy %[[RESULT]], %[[ARG1]] : memref<2xf32> to memref<2xf32>
// CHECK: return
// CHECK: }
func.func @presence_of_existing_arguments(%arg0: memref<1xf32>) -> (memref<2xf32>) {
func.func private @presence_of_existing_arguments(%arg0: memref<1xf32>) -> (memref<2xf32>) {
%0 = "test.source"() : () -> (memref<2xf32>)
return %0 : memref<2xf32>
}

// CHECK-LABEL: func @multiple_results(
// CHECK-LABEL: func private @multiple_results(
// CHECK-SAME: %[[ARG0:.*]]: memref<1xf32>,
// CHECK-SAME: %[[ARG1:.*]]: memref<2xf32>) {
// CHECK: %[[RESULTS:.*]]:2 = "test.source"() : () -> (memref<1xf32>, memref<2xf32>)
// CHECK: memref.copy %[[RESULTS]]#0, %[[ARG0]] : memref<1xf32> to memref<1xf32>
// CHECK: memref.copy %[[RESULTS]]#1, %[[ARG1]] : memref<2xf32> to memref<2xf32>
// CHECK: return
// CHECK: }
func.func @multiple_results() -> (memref<1xf32>, memref<2xf32>) {
func.func private @multiple_results() -> (memref<1xf32>, memref<2xf32>) {
%0, %1 = "test.source"() : () -> (memref<1xf32>, memref<2xf32>)
return %0, %1 : memref<1xf32>, memref<2xf32>
}

// CHECK-LABEL: func @non_memref_types(
// CHECK-LABEL: func private @non_memref_types(
// CHECK-SAME: %[[OUTPARAM:.*]]: memref<f32>) -> (i1, i32) {
// CHECK: %[[RESULT1:.*]]:3 = "test.source"() : () -> (i1, memref<f32>, i32)
// CHECK: memref.copy %[[RESULT1]]#1, %[[OUTPARAM]] : memref<f32> to memref<f32>
// CHECK: return %[[RESULT1]]#0, %[[RESULT1]]#2 : i1, i32
// CHECK: }
func.func @non_memref_types() -> (i1, memref<f32>, i32) {
func.func private @non_memref_types() -> (i1, memref<f32>, i32) {
%0, %1, %2 = "test.source"() : () -> (i1, memref<f32>, i32)
return %0, %1, %2 : i1, memref<f32>, i32
}

// CHECK: func private @external_function(memref<f32>)
// CHECK: func private @external_function() -> memref<f32>
func.func private @external_function() -> (memref<f32>)
// CHECK: func private @result_attrs(memref<f32> {test.some_attr})
// CHECK: func private @result_attrs() -> (memref<f32> {test.some_attr})
func.func private @result_attrs() -> (memref<f32> {test.some_attr})
// CHECK: func private @mixed_result_attrs(memref<1xf32>, memref<2xf32> {test.some_attr}, memref<3xf32>)
// CHECK: func private @mixed_result_attrs() -> (memref<1xf32>, memref<2xf32> {test.some_attr}, memref<3xf32>)
func.func private @mixed_result_attrs() -> (memref<1xf32>, memref<2xf32> {test.some_attr}, memref<3xf32>)

// -----

// CHECK-LABEL: func private @callee(memref<1xf32>)
// CHECK-LABEL: func private @callee() -> memref<1xf32>
func.func private @callee() -> memref<1xf32>

// CHECK-LABEL: func @call_basic() {
// CHECK: %[[OUTPARAM:.*]] = memref.alloc() : memref<1xf32>
// CHECK: call @callee(%[[OUTPARAM]]) : (memref<1xf32>) -> ()
// CHECK: %[[OUTPARAM:.*]] = call @callee() : () -> memref<1xf32>
// CHECK: "test.sink"(%[[OUTPARAM]]) : (memref<1xf32>) -> ()
// CHECK: return
// CHECK: }
Expand All @@ -73,14 +72,12 @@ func.func @call_basic() {

// -----

// CHECK-LABEL: func private @callee(memref<1xf32>, memref<2xf32>)
// CHECK-LABEL: func private @callee() -> (memref<1xf32>, memref<2xf32>)
func.func private @callee() -> (memref<1xf32>, memref<2xf32>)

// CHECK-LABEL: func @call_multiple_result() {
// CHECK: %[[RESULT0:.*]] = memref.alloc() : memref<1xf32>
// CHECK: %[[RESULT1:.*]] = memref.alloc() : memref<2xf32>
// CHECK: call @callee(%[[RESULT0]], %[[RESULT1]]) : (memref<1xf32>, memref<2xf32>) -> ()
// CHECK: "test.sink"(%[[RESULT0]], %[[RESULT1]]) : (memref<1xf32>, memref<2xf32>) -> ()
// CHECK: %[[RESULTS:.*]]:2 = call @callee() : () -> (memref<1xf32>, memref<2xf32>)
// CHECK: "test.sink"(%[[RESULTS]]#0, %[[RESULTS]]#1) : (memref<1xf32>, memref<2xf32>) -> ()
// CHECK: }
func.func @call_multiple_result() {
%0, %1 = call @callee() : () -> (memref<1xf32>, memref<2xf32>)
Expand All @@ -89,13 +86,12 @@ func.func @call_multiple_result() {

// -----

// CHECK-LABEL: func private @callee(memref<1xf32>) -> (i1, i32)
// CHECK-LABEL: func private @callee() -> (i1, memref<1xf32>, i32)
func.func private @callee() -> (i1, memref<1xf32>, i32)

// CHECK-LABEL: func @call_non_memref_result() {
// CHECK: %[[RESULT0:.*]] = memref.alloc() : memref<1xf32>
// CHECK: %[[NON_MEMREF_RESULTS:.*]]:2 = call @callee(%[[RESULT0]]) : (memref<1xf32>) -> (i1, i32)
// CHECK: "test.sink"(%[[NON_MEMREF_RESULTS]]#0, %[[RESULT0]], %[[NON_MEMREF_RESULTS]]#1) : (i1, memref<1xf32>, i32) -> ()
// CHECK: %[[RESULTS:.*]]:3 = call @callee() : () -> (i1, memref<1xf32>, i32)
// CHECK: "test.sink"(%[[RESULTS]]#0, %[[RESULTS]]#1, %[[RESULTS]]#2) : (i1, memref<1xf32>, i32) -> ()
// CHECK: }
func.func @call_non_memref_result() {
%0, %1, %2 = call @callee() : () -> (i1, memref<1xf32>, i32)
Expand All @@ -104,10 +100,13 @@ func.func @call_non_memref_result() {

// -----

func.func private @callee() -> (memref<?xf32>)
func.func private @callee(%size: index) -> (memref<?xf32>) {
%alloc = memref.alloc(%size) : memref<?xf32>
return %alloc : memref<?xf32>
}

func.func @call_non_memref_result() {
func.func @call_non_memref_result(%size: index) {
// expected-error @+1 {{cannot create out param for dynamically shaped result}}
%0 = call @callee() : () -> (memref<?xf32>)
%0 = call @callee(%size) : (index) -> (memref<?xf32>)
"test.sink"(%0) : (memref<?xf32>) -> ()
}