mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
commit
af197d4954
@ -31,7 +31,7 @@ pub const Inst = struct {
|
||||
/// The first N instructions in the main block must be one arg instruction per
|
||||
/// function parameter. This makes function parameters participate in
|
||||
/// liveness analysis without any special handling.
|
||||
/// Uses the `ty` field.
|
||||
/// Uses the `arg` field.
|
||||
arg,
|
||||
/// Float or integer addition. For integers, wrapping is undefined behavior.
|
||||
/// Both operands are guaranteed to be the same type, and the result type
|
||||
@ -795,6 +795,10 @@ pub const Inst = struct {
|
||||
rhs: Ref,
|
||||
},
|
||||
ty: Type,
|
||||
arg: struct {
|
||||
ty: Ref,
|
||||
src_index: u32,
|
||||
},
|
||||
ty_op: struct {
|
||||
ty: Ref,
|
||||
operand: Ref,
|
||||
@ -1103,11 +1107,12 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
|
||||
|
||||
.alloc,
|
||||
.ret_ptr,
|
||||
.arg,
|
||||
.err_return_trace,
|
||||
.c_va_start,
|
||||
=> return datas[inst].ty,
|
||||
|
||||
.arg => return air.getRefType(datas[inst].arg.ty),
|
||||
|
||||
.assembly,
|
||||
.block,
|
||||
.constant,
|
||||
|
||||
@ -6942,7 +6942,13 @@ fn switchExpr(
|
||||
// it as the break operand.
|
||||
if (body_len < 2)
|
||||
break :blk;
|
||||
const store_inst = payloads.items[end_index - 2];
|
||||
|
||||
var store_index = end_index - 2;
|
||||
while (true) : (store_index -= 1) switch (zir_tags[payloads.items[store_index]]) {
|
||||
.dbg_block_end, .dbg_block_begin, .dbg_stmt, .dbg_var_val, .dbg_var_ptr => {},
|
||||
else => break,
|
||||
};
|
||||
const store_inst = payloads.items[store_index];
|
||||
if (zir_tags[store_inst] != .store_to_block_ptr or
|
||||
zir_datas[store_inst].bin.lhs != block_scope.rl_ptr)
|
||||
break :blk;
|
||||
@ -12150,7 +12156,7 @@ const GenZir = struct {
|
||||
|
||||
const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
|
||||
try gz.astgen.instructions.append(gpa, .{ .tag = .dbg_block_end, .data = undefined });
|
||||
try gz.instructions.insert(gpa, gz.instructions.items.len - 1, new_index);
|
||||
try gz.instructions.append(gpa, new_index);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -5672,11 +5672,15 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air {
|
||||
runtime_param_index += 1;
|
||||
continue;
|
||||
}
|
||||
const air_ty = try sema.addType(param_ty);
|
||||
const arg_index = @intCast(u32, sema.air_instructions.len);
|
||||
inner_block.instructions.appendAssumeCapacity(arg_index);
|
||||
sema.air_instructions.appendAssumeCapacity(.{
|
||||
.tag = .arg,
|
||||
.data = .{ .ty = param_ty },
|
||||
.data = .{ .arg = .{
|
||||
.ty = air_ty,
|
||||
.src_index = @intCast(u32, total_param_index),
|
||||
} },
|
||||
});
|
||||
sema.inst_map.putAssumeCapacityNoClobber(inst, Air.indexToRef(arg_index));
|
||||
total_param_index += 1;
|
||||
|
||||
15
src/Sema.zig
15
src/Sema.zig
@ -476,13 +476,6 @@ pub const Block = struct {
|
||||
});
|
||||
}
|
||||
|
||||
fn addArg(block: *Block, ty: Type) error{OutOfMemory}!Air.Inst.Ref {
|
||||
return block.addInst(.{
|
||||
.tag = .arg,
|
||||
.data = .{ .ty = ty },
|
||||
});
|
||||
}
|
||||
|
||||
fn addStructFieldPtr(
|
||||
block: *Block,
|
||||
struct_ptr: Air.Inst.Ref,
|
||||
@ -7258,7 +7251,13 @@ fn instantiateGenericCall(
|
||||
} else {
|
||||
// We insert into the map an instruction which is runtime-known
|
||||
// but has the type of the argument.
|
||||
const child_arg = try child_block.addArg(arg_ty);
|
||||
const child_arg = try child_block.addInst(.{
|
||||
.tag = .arg,
|
||||
.data = .{ .arg = .{
|
||||
.ty = try child_sema.addType(arg_ty),
|
||||
.src_index = @intCast(u32, arg_i),
|
||||
} },
|
||||
});
|
||||
child_sema.inst_map.putAssumeCapacityNoClobber(inst, child_arg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4158,7 +4158,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
|
||||
const ty = self.air.typeOfIndex(inst);
|
||||
const result = self.args[arg_index];
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);
|
||||
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
|
||||
|
||||
const mcv = switch (result) {
|
||||
// Copy registers to the stack
|
||||
|
||||
@ -4037,8 +4037,9 @@ fn genInlineMemsetCode(
|
||||
|
||||
fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, arg_index: u32) error{OutOfMemory}!void {
|
||||
const mcv = self.args[arg_index];
|
||||
const ty = self.air.instructions.items(.data)[inst].ty;
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);
|
||||
const arg = self.air.instructions.items(.data)[inst].arg;
|
||||
const ty = self.air.getRefType(arg.ty);
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg.src_index);
|
||||
|
||||
switch (self.debug_output) {
|
||||
.dwarf => |dw| {
|
||||
|
||||
@ -1608,9 +1608,10 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
|
||||
return self.fail("TODO implement codegen airFieldParentPtr", .{});
|
||||
}
|
||||
|
||||
fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32) !void {
|
||||
const ty = self.air.instructions.items(.data)[inst].ty;
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);
|
||||
fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
|
||||
const arg = self.air.instructions.items(.data)[inst].arg;
|
||||
const ty = self.air.getRefType(arg.ty);
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg.src_index);
|
||||
|
||||
switch (self.debug_output) {
|
||||
.dwarf => |dw| switch (mcv) {
|
||||
@ -1640,7 +1641,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
// TODO support stack-only arguments
|
||||
// TODO Copy registers to the stack
|
||||
const mcv = result;
|
||||
try self.genArgDbgInfo(inst, mcv, @intCast(u32, arg_index));
|
||||
try self.genArgDbgInfo(inst, mcv);
|
||||
|
||||
if (self.liveness.isUnused(inst))
|
||||
return self.finishAirBookkeeping();
|
||||
|
||||
@ -1016,7 +1016,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
}
|
||||
};
|
||||
|
||||
try self.genArgDbgInfo(inst, mcv, @intCast(u32, arg_index));
|
||||
try self.genArgDbgInfo(inst, mcv);
|
||||
|
||||
if (self.liveness.isUnused(inst))
|
||||
return self.finishAirBookkeeping();
|
||||
@ -3407,9 +3407,10 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
|
||||
self.finishAirBookkeeping();
|
||||
}
|
||||
|
||||
fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32) !void {
|
||||
const ty = self.air.instructions.items(.data)[inst].ty;
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);
|
||||
fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
|
||||
const arg = self.air.instructions.items(.data)[inst].arg;
|
||||
const ty = self.air.getRefType(arg.ty);
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg.src_index);
|
||||
|
||||
switch (self.debug_output) {
|
||||
.dwarf => |dw| switch (mcv) {
|
||||
|
||||
@ -2474,8 +2474,8 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||
|
||||
switch (func.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
// TODO: Get the original arg index rather than wasm arg index
|
||||
const name = func.mod_fn.getParamName(func.bin_file.base.options.module.?, arg_index);
|
||||
const src_index = func.air.instructions.items(.data)[inst].arg.src_index;
|
||||
const name = func.mod_fn.getParamName(func.bin_file.base.options.module.?, src_index);
|
||||
try dwarf.genArgDbgInfo(name, arg_ty, .wasm, func.mod_fn.owner_decl, .{
|
||||
.wasm_local = arg.local.value,
|
||||
});
|
||||
|
||||
@ -3799,7 +3799,8 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
|
||||
|
||||
const ty = self.air.typeOfIndex(inst);
|
||||
const mcv = self.args[arg_index];
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);
|
||||
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
|
||||
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, src_index);
|
||||
|
||||
if (self.liveness.isUnused(inst))
|
||||
return self.finishAirBookkeeping();
|
||||
|
||||
@ -1459,7 +1459,8 @@ pub const Object = struct {
|
||||
.signed => DW.ATE.signed,
|
||||
.unsigned => DW.ATE.unsigned,
|
||||
};
|
||||
const di_type = dib.createBasicType(name, info.bits, dwarf_encoding);
|
||||
const di_bits = ty.abiSize(target) * 8; // lldb cannot handle non-byte sized types
|
||||
const di_type = dib.createBasicType(name, di_bits, dwarf_encoding);
|
||||
gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
|
||||
return di_type;
|
||||
},
|
||||
@ -1550,7 +1551,8 @@ pub const Object = struct {
|
||||
return di_type;
|
||||
},
|
||||
.Bool => {
|
||||
const di_type = dib.createBasicType("bool", 1, DW.ATE.boolean);
|
||||
const di_bits = 8; // lldb cannot handle non-byte sized types
|
||||
const di_type = dib.createBasicType("bool", di_bits, DW.ATE.boolean);
|
||||
gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_type);
|
||||
return di_type;
|
||||
},
|
||||
@ -1723,10 +1725,31 @@ pub const Object = struct {
|
||||
return array_di_ty;
|
||||
},
|
||||
.Vector => {
|
||||
const elem_ty = ty.elemType2();
|
||||
// Vector elements cannot be padded since that would make
|
||||
// @bitSizOf(elem) * len > @bitSizOf(vec).
|
||||
// Neither gdb nor lldb seem to be able to display non-byte sized
|
||||
// vectors properly.
|
||||
const elem_di_type = switch (elem_ty.zigTypeTag()) {
|
||||
.Int => blk: {
|
||||
const info = elem_ty.intInfo(target);
|
||||
assert(info.bits != 0);
|
||||
const name = try ty.nameAlloc(gpa, o.module);
|
||||
defer gpa.free(name);
|
||||
const dwarf_encoding: c_uint = switch (info.signedness) {
|
||||
.signed => DW.ATE.signed,
|
||||
.unsigned => DW.ATE.unsigned,
|
||||
};
|
||||
break :blk dib.createBasicType(name, info.bits, dwarf_encoding);
|
||||
},
|
||||
.Bool => dib.createBasicType("bool", 1, DW.ATE.boolean),
|
||||
else => try o.lowerDebugType(ty.childType(), .full),
|
||||
};
|
||||
|
||||
const vector_di_ty = dib.createVectorType(
|
||||
ty.abiSize(target) * 8,
|
||||
ty.abiAlignment(target) * 8,
|
||||
try o.lowerDebugType(ty.childType(), .full),
|
||||
elem_di_type,
|
||||
ty.vectorLen(),
|
||||
);
|
||||
// The recursive call to `lowerDebugType` means we can't use `gop` anymore.
|
||||
@ -1739,7 +1762,8 @@ pub const Object = struct {
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
const child_ty = ty.optionalChild(&buf);
|
||||
if (!child_ty.hasRuntimeBitsIgnoreComptime()) {
|
||||
const di_ty = dib.createBasicType(name, 1, DW.ATE.boolean);
|
||||
const di_bits = 8; // lldb cannot handle non-byte sized types
|
||||
const di_ty = dib.createBasicType(name, di_bits, DW.ATE.boolean);
|
||||
gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
|
||||
return di_ty;
|
||||
}
|
||||
@ -1934,7 +1958,8 @@ pub const Object = struct {
|
||||
.signed => DW.ATE.signed,
|
||||
.unsigned => DW.ATE.unsigned,
|
||||
};
|
||||
const di_ty = dib.createBasicType(name, info.bits, dwarf_encoding);
|
||||
const di_bits = ty.abiSize(target) * 8; // lldb cannot handle non-byte sized types
|
||||
const di_ty = dib.createBasicType(name, di_bits, dwarf_encoding);
|
||||
gop.value_ptr.* = AnnotatedDITypePtr.initFull(di_ty);
|
||||
return di_ty;
|
||||
}
|
||||
@ -8062,7 +8087,7 @@ pub const FuncGen = struct {
|
||||
return arg_val;
|
||||
}
|
||||
|
||||
const src_index = self.getSrcArgIndex(self.arg_index - 1);
|
||||
const src_index = self.air.instructions.items(.data)[inst].arg.src_index;
|
||||
const func = self.dg.decl.getFunction().?;
|
||||
const lbrace_line = self.dg.module.declPtr(func.owner_decl).src_line + func.lbrace_line + 1;
|
||||
const lbrace_col = func.lbrace_column + 1;
|
||||
@ -8095,16 +8120,6 @@ pub const FuncGen = struct {
|
||||
return arg_val;
|
||||
}
|
||||
|
||||
fn getSrcArgIndex(self: *FuncGen, runtime_index: u32) u32 {
|
||||
const fn_info = self.dg.decl.ty.fnInfo();
|
||||
var i: u32 = 0;
|
||||
for (fn_info.param_types) |param_ty, src_index| {
|
||||
if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue;
|
||||
if (i == runtime_index) return @intCast(u32, src_index);
|
||||
i += 1;
|
||||
} else unreachable;
|
||||
}
|
||||
|
||||
fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
|
||||
if (self.liveness.isUnused(inst)) return null;
|
||||
const ptr_ty = self.air.typeOfIndex(inst);
|
||||
|
||||
@ -314,7 +314,7 @@ fn cloneAir(air: Air, gpa: Allocator, air_arena: Allocator) !Air {
|
||||
|
||||
for (air_tags) |tag, i| {
|
||||
switch (tag) {
|
||||
.arg, .alloc, .ret_ptr, .const_ty => air_datas[i].ty = try air_datas[i].ty.copy(air_arena),
|
||||
.alloc, .ret_ptr, .const_ty => air_datas[i].ty = try air_datas[i].ty.copy(air_arena),
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,11 +204,12 @@ const Writer = struct {
|
||||
.const_ty,
|
||||
.alloc,
|
||||
.ret_ptr,
|
||||
.arg,
|
||||
.err_return_trace,
|
||||
.c_va_start,
|
||||
=> try w.writeTy(s, inst),
|
||||
|
||||
.arg => try w.writeArg(s, inst),
|
||||
|
||||
.not,
|
||||
.bitcast,
|
||||
.load,
|
||||
@ -351,6 +352,12 @@ const Writer = struct {
|
||||
try w.writeType(s, ty);
|
||||
}
|
||||
|
||||
fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
const arg = w.air.instructions.items(.data)[inst].arg;
|
||||
try w.writeType(s, w.air.getRefType(arg.ty));
|
||||
try s.print(", {d}", .{arg.src_index});
|
||||
}
|
||||
|
||||
fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
|
||||
const ty_op = w.air.instructions.items(.data)[inst].ty_op;
|
||||
try w.writeType(s, w.air.getRefType(ty_op.ty));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user