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 {...@@ -4277,6 +4277,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
4277 const extra = f.air.extraData(Air.CondBr, pl_op.payload);4277 const extra = f.air.extraData(Air.CondBr, pl_op.payload);
4278 const then_body = f.air.extra[extra.end..][0..extra.data.then_body_len];4278 const then_body = f.air.extra[extra.end..][0..extra.data.then_body_len];
4279 const else_body = f.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];4279 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);
4280 const writer = f.object.writer();4281 const writer = f.object.writer();
42814282
4282 // Keep using the original for the then branch; use a clone of the value4283 // 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 {...@@ -4287,6 +4288,10 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
4287 var cloned_frees = try f.free_locals.clone(gpa);4288 var cloned_frees = try f.free_locals.clone(gpa);
4288 defer cloned_frees.deinit(gpa);4289 defer cloned_frees.deinit(gpa);
42894290
4291 for (liveness_condbr.then_deaths) |operand| {
4292 try die(f, inst, Air.indexToRef(operand));
4293 }
4294
4290 try writer.writeAll("if (");4295 try writer.writeAll("if (");
4291 try f.writeCValue(writer, cond, .Other);4296 try f.writeCValue(writer, cond, .Other);
4292 try writer.writeAll(") ");4297 try writer.writeAll(") ");
...@@ -4296,6 +4301,9 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4296,6 +4301,9 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue {
4296 f.value_map = cloned_map.move();4301 f.value_map = cloned_map.move();
4297 f.free_locals.deinit(gpa);4302 f.free_locals.deinit(gpa);
4298 f.free_locals = cloned_frees.move();4303 f.free_locals = cloned_frees.move();
4304 for (liveness_condbr.else_deaths) |operand| {
4305 try die(f, inst, Air.indexToRef(operand));
4306 }
4299 try genBody(f, else_body);4307 try genBody(f, else_body);
4300 try f.object.indent_writer.insertNewline();4308 try f.object.indent_writer.insertNewline();
43014309
...@@ -4325,6 +4333,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4325,6 +4333,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4325 f.object.indent_writer.pushIndent();4333 f.object.indent_writer.pushIndent();
43264334
4327 const gpa = f.object.dg.gpa;4335 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);
4328 var extra_index: usize = switch_br.end;4342 var extra_index: usize = switch_br.end;
4329 var case_i: u32 = 0;4343 var case_i: u32 = 0;
4330 while (case_i < switch_br.data.cases_len) : (case_i += 1) {4344 while (case_i < switch_br.data.cases_len) : (case_i += 1) {
...@@ -4344,15 +4358,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4344,15 +4358,16 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4344 try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?, .Other);4358 try f.object.dg.renderValue(writer, condition_ty, f.air.value(item).?, .Other);
4345 try writer.writeAll(": ");4359 try writer.writeAll(": ");
4346 }4360 }
4347 // On the final iteration we do not clone the map. This ensures that4361 if (case_i != last_case_i) {
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) {
4352 const old_value_map = f.value_map;4362 const old_value_map = f.value_map;
4353 f.value_map = try old_value_map.clone();4363 f.value_map = try old_value_map.clone();
4354 const old_free_locals = f.free_locals;4364 const old_free_locals = f.free_locals;
4355 f.free_locals = try f.free_locals.clone(gpa);4365 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
4356 defer {4371 defer {
4357 f.value_map.deinit();4372 f.value_map.deinit();
4358 f.free_locals.deinit(gpa);4373 f.free_locals.deinit(gpa);
...@@ -4361,14 +4376,25 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4361,14 +4376,25 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue {
4361 }4376 }
4362 try genBody(f, case_body);4377 try genBody(f, case_body);
4363 } else {4378 } else {
4379 for (liveness.deaths[case_i]) |operand| {
4380 try die(f, inst, Air.indexToRef(operand));
4381 }
4364 try genBody(f, case_body);4382 try genBody(f, case_body);
4365 }4383 }
4384 // The case body must be noreturn so we don't need to insert a break.
4366 }4385 }
43674386
4368 const else_body = f.air.extra[extra_index..][0..switch_br.data.else_body_len];4387 const else_body = f.air.extra[extra_index..][0..switch_br.data.else_body_len];
4369 try f.object.indent_writer.insertNewline();4388 try f.object.indent_writer.insertNewline();
4370 try writer.writeAll("default: ");4389 if (else_body.len > 0) {
4371 try genBody(f, else_body);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 }
4372 try f.object.indent_writer.insertNewline();4398 try f.object.indent_writer.insertNewline();
43734399
4374 f.object.indent_writer.popIndent();4400 f.object.indent_writer.popIndent();