authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-25 17:27:21-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-05-25 23:32:52-04:00
logab88165326abfd81c5046e8c064bd6603198ed94
tree26de606950aae4029d07f0cfc7612d47914d6c98
parent1dd710947696ed11e35e9fc98b7dab4a1188c0d5

Sema: generic function instantiations inherit branch quota


3 files changed, 12 insertions(+), 5 deletions(-)

src/Module.zig+5
......@@ -1476,6 +1476,10 @@ pub const Fn = struct {
14761476 lbrace_column: u16,
14771477 rbrace_column: u16,
14781478
1479 /// When a generic function is instantiated, this value is inherited from the
1480 /// active Sema context. Importantly, this value is also updated when an existing
1481 /// generic function instantiation is found and called.
1482 branch_quota: u32,
14791483 state: Analysis,
14801484 is_cold: bool = false,
14811485 is_noinline: bool = false,
......@@ -4891,6 +4895,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
48914895 .func = func,
48924896 .fn_ret_ty = decl.ty.fnReturnType(),
48934897 .owner_func = func,
4898 .branch_quota = @maximum(func.branch_quota, Sema.default_branch_quota),
48944899 };
48954900 defer sema.deinit();
48964901
src/Sema.zig+7-3
......@@ -38,7 +38,7 @@ func: ?*Module.Fn,
3838/// generic function which uses a type expression for the return type.
3939/// The type will be `void` in the case that `func` is `null`.
4040fn_ret_ty: Type,
41branch_quota: u32 = 1000,
41branch_quota: u32 = default_branch_quota,
4242branch_count: u32 = 0,
4343/// Populated when returning `error.ComptimeBreak`. Used to communicate the
4444/// break instruction up the stack to find the corresponding Block.
......@@ -102,6 +102,8 @@ const Package = @import("Package.zig");
102102const crash_report = @import("crash_report.zig");
103103const build_options = @import("build_options");
104104
105pub const default_branch_quota = 1000;
106
105107pub const InstMap = std.AutoHashMapUnmanaged(Zir.Inst.Index, Air.Inst.Ref);
106108
107109/// This is the context needed to semantically analyze ZIR instructions and
......@@ -3752,8 +3754,7 @@ fn zirSetEvalBranchQuota(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
37523754 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
37533755 const src = inst_data.src();
37543756 const quota = @intCast(u32, try sema.resolveInt(block, src, inst_data.operand, Type.u32));
3755 if (sema.branch_quota < quota)
3756 sema.branch_quota = quota;
3757 sema.branch_quota = @maximum(sema.branch_quota, quota);
37573758}
37583759
37593760fn zirStore(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
......@@ -5679,6 +5680,8 @@ fn instantiateGenericCall(
56795680 break :callee new_func;
56805681 } else gop.key_ptr.*;
56815682
5683 callee.branch_quota = @maximum(callee.branch_quota, sema.branch_quota);
5684
56825685 const callee_inst = try sema.analyzeDeclVal(block, func_src, callee.owner_decl);
56835686
56845687 // Make a runtime call to the new function, making sure to omit the comptime args.
......@@ -6773,6 +6776,7 @@ fn funcCommon(
67736776 .lbrace_column = @truncate(u16, src_locs.columns),
67746777 .rbrace_column = @truncate(u16, src_locs.columns >> 16),
67756778 .param_names = param_names,
6779 .branch_quota = default_branch_quota,
67766780 };
67776781 if (maybe_inferred_error_set_node) |node| {
67786782 new_func.inferred_error_sets.prepend(node);
test/behavior/eval.zig-2
......@@ -704,8 +704,6 @@ test "call method with comptime pass-by-non-copying-value self parameter" {
704704}
705705
706706test "setting backward branch quota just before a generic fn call" {
707 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
708
709707 @setEvalBranchQuota(1001);
710708 loopNTimes(1001);
711709}