authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-02 23:58:54-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-04 15:57:40-07:00
log73a76b45c5a2c8fc6ff884c4d3c84c29d37c3034
tree6b0b43b1d12d7ae568f9550735963134cd477f9b
parent8d8b2c834d87494fc6c7c0386c04206a4c134801

CBE: take advantage of switch_br and cond_br liveness


1 files changed, 33 insertions(+), 7 deletions(-)

src/codegen/c.zig+33-7
......@@ -4277,6 +4277,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
42774277 const extra = f.air.extraData(Air.CondBr, pl_op.payload);
42784278 const then_body = f.air.extra[extra.end..][0..extra.data.then_body_len];
42794279 const else_body = f.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
4280 const liveness_condbr = f.liveness.getCondBr(inst);
42804281 const writer = f.object.writer();
42814282
42824283 // 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 {
42874288 var cloned_frees = try f.free_locals.clone(gpa);
42884289 defer cloned_frees.deinit(gpa);
42894290
4291 for (liveness_condbr.then_deaths) |operand| {
4292 try die(f, inst, Air.indexToRef(operand));
4293 }
4294
42904295 try writer.writeAll("if (");
42914296 try f.writeCValue(writer, cond, .Other);
42924297 try writer.writeAll(") ");
......@@ -4296,6 +4301,9 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
42964301 f.value_map = cloned_map.move();
42974302 f.free_locals.deinit(gpa);
42984303 f.free_locals = cloned_frees.move();
4304 for (liveness_condbr.else_deaths) |operand| {
4305 try die(f, inst, Air.indexToRef(operand));
4306 }
42994307 try genBody(f, else_body);
43004308 try f.object.indent_writer.insertNewline();
43014309
......@@ -4325,6 +4333,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
43254333 f.object.indent_writer.pushIndent();
43264334
43274335 const gpa = f.object.dg.gpa;
4336 const liveness = try f.liveness.getSwitchBr(gpa, inst, switch_br.data.cases_len + 1);
4337 defer gpa.free(liveness.deaths);
4338 // On the final iteration we do not clone the map. This ensures that
4339 // lowering proceeds after the switch_br taking into account the
4340 // mutations to the liveness information.
4341 const last_case_i = switch_br.data.cases_len - @boolToInt(switch_br.data.else_body_len == 0);
43284342 var extra_index: usize = switch_br.end;
43294343 var case_i: u32 = 0;
43304344 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
......@@ -4344,15 +4358,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
43444358 try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?, .Other);
43454359 try writer.writeAll(": ");
43464360 }
4347 // On the final iteration we do not clone the map. This ensures that
4348 // lowering proceeds after the switch_br taking into account the
4349 // mutations to the liveness information.
4350 // The case body must be noreturn so we don't need to insert a break.
4351 if (case_i < switch_br.data.cases_len - 1) {
4361 if (case_i != last_case_i) {
43524362 const old_value_map = f.value_map;
43534363 f.value_map = try old_value_map.clone();
43544364 const old_free_locals = f.free_locals;
43554365 f.free_locals = try f.free_locals.clone(gpa);
4366
4367 for (liveness.deaths[case_i]) |operand| {
4368 try die(f, inst, Air.indexToRef(operand));
4369 }
4370
43564371 defer {
43574372 f.value_map.deinit();
43584373 f.free_locals.deinit(gpa);
......@@ -4361,14 +4376,25 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
43614376 }
43624377 try genBody(f, case_body);
43634378 } else {
4379 for (liveness.deaths[case_i]) |operand| {
4380 try die(f, inst, Air.indexToRef(operand));
4381 }
43644382 try genBody(f, case_body);
43654383 }
4384 // The case body must be noreturn so we don't need to insert a break.
43664385 }
43674386
43684387 const else_body = f.air.extra[extra_index..][0..switch_br.data.else_body_len];
43694388 try f.object.indent_writer.insertNewline();
4370 try writer.writeAll("default: ");
4371 try genBody(f, else_body);
4389 if (else_body.len > 0) {
4390 for (liveness.deaths[liveness.deaths.len - 1]) |operand| {
4391 try die(f, inst, Air.indexToRef(operand));
4392 }
4393 try writer.writeAll("default: ");
4394 try genBody(f, else_body);
4395 } else {
4396 try writer.writeAll("default: zig_unreachable();");
4397 }
43724398 try f.object.indent_writer.insertNewline();
43734399
43744400 f.object.indent_writer.popIndent();