authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-08-13 03:08:55+01:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-08-17 18:50:10-04:00
log434ad906101a72c3c94f6a0fec1aa11d36b46ebb
treee6a5aafef1163bbe9930f8b9579c38f7629fda10
parent936a79f428241f25468f5e54bd24bb6e9a78adbd

Sema: disable comptime call memoization under -fincremental


1 files changed, 21 insertions(+), 18 deletions(-)

src/Sema.zig+21-18
...@@ -7560,14 +7560,14 @@ fn analyzeCall(...@@ -7560,14 +7560,14 @@ fn analyzeCall(
7560 operation: CallOperation,7560 operation: CallOperation,
7561) CompileError!Air.Inst.Ref {7561) CompileError!Air.Inst.Ref {
7562 const pt = sema.pt;7562 const pt = sema.pt;
7563 const mod = pt.zcu;7563 const zcu = pt.zcu;
7564 const ip = &mod.intern_pool;7564 const ip = &zcu.intern_pool;
75657565
7566 const callee_ty = sema.typeOf(func);7566 const callee_ty = sema.typeOf(func);
7567 const func_ty_info = mod.typeToFunc(func_ty).?;7567 const func_ty_info = zcu.typeToFunc(func_ty).?;
7568 const cc = func_ty_info.cc;7568 const cc = func_ty_info.cc;
7569 if (try sema.resolveValue(func)) |func_val|7569 if (try sema.resolveValue(func)) |func_val|
7570 if (func_val.isUndef(mod))7570 if (func_val.isUndef(zcu))
7571 return sema.failWithUseOfUndef(block, call_src);7571 return sema.failWithUseOfUndef(block, call_src);
7572 if (cc == .Naked) {7572 if (cc == .Naked) {
7573 const maybe_func_inst = try sema.funcDeclSrcInst(func);7573 const maybe_func_inst = try sema.funcDeclSrcInst(func);
...@@ -7679,7 +7679,7 @@ fn analyzeCall(...@@ -7679,7 +7679,7 @@ fn analyzeCall(
7679 .needed_comptime_reason = "function being called at comptime must be comptime-known",7679 .needed_comptime_reason = "function being called at comptime must be comptime-known",
7680 .block_comptime_reason = comptime_reason,7680 .block_comptime_reason = comptime_reason,
7681 });7681 });
7682 const module_fn_index = switch (mod.intern_pool.indexToKey(func_val.toIntern())) {7682 const module_fn_index = switch (zcu.intern_pool.indexToKey(func_val.toIntern())) {
7683 .@"extern" => return sema.fail(block, call_src, "{s} call of extern function", .{7683 .@"extern" => return sema.fail(block, call_src, "{s} call of extern function", .{
7684 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),7684 @as([]const u8, if (is_comptime_call) "comptime" else "inline"),
7685 }),7685 }),
...@@ -7696,7 +7696,7 @@ fn analyzeCall(...@@ -7696,7 +7696,7 @@ fn analyzeCall(
7696 },7696 },
7697 else => {},7697 else => {},
7698 }7698 }
7699 assert(callee_ty.isPtrAtRuntime(mod));7699 assert(callee_ty.isPtrAtRuntime(zcu));
7700 return sema.fail(block, call_src, "{s} call of function pointer", .{7700 return sema.fail(block, call_src, "{s} call of function pointer", .{
7701 if (is_comptime_call) "comptime" else "inline",7701 if (is_comptime_call) "comptime" else "inline",
7702 });7702 });
...@@ -7736,7 +7736,7 @@ fn analyzeCall(...@@ -7736,7 +7736,7 @@ fn analyzeCall(
7736 },7736 },
7737 };7737 };
77387738
7739 const module_fn = mod.funcInfo(module_fn_index);7739 const module_fn = zcu.funcInfo(module_fn_index);
77407740
7741 // This is not a function instance, so the function's `Nav` has a7741 // This is not a function instance, so the function's `Nav` has a
7742 // `Cau` -- we don't need to check `generic_owner`.7742 // `Cau` -- we don't need to check `generic_owner`.
...@@ -7750,7 +7750,7 @@ fn analyzeCall(...@@ -7750,7 +7750,7 @@ fn analyzeCall(
7750 // whenever performing an operation where the difference matters.7750 // whenever performing an operation where the difference matters.
7751 var ics = InlineCallSema.init(7751 var ics = InlineCallSema.init(
7752 sema,7752 sema,
7753 mod.cauFileScope(fn_cau_index).zir,7753 zcu.cauFileScope(fn_cau_index).zir,
7754 module_fn_index,7754 module_fn_index,
7755 block.error_return_trace_index,7755 block.error_return_trace_index,
7756 );7756 );
...@@ -7784,13 +7784,16 @@ fn analyzeCall(...@@ -7784,13 +7784,16 @@ fn analyzeCall(
77847784
7785 // Whether this call should be memoized, set to false if the call can7785 // Whether this call should be memoized, set to false if the call can
7786 // mutate comptime state.7786 // mutate comptime state.
7787 var should_memoize = true;7787 // TODO: comptime call memoization is currently not supported under incremental compilation
7788 // since dependencies are not marked on callers. If we want to keep this around (we should
7789 // check that it's worthwhile first!), each memoized call needs a `Cau`.
7790 var should_memoize = !zcu.comp.incremental;
77887791
7789 // If it's a comptime function call, we need to memoize it as long as no external7792 // If it's a comptime function call, we need to memoize it as long as no external
7790 // comptime memory is mutated.7793 // comptime memory is mutated.
7791 const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);7794 const memoized_arg_values = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
77927795
7793 const owner_info = mod.typeToFunc(Type.fromInterned(module_fn.ty)).?;7796 const owner_info = zcu.typeToFunc(Type.fromInterned(module_fn.ty)).?;
7794 const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len);7797 const new_param_types = try sema.arena.alloc(InternPool.Index, owner_info.param_types.len);
7795 var new_fn_info: InternPool.GetFuncTypeKey = .{7798 var new_fn_info: InternPool.GetFuncTypeKey = .{
7796 .param_types = new_param_types,7799 .param_types = new_param_types,
...@@ -7875,12 +7878,12 @@ fn analyzeCall(...@@ -7875,12 +7878,12 @@ fn analyzeCall(
7875 // bug generating invalid LLVM IR.7878 // bug generating invalid LLVM IR.
7876 const res2: Air.Inst.Ref = res2: {7879 const res2: Air.Inst.Ref = res2: {
7877 if (should_memoize and is_comptime_call) {7880 if (should_memoize and is_comptime_call) {
7878 if (mod.intern_pool.getIfExists(.{ .memoized_call = .{7881 if (zcu.intern_pool.getIfExists(.{ .memoized_call = .{
7879 .func = module_fn_index,7882 .func = module_fn_index,
7880 .arg_values = memoized_arg_values,7883 .arg_values = memoized_arg_values,
7881 .result = .none,7884 .result = .none,
7882 } })) |memoized_call_index| {7885 } })) |memoized_call_index| {
7883 const memoized_call = mod.intern_pool.indexToKey(memoized_call_index).memoized_call;7886 const memoized_call = zcu.intern_pool.indexToKey(memoized_call_index).memoized_call;
7884 break :res2 Air.internedToRef(memoized_call.result);7887 break :res2 Air.internedToRef(memoized_call.result);
7885 }7888 }
7886 }7889 }
...@@ -7939,7 +7942,7 @@ fn analyzeCall(...@@ -7939,7 +7942,7 @@ fn analyzeCall(
7939 // a reference to `comptime_allocs` so is not stable across instances of `Sema`.7942 // a reference to `comptime_allocs` so is not stable across instances of `Sema`.
7940 // TODO: check whether any external comptime memory was mutated by the7943 // TODO: check whether any external comptime memory was mutated by the
7941 // comptime function call. If so, then do not memoize the call here.7944 // comptime function call. If so, then do not memoize the call here.
7942 if (should_memoize and !Value.fromInterned(result_interned).canMutateComptimeVarState(mod)) {7945 if (should_memoize and !Value.fromInterned(result_interned).canMutateComptimeVarState(zcu)) {
7943 _ = try pt.intern(.{ .memoized_call = .{7946 _ = try pt.intern(.{ .memoized_call = .{
7944 .func = module_fn_index,7947 .func = module_fn_index,
7945 .arg_values = memoized_arg_values,7948 .arg_values = memoized_arg_values,
...@@ -7978,7 +7981,7 @@ fn analyzeCall(...@@ -7978,7 +7981,7 @@ fn analyzeCall(
7978 if (param_ty) |t| assert(!t.isGenericPoison());7981 if (param_ty) |t| assert(!t.isGenericPoison());
7979 arg_out.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, func);7982 arg_out.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, func);
7980 try sema.validateRuntimeValue(block, args_info.argSrc(block, arg_idx), arg_out.*);7983 try sema.validateRuntimeValue(block, args_info.argSrc(block, arg_idx), arg_out.*);
7981 if (sema.typeOf(arg_out.*).zigTypeTag(mod) == .NoReturn) {7984 if (sema.typeOf(arg_out.*).zigTypeTag(zcu) == .NoReturn) {
7982 return arg_out.*;7985 return arg_out.*;
7983 }7986 }
7984 }7987 }
...@@ -7987,15 +7990,15 @@ fn analyzeCall(...@@ -7987,15 +7990,15 @@ fn analyzeCall(
79877990
7988 switch (sema.owner.unwrap()) {7991 switch (sema.owner.unwrap()) {
7989 .cau => {},7992 .cau => {},
7990 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(mod)) {7993 .func => |owner_func| if (Type.fromInterned(func_ty_info.return_type).isError(zcu)) {
7991 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);7994 ip.funcSetCallsOrAwaitsErrorableFn(owner_func);
7992 },7995 },
7993 }7996 }
79947997
7995 if (try sema.resolveValue(func)) |func_val| {7998 if (try sema.resolveValue(func)) |func_val| {
7996 if (mod.intern_pool.isFuncBody(func_val.toIntern())) {7999 if (zcu.intern_pool.isFuncBody(func_val.toIntern())) {
7997 try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = func_val.toIntern() }));8000 try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = func_val.toIntern() }));
7998 try mod.ensureFuncBodyAnalysisQueued(func_val.toIntern());8001 try zcu.ensureFuncBodyAnalysisQueued(func_val.toIntern());
7999 }8002 }
8000 }8003 }
80018004
...@@ -8022,7 +8025,7 @@ fn analyzeCall(...@@ -8022,7 +8025,7 @@ fn analyzeCall(
8022 // Function pointers and extern functions aren't guaranteed to8025 // Function pointers and extern functions aren't guaranteed to
8023 // actually be noreturn so we add a safety check for them.8026 // actually be noreturn so we add a safety check for them.
8024 if (try sema.resolveValue(func)) |func_val| {8027 if (try sema.resolveValue(func)) |func_val| {
8025 switch (mod.intern_pool.indexToKey(func_val.toIntern())) {8028 switch (zcu.intern_pool.indexToKey(func_val.toIntern())) {
8026 .func => break :skip_safety,8029 .func => break :skip_safety,
8027 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {8030 .ptr => |ptr| if (ptr.byte_offset == 0) switch (ptr.base_addr) {
8028 .nav => |nav| if (!ip.getNav(nav).isExtern(ip)) break :skip_safety,8031 .nav => |nav| if (!ip.getNav(nav).isExtern(ip)) break :skip_safety,