astgen: add isAlwaysVoid and endsWithNoReturn checks to rvalue
Port two missing checks from upstream AstGen.zig rvalueInner to the C rvalue function: 1. isAlwaysVoid (Zir.zig:1343-1608): When the result refers to an instruction that always produces void (e.g., dbg_stmt, store_node, export, memcpy, etc.), replace the result with void_value before proceeding. This prevents emitting unnecessary type coercions or stores on always-void instructions. 2. endsWithNoReturn (AstGen.zig:11068): When the current GenZir block ends with a noreturn instruction, return the result immediately without emitting any rvalue instructions. This avoids emitting dead ZIR instructions after noreturn. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
63
astgen.c
63
astgen.c
@@ -1906,9 +1906,72 @@ static uint32_t rlResultType(GenZir* gz, ResultLoc rl, uint32_t node) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool endsWithNoReturn(GenZir* gz);
|
||||
|
||||
// Mirrors Zir.Inst.Tag.isAlwaysVoid (Zir.zig:1343-1608).
|
||||
static bool isAlwaysVoid(ZirInstTag tag, ZirInstData data) {
|
||||
switch (tag) {
|
||||
case ZIR_INST_DBG_STMT:
|
||||
case ZIR_INST_DBG_VAR_PTR:
|
||||
case ZIR_INST_DBG_VAR_VAL:
|
||||
case ZIR_INST_ENSURE_RESULT_USED:
|
||||
case ZIR_INST_ENSURE_RESULT_NON_ERROR:
|
||||
case ZIR_INST_ENSURE_ERR_UNION_PAYLOAD_VOID:
|
||||
case ZIR_INST_SET_EVAL_BRANCH_QUOTA:
|
||||
case ZIR_INST_ATOMIC_STORE:
|
||||
case ZIR_INST_STORE_NODE:
|
||||
case ZIR_INST_STORE_TO_INFERRED_PTR:
|
||||
case ZIR_INST_VALIDATE_DEREF:
|
||||
case ZIR_INST_VALIDATE_DESTRUCTURE:
|
||||
case ZIR_INST_EXPORT:
|
||||
case ZIR_INST_SET_RUNTIME_SAFETY:
|
||||
case ZIR_INST_MEMCPY:
|
||||
case ZIR_INST_MEMSET:
|
||||
case ZIR_INST_MEMMOVE:
|
||||
case ZIR_INST_CHECK_COMPTIME_CONTROL_FLOW:
|
||||
case ZIR_INST_DEFER:
|
||||
case ZIR_INST_DEFER_ERR_CODE:
|
||||
case ZIR_INST_SAVE_ERR_RET_INDEX:
|
||||
case ZIR_INST_RESTORE_ERR_RET_INDEX_UNCONDITIONAL:
|
||||
case ZIR_INST_RESTORE_ERR_RET_INDEX_FN_ENTRY:
|
||||
case ZIR_INST_VALIDATE_STRUCT_INIT_TY:
|
||||
case ZIR_INST_VALIDATE_STRUCT_INIT_RESULT_TY:
|
||||
case ZIR_INST_VALIDATE_PTR_STRUCT_INIT:
|
||||
case ZIR_INST_VALIDATE_ARRAY_INIT_TY:
|
||||
case ZIR_INST_VALIDATE_ARRAY_INIT_RESULT_TY:
|
||||
case ZIR_INST_VALIDATE_PTR_ARRAY_INIT:
|
||||
case ZIR_INST_VALIDATE_REF_TY:
|
||||
case ZIR_INST_VALIDATE_CONST:
|
||||
return true;
|
||||
case ZIR_INST_EXTENDED:
|
||||
switch (data.extended.opcode) {
|
||||
case ZIR_EXT_BRANCH_HINT:
|
||||
case ZIR_EXT_BREAKPOINT:
|
||||
case ZIR_EXT_DISABLE_INSTRUMENTATION:
|
||||
case ZIR_EXT_DISABLE_INTRINSICS:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// rvalue (AstGen.zig:11051-11224): apply result location wrapping.
|
||||
static uint32_t rvalue(
|
||||
GenZir* gz, ResultLoc rl, uint32_t result, uint32_t node) {
|
||||
// isAlwaysVoid check (AstGen.zig:11058-11067).
|
||||
if (result >= ZIR_REF_START_INDEX) {
|
||||
uint32_t result_index = result - ZIR_REF_START_INDEX;
|
||||
if (isAlwaysVoid(gz->astgen->inst_tags[result_index],
|
||||
gz->astgen->inst_datas[result_index])) {
|
||||
result = ZIR_REF_VOID_VALUE;
|
||||
}
|
||||
}
|
||||
// endsWithNoReturn check (AstGen.zig:11068).
|
||||
if (endsWithNoReturn(gz))
|
||||
return result;
|
||||
switch (rl.tag) {
|
||||
case RL_NONE:
|
||||
case RL_COERCED_TY:
|
||||
|
||||
Reference in New Issue
Block a user