Skip to content

Commit 002f7dd

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

File tree

6 files changed

+35
-7
lines changed

6 files changed

+35
-7
lines changed

src/AstGen.zig

Lines changed: 17 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

@@ -3599,6 +3603,10 @@ fn fnDecl(
35993603
break :inst inst;
36003604
};
36013605

3606+
if (has_inline_keyword and is_noinline) {
3607+
return astgen.failTok(fn_name_token, "function prototype may not be both inline and noinline", .{});
3608+
}
3609+
36023610
const func_inst: Zir.Inst.Ref = if (body_node == 0) func: {
36033611
if (!is_extern) {
36043612
return astgen.failTok(fn_proto.ast.fn_token, "non-extern function has no body", .{});
@@ -3625,6 +3633,7 @@ fn fnDecl(
36253633
.is_inferred_error = false,
36263634
.is_test = false,
36273635
.is_extern = true,
3636+
.is_noinline = is_noinline,
36283637
.noalias_bits = noalias_bits,
36293638
});
36303639
} else func: {
@@ -3673,6 +3682,7 @@ fn fnDecl(
36733682
.is_inferred_error = is_inferred_error,
36743683
.is_test = false,
36753684
.is_extern = false,
3685+
.is_noinline = is_noinline,
36763686
.noalias_bits = noalias_bits,
36773687
});
36783688
};
@@ -4108,6 +4118,7 @@ fn testDecl(
41084118
.is_inferred_error = true,
41094119
.is_test = true,
41104120
.is_extern = false,
4121+
.is_noinline = false,
41114122
.noalias_bits = 0,
41124123
});
41134124

@@ -10191,6 +10202,7 @@ const GenZir = struct {
1019110202
is_inferred_error: bool,
1019210203
is_test: bool,
1019310204
is_extern: bool,
10205+
is_noinline: bool,
1019410206
}) !Zir.Inst.Ref {
1019510207
assert(args.src_node != 0);
1019610208
const astgen = gz.astgen;
@@ -10232,10 +10244,9 @@ const GenZir = struct {
1023210244
}
1023310245
const body_len = astgen.countBodyLenAfterFixups(body);
1023410246

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)
10247+
if (args.cc_ref != .none or args.lib_name != 0 or args.is_var_args or args.is_test or
10248+
args.is_extern or args.align_ref != .none or args.section_ref != .none or
10249+
args.addrspace_ref != .none or args.noalias_bits != 0 or args.is_noinline)
1023910250
{
1024010251
var align_body: []Zir.Inst.Index = &.{};
1024110252
var addrspace_body: []Zir.Inst.Index = &.{};
@@ -10268,6 +10279,7 @@ const GenZir = struct {
1026810279
.is_inferred_error = args.is_inferred_error,
1026910280
.is_test = args.is_test,
1027010281
.is_extern = args.is_extern,
10282+
.is_noinline = args.is_noinline,
1027110283
.has_lib_name = args.lib_name != 0,
1027210284
.has_any_noalias = args.noalias_bits != 0,
1027310285

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: 5 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 };
@@ -7430,6 +7432,7 @@ fn funcCommon(
74307432
.rbrace_column = @truncate(u16, src_locs.columns >> 16),
74317433
.param_names = param_names,
74327434
.branch_quota = default_branch_quota,
7435+
.is_noinline = is_noinline,
74337436
};
74347437
if (maybe_inferred_error_set_node) |node| {
74357438
new_func.inferred_error_sets.prepend(node);
@@ -17858,6 +17861,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1785817861
const is_var_args = extra.data.bits.is_var_args;
1785917862
const is_inferred_error = extra.data.bits.is_inferred_error;
1786017863
const is_extern = extra.data.bits.is_extern;
17864+
const is_noinline = extra.data.bits.is_noinline;
1786117865

1786217866
return sema.funcCommon(
1786317867
block,
@@ -17875,6 +17879,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1787517879
src_locs,
1787617880
lib_name,
1787717881
noalias_bits,
17882+
is_noinline,
1787817883
);
1787917884
}
1788017885

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)