From 4aae0b09cfdc444a0b4e98d3ed7f83bfe421c06f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 3 Dec 2022 19:30:08 -0700 Subject: 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. --- src/codegen/c.zig | 7 ++++++- src/codegen/llvm.zig | 10 ++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src/codegen') diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 372e89bac7..ac22ac3fa6 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -4092,9 +4092,14 @@ fn lowerTry( } } + try reap(f, inst, &.{operand}); + + if (f.liveness.isUnused(inst)) { + return CValue.none; + } + const target = f.object.dg.module.getTarget(); const is_array = lowersToArray(payload_ty, target); - try reap(f, inst, &.{operand}); const local = try f.allocLocal(inst, result_ty); if (is_array) { try writer.writeAll("memcpy("); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 3fd1effc21..29d074ea1c 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -5346,7 +5346,8 @@ pub const FuncGen = struct { const err_union_ty = self.air.typeOf(pl_op.operand); const payload_ty = self.air.typeOfIndex(inst); const can_elide_load = if (isByRef(payload_ty)) self.canElideLoad(body_tail) else false; - return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, payload_ty); + const is_unused = self.liveness.isUnused(inst); + return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused, payload_ty); } fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { @@ -5356,7 +5357,8 @@ pub const FuncGen = struct { const body = self.air.extra[extra.end..][0..extra.data.body_len]; const err_union_ty = self.air.typeOf(extra.data.ptr).childType(); const payload_ty = self.air.typeOfIndex(inst); - return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, payload_ty); + const is_unused = self.liveness.isUnused(inst); + return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused, payload_ty); } fn lowerTry( @@ -5366,6 +5368,7 @@ pub const FuncGen = struct { err_union_ty: Type, operand_is_ptr: bool, can_elide_load: bool, + is_unused: bool, result_ty: Type, ) !?*llvm.Value { const payload_ty = err_union_ty.errorUnionPayload(); @@ -5405,6 +5408,9 @@ pub const FuncGen = struct { fg.builder.positionBuilderAtEnd(continue_block); } + if (is_unused) { + return null; + } if (!payload_has_bits) { if (!operand_is_ptr) return null; -- cgit v1.2.3