diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-12-02 23:58:54 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-12-04 15:57:40 -0700 |
| commit | 73a76b45c5a2c8fc6ff884c4d3c84c29d37c3034 (patch) | |
| tree | 6b0b43b1d12d7ae568f9550735963134cd477f9b /src | |
| parent | 8d8b2c834d87494fc6c7c0386c04206a4c134801 (diff) | |
| download | zig-73a76b45c5a2c8fc6ff884c4d3c84c29d37c3034.tar.gz zig-73a76b45c5a2c8fc6ff884c4d3c84c29d37c3034.zip | |
CBE: take advantage of switch_br and cond_br liveness
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen/c.zig | 40 |
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(); |
