sema: extract runtime switch AIR generation to function

This commit is contained in:
dweiller 2023-11-24 12:53:10 +11:00
parent ae19f699ab
commit 6bf319ebbb

View File

@ -11355,7 +11355,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
const mod = sema.mod;
const gpa = sema.gpa;
const ip = &mod.intern_pool;
const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
const src = inst_data.src();
const src_node_offset = inst_data.src_node;
@ -11944,6 +11943,71 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
unreachable;
}
_ = try sema.analyzeSwitchRuntimeBlock(
spa,
&child_block,
src,
operand,
operand_ty,
operand_src,
case_vals,
special,
scalar_cases_len,
multi_cases_len,
union_originally,
maybe_union_ty,
err_set,
src_node_offset,
special_prong_src,
seen_enum_fields,
seen_errors,
range_set,
true_count,
false_count,
cond_dbg_node_index,
);
return sema.analyzeBlockBody(block, src, &child_block, merges);
}
const SpecialProng = struct {
body: []const Zir.Inst.Index,
end: usize,
capture: Zir.Inst.SwitchBlock.ProngInfo.Capture,
is_inline: bool,
has_tag_capture: bool,
};
fn analyzeSwitchRuntimeBlock(
sema: *Sema,
spa: SwitchProngAnalysis,
child_block: *Block,
src: LazySrcLoc,
operand: Air.Inst.Ref,
operand_ty: Type,
operand_src: LazySrcLoc,
case_vals: std.ArrayListUnmanaged(Air.Inst.Ref),
special: SpecialProng,
scalar_cases_len: usize,
multi_cases_len: usize,
union_originally: bool,
maybe_union_ty: Type,
err_set: bool,
src_node_offset: i32,
special_prong_src: LazySrcLoc,
seen_enum_fields: []?Module.SwitchProngSrc,
seen_errors: SwitchErrorSet,
range_set: RangeSet,
true_count: u8,
false_count: u8,
cond_dbg_node_index: Zir.Inst.Index,
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const gpa = sema.gpa;
const ip = &mod.intern_pool;
const block = child_block.parent.?;
const estimated_cases_extra = (scalar_cases_len + multi_cases_len) *
@typeInfo(Air.SwitchBr.Case).Struct.fields.len + 2;
var cases_extra = try std.ArrayListUnmanaged(u32).initCapacity(gpa, estimated_cases_extra);
@ -12534,27 +12598,23 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr).Struct.fields.len +
cases_extra.items.len + final_else_body.len);
_ = try child_block.addInst(.{ .tag = .switch_br, .data = .{ .pl_op = .{
.operand = operand,
.payload = sema.addExtraAssumeCapacity(Air.SwitchBr{
.cases_len = @intCast(cases_len),
.else_body_len = @intCast(final_else_body.len),
}),
} } });
const payload_index = sema.addExtraAssumeCapacity(Air.SwitchBr{
.cases_len = @intCast(cases_len),
.else_body_len = @intCast(final_else_body.len),
});
sema.air_extra.appendSliceAssumeCapacity(@ptrCast(cases_extra.items));
sema.air_extra.appendSliceAssumeCapacity(@ptrCast(final_else_body));
return sema.analyzeBlockBody(block, src, &child_block, merges);
return try child_block.addInst(.{
.tag = .switch_br,
.data = .{ .pl_op = .{
.operand = operand,
.payload = payload_index,
} },
});
}
const SpecialProng = struct {
body: []const Zir.Inst.Index,
end: usize,
capture: Zir.Inst.SwitchBlock.ProngInfo.Capture,
is_inline: bool,
has_tag_capture: bool,
};
fn resolveSwitchComptime(
sema: *Sema,
spa: SwitchProngAnalysis,