Legalize: introduce a new pass before liveness
Each target can opt into different sets of legalize features. By performing these transformations before liveness, instructions that become unreferenced will have up-to-date liveness information.
This commit is contained in:
@@ -18,7 +18,6 @@ const Zcu = @import("../Zcu.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
const Package = @import("../Package.zig");
|
||||
const Air = @import("../Air.zig");
|
||||
const Liveness = @import("../Liveness.zig");
|
||||
const Value = @import("../Value.zig");
|
||||
const Type = @import("../Type.zig");
|
||||
const x86_64_abi = @import("../arch/x86_64/abi.zig");
|
||||
@@ -1121,7 +1120,7 @@ pub const Object = struct {
|
||||
pt: Zcu.PerThread,
|
||||
func_index: InternPool.Index,
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
liveness: Air.Liveness,
|
||||
) !void {
|
||||
assert(std.meta.eql(pt, o.pt));
|
||||
const zcu = pt.zcu;
|
||||
@@ -4616,7 +4615,7 @@ pub const FuncGen = struct {
|
||||
gpa: Allocator,
|
||||
ng: *NavGen,
|
||||
air: Air,
|
||||
liveness: Liveness,
|
||||
liveness: Air.Liveness,
|
||||
wip: Builder.WipFunction,
|
||||
is_naked: bool,
|
||||
fuzz: ?Fuzz,
|
||||
@@ -5183,7 +5182,7 @@ pub const FuncGen = struct {
|
||||
fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !Builder.Value {
|
||||
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const extra = self.air.extraData(Air.Call, pl_op.payload);
|
||||
const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
|
||||
const args: []const Air.Inst.Ref = @ptrCast(self.air.extra.items[extra.end..][0..extra.data.args_len]);
|
||||
const o = self.ng.object;
|
||||
const pt = o.pt;
|
||||
const zcu = pt.zcu;
|
||||
@@ -5856,7 +5855,7 @@ pub const FuncGen = struct {
|
||||
fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = self.air.extraData(Air.Block, ty_pl.payload);
|
||||
return self.lowerBlock(inst, null, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
|
||||
return self.lowerBlock(inst, null, @ptrCast(self.air.extra.items[extra.end..][0..extra.data.body_len]));
|
||||
}
|
||||
|
||||
fn lowerBlock(
|
||||
@@ -6140,8 +6139,8 @@ pub const FuncGen = struct {
|
||||
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const cond = try self.resolveInst(pl_op.operand);
|
||||
const extra = self.air.extraData(Air.CondBr, pl_op.payload);
|
||||
const then_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.then_body_len]);
|
||||
const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]);
|
||||
const then_body: []const Air.Inst.Index = @ptrCast(self.air.extra.items[extra.end..][0..extra.data.then_body_len]);
|
||||
const else_body: []const Air.Inst.Index = @ptrCast(self.air.extra.items[extra.end + then_body.len ..][0..extra.data.else_body_len]);
|
||||
|
||||
const Hint = enum {
|
||||
none,
|
||||
@@ -6205,7 +6204,7 @@ pub const FuncGen = struct {
|
||||
const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
|
||||
const err_union = try self.resolveInst(pl_op.operand);
|
||||
const extra = self.air.extraData(Air.Try, pl_op.payload);
|
||||
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
|
||||
const body: []const Air.Inst.Index = @ptrCast(self.air.extra.items[extra.end..][0..extra.data.body_len]);
|
||||
const err_union_ty = self.typeOf(pl_op.operand);
|
||||
const payload_ty = self.typeOfIndex(inst);
|
||||
const can_elide_load = if (isByRef(payload_ty, zcu)) self.canElideLoad(body_tail) else false;
|
||||
@@ -6219,7 +6218,7 @@ pub const FuncGen = struct {
|
||||
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = self.air.extraData(Air.TryPtr, ty_pl.payload);
|
||||
const err_union_ptr = try self.resolveInst(extra.data.ptr);
|
||||
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
|
||||
const body: []const Air.Inst.Index = @ptrCast(self.air.extra.items[extra.end..][0..extra.data.body_len]);
|
||||
const err_union_ty = self.typeOf(extra.data.ptr).childType(zcu);
|
||||
const is_unused = self.liveness.isUnused(inst);
|
||||
|
||||
@@ -6550,7 +6549,7 @@ pub const FuncGen = struct {
|
||||
fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !void {
|
||||
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const loop = self.air.extraData(Air.Block, ty_pl.payload);
|
||||
const body: []const Air.Inst.Index = @ptrCast(self.air.extra[loop.end..][0..loop.data.body_len]);
|
||||
const body: []const Air.Inst.Index = @ptrCast(self.air.extra.items[loop.end..][0..loop.data.body_len]);
|
||||
const loop_block = try self.wip.block(1, "Loop"); // `airRepeat` will increment incoming each time
|
||||
_ = try self.wip.br(loop_block);
|
||||
|
||||
@@ -7076,7 +7075,7 @@ pub const FuncGen = struct {
|
||||
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
|
||||
self.arg_inline_index = 0;
|
||||
return self.lowerBlock(inst, extra.data.func, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
|
||||
return self.lowerBlock(inst, extra.data.func, @ptrCast(self.air.extra.items[extra.end..][0..extra.data.body_len]));
|
||||
}
|
||||
|
||||
fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||
@@ -7201,9 +7200,9 @@ pub const FuncGen = struct {
|
||||
const clobbers_len: u31 = @truncate(extra.data.flags);
|
||||
var extra_i: usize = extra.end;
|
||||
|
||||
const outputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.outputs_len]);
|
||||
const outputs: []const Air.Inst.Ref = @ptrCast(self.air.extra.items[extra_i..][0..extra.data.outputs_len]);
|
||||
extra_i += outputs.len;
|
||||
const inputs: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra_i..][0..extra.data.inputs_len]);
|
||||
const inputs: []const Air.Inst.Ref = @ptrCast(self.air.extra.items[extra_i..][0..extra.data.inputs_len]);
|
||||
extra_i += inputs.len;
|
||||
|
||||
var llvm_constraints: std.ArrayListUnmanaged(u8) = .empty;
|
||||
@@ -7239,8 +7238,8 @@ pub const FuncGen = struct {
|
||||
|
||||
var rw_extra_i = extra_i;
|
||||
for (outputs, llvm_ret_indirect, llvm_rw_vals) |output, *is_indirect, *llvm_rw_val| {
|
||||
const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
|
||||
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
|
||||
const extra_bytes = std.mem.sliceAsBytes(self.air.extra.items[extra_i..]);
|
||||
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra.items[extra_i..]), 0);
|
||||
const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
|
||||
// This equation accounts for the fact that even if we have exactly 4 bytes
|
||||
// for the string, we still use the next u32 for the null terminator.
|
||||
@@ -7320,7 +7319,7 @@ pub const FuncGen = struct {
|
||||
}
|
||||
|
||||
for (inputs) |input| {
|
||||
const extra_bytes = std.mem.sliceAsBytes(self.air.extra[extra_i..]);
|
||||
const extra_bytes = std.mem.sliceAsBytes(self.air.extra.items[extra_i..]);
|
||||
const constraint = std.mem.sliceTo(extra_bytes, 0);
|
||||
const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
|
||||
// This equation accounts for the fact that even if we have exactly 4 bytes
|
||||
@@ -7385,8 +7384,8 @@ pub const FuncGen = struct {
|
||||
}
|
||||
|
||||
for (outputs, llvm_ret_indirect, llvm_rw_vals, 0..) |output, is_indirect, llvm_rw_val, output_index| {
|
||||
const extra_bytes = std.mem.sliceAsBytes(self.air.extra[rw_extra_i..]);
|
||||
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[rw_extra_i..]), 0);
|
||||
const extra_bytes = std.mem.sliceAsBytes(self.air.extra.items[rw_extra_i..]);
|
||||
const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra.items[rw_extra_i..]), 0);
|
||||
const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0);
|
||||
// This equation accounts for the fact that even if we have exactly 4 bytes
|
||||
// for the string, we still use the next u32 for the null terminator.
|
||||
@@ -7425,7 +7424,7 @@ pub const FuncGen = struct {
|
||||
{
|
||||
var clobber_i: u32 = 0;
|
||||
while (clobber_i < clobbers_len) : (clobber_i += 1) {
|
||||
const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra[extra_i..]), 0);
|
||||
const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(self.air.extra.items[extra_i..]), 0);
|
||||
// This equation accounts for the fact that even if we have exactly 4 bytes
|
||||
// for the string, we still use the next u32 for the null terminator.
|
||||
extra_i += clobber.len / 4 + 1;
|
||||
@@ -7465,7 +7464,7 @@ pub const FuncGen = struct {
|
||||
else => {},
|
||||
}
|
||||
|
||||
const asm_source = std.mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len];
|
||||
const asm_source = std.mem.sliceAsBytes(self.air.extra.items[extra_i..])[0..extra.data.source_len];
|
||||
|
||||
// hackety hacks until stage2 has proper inline asm in the frontend.
|
||||
var rendered_template = std.ArrayList(u8).init(self.gpa);
|
||||
@@ -10628,7 +10627,7 @@ pub const FuncGen = struct {
|
||||
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
|
||||
const result_ty = self.typeOfIndex(inst);
|
||||
const len: usize = @intCast(result_ty.arrayLen(zcu));
|
||||
const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra[ty_pl.payload..][0..len]);
|
||||
const elements: []const Air.Inst.Ref = @ptrCast(self.air.extra.items[ty_pl.payload..][0..len]);
|
||||
const llvm_result_ty = try o.lowerType(result_ty);
|
||||
|
||||
switch (result_ty.zigTypeTag(zcu)) {
|
||||
|
||||
Reference in New Issue
Block a user