zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 1a947d3db434832ae30c7cedb1cfd364999dc078 (tree)
parent 8e876c92a8def88c4085db6ecc7b80f28237d1c2
Author: Motiejus <motiejus@jakstys.lt>
Date:   Sun,  1 Mar 2026 17:38:04 +0000

stage0: fix comptime call frame and memoized_call entries

Two fixes for IP entry alignment with the Zig compiler:

1. Skip call frame setup (ptr_uav, undef, ptr_comptime_alloc) when
   both parameter and return types are pre-interned. The Zig compiler
   doesn't create these entries for trivial comptime calls like
   debug.assert(true) where everything deduplicates to existing entries.

2. Create memoized_call entries even for void-returning functions.
   The Zig compiler always creates memoized_call for comptime function
   calls, including void results.

3. Don't create the dbg_inline_block func IP entry in comptime context
   where no AIR is emitted. This removes a spurious func entry with
   ty=0 that appeared in the IP sequence.

These fixes align entries $124-$135 between C sema and Zig compiler
for return_integer.zig. Remaining gap: 66 entries starting at $136.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Diffstat:
Mstage0/sema.c | 78+++++++++++++++++++++++++++++++++++++++++++-----------------------------------
1 file changed, 43 insertions(+), 35 deletions(-)

diff --git a/stage0/sema.c b/stage0/sema.c @@ -6255,8 +6255,9 @@ static AirInstRef comptimeFieldCall(Sema* sema, SemaBlock* block, // --- Call frame setup for comptime function calls --- // Ported from Sema.zig analyzeCall comptime path. // Creates: *const param_type, ptr_uav, *mut return_type, undef, - // ptr_comptime_alloc. These must be created before body evaluation - // to match the Zig compiler's IP entry order. + // ptr_comptime_alloc. These are only created when the types are + // non-pre-interned (the Zig compiler skips them for pre-interned + // types because they get deduped to existing entries). { // Get function type to extract return type. const Nav* fn_nav_resolved = ipGetNav(fn_nav_idx); @@ -6272,18 +6273,19 @@ static AirInstRef comptimeFieldCall(Sema* sema, SemaBlock* block, // Set inner sema's return type so zirRetPtr/zirRetType // produce the correct pointer type during body evaluation. fn_sema.fn_ret_ty = ret_ty; - // Create *const param_type (pointer to the parameter). - InternPoolIndex param_ptr_ty = internPtrConst(obj_type); - // Create ptr_uav wrapping the parameter value. - (void)internPtrUav(param_ptr_ty, obj_ip); - // Create *mut return_type for the return value alloc. - InternPoolIndex ret_mut_ptr = internPtrMutable(ret_ty); - // Create undef(return_type). - (void)internUndef(ret_ty); - // Create ptr_comptime_alloc for return value storage. - InternPoolIndex ret_alloc - = internPtrComptimeAlloc(ret_mut_ptr, 0); - fn_sema.comptime_ret_ptr = ret_alloc; + // Only create call frame entries for non-pre-interned + // types. When both param and return types are pre-interned, + // the Zig compiler creates no new IP entries for the frame. + if (obj_type >= ZIR_REF_START_INDEX + || ret_ty >= ZIR_REF_START_INDEX) { + InternPoolIndex param_ptr_ty = internPtrConst(obj_type); + (void)internPtrUav(param_ptr_ty, obj_ip); + InternPoolIndex ret_mut_ptr = internPtrMutable(ret_ty); + (void)internUndef(ret_ty); + InternPoolIndex ret_alloc + = internPtrComptimeAlloc(ret_mut_ptr, 0); + fn_sema.comptime_ret_ptr = ret_alloc; + } } } } @@ -6320,22 +6322,23 @@ static AirInstRef comptimeFieldCall(Sema* sema, SemaBlock* block, semaBlockDeinit(&fn_block); semaDeinit(&fn_sema); - // Create memoized_call entry if we got a real result. + // Create memoized_call entry for the comptime call result. // Ported from Sema.zig analyzeCall comptime path (line 7889-7898). - if (AIR_REF_IS_IP(result)) { - InternPoolIndex result_ip = AIR_REF_TO_IP(result); - if (result_ip != IP_INDEX_VOID_VALUE) { - const Nav* fn_nav2 = ipGetNav(fn_nav_idx); - InternPoolIndex func_ip = fn_nav2->resolved_type; - if (func_ip != IP_INDEX_NONE - && s_module_ip->items[func_ip].tag == IP_KEY_FUNC) { - InternPoolKey mc_key; - memset(&mc_key, 0, sizeof(mc_key)); - mc_key.tag = IP_KEY_MEMOIZED_CALL; - mc_key.data.memoized_call.func = func_ip; - mc_key.data.memoized_call.result = result_ip; - (void)ipIntern(s_module_ip, mc_key); - } + // The Zig compiler creates memoized_call even for void results. + { + InternPoolIndex result_ip = AIR_REF_IS_IP(result) + ? AIR_REF_TO_IP(result) + : IP_INDEX_VOID_VALUE; + const Nav* fn_nav2 = ipGetNav(fn_nav_idx); + InternPoolIndex func_ip = fn_nav2->resolved_type; + if (func_ip != IP_INDEX_NONE + && s_module_ip->items[func_ip].tag == IP_KEY_FUNC) { + InternPoolKey mc_key; + memset(&mc_key, 0, sizeof(mc_key)); + mc_key.tag = IP_KEY_MEMOIZED_CALL; + mc_key.data.memoized_call.func = func_ip; + mc_key.data.memoized_call.result = result_ip; + (void)ipIntern(s_module_ip, mc_key); } } @@ -7590,12 +7593,17 @@ static AirInstRef zirCall( // Intern a func value for the dbg_inline_block's func field. // The exact value doesn't matter for correctness; it just needs to be // a unique IP index that the comparison can canonicalize. - InternPoolKey func_key; - memset(&func_key, 0, sizeof(func_key)); - func_key.tag = IP_KEY_FUNC; - func_key.data.func_decl.owner_nav = func_inst; - func_key.data.func_decl.ty = 0; // use ZIR inst as unique id - InternPoolIndex func_ip = ipIntern(sema->ip, func_key); + // Only create when need_debug_scope is true (non-comptime, non-strip); + // in comptime context, no AIR is emitted so no IP entry is needed. + InternPoolIndex func_ip = IP_INDEX_NONE; + if (need_debug_scope) { + InternPoolKey func_key; + memset(&func_key, 0, sizeof(func_key)); + func_key.tag = IP_KEY_FUNC; + func_key.data.func_decl.owner_nav = func_inst; + func_key.data.func_decl.ty = 0; // use ZIR inst as unique id + func_ip = ipIntern(sema->ip, func_key); + } SemaBlockInlining inlining; memset(&inlining, 0, sizeof(inlining));