From 2e23ddbe7ba48857fbdcf014da3251f1decca00d Mon Sep 17 00:00:00 2001 From: mlugg Date: Tue, 25 Apr 2023 04:49:47 +0100 Subject: [PATCH 1/2] CBE: minor optimizations to output source --- src/codegen/c.zig | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 903d2449fd..30227d747e 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -4291,9 +4291,13 @@ fn airBlock(f: *Function, inst: Air.Inst.Index) !CValue { } try f.object.indent_writer.insertNewline(); - // label might be unused, add a dummy goto - // label must be followed by an expression, add an empty one. - try writer.print("goto zig_block_{d};\nzig_block_{d}: (void)0;\n", .{ block_id, block_id }); + + // noreturn blocks have no `br` instructions reaching them, so we don't want a label + if (!f.air.typeOfIndex(inst).isNoReturn()) { + // label must be followed by an expression, include an empty one. + try writer.print("zig_block_{d}:;\n", .{block_id}); + } + return result; } @@ -4345,7 +4349,7 @@ fn lowerTry( else try f.writeCValueMember(writer, err_union, .{ .identifier = "error" }); } - try writer.writeByte(')'); + try writer.writeAll(") "); try genBodyResolveState(f, inst, liveness_condbr.else_deaths, body, false); try f.object.indent_writer.insertNewline(); @@ -4417,7 +4421,11 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { const local = try f.allocLocal(inst, dest_ty); + // If the assignment looks like 'x = x', we don't need it + const can_elide = operand == .local and operand.local == local.new_local; + if (operand_ty.isAbiInt() and dest_ty.isAbiInt()) { + if (can_elide) return local; const src_info = dest_ty.intInfo(target); const dest_info = operand_ty.intInfo(target); if (src_info.signedness == dest_info.signedness and @@ -4432,6 +4440,7 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { } if (dest_ty.isPtrAtRuntime() and operand_ty.isPtrAtRuntime()) { + if (can_elide) return local; try f.writeCValue(writer, local, .Other); try writer.writeAll(" = ("); try f.renderType(writer, dest_ty); @@ -5463,6 +5472,12 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { const error_ty = error_union_ty.errorUnionSet(); const payload_ty = error_union_ty.errorUnionPayload(); const local = try f.allocLocal(inst, inst_ty); + + if (!payload_ty.hasRuntimeBits() and operand == .local and operand.local == local.new_local) { + // The store will be 'x = x'; elide it. + return local; + } + const writer = f.object.writer(); try f.writeCValue(writer, local, .Other); try writer.writeAll(" = "); @@ -5560,6 +5575,12 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { const writer = f.object.writer(); const local = try f.allocLocal(inst, inst_ty); + + if (repr_is_err and err == .local and err.local == local.new_local) { + // The store will be 'x = x'; elide it. + return local; + } + if (!repr_is_err) { const a = try Assignment.start(f, writer, payload_ty); try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); From 3df2f356eba9b0882ee3fa09704aae7dc173f3d4 Mon Sep 17 00:00:00 2001 From: mlugg Date: Wed, 26 Apr 2023 01:43:55 +0100 Subject: [PATCH 2/2] Sema: avoid emitting sequential dbg_stmt instructions Often, a `dbg_stmt` ends up being associated with no real code because whatever it referred to was eliminated by semantic analysis. In these cases, Sema can replace the last `dbg_stmt` with the new one to avoid redundant AIR instructions which at best are nops and at worst cause backends to emit useless info (e.g. CBE does this). --- src/Sema.zig | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Sema.zig b/src/Sema.zig index 199bdc43ab..8e4a82ccb5 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5852,6 +5852,19 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return; const inst_data = sema.code.instructions.items(.data)[inst].dbg_stmt; + + if (block.instructions.items.len != 0) { + const idx = block.instructions.items[block.instructions.items.len - 1]; + if (sema.air_instructions.items(.tag)[idx] == .dbg_stmt) { + // The previous dbg_stmt didn't correspond to any actual code, so replace it. + sema.air_instructions.items(.data)[idx].dbg_stmt = .{ + .line = inst_data.line, + .column = inst_data.column, + }; + return; + } + } + _ = try block.addInst(.{ .tag = .dbg_stmt, .data = .{ .dbg_stmt = .{