aboutsummaryrefslogtreecommitdiff
path: root/src/codegen/c.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen/c.zig')
-rw-r--r--src/codegen/c.zig40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 49d6b9ec18..82ceaacd43 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -4277,6 +4277,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
const extra = f.air.extraData(Air.CondBr, pl_op.payload);
const then_body = f.air.extra[extra.end..][0..extra.data.then_body_len];
const else_body = f.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
+ const liveness_condbr = f.liveness.getCondBr(inst);
const writer = f.object.writer();
// Keep using the original for the then branch; use a clone of the value
@@ -4287,6 +4288,10 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
var cloned_frees = try f.free_locals.clone(gpa);
defer cloned_frees.deinit(gpa);
+ for (liveness_condbr.then_deaths) |operand| {
+ try die(f, inst, Air.indexToRef(operand));
+ }
+
try writer.writeAll("if (");
try f.writeCValue(writer, cond, .Other);
try writer.writeAll(") ");
@@ -4296,6 +4301,9 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
f.value_map = cloned_map.move();
f.free_locals.deinit(gpa);
f.free_locals = cloned_frees.move();
+ for (liveness_condbr.else_deaths) |operand| {
+ try die(f, inst, Air.indexToRef(operand));
+ }
try genBody(f, else_body);
try f.object.indent_writer.insertNewline();
@@ -4325,6 +4333,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
f.object.indent_writer.pushIndent();
const gpa = f.object.dg.gpa;
+ const liveness = try f.liveness.getSwitchBr(gpa, inst, switch_br.data.cases_len + 1);
+ defer gpa.free(liveness.deaths);
+ // On the final iteration we do not clone the map. This ensures that
+ // lowering proceeds after the switch_br taking into account the
+ // mutations to the liveness information.
+ const last_case_i = switch_br.data.cases_len - @boolToInt(switch_br.data.else_body_len == 0);
var extra_index: usize = switch_br.end;
var case_i: u32 = 0;
while (case_i < switch_br.data.cases_len) : (case_i += 1) {
@@ -4344,15 +4358,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?, .Other);
try writer.writeAll(": ");
}
- // On the final iteration we do not clone the map. This ensures that
- // lowering proceeds after the switch_br taking into account the
- // mutations to the liveness information.
- // The case body must be noreturn so we don't need to insert a break.
- if (case_i < switch_br.data.cases_len - 1) {
+ if (case_i != last_case_i) {
const old_value_map = f.value_map;
f.value_map = try old_value_map.clone();
const old_free_locals = f.free_locals;
f.free_locals = try f.free_locals.clone(gpa);
+
+ for (liveness.deaths[case_i]) |operand| {
+ try die(f, inst, Air.indexToRef(operand));
+ }
+
defer {
f.value_map.deinit();
f.free_locals.deinit(gpa);
@@ -4361,14 +4376,25 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
}
try genBody(f, case_body);
} else {
+ for (liveness.deaths[case_i]) |operand| {
+ try die(f, inst, Air.indexToRef(operand));
+ }
try genBody(f, case_body);
}
+ // The case body must be noreturn so we don't need to insert a break.
}
const else_body = f.air.extra[extra_index..][0..switch_br.data.else_body_len];
try f.object.indent_writer.insertNewline();
- try writer.writeAll("default: ");
- try genBody(f, else_body);
+ if (else_body.len > 0) {
+ for (liveness.deaths[liveness.deaths.len - 1]) |operand| {
+ try die(f, inst, Air.indexToRef(operand));
+ }
+ try writer.writeAll("default: ");
+ try genBody(f, else_body);
+ } else {
+ try writer.writeAll("default: zig_unreachable();");
+ }
try f.object.indent_writer.insertNewline();
f.object.indent_writer.popIndent();