authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-08 06:38:27-05:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-16 20:47:30-05:00
log5069f574f43f1c9fe7ced12f9fd5f05bdedf6abb
tree38e692c671b7b9a9e377a2794c4294f61c39b4ef
parent3240adfa16cd09d6664223975776c80990cb55cc

x86_64: remove pointless jump to epilogue


1 files changed, 34 insertions(+), 34 deletions(-)

src/arch/x86_64/CodeGen.zig+34-34
......@@ -73,7 +73,7 @@ end_di_column: u32,
7373/// The value is an offset into the `Function` `code` from the beginning.
7474/// To perform the reloc, write 32-bit signed little-endian integer
7575/// which is a relative jump, based on the address following the reloc.
76exitlude_jump_relocs: std.ArrayListUnmanaged(Mir.Inst.Index) = .empty,
76epilogue_relocs: std.ArrayListUnmanaged(Mir.Inst.Index) = .empty,
7777
7878reused_operands: std.StaticBitSet(Liveness.bpi - 1) = undefined,
7979const_tracking: ConstTrackingMap = .empty,
......@@ -928,7 +928,7 @@ pub fn generate(
928928 function.blocks.deinit(gpa);
929929 function.inst_tracking.deinit(gpa);
930930 function.const_tracking.deinit(gpa);
931 function.exitlude_jump_relocs.deinit(gpa);
931 function.epilogue_relocs.deinit(gpa);
932932 function.mir_instructions.deinit(gpa);
933933 function.mir_extra.deinit(gpa);
934934 function.mir_table.deinit(gpa);
......@@ -2193,24 +2193,24 @@ fn gen(self: *CodeGen) InnerError!void {
21932193
21942194 try self.genBody(self.air.getMainBody());
21952195
2196 // TODO can single exitlude jump reloc be elided? What if it is not at the end of the code?
2197 // Example:
2198 // pub fn main() void {
2199 // maybeErr() catch return;
2200 // unreachable;
2201 // }
2202 // Eliding the reloc will cause a miscompilation in this case.
2203 for (self.exitlude_jump_relocs.items) |jmp_reloc| {
2204 self.mir_instructions.items(.data)[jmp_reloc].inst.inst =
2205 @intCast(self.mir_instructions.len);
2206 }
2207
2208 try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
2209 const backpatch_stack_dealloc = try self.asmPlaceholder();
2210 const backpatch_pop_callee_preserved_regs = try self.asmPlaceholder();
2211 try self.asmRegister(.{ ._, .pop }, .rbp);
2212 try self.asmPseudoRegisterImmediate(.pseudo_cfi_def_cfa_ri_s, .rsp, .s(8));
2213 try self.asmOpOnly(.{ ._, .ret });
2196 const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: {
2197 const epilogue_relocs_last_index = self.epilogue_relocs.items.len - 1;
2198 for (if (self.epilogue_relocs.items[epilogue_relocs_last_index] == self.mir_instructions.len - 1) epilogue_relocs: {
2199 _ = self.mir_instructions.pop();
2200 break :epilogue_relocs self.epilogue_relocs.items[0..epilogue_relocs_last_index];
2201 } else self.epilogue_relocs.items) |epilogue_reloc| self.performReloc(epilogue_reloc);
2202
2203 try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
2204 const backpatch_stack_dealloc = try self.asmPlaceholder();
2205 const backpatch_pop_callee_preserved_regs = try self.asmPlaceholder();
2206 try self.asmRegister(.{ ._, .pop }, .rbp);
2207 try self.asmPseudoRegisterImmediate(.pseudo_cfi_def_cfa_ri_s, .rsp, .s(8));
2208 try self.asmOpOnly(.{ ._, .ret });
2209 break :epilogue .{
2210 .backpatch_stack_dealloc = backpatch_stack_dealloc,
2211 .backpatch_pop_callee_preserved_regs = backpatch_pop_callee_preserved_regs,
2212 };
2213 } else null;
22142214
22152215 const frame_layout = try self.computeFrameLayout(fn_info.cc);
22162216 const need_frame_align = frame_layout.stack_mask != std.math.maxInt(u32);
......@@ -2280,8 +2280,8 @@ fn gen(self: *CodeGen) InnerError!void {
22802280 });
22812281 }
22822282 }
2283 if (need_frame_align or need_stack_adjust) {
2284 self.mir_instructions.set(backpatch_stack_dealloc, switch (-frame_layout.save_reg_list.size(self.target)) {
2283 if (epilogue) |e| if (need_frame_align or need_stack_adjust) {
2284 self.mir_instructions.set(e.backpatch_stack_dealloc, switch (-frame_layout.save_reg_list.size(self.target)) {
22852285 0 => .{
22862286 .tag = .mov,
22872287 .ops = .rr,
......@@ -2305,14 +2305,14 @@ fn gen(self: *CodeGen) InnerError!void {
23052305 } },
23062306 },
23072307 });
2308 }
2308 };
23092309 if (need_save_reg) {
23102310 self.mir_instructions.set(backpatch_push_callee_preserved_regs, .{
23112311 .tag = .pseudo,
23122312 .ops = .pseudo_push_reg_list,
23132313 .data = .{ .reg_list = frame_layout.save_reg_list },
23142314 });
2315 self.mir_instructions.set(backpatch_pop_callee_preserved_regs, .{
2315 if (epilogue) |e| self.mir_instructions.set(e.backpatch_pop_callee_preserved_regs, .{
23162316 .tag = .pseudo,
23172317 .ops = .pseudo_pop_reg_list,
23182318 .data = .{ .reg_list = frame_layout.save_reg_list },
......@@ -10007,8 +10007,8 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
1000710007 const ret_reg = param_regs[0];
1000810008 const enum_mcv = MCValue{ .register = param_regs[1] };
1000910009
10010 const exitlude_jump_relocs = try self.gpa.alloc(Mir.Inst.Index, enum_ty.enumFieldCount(zcu));
10011 defer self.gpa.free(exitlude_jump_relocs);
10010 const epilogue_relocs = try self.gpa.alloc(Mir.Inst.Index, enum_ty.enumFieldCount(zcu));
10011 defer self.gpa.free(epilogue_relocs);
1001210012
1001310013 const data_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
1001410014 const data_lock = self.register_manager.lockRegAssumeUnused(data_reg);
......@@ -10017,7 +10017,7 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
1001710017
1001810018 var data_off: i32 = 0;
1001910019 const tag_names = enum_ty.enumFields(zcu);
10020 for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| {
10020 for (epilogue_relocs, 0..) |*epilogue_reloc, tag_index| {
1002110021 const tag_name_len = tag_names.get(ip)[tag_index].length(ip);
1002210022 const tag_val = try pt.enumValueFieldIndex(enum_ty, @intCast(tag_index));
1002310023 const tag_mcv = try self.genTypedValue(tag_val);
......@@ -10033,7 +10033,7 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
1003310033 );
1003410034 try self.genSetMem(.{ .reg = ret_reg }, 8, .usize, .{ .immediate = tag_name_len }, .{});
1003510035
10036 exitlude_jump_reloc.* = try self.asmJmpReloc(undefined);
10036 epilogue_reloc.* = try self.asmJmpReloc(undefined);
1003710037 self.performReloc(skip_reloc);
1003810038
1003910039 data_off += @intCast(tag_name_len + 1);
......@@ -10041,7 +10041,7 @@ fn genLazy(self: *CodeGen, lazy_sym: link.File.LazySymbol) InnerError!void {
1004110041
1004210042 try self.asmOpOnly(.{ ._, .ud2 });
1004310043
10044 for (exitlude_jump_relocs) |reloc| self.performReloc(reloc);
10044 for (epilogue_relocs) |reloc| self.performReloc(reloc);
1004510045 try self.asmOpOnly(.{ ._, .ret });
1004610046 },
1004710047 else => return self.fail(
......@@ -20114,7 +20114,7 @@ fn airRet(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {
2011420114 // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction
2011520115 // which is available if the jump is 127 bytes or less forward.
2011620116 const jmp_reloc = try self.asmJmpReloc(undefined);
20117 try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc);
20117 try self.epilogue_relocs.append(self.gpa, jmp_reloc);
2011820118}
2011920119
2012020120fn airRetLoad(self: *CodeGen, inst: Air.Inst.Index) !void {
......@@ -20134,7 +20134,7 @@ fn airRetLoad(self: *CodeGen, inst: Air.Inst.Index) !void {
2013420134 // TODO optimization opportunity: figure out when we can emit this as a 2 byte instruction
2013520135 // which is available if the jump is 127 bytes or less forward.
2013620136 const jmp_reloc = try self.asmJmpReloc(undefined);
20137 try self.exitlude_jump_relocs.append(self.gpa, jmp_reloc);
20137 try self.epilogue_relocs.append(self.gpa, jmp_reloc);
2013820138}
2013920139
2014020140fn airCmp(self: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) !void {
......@@ -24486,7 +24486,7 @@ fn airMemset(self: *CodeGen, inst: Air.Inst.Index, safety: bool) !void {
2448624486 self.register_manager.lockRegAssumeUnused(dst_regs[0]),
2448724487 self.register_manager.lockRegAssumeUnused(dst_regs[1]),
2448824488 },
24489 else => .{ null, null },
24489 else => @splat(null),
2449024490 };
2449124491 for (dst_locks) |dst_lock| if (dst_lock) |lock| self.register_manager.unlockReg(lock);
2449224492
......@@ -24625,7 +24625,7 @@ fn airMemcpy(self: *CodeGen, inst: Air.Inst.Index) !void {
2462524625 self.register_manager.lockRegAssumeUnused(dst_regs[0]),
2462624626 self.register_manager.lockReg(dst_regs[1]),
2462724627 },
24628 else => .{ null, null },
24628 else => @splat(null),
2462924629 };
2463024630 for (dst_locks) |dst_lock| if (dst_lock) |lock| self.register_manager.unlockReg(lock);
2463124631
......@@ -24636,7 +24636,7 @@ fn airMemcpy(self: *CodeGen, inst: Air.Inst.Index) !void {
2463624636 self.register_manager.lockRegAssumeUnused(src_regs[0]),
2463724637 self.register_manager.lockRegAssumeUnused(src_regs[1]),
2463824638 },
24639 else => .{ null, null },
24639 else => @splat(null),
2464024640 };
2464124641 for (src_locks) |src_lock| if (src_lock) |lock| self.register_manager.unlockReg(lock);
2464224642