Skip to content

Commit

Permalink
stage2: implement noinline fn
Browse files Browse the repository at this point in the history
  • Loading branch information
nektro committed Jul 21, 2022
1 parent 5b7e332 commit dda0f49
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 7 deletions.
18 changes: 13 additions & 5 deletions src/AstGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,7 @@ fn fnProtoExpr(
.is_inferred_error = false,
.is_test = false,
.is_extern = false,
.is_noinline = false,
.noalias_bits = noalias_bits,
});

Expand Down Expand Up @@ -3404,7 +3405,6 @@ fn fnDecl(
};
defer fn_gz.unstack();

// TODO: support noinline
const is_pub = fn_proto.visib_token != null;
const is_export = blk: {
const maybe_export_token = fn_proto.extern_export_inline_token orelse break :blk false;
Expand All @@ -3418,6 +3418,10 @@ fn fnDecl(
const maybe_inline_token = fn_proto.extern_export_inline_token orelse break :blk false;
break :blk token_tags[maybe_inline_token] == .keyword_inline;
};
const is_noinline = blk: {
const maybe_noinline_token = fn_proto.extern_export_inline_token orelse break :blk false;
break :blk token_tags[maybe_noinline_token] == .keyword_noinline;
};

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

Expand Down Expand Up @@ -3625,6 +3629,7 @@ fn fnDecl(
.is_inferred_error = false,
.is_test = false,
.is_extern = true,
.is_noinline = is_noinline,
.noalias_bits = noalias_bits,
});
} else func: {
Expand Down Expand Up @@ -3673,6 +3678,7 @@ fn fnDecl(
.is_inferred_error = is_inferred_error,
.is_test = false,
.is_extern = false,
.is_noinline = is_noinline,
.noalias_bits = noalias_bits,
});
};
Expand Down Expand Up @@ -4108,6 +4114,7 @@ fn testDecl(
.is_inferred_error = true,
.is_test = true,
.is_extern = false,
.is_noinline = false,
.noalias_bits = 0,
});

Expand Down Expand Up @@ -10191,6 +10198,7 @@ const GenZir = struct {
is_inferred_error: bool,
is_test: bool,
is_extern: bool,
is_noinline: bool,
}) !Zir.Inst.Ref {
assert(args.src_node != 0);
const astgen = gz.astgen;
Expand Down Expand Up @@ -10232,10 +10240,9 @@ const GenZir = struct {
}
const body_len = astgen.countBodyLenAfterFixups(body);

if (args.cc_ref != .none or args.lib_name != 0 or
args.is_var_args or args.is_test or args.is_extern or
args.align_ref != .none or args.section_ref != .none or
args.addrspace_ref != .none or args.noalias_bits != 0)
if (args.cc_ref != .none or args.lib_name != 0 or args.is_var_args or args.is_test or
args.is_extern or args.align_ref != .none or args.section_ref != .none or
args.addrspace_ref != .none or args.noalias_bits != 0 or args.is_noinline)
{
var align_body: []Zir.Inst.Index = &.{};
var addrspace_body: []Zir.Inst.Index = &.{};
Expand Down Expand Up @@ -10268,6 +10275,7 @@ const GenZir = struct {
.is_inferred_error = args.is_inferred_error,
.is_test = args.is_test,
.is_extern = args.is_extern,
.is_noinline = args.is_noinline,
.has_lib_name = args.lib_name != 0,
.has_any_noalias = args.noalias_bits != 0,

Expand Down
2 changes: 1 addition & 1 deletion src/Module.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1488,7 +1488,7 @@ pub const Fn = struct {
branch_quota: u32,
state: Analysis,
is_cold: bool = false,
is_noinline: bool = false,
is_noinline: bool,
calls_or_awaits_errorable_fn: bool = false,

/// Any inferred error sets that this function owns, both its own inferred error set and
Expand Down
9 changes: 9 additions & 0 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7075,6 +7075,7 @@ fn zirFunc(
src_locs,
null,
0,
false,
);
}

Expand Down Expand Up @@ -7204,6 +7205,7 @@ fn funcCommon(
src_locs: Zir.Inst.Func.SrcLocs,
opt_lib_name: ?[]const u8,
noalias_bits: u32,
is_noinline: bool,
) CompileError!Air.Inst.Ref {
const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };
Expand Down Expand Up @@ -7350,6 +7352,10 @@ fn funcCommon(
});
}

if (cc_workaround == .Inline and is_noinline) {
return sema.fail(block, cc_src, "callconv(.Inline) and noinline are incompatible together", .{});
}

break :fn_ty try Type.Tag.function.create(sema.arena, .{
.param_types = param_types,
.comptime_params = comptime_params.ptr,
Expand Down Expand Up @@ -7430,6 +7436,7 @@ fn funcCommon(
.rbrace_column = @truncate(u16, src_locs.columns >> 16),
.param_names = param_names,
.branch_quota = default_branch_quota,
.is_noinline = is_noinline,
};
if (maybe_inferred_error_set_node) |node| {
new_func.inferred_error_sets.prepend(node);
Expand Down Expand Up @@ -17858,6 +17865,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
const is_var_args = extra.data.bits.is_var_args;
const is_inferred_error = extra.data.bits.is_inferred_error;
const is_extern = extra.data.bits.is_extern;
const is_noinline = extra.data.bits.is_noinline;

return sema.funcCommon(
block,
Expand All @@ -17875,6 +17883,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
src_locs,
lib_name,
noalias_bits,
is_noinline,
);
}

Expand Down
3 changes: 2 additions & 1 deletion src/Zir.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2739,6 +2739,7 @@ pub const Inst = struct {
is_inferred_error: bool,
is_test: bool,
is_extern: bool,
is_noinline: bool,
has_align_ref: bool,
has_align_body: bool,
has_addrspace_ref: bool,
Expand All @@ -2751,7 +2752,7 @@ pub const Inst = struct {
has_ret_ty_body: bool,
has_lib_name: bool,
has_any_noalias: bool,
_: u16 = undefined,
_: u15 = undefined,
};
};

Expand Down
6 changes: 6 additions & 0 deletions src/codegen/llvm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,12 @@ pub const Object = struct {
DeclGen.removeFnAttr(llvm_func, "cold");
}

if (func.is_noinline) {
dg.addFnAttr(llvm_func, "noinline");
} else {
DeclGen.removeFnAttr(llvm_func, "noinline");
}

// Remove all the basic blocks of a function in order to start over, generating
// LLVM IR from an empty function body.
while (llvm_func.getFirstBasicBlock()) |bb| {
Expand Down
4 changes: 4 additions & 0 deletions src/print_zir.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2000,6 +2000,7 @@ const Writer = struct {
inferred_error_set,
false,
false,
false,

.none,
&.{},
Expand Down Expand Up @@ -2107,6 +2108,7 @@ const Writer = struct {
extra.data.bits.is_inferred_error,
extra.data.bits.is_var_args,
extra.data.bits.is_extern,
extra.data.bits.is_noinline,
align_ref,
align_body,
addrspace_ref,
Expand Down Expand Up @@ -2266,6 +2268,7 @@ const Writer = struct {
inferred_error_set: bool,
var_args: bool,
is_extern: bool,
is_noinline: bool,
align_ref: Zir.Inst.Ref,
align_body: []const Zir.Inst.Index,
addrspace_ref: Zir.Inst.Ref,
Expand All @@ -2289,6 +2292,7 @@ const Writer = struct {
try self.writeFlag(stream, "vargs, ", var_args);
try self.writeFlag(stream, "extern, ", is_extern);
try self.writeFlag(stream, "inferror, ", inferred_error_set);
try self.writeFlag(stream, "noinline, ", is_noinline);

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

0 comments on commit dda0f49

Please sign in to comment.