Skip to content

Commit dda0f49

Browse files
committed
stage2: implement noinline fn
1 parent 5b7e332 commit dda0f49

File tree

6 files changed

+35
-7
lines changed

6 files changed

+35
-7
lines changed

src/AstGen.zig

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,7 @@ fn fnProtoExpr(
12741274
.is_inferred_error = false,
12751275
.is_test = false,
12761276
.is_extern = false,
1277+
.is_noinline = false,
12771278
.noalias_bits = noalias_bits,
12781279
});
12791280

@@ -3404,7 +3405,6 @@ fn fnDecl(
34043405
};
34053406
defer fn_gz.unstack();
34063407

3407-
// TODO: support noinline
34083408
const is_pub = fn_proto.visib_token != null;
34093409
const is_export = blk: {
34103410
const maybe_export_token = fn_proto.extern_export_inline_token orelse break :blk false;
@@ -3418,6 +3418,10 @@ fn fnDecl(
34183418
const maybe_inline_token = fn_proto.extern_export_inline_token orelse break :blk false;
34193419
break :blk token_tags[maybe_inline_token] == .keyword_inline;
34203420
};
3421+
const is_noinline = blk: {
3422+
const maybe_noinline_token = fn_proto.extern_export_inline_token orelse break :blk false;
3423+
break :blk token_tags[maybe_noinline_token] == .keyword_noinline;
3424+
};
34213425

34223426
const doc_comment_index = try astgen.docCommentAsString(fn_proto.firstToken());
34233427

@@ -3625,6 +3629,7 @@ fn fnDecl(
36253629
.is_inferred_error = false,
36263630
.is_test = false,
36273631
.is_extern = true,
3632+
.is_noinline = is_noinline,
36283633
.noalias_bits = noalias_bits,
36293634
});
36303635
} else func: {
@@ -3673,6 +3678,7 @@ fn fnDecl(
36733678
.is_inferred_error = is_inferred_error,
36743679
.is_test = false,
36753680
.is_extern = false,
3681+
.is_noinline = is_noinline,
36763682
.noalias_bits = noalias_bits,
36773683
});
36783684
};
@@ -4108,6 +4114,7 @@ fn testDecl(
41084114
.is_inferred_error = true,
41094115
.is_test = true,
41104116
.is_extern = false,
4117+
.is_noinline = false,
41114118
.noalias_bits = 0,
41124119
});
41134120

@@ -10191,6 +10198,7 @@ const GenZir = struct {
1019110198
is_inferred_error: bool,
1019210199
is_test: bool,
1019310200
is_extern: bool,
10201+
is_noinline: bool,
1019410202
}) !Zir.Inst.Ref {
1019510203
assert(args.src_node != 0);
1019610204
const astgen = gz.astgen;
@@ -10232,10 +10240,9 @@ const GenZir = struct {
1023210240
}
1023310241
const body_len = astgen.countBodyLenAfterFixups(body);
1023410242

10235-
if (args.cc_ref != .none or args.lib_name != 0 or
10236-
args.is_var_args or args.is_test or args.is_extern or
10237-
args.align_ref != .none or args.section_ref != .none or
10238-
args.addrspace_ref != .none or args.noalias_bits != 0)
10243+
if (args.cc_ref != .none or args.lib_name != 0 or args.is_var_args or args.is_test or
10244+
args.is_extern or args.align_ref != .none or args.section_ref != .none or
10245+
args.addrspace_ref != .none or args.noalias_bits != 0 or args.is_noinline)
1023910246
{
1024010247
var align_body: []Zir.Inst.Index = &.{};
1024110248
var addrspace_body: []Zir.Inst.Index = &.{};
@@ -10268,6 +10275,7 @@ const GenZir = struct {
1026810275
.is_inferred_error = args.is_inferred_error,
1026910276
.is_test = args.is_test,
1027010277
.is_extern = args.is_extern,
10278+
.is_noinline = args.is_noinline,
1027110279
.has_lib_name = args.lib_name != 0,
1027210280
.has_any_noalias = args.noalias_bits != 0,
1027310281

src/Module.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ pub const Fn = struct {
14881488
branch_quota: u32,
14891489
state: Analysis,
14901490
is_cold: bool = false,
1491-
is_noinline: bool = false,
1491+
is_noinline: bool,
14921492
calls_or_awaits_errorable_fn: bool = false,
14931493

14941494
/// Any inferred error sets that this function owns, both its own inferred error set and

src/Sema.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7075,6 +7075,7 @@ fn zirFunc(
70757075
src_locs,
70767076
null,
70777077
0,
7078+
false,
70787079
);
70797080
}
70807081

@@ -7204,6 +7205,7 @@ fn funcCommon(
72047205
src_locs: Zir.Inst.Func.SrcLocs,
72057206
opt_lib_name: ?[]const u8,
72067207
noalias_bits: u32,
7208+
is_noinline: bool,
72077209
) CompileError!Air.Inst.Ref {
72087210
const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
72097211
const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };
@@ -7350,6 +7352,10 @@ fn funcCommon(
73507352
});
73517353
}
73527354

7355+
if (cc_workaround == .Inline and is_noinline) {
7356+
return sema.fail(block, cc_src, "callconv(.Inline) and noinline are incompatible together", .{});
7357+
}
7358+
73537359
break :fn_ty try Type.Tag.function.create(sema.arena, .{
73547360
.param_types = param_types,
73557361
.comptime_params = comptime_params.ptr,
@@ -7430,6 +7436,7 @@ fn funcCommon(
74307436
.rbrace_column = @truncate(u16, src_locs.columns >> 16),
74317437
.param_names = param_names,
74327438
.branch_quota = default_branch_quota,
7439+
.is_noinline = is_noinline,
74337440
};
74347441
if (maybe_inferred_error_set_node) |node| {
74357442
new_func.inferred_error_sets.prepend(node);
@@ -17858,6 +17865,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1785817865
const is_var_args = extra.data.bits.is_var_args;
1785917866
const is_inferred_error = extra.data.bits.is_inferred_error;
1786017867
const is_extern = extra.data.bits.is_extern;
17868+
const is_noinline = extra.data.bits.is_noinline;
1786117869

1786217870
return sema.funcCommon(
1786317871
block,
@@ -17875,6 +17883,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1787517883
src_locs,
1787617884
lib_name,
1787717885
noalias_bits,
17886+
is_noinline,
1787817887
);
1787917888
}
1788017889

src/Zir.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2739,6 +2739,7 @@ pub const Inst = struct {
27392739
is_inferred_error: bool,
27402740
is_test: bool,
27412741
is_extern: bool,
2742+
is_noinline: bool,
27422743
has_align_ref: bool,
27432744
has_align_body: bool,
27442745
has_addrspace_ref: bool,
@@ -2751,7 +2752,7 @@ pub const Inst = struct {
27512752
has_ret_ty_body: bool,
27522753
has_lib_name: bool,
27532754
has_any_noalias: bool,
2754-
_: u16 = undefined,
2755+
_: u15 = undefined,
27552756
};
27562757
};
27572758

src/codegen/llvm.zig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,12 @@ pub const Object = struct {
699699
DeclGen.removeFnAttr(llvm_func, "cold");
700700
}
701701

702+
if (func.is_noinline) {
703+
dg.addFnAttr(llvm_func, "noinline");
704+
} else {
705+
DeclGen.removeFnAttr(llvm_func, "noinline");
706+
}
707+
702708
// Remove all the basic blocks of a function in order to start over, generating
703709
// LLVM IR from an empty function body.
704710
while (llvm_func.getFirstBasicBlock()) |bb| {

src/print_zir.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,6 +2000,7 @@ const Writer = struct {
20002000
inferred_error_set,
20012001
false,
20022002
false,
2003+
false,
20032004

20042005
.none,
20052006
&.{},
@@ -2107,6 +2108,7 @@ const Writer = struct {
21072108
extra.data.bits.is_inferred_error,
21082109
extra.data.bits.is_var_args,
21092110
extra.data.bits.is_extern,
2111+
extra.data.bits.is_noinline,
21102112
align_ref,
21112113
align_body,
21122114
addrspace_ref,
@@ -2266,6 +2268,7 @@ const Writer = struct {
22662268
inferred_error_set: bool,
22672269
var_args: bool,
22682270
is_extern: bool,
2271+
is_noinline: bool,
22692272
align_ref: Zir.Inst.Ref,
22702273
align_body: []const Zir.Inst.Index,
22712274
addrspace_ref: Zir.Inst.Ref,
@@ -2289,6 +2292,7 @@ const Writer = struct {
22892292
try self.writeFlag(stream, "vargs, ", var_args);
22902293
try self.writeFlag(stream, "extern, ", is_extern);
22912294
try self.writeFlag(stream, "inferror, ", inferred_error_set);
2295+
try self.writeFlag(stream, "noinline, ", is_noinline);
22922296

22932297
if (noalias_bits != 0) {
22942298
try stream.print("noalias=0b{b}, ", .{noalias_bits});

0 commit comments

Comments
 (0)