Skip to content

Commit 1a3f924

Browse files
author
git apple-llvm automerger
committed
Merge commit '1253c40727d2' from llvm.org/master into apple/main
2 parents c69fafe + 1253c40 commit 1a3f924

File tree

4 files changed

+130
-4
lines changed

4 files changed

+130
-4
lines changed

mlir/include/mlir/IR/Function.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ class FuncOp
6565
/// `argIndices` is allowed to have duplicates and can be in any order.
6666
void eraseArguments(ArrayRef<unsigned> argIndices);
6767

68+
/// Erase a single result at `resultIndex`.
69+
void eraseResult(unsigned resultIndex) { eraseResults({resultIndex}); }
70+
/// Erases the results listed in `resultIndices`.
71+
/// `resultIndices` is allowed to have duplicates and can be in any order.
72+
void eraseResults(ArrayRef<unsigned> resultIndices);
73+
6874
/// Create a deep copy of this function and all of its blocks, remapping
6975
/// any operands that use values outside of the function using the map that is
7076
/// provided (leaving them alone if no entry is present). If the mapper

mlir/lib/IR/Function.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,31 @@ void FuncOp::eraseArguments(ArrayRef<unsigned> argIndices) {
132132
entry.eraseArgument(originalNumArgs - i - 1);
133133
}
134134

135+
void FuncOp::eraseResults(ArrayRef<unsigned> resultIndices) {
136+
auto oldType = getType();
137+
int originalNumResults = oldType.getNumResults();
138+
llvm::BitVector eraseIndices(originalNumResults);
139+
for (auto index : resultIndices)
140+
eraseIndices.set(index);
141+
auto shouldEraseResult = [&](int i) { return eraseIndices.test(i); };
142+
143+
// There are 2 things that need to be updated:
144+
// - Function type.
145+
// - Result attrs.
146+
147+
// Update the function type and result attrs.
148+
SmallVector<Type, 4> newResultTypes;
149+
SmallVector<MutableDictionaryAttr, 4> newResultAttrs;
150+
for (int i = 0; i < originalNumResults; i++) {
151+
if (shouldEraseResult(i))
152+
continue;
153+
newResultTypes.emplace_back(oldType.getResult(i));
154+
newResultAttrs.emplace_back(getResultAttrDict(i));
155+
}
156+
setType(FunctionType::get(oldType.getInputs(), newResultTypes, getContext()));
157+
setAllResultAttrs(newResultAttrs);
158+
}
159+
135160
/// Clone the internal blocks from this function into dest and all attributes
136161
/// from this function to dest.
137162
void FuncOp::cloneInto(FuncOp dest, BlockAndValueMapping &mapper) {
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// RUN: mlir-opt %s -test-func-erase-result -split-input-file | FileCheck %s
2+
3+
// CHECK: func @f(){{$}}
4+
// CHECK-NOT: attributes{{.*}}result
5+
func @f() -> (f32 {test.erase_this_result})
6+
7+
// -----
8+
9+
// CHECK: func @f() -> (f32 {test.A})
10+
// CHECK-NOT: attributes{{.*}}result
11+
func @f() -> (
12+
f32 {test.erase_this_result},
13+
f32 {test.A}
14+
)
15+
16+
// -----
17+
18+
// CHECK: func @f() -> (f32 {test.A})
19+
// CHECK-NOT: attributes{{.*}}result
20+
func @f() -> (
21+
f32 {test.A},
22+
f32 {test.erase_this_result}
23+
)
24+
25+
// -----
26+
27+
// CHECK: func @f() -> (f32 {test.A}, f32 {test.B})
28+
// CHECK-NOT: attributes{{.*}}result
29+
func @f() -> (
30+
f32 {test.A},
31+
f32 {test.erase_this_result},
32+
f32 {test.B}
33+
)
34+
35+
// -----
36+
37+
// CHECK: func @f() -> (f32 {test.A}, f32 {test.B})
38+
// CHECK-NOT: attributes{{.*}}result
39+
func @f() -> (
40+
f32 {test.A},
41+
f32 {test.erase_this_result},
42+
f32 {test.erase_this_result},
43+
f32 {test.B}
44+
)
45+
46+
// -----
47+
48+
// CHECK: func @f() -> (f32 {test.A}, f32 {test.B}, f32 {test.C})
49+
// CHECK-NOT: attributes{{.*}}result
50+
func @f() -> (
51+
f32 {test.A},
52+
f32 {test.erase_this_result},
53+
f32 {test.B},
54+
f32 {test.erase_this_result},
55+
f32 {test.C}
56+
)
57+
58+
// -----
59+
60+
// CHECK: func @f() -> (tensor<1xf32>, tensor<2xf32>, tensor<3xf32>)
61+
// CHECK-NOT: attributes{{.*}}result
62+
func @f() -> (
63+
tensor<1xf32>,
64+
f32 {test.erase_this_result},
65+
tensor<2xf32>,
66+
f32 {test.erase_this_result},
67+
tensor<3xf32>
68+
)

mlir/test/lib/IR/TestFunc.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,30 @@ struct TestFuncEraseArg
3636
}
3737
};
3838

39+
/// This is a test pass for verifying FuncOp's eraseResult method.
40+
struct TestFuncEraseResult
41+
: public PassWrapper<TestFuncEraseResult, OperationPass<ModuleOp>> {
42+
void runOnOperation() override {
43+
auto module = getOperation();
44+
45+
for (FuncOp func : module.getOps<FuncOp>()) {
46+
SmallVector<unsigned, 4> indicesToErase;
47+
for (auto resultIndex : llvm::seq<int>(0, func.getNumResults())) {
48+
if (func.getResultAttr(resultIndex, "test.erase_this_result")) {
49+
// Push back twice to test that duplicate indices are handled
50+
// correctly.
51+
indicesToErase.push_back(resultIndex);
52+
indicesToErase.push_back(resultIndex);
53+
}
54+
}
55+
// Reverse the order to test that unsorted index lists are handled
56+
// correctly.
57+
std::reverse(indicesToErase.begin(), indicesToErase.end());
58+
func.eraseResults(indicesToErase);
59+
}
60+
}
61+
};
62+
3963
/// This is a test pass for verifying FuncOp's setType method.
4064
struct TestFuncSetType
4165
: public PassWrapper<TestFuncSetType, OperationPass<ModuleOp>> {
@@ -55,10 +79,13 @@ struct TestFuncSetType
5579

5680
namespace mlir {
5781
void registerTestFunc() {
58-
PassRegistration<TestFuncEraseArg> pass("test-func-erase-arg",
59-
"Test erasing func args.");
82+
PassRegistration<TestFuncEraseArg>("test-func-erase-arg",
83+
"Test erasing func args.");
84+
85+
PassRegistration<TestFuncEraseResult>("test-func-erase-result",
86+
"Test erasing func results.");
6087

61-
PassRegistration<TestFuncSetType> pass2("test-func-set-type",
62-
"Test FuncOp::setType.");
88+
PassRegistration<TestFuncSetType>("test-func-set-type",
89+
"Test FuncOp::setType.");
6390
}
6491
} // namespace mlir

0 commit comments

Comments
 (0)