authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-08-19 07:55:18+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-08-21 01:30:44+01:00
log95fbfde9daa165ca74a4d7267720fd32b42af45e
tree34514e561df0d168b892a5667d0ed5a68614f37e
parent9cf8a7661f34e764f785583a3028429e2a700d20
signaturelock-open Commit is signed but in an unrecognized format.

Sema: delete bootstrap compiler bug workaround


1 files changed, 96 insertions(+), 102 deletions(-)

src/Sema.zig+96-102
...@@ -7734,123 +7734,117 @@ fn analyzeCall(...@@ -7734,123 +7734,117 @@ fn analyzeCall(
7734 } }));7734 } }));
7735 }7735 }
77367736
7737 // This `res2` is here instead of directly breaking from `res` due to a stage17737 memoize: {
7738 // bug generating invalid LLVM IR.7738 if (!should_memoize) break :memoize;
7739 const res2: Air.Inst.Ref = res2: {7739 if (!is_comptime_call) break :memoize;
7740 memoize: {7740 const memoized_call_index = ip.getIfExists(.{
7741 if (!should_memoize) break :memoize;7741 .memoized_call = .{
7742 if (!is_comptime_call) break :memoize;7742 .func = module_fn_index,
7743 const memoized_call_index = ip.getIfExists(.{7743 .arg_values = memoized_arg_values,
7744 .memoized_call = .{7744 .result = undefined, // ignored by hash+eql
7745 .func = module_fn_index,7745 .branch_count = undefined, // ignored by hash+eql
7746 .arg_values = memoized_arg_values,7746 },
7747 .result = undefined, // ignored by hash+eql7747 }) orelse break :memoize;
7748 .branch_count = undefined, // ignored by hash+eql7748 const memoized_call = ip.indexToKey(memoized_call_index).memoized_call;
7749 },7749 if (sema.branch_count + memoized_call.branch_count > sema.branch_quota) {
7750 }) orelse break :memoize;7750 // Let the call play out se we get the correct source location for the
7751 const memoized_call = ip.indexToKey(memoized_call_index).memoized_call;7751 // "evaluation exceeded X backwards branches" error.
7752 if (sema.branch_count + memoized_call.branch_count > sema.branch_quota) {7752 break :memoize;
7753 // Let the call play out se we get the correct source location for the
7754 // "evaluation exceeded X backwards branches" error.
7755 break :memoize;
7756 }
7757 sema.branch_count += memoized_call.branch_count;
7758 break :res2 Air.internedToRef(memoized_call.result);
7759 }7753 }
7754 sema.branch_count += memoized_call.branch_count;
7755 break :res Air.internedToRef(memoized_call.result);
7756 }
77607757
7761 new_fn_info.return_type = sema.fn_ret_ty.toIntern();7758 new_fn_info.return_type = sema.fn_ret_ty.toIntern();
7762 if (!is_comptime_call and !block.is_typeof) {7759 if (!is_comptime_call and !block.is_typeof) {
7763 const zir_tags = sema.code.instructions.items(.tag);7760 const zir_tags = sema.code.instructions.items(.tag);
7764 for (fn_info.param_body) |param| switch (zir_tags[@intFromEnum(param)]) {7761 for (fn_info.param_body) |param| switch (zir_tags[@intFromEnum(param)]) {
7765 .param, .param_comptime => {7762 .param, .param_comptime => {
7766 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(param)].pl_tok;7763 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(param)].pl_tok;
7767 const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index);7764 const extra = sema.code.extraData(Zir.Inst.Param, inst_data.payload_index);
7768 const param_name = sema.code.nullTerminatedString(extra.data.name);7765 const param_name = sema.code.nullTerminatedString(extra.data.name);
7769 const inst = sema.inst_map.get(param).?;7766 const inst = sema.inst_map.get(param).?;
77707767
7771 try sema.addDbgVar(&child_block, inst, .dbg_arg_inline, param_name);7768 try sema.addDbgVar(&child_block, inst, .dbg_arg_inline, param_name);
7772 },7769 },
7773 .param_anytype, .param_anytype_comptime => {7770 .param_anytype, .param_anytype_comptime => {
7774 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(param)].str_tok;7771 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(param)].str_tok;
7775 const param_name = inst_data.get(sema.code);7772 const param_name = inst_data.get(sema.code);
7776 const inst = sema.inst_map.get(param).?;7773 const inst = sema.inst_map.get(param).?;
77777774
7778 try sema.addDbgVar(&child_block, inst, .dbg_arg_inline, param_name);7775 try sema.addDbgVar(&child_block, inst, .dbg_arg_inline, param_name);
7779 },7776 },
7780 else => continue,7777 else => continue,
7781 };7778 };
7782 }7779 }
77837780
7784 if (is_comptime_call and ensure_result_used) {7781 if (is_comptime_call and ensure_result_used) {
7785 try sema.ensureResultUsed(block, sema.fn_ret_ty, call_src);7782 try sema.ensureResultUsed(block, sema.fn_ret_ty, call_src);
7786 }7783 }
77877784
7788 if (is_comptime_call or block.is_typeof) {7785 if (is_comptime_call or block.is_typeof) {
7789 // Save the error trace as our first action in the function7786 // Save the error trace as our first action in the function
7790 // to match the behavior of runtime function calls.7787 // to match the behavior of runtime function calls.
7791 const error_return_trace_index = try sema.analyzeSaveErrRetIndex(&child_block);7788 const error_return_trace_index = try sema.analyzeSaveErrRetIndex(&child_block);
7792 sema.error_return_trace_index_on_fn_entry = error_return_trace_index;7789 sema.error_return_trace_index_on_fn_entry = error_return_trace_index;
7793 child_block.error_return_trace_index = error_return_trace_index;7790 child_block.error_return_trace_index = error_return_trace_index;
7794 }7791 }
77957792
7796 // We temporarily set `allow_memoize` to `true` to track this comptime call.7793 // We temporarily set `allow_memoize` to `true` to track this comptime call.
7797 // It is restored after this call finishes analysis, so that a caller may7794 // It is restored after this call finishes analysis, so that a caller may
7798 // know whether an in-progress call (containing this call) may be memoized.7795 // know whether an in-progress call (containing this call) may be memoized.
7799 const old_allow_memoize = sema.allow_memoize;7796 const old_allow_memoize = sema.allow_memoize;
7800 defer sema.allow_memoize = old_allow_memoize and sema.allow_memoize;7797 defer sema.allow_memoize = old_allow_memoize and sema.allow_memoize;
7801 sema.allow_memoize = true;7798 sema.allow_memoize = true;
78027799
7803 // Store the current eval branch count so we can find out how many eval branches7800 // Store the current eval branch count so we can find out how many eval branches
7804 // the comptime call caused.7801 // the comptime call caused.
7805 const old_branch_count = sema.branch_count;7802 const old_branch_count = sema.branch_count;
78067803
7807 const result = result: {7804 const result = result: {
7808 sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) {7805 sema.analyzeFnBody(&child_block, fn_info.body) catch |err| switch (err) {
7809 error.ComptimeReturn => break :result inlining.comptime_result,7806 error.ComptimeReturn => break :result inlining.comptime_result,
7810 else => |e| return e,7807 else => |e| return e,
7811 };
7812 break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, merges, need_debug_scope);
7813 };7808 };
7809 break :result try sema.resolveAnalyzedBlock(block, call_src, &child_block, merges, need_debug_scope);
7810 };
78147811
7815 if (is_comptime_call) {7812 if (is_comptime_call) {
7816 const result_val = try sema.resolveConstValue(block, LazySrcLoc.unneeded, result, undefined);7813 const result_val = try sema.resolveConstValue(block, LazySrcLoc.unneeded, result, undefined);
7817 const result_interned = result_val.toIntern();7814 const result_interned = result_val.toIntern();
78187815
7819 // Transform ad-hoc inferred error set types into concrete error sets.7816 // Transform ad-hoc inferred error set types into concrete error sets.
7820 const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned);7817 const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_interned);
78217818
7822 // If the result can mutate comptime vars, we must not memoize it, as it contains7819 // If the result can mutate comptime vars, we must not memoize it, as it contains
7823 // a reference to `comptime_allocs` so is not stable across instances of `Sema`.7820 // a reference to `comptime_allocs` so is not stable across instances of `Sema`.
7824 // TODO: check whether any external comptime memory was mutated by the7821 // TODO: check whether any external comptime memory was mutated by the
7825 // comptime function call. If so, then do not memoize the call here.7822 // comptime function call. If so, then do not memoize the call here.
7826 if (should_memoize and sema.allow_memoize and !Value.fromInterned(result_interned).canMutateComptimeVarState(zcu)) {7823 if (should_memoize and sema.allow_memoize and !Value.fromInterned(result_interned).canMutateComptimeVarState(zcu)) {
7827 _ = try pt.intern(.{ .memoized_call = .{7824 _ = try pt.intern(.{ .memoized_call = .{
7828 .func = module_fn_index,7825 .func = module_fn_index,
7829 .arg_values = memoized_arg_values,7826 .arg_values = memoized_arg_values,
7830 .result = result_transformed,7827 .result = result_transformed,
7831 .branch_count = sema.branch_count - old_branch_count,7828 .branch_count = sema.branch_count - old_branch_count,
7832 } });7829 } });
7833 }
7834
7835 break :res2 Air.internedToRef(result_transformed);
7836 }7830 }
78377831
7838 if (try sema.resolveValue(result)) |result_val| {7832 break :res Air.internedToRef(result_transformed);
7839 const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern());7833 }
7840 break :res2 Air.internedToRef(result_transformed);
7841 }
78427834
7843 const new_ty = try sema.resolveAdHocInferredErrorSetTy(block, call_src, sema.typeOf(result).toIntern());7835 if (try sema.resolveValue(result)) |result_val| {
7844 if (new_ty != .none) {7836 const result_transformed = try sema.resolveAdHocInferredErrorSet(block, call_src, result_val.toIntern());
7845 // TODO: mutate in place the previous instruction if possible7837 break :res Air.internedToRef(result_transformed);
7846 // rather than adding a bitcast instruction.7838 }
7847 break :res2 try block.addBitCast(Type.fromInterned(new_ty), result);
7848 }
78497839
7850 break :res2 result;7840 const new_ty = try sema.resolveAdHocInferredErrorSetTy(block, call_src, sema.typeOf(result).toIntern());
7851 };7841 if (new_ty != .none) {
7842 // TODO: mutate in place the previous instruction if possible
7843 // rather than adding a bitcast instruction.
7844 break :res try block.addBitCast(Type.fromInterned(new_ty), result);
7845 }
78527846
7853 break :res res2;7847 break :res result;
7854 } else res: {7848 } else res: {
7855 assert(!func_ty_info.is_generic);7849 assert(!func_ty_info.is_generic);
78567850