| ... | @@ -184,8 +184,7 @@ const Branch = struct { | ... | @@ -184,8 +184,7 @@ const Branch = struct { |
| 184 | _ = options; | 184 | _ = options; |
| 185 | comptime assert(unused_format_string.len == 0); | 185 | comptime assert(unused_format_string.len == 0); |
| 186 | try writer.writeAll("Branch {\n"); | 186 | try writer.writeAll("Branch {\n"); |
| 187 | for (ctx.insts, 0..) |inst, i| { | 187 | for (ctx.insts, ctx.mcvs) |inst, mcv| { |
| 188 | const mcv = ctx.mcvs[i]; | | |
| 189 | try writer.print(" %{d} => {}\n", .{ inst, mcv }); | 188 | try writer.print(" %{d} => {}\n", .{ inst, mcv }); |
| 190 | } | 189 | } |
| 191 | try writer.writeAll("}"); | 190 | try writer.writeAll("}"); |
| ... | @@ -3982,10 +3981,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -3982,10 +3981,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 3982 | }; | 3981 | }; |
| 3983 | defer if (ret_reg_lock) |lock| self.register_manager.unlockReg(lock); | 3982 | defer if (ret_reg_lock) |lock| self.register_manager.unlockReg(lock); |
| 3984 | | 3983 | |
| 3985 | for (args, 0..) |arg, arg_i| { | 3984 | for (args, info.args) |arg, info_arg| { |
| 3986 | const mc_arg = info.args[arg_i]; | 3985 | const mc_arg = info_arg; |
| 3987 | const arg_ty = self.air.typeOf(arg); | 3986 | const arg_ty = self.air.typeOf(arg); |
| 3988 | const arg_mcv = try self.resolveInst(args[arg_i]); | 3987 | const arg_mcv = try self.resolveInst(arg); |
| 3989 | // Here we do not use setRegOrMem even though the logic is similar, because | 3988 | // Here we do not use setRegOrMem even though the logic is similar, because |
| 3990 | // the function call will move the stack pointer, so the offsets are different. | 3989 | // the function call will move the stack pointer, so the offsets are different. |
| 3991 | switch (mc_arg) { | 3990 | switch (mc_arg) { |
| ... | @@ -4851,9 +4850,9 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -4851,9 +4850,9 @@ fn airSwitch(self: *Self, inst: Air.Inst.Index) !void { |
| 4851 | var relocs = try self.gpa.alloc(u32, items.len); | 4850 | var relocs = try self.gpa.alloc(u32, items.len); |
| 4852 | defer self.gpa.free(relocs); | 4851 | defer self.gpa.free(relocs); |
| 4853 | | 4852 | |
| 4854 | for (items, 0..) |item, item_i| { | 4853 | for (items, relocs) |item, *reloc| { |
| 4855 | const item_mcv = try self.resolveInst(item); | 4854 | const item_mcv = try self.resolveInst(item); |
| 4856 | relocs[item_i] = try self.genCondSwitchMir(condition_ty, condition, item_mcv); | 4855 | reloc.* = try self.genCondSwitchMir(condition_ty, condition, item_mcv); |
| 4857 | } | 4856 | } |
| 4858 | | 4857 | |
| 4859 | // Capture the state of register and stack allocation state so that we can revert to it. | 4858 | // Capture the state of register and stack allocation state so that we can revert to it. |
| ... | @@ -4935,11 +4934,7 @@ fn canonicaliseBranches(self: *Self, parent_branch: *Branch, canon_branch: *Bran | ... | @@ -4935,11 +4934,7 @@ fn canonicaliseBranches(self: *Self, parent_branch: *Branch, canon_branch: *Bran |
| 4935 | try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, target_branch.inst_table.count()); | 4934 | try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, target_branch.inst_table.count()); |
| 4936 | | 4935 | |
| 4937 | const target_slice = target_branch.inst_table.entries.slice(); | 4936 | const target_slice = target_branch.inst_table.entries.slice(); |
| 4938 | const target_keys = target_slice.items(.key); | 4937 | for (target_slice.items(.key), target_slice.items(.value)) |target_key, target_value| { |
| 4939 | const target_values = target_slice.items(.value); | | |
| 4940 | | | |
| 4941 | for (target_keys, 0..) |target_key, target_idx| { | | |
| 4942 | const target_value = target_values[target_idx]; | | |
| 4943 | const canon_mcv = if (canon_branch.inst_table.fetchSwapRemove(target_key)) |canon_entry| blk: { | 4938 | const canon_mcv = if (canon_branch.inst_table.fetchSwapRemove(target_key)) |canon_entry| blk: { |
| 4944 | // The instruction's MCValue is overridden in both branches. | 4939 | // The instruction's MCValue is overridden in both branches. |
| 4945 | parent_branch.inst_table.putAssumeCapacity(target_key, canon_entry.value); | 4940 | parent_branch.inst_table.putAssumeCapacity(target_key, canon_entry.value); |
| ... | @@ -4969,10 +4964,7 @@ fn canonicaliseBranches(self: *Self, parent_branch: *Branch, canon_branch: *Bran | ... | @@ -4969,10 +4964,7 @@ fn canonicaliseBranches(self: *Self, parent_branch: *Branch, canon_branch: *Bran |
| 4969 | } | 4964 | } |
| 4970 | try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, canon_branch.inst_table.count()); | 4965 | try parent_branch.inst_table.ensureUnusedCapacity(self.gpa, canon_branch.inst_table.count()); |
| 4971 | const canon_slice = canon_branch.inst_table.entries.slice(); | 4966 | const canon_slice = canon_branch.inst_table.entries.slice(); |
| 4972 | const canon_keys = canon_slice.items(.key); | 4967 | for (canon_slice.items(.key), canon_slice.items(.value)) |canon_key, canon_value| { |
| 4973 | const canon_values = canon_slice.items(.value); | | |
| 4974 | for (canon_keys, 0..) |canon_key, canon_idx| { | | |
| 4975 | const canon_value = canon_values[canon_idx]; | | |
| 4976 | // We already deleted the items from this table that matched the target_branch. | 4968 | // We already deleted the items from this table that matched the target_branch. |
| 4977 | // So these are all instructions that are only overridden in the canon branch. | 4969 | // So these are all instructions that are only overridden in the canon branch. |
| 4978 | parent_branch.inst_table.putAssumeCapacity(canon_key, canon_value); | 4970 | parent_branch.inst_table.putAssumeCapacity(canon_key, canon_value); |
| ... | @@ -6446,7 +6438,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6446,7 +6438,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6446 | else => 0, | 6438 | else => 0, |
| 6447 | }; | 6439 | }; |
| 6448 | | 6440 | |
| 6449 | for (param_types, 0..) |ty, i| { | 6441 | for (param_types, result.args, 0..) |ty, *arg, i| { |
| 6450 | assert(ty.hasRuntimeBits()); | 6442 | assert(ty.hasRuntimeBits()); |
| 6451 | | 6443 | |
| 6452 | const classes: []const abi.Class = switch (self.target.os.tag) { | 6444 | const classes: []const abi.Class = switch (self.target.os.tag) { |
| ... | @@ -6459,7 +6451,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6459,7 +6451,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6459 | switch (classes[0]) { | 6451 | switch (classes[0]) { |
| 6460 | .integer => blk: { | 6452 | .integer => blk: { |
| 6461 | if (i >= abi.getCAbiIntParamRegs(self.target.*).len) break :blk; // fallthrough | 6453 | if (i >= abi.getCAbiIntParamRegs(self.target.*).len) break :blk; // fallthrough |
| 6462 | result.args[i] = .{ .register = abi.getCAbiIntParamRegs(self.target.*)[i] }; | 6454 | arg.* = .{ .register = abi.getCAbiIntParamRegs(self.target.*)[i] }; |
| 6463 | continue; | 6455 | continue; |
| 6464 | }, | 6456 | }, |
| 6465 | .memory => {}, // fallthrough | 6457 | .memory => {}, // fallthrough |
| ... | @@ -6471,7 +6463,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6471,7 +6463,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6471 | const param_size = @intCast(u32, ty.abiSize(self.target.*)); | 6463 | const param_size = @intCast(u32, ty.abiSize(self.target.*)); |
| 6472 | const param_align = @intCast(u32, ty.abiAlignment(self.target.*)); | 6464 | const param_align = @intCast(u32, ty.abiAlignment(self.target.*)); |
| 6473 | const offset = mem.alignForwardGeneric(u32, next_stack_offset + param_size, param_align); | 6465 | const offset = mem.alignForwardGeneric(u32, next_stack_offset + param_size, param_align); |
| 6474 | result.args[i] = .{ .stack_offset = @intCast(i32, offset) }; | 6466 | arg.* = .{ .stack_offset = @intCast(i32, offset) }; |
| 6475 | next_stack_offset = offset; | 6467 | next_stack_offset = offset; |
| 6476 | } | 6468 | } |
| 6477 | | 6469 | |
| ... | @@ -6522,15 +6514,15 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { | ... | @@ -6522,15 +6514,15 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 6522 | else => 0, | 6514 | else => 0, |
| 6523 | }; | 6515 | }; |
| 6524 | | 6516 | |
| 6525 | for (param_types, 0..) |ty, i| { | 6517 | for (param_types, result.args) |ty, *arg| { |
| 6526 | if (!ty.hasRuntimeBits()) { | 6518 | if (!ty.hasRuntimeBits()) { |
| 6527 | result.args[i] = .{ .none = {} }; | 6519 | arg.* = .{ .none = {} }; |
| 6528 | continue; | 6520 | continue; |
| 6529 | } | 6521 | } |
| 6530 | const param_size = @intCast(u32, ty.abiSize(self.target.*)); | 6522 | const param_size = @intCast(u32, ty.abiSize(self.target.*)); |
| 6531 | const param_align = @intCast(u32, ty.abiAlignment(self.target.*)); | 6523 | const param_align = @intCast(u32, ty.abiAlignment(self.target.*)); |
| 6532 | const offset = mem.alignForwardGeneric(u32, next_stack_offset + param_size, param_align); | 6524 | const offset = mem.alignForwardGeneric(u32, next_stack_offset + param_size, param_align); |
| 6533 | result.args[i] = .{ .stack_offset = @intCast(i32, offset) }; | 6525 | arg.* = .{ .stack_offset = @intCast(i32, offset) }; |
| 6534 | next_stack_offset = offset; | 6526 | next_stack_offset = offset; |
| 6535 | } | 6527 | } |
| 6536 | | 6528 | |