authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-03 19:30:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-04 15:57:40-07:00
log4aae0b09cfdc444a0b4e98d3ed7f83bfe421c06f
treeb39b9beb40acde354abd178a47f10a0f73d8af33
parentf2e59e41c1ea3884a50e45f54a74c29f52954b24

CBE and LLVM: handle unused try instructions

In both backends they did not observe the Liveness information for try instructions. Now they do. For the C backend this is necessary for correctness; for the LLVM backend, it improves code generation.

2 files changed, 14 insertions(+), 3 deletions(-)

src/codegen/c.zig+6-1
......@@ -4092,9 +4092,14 @@ fn lowerTry(
40924092 }
40934093 }
40944094
4095 try reap(f, inst, &.{operand});
4096
4097 if (f.liveness.isUnused(inst)) {
4098 return CValue.none;
4099 }
4100
40954101 const target = f.object.dg.module.getTarget();
40964102 const is_array = lowersToArray(payload_ty, target);
4097 try reap(f, inst, &.{operand});
40984103 const local = try f.allocLocal(inst, result_ty);
40994104 if (is_array) {
41004105 try writer.writeAll("memcpy(");
src/codegen/llvm.zig+8-2
......@@ -5346,7 +5346,8 @@ pub const FuncGen = struct {
53465346 const err_union_ty = self.air.typeOf(pl_op.operand);
53475347 const payload_ty = self.air.typeOfIndex(inst);
53485348 const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;
5349 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, payload_ty);
5349 const is_unused = self.liveness.isUnused(inst);
5350 return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused, payload_ty);
53505351 }
53515352
53525353 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
......@@ -5356,7 +5357,8 @@ pub const FuncGen = struct {
53565357 const body = self.air.extra[extra.end..][0..extra.data.body_len];
53575358 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();
53585359 const payload_ty = self.air.typeOfIndex(inst);
5359 return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, payload_ty);
5360 const is_unused = self.liveness.isUnused(inst);
5361 return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused, payload_ty);
53605362 }
53615363
53625364 fn lowerTry(
......@@ -5366,6 +5368,7 @@ pub const FuncGen = struct {
53665368 err_union_ty: Type,
53675369 operand_is_ptr: bool,
53685370 can_elide_load: bool,
5371 is_unused: bool,
53695372 result_ty: Type,
53705373 ) !?*llvm.Value {
53715374 const payload_ty = err_union_ty.errorUnionPayload();
......@@ -5405,6 +5408,9 @@ pub const FuncGen = struct {
54055408
54065409 fg.builder.positionBuilderAtEnd(continue_block);
54075410 }
5411 if (is_unused) {
5412 return null;
5413 }
54085414 if (!payload_has_bits) {
54095415 if (!operand_is_ptr) return null;
54105416