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(...@@ -4092,9 +4092,14 @@ fn lowerTry(
4092 }4092 }
4093 }4093 }
40944094
4095 try reap(f, inst, &.{operand});
4096
4097 if (f.liveness.isUnused(inst)) {
4098 return CValue.none;
4099 }
4100
4095 const target = f.object.dg.module.getTarget();4101 const target = f.object.dg.module.getTarget();
4096 const is_array = lowersToArray(payload_ty, target);4102 const is_array = lowersToArray(payload_ty, target);
4097 try reap(f, inst, &.{operand});
4098 const local = try f.allocLocal(inst, result_ty);4103 const local = try f.allocLocal(inst, result_ty);
4099 if (is_array) {4104 if (is_array) {
4100 try writer.writeAll("memcpy(");4105 try writer.writeAll("memcpy(");
src/codegen/llvm.zig+8-2
...@@ -5346,7 +5346,8 @@ pub const FuncGen = struct {...@@ -5346,7 +5346,8 @@ pub const FuncGen = struct {
5346 const err_union_ty = self.air.typeOf(pl_op.operand);5346 const err_union_ty = self.air.typeOf(pl_op.operand);
5347 const payload_ty = self.air.typeOfIndex(inst);5347 const payload_ty = self.air.typeOfIndex(inst);
5348 const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false;5348 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);
5350 }5351 }
53515352
5352 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {5353 fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
...@@ -5356,7 +5357,8 @@ pub const FuncGen = struct {...@@ -5356,7 +5357,8 @@ pub const FuncGen = struct {
5356 const body = self.air.extra[extra.end..][0..extra.data.body_len];5357 const body = self.air.extra[extra.end..][0..extra.data.body_len];
5357 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();5358 const err_union_ty = self.air.typeOf(extra.data.ptr).childType();
5358 const payload_ty = self.air.typeOfIndex(inst);5359 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);
5360 }5362 }
53615363
5362 fn lowerTry(5364 fn lowerTry(
...@@ -5366,6 +5368,7 @@ pub const FuncGen = struct {...@@ -5366,6 +5368,7 @@ pub const FuncGen = struct {
5366 err_union_ty: Type,5368 err_union_ty: Type,
5367 operand_is_ptr: bool,5369 operand_is_ptr: bool,
5368 can_elide_load: bool,5370 can_elide_load: bool,
5371 is_unused: bool,
5369 result_ty: Type,5372 result_ty: Type,
5370 ) !?*llvm.Value {5373 ) !?*llvm.Value {
5371 const payload_ty = err_union_ty.errorUnionPayload();5374 const payload_ty = err_union_ty.errorUnionPayload();
...@@ -5405,6 +5408,9 @@ pub const FuncGen = struct {...@@ -5405,6 +5408,9 @@ pub const FuncGen = struct {
54055408
5406 fg.builder.positionBuilderAtEnd(continue_block);5409 fg.builder.positionBuilderAtEnd(continue_block);
5407 }5410 }
5411 if (is_unused) {
5412 return null;
5413 }
5408 if (!payload_has_bits) {5414 if (!payload_has_bits) {
5409 if (!operand_is_ptr) return null;5415 if (!operand_is_ptr) return null;
54105416