Skip to content

Commit d072ca1

Browse files
authored
[mlir] add noinline attribute to func.func/call (#119970)
This allows for inlining to be somewhat controlled by the user instead of always inlining everything. External heuristics may be used to place `no_inline` attributes on invidiual calls or functions to prevent inlining.
1 parent 1c352e6 commit d072ca1

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

mlir/include/mlir/Dialect/Func/IR/FuncOps.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ def CallOp : Func_Op<"call",
4949
```
5050
}];
5151

52-
let arguments = (ins FlatSymbolRefAttr:$callee, Variadic<AnyType>:$operands);
52+
let arguments = (ins FlatSymbolRefAttr:$callee, Variadic<AnyType>:$operands,
53+
UnitAttr:$no_inline);
5354
let results = (outs Variadic<AnyType>);
5455

5556
let builders = [
@@ -270,7 +271,8 @@ def FuncOp : Func_Op<"func", [
270271
TypeAttrOf<FunctionType>:$function_type,
271272
OptionalAttr<StrAttr>:$sym_visibility,
272273
OptionalAttr<DictArrayAttr>:$arg_attrs,
273-
OptionalAttr<DictArrayAttr>:$res_attrs);
274+
OptionalAttr<DictArrayAttr>:$res_attrs,
275+
UnitAttr:$no_inline);
274276
let regions = (region AnyRegion:$body);
275277

276278
let builders = [OpBuilder<(ins

mlir/lib/Dialect/Func/Extensions/InlinerExtension.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,22 @@ struct FuncInlinerInterface : public DialectInlinerInterface {
2727
// Analysis Hooks
2828
//===--------------------------------------------------------------------===//
2929

30-
/// All call operations can be inlined.
30+
/// Call operations can be inlined unless specified otherwise by attributes
31+
/// on either the call or the callbale.
3132
bool isLegalToInline(Operation *call, Operation *callable,
3233
bool wouldBeCloned) const final {
33-
return true;
34+
auto callOp = dyn_cast<func::CallOp>(call);
35+
auto funcOp = dyn_cast<func::FuncOp>(callable);
36+
return !(callOp && callOp.getNoInline()) &&
37+
!(funcOp && funcOp.getNoInline());
3438
}
3539

3640
/// All operations can be inlined.
3741
bool isLegalToInline(Operation *, Region *, bool, IRMapping &) const final {
3842
return true;
3943
}
4044

41-
/// All functions can be inlined.
45+
/// All function bodies can be inlined.
4246
bool isLegalToInline(Region *, Region *, bool, IRMapping &) const final {
4347
return true;
4448
}

mlir/test/Transforms/inlining.mlir

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,29 @@ func.func @inline_with_arg(%arg0 : i32) -> i32 {
1919
return %0 : i32
2020
}
2121

22+
// CHECK-LABEL: func @noinline_with_arg
23+
func.func @noinline_with_arg(%arg0 : i32) -> i32 {
24+
// CHECK-NEXT: func_with_arg
25+
// CHECK-NEXT: return
26+
27+
%0 = call @func_with_arg(%arg0) {no_inline} : (i32) -> i32
28+
return %0 : i32
29+
}
30+
31+
func.func @non_inlinable_func_with_arg(%c : i32) -> i32 attributes {no_inline} {
32+
%b = arith.addi %c, %c : i32
33+
return %b : i32
34+
}
35+
36+
// CHECK-LABEL: func @noinline_with_func_arg
37+
func.func @noinline_with_func_arg(%arg0 : i32) -> i32 {
38+
// CHECK-NEXT: non_inlinable_func_with_arg
39+
// CHECK-NEXT: return
40+
41+
%0 = call @non_inlinable_func_with_arg(%arg0) : (i32) -> i32
42+
return %0 : i32
43+
}
44+
2245
// Inline a function that has multiple return operations.
2346
func.func @func_with_multi_return(%a : i1) -> (i32) {
2447
cf.cond_br %a, ^bb1, ^bb2

0 commit comments

Comments
 (0)