From 4dcec74f070ecc46c04d8c0740175b8643c35038 Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Tue, 8 Oct 2024 13:02:38 -0700 Subject: [PATCH] Interner: rename global_var_offset to pointer and store decl node index --- src/aro/Attribute.zig | 2 +- src/aro/Compilation.zig | 4 +++ src/aro/Parser.zig | 19 ++++++------ src/aro/Tree.zig | 2 +- src/aro/Value.zig | 64 +++++++++++++++++----------------------- src/backend/Interner.zig | 36 +++++++++++----------- 6 files changed, 61 insertions(+), 66 deletions(-) diff --git a/src/aro/Attribute.zig b/src/aro/Attribute.zig index 01fac90c..30f728ed 100644 --- a/src/aro/Attribute.zig +++ b/src/aro/Attribute.zig @@ -340,7 +340,7 @@ fn diagnoseField( .array_ty, .vector_ty, .record_ty, - .global_var_offset, + .pointer, => unreachable, }); } diff --git a/src/aro/Compilation.zig b/src/aro/Compilation.zig index aef3a452..d2d36d35 100644 --- a/src/aro/Compilation.zig +++ b/src/aro/Compilation.zig @@ -753,6 +753,10 @@ pub fn float80Type(comp: *const Compilation) ?Type { return target_util.float80Type(comp.target); } +pub fn internString(comp: *Compilation, str: []const u8) !StrInt.StringId { + return comp.string_interner.internExtra(comp.gpa, str); +} + /// Smallest integer type with at least N bits pub fn intLeastN(comp: *const Compilation, bits: usize, signedness: std.builtin.Signedness) Type { if (bits == 64 and (comp.target.isDarwin() or comp.target.isWasm())) { diff --git a/src/aro/Parser.zig b/src/aro/Parser.zig index 8ed91d14..fa56c7fc 100644 --- a/src/aro/Parser.zig +++ b/src/aro/Parser.zig @@ -26,7 +26,7 @@ const Symbol = SymbolStack.Symbol; const record_layout = @import("record_layout.zig"); const StrInt = @import("StringInterner.zig"); const StringId = StrInt.StringId; -const GlobalVarOffset = @import("backend").Interner.Key.GlobalVarOffset; +const Pointer = @import("backend").Interner.Key.Pointer; const Builtins = @import("Builtins.zig"); const Builtin = Builtins.Builtin; const evalBuiltin = @import("Builtins/eval.zig").eval; @@ -505,9 +505,9 @@ pub fn valueChangedStr(p: *Parser, res: *Result, old_value: Value, int_ty: Type) try w.writeAll(" changes "); if (res.val.isZero(p.comp)) try w.writeAll("non-zero "); try w.writeAll("value from "); - try old_value.print(res.ty, p.comp, p.comp.string_interner.getSlowTypeMapper(), w); + try old_value.print(res.ty, p.comp, w); try w.writeAll(" to "); - try res.val.print(int_ty, p.comp, p.comp.string_interner.getSlowTypeMapper(), w); + try res.val.print(int_ty, p.comp, w); return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]); } @@ -5197,7 +5197,7 @@ pub const Result = struct { const strings_top = p.strings.items.len; defer p.strings.items.len = strings_top; - try res.val.print(res.ty, p.comp, p.comp.string_interner.getSlowTypeMapper(), p.strings.writer()); + try res.val.print(res.ty, p.comp, p.strings.writer()); return try p.comp.diagnostics.arena.allocator().dupe(u8, p.strings.items[strings_top..]); } @@ -7060,7 +7060,7 @@ fn offsetofMemberDesignator(p: *Parser, base_ty: Type, want_bits: bool) Error!Re return Result{ .ty = base_ty, .val = val, .node = lhs.node }; } -fn computeOffsetExtra(p: *Parser, node: NodeIndex, offset_so_far: i64) !GlobalVarOffset { +fn computeOffsetExtra(p: *Parser, node: NodeIndex, offset_so_far: i64) !Pointer { const tys = p.nodes.items(.ty); const tags = p.nodes.items(.tag); const data = p.nodes.items(.data); @@ -7077,7 +7077,8 @@ fn computeOffsetExtra(p: *Parser, node: NodeIndex, offset_so_far: i64) !GlobalVa .paren_expr => return p.computeOffsetExtra(data[@intFromEnum(node)].un, offset_so_far), .decl_ref_expr => { const var_name = try p.comp.internString(p.tokSlice(data[@intFromEnum(node)].decl_ref)); - return .{ .name = var_name, .offset = offset_so_far }; + const sym = p.syms.findSymbol(var_name).?; // symbol must exist if we get here; otherwise it's a syntax error + return .{ .decl = @intFromEnum(sym.node), .offset = offset_so_far }; }, .array_access_expr => { const bin_data = data[@intFromEnum(node)].bin; @@ -7100,7 +7101,7 @@ fn computeOffsetExtra(p: *Parser, node: NodeIndex, offset_so_far: i64) !GlobalVa } /// Compute the offset (in bytes) of an expression from a base pointer. -fn computeOffset(p: *Parser, node: NodeIndex) !GlobalVarOffset { +fn computeOffset(p: *Parser, node: NodeIndex) !Pointer { return p.computeOffsetExtra(node, 0); } @@ -7161,10 +7162,10 @@ fn unExpr(p: *Parser) Error!Result { try p.errTok(.addr_of_rvalue, tok); } else if (operand_ty_valid and p.func.ty == null) { // address of global - const reloc: GlobalVarOffset = p.computeOffset(operand.node) catch |e| switch (e) { + const reloc: Pointer = p.computeOffset(operand.node) catch |e| switch (e) { error.InvalidReloc => blk: { try p.errTok(.non_constant_initializer, ampersand_tok); - break :blk .{ .name = .empty, .offset = 0 }; + break :blk .{ .decl = @intFromEnum(NodeIndex.none), .offset = 0 }; }, else => |er| return er, }; diff --git a/src/aro/Tree.zig b/src/aro/Tree.zig index fd639e5d..3bab9453 100644 --- a/src/aro/Tree.zig +++ b/src/aro/Tree.zig @@ -899,7 +899,7 @@ fn dumpNode( if (tree.value_map.get(node)) |val| { try config.setColor(w, LITERAL); try w.writeAll(" (value: "); - try val.print(ty, tree.comp, mapper, w); + try val.print(ty, tree.comp, w); try w.writeByte(')'); } if (tag == .implicit_return and data.return_zero) { diff --git a/src/aro/Value.zig b/src/aro/Value.zig index 21efd232..d6b4d736 100644 --- a/src/aro/Value.zig +++ b/src/aro/Value.zig @@ -2,11 +2,10 @@ const std = @import("std"); const assert = std.debug.assert; const BigIntConst = std.math.big.int.Const; const BigIntMutable = std.math.big.int.Mutable; -const backend = @import("backend"); -const Interner = backend.Interner; -const StringInterner = backend.StringInterner; -const StringId = StringInterner.StringId; +const Interner = @import("backend").Interner; const BigIntSpace = Interner.Tag.Int.BigIntSpace; +const StringInterner = @import("StringInterner.zig"); +const StringId = StringInterner.StringId; const Compilation = @import("Compilation.zig"); const Type = @import("Type.zig"); const target_util = @import("target.zig"); @@ -34,8 +33,8 @@ pub fn int(i: anytype, comp: *Compilation) !Value { } } -pub fn reloc(r: Interner.Key.GlobalVarOffset, comp: *Compilation) !Value { - return intern(comp, .{ .global_var_offset = r }); +pub fn reloc(r: Interner.Key.Pointer, comp: *Compilation) !Value { + return intern(comp, .{ .pointer = r }); } pub fn ref(v: Value) Interner.Ref { @@ -250,7 +249,7 @@ pub const IntCastChangeKind = enum { pub fn intCast(v: *Value, dest_ty: Type, comp: *Compilation) !IntCastChangeKind { if (v.opt_ref == .none) return .none; const key = comp.interner.get(v.ref()); - if (key == .global_var_offset) return .none; + if (key == .pointer) return .none; const dest_bits: usize = @intCast(dest_ty.bitSizeof(comp).?); const dest_signed = dest_ty.signedness(comp) == .signed; @@ -416,7 +415,7 @@ pub fn isZero(v: Value, comp: *const Compilation) bool { inline else => |data| return data[0] == 0.0 and data[1] == 0.0, }, .bytes => return false, - .global_var_offset => return false, + .pointer => return false, else => unreachable, } } @@ -539,11 +538,11 @@ pub fn add(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !b } const lhs_key = comp.interner.get(lhs.ref()); const rhs_key = comp.interner.get(rhs.ref()); - if (lhs_key == .global_var_offset or rhs_key == .global_var_offset) { - const rel, const index = if (lhs_key == .global_var_offset) - .{ lhs_key.global_var_offset, rhs } + if (lhs_key == .pointer or rhs_key == .pointer) { + const rel, const index = if (lhs_key == .pointer) + .{ lhs_key.pointer, rhs } else - .{ rhs_key.global_var_offset, lhs }; + .{ rhs_key.pointer, lhs }; const elem_size = try int(ty.elemType().sizeof(comp) orelse 1, comp); var total_offset: Value = undefined; @@ -551,7 +550,7 @@ pub fn add(res: *Value, lhs: Value, rhs: Value, ty: Type, comp: *Compilation) !b const old_offset = try int(rel.offset, comp); const add_overflow = try total_offset.add(total_offset, old_offset, comp.types.ptrdiff, comp); _ = try total_offset.intCast(comp.types.ptrdiff, comp); - res.* = try reloc(.{ .name = rel.name, .offset = total_offset.toInt(i64, comp).? }, comp); + res.* = try reloc(.{ .decl = rel.decl, .offset = total_offset.toInt(i64, comp).? }, comp); return mul_overflow or add_overflow; } @@ -608,10 +607,10 @@ pub fn sub(res: *Value, lhs: Value, rhs: Value, ty: Type, rhs_ty: Type, comp: *C } const lhs_key = comp.interner.get(lhs.ref()); const rhs_key = comp.interner.get(rhs.ref()); - if (lhs_key == .global_var_offset and rhs_key == .global_var_offset) { - const lhs_reloc = lhs_key.global_var_offset; - const rhs_reloc = rhs_key.global_var_offset; - if (lhs_reloc.name != rhs_reloc.name) { + if (lhs_key == .pointer and rhs_key == .pointer) { + const lhs_reloc = lhs_key.pointer; + const rhs_reloc = rhs_key.pointer; + if (lhs_reloc.decl != rhs_reloc.decl) { res.* = .{}; return false; } @@ -619,8 +618,8 @@ pub fn sub(res: *Value, lhs: Value, rhs: Value, ty: Type, rhs_ty: Type, comp: *C const rhs_size: i64 = @intCast(rhs_ty.elemType().sizeof(comp) orelse 1); res.* = try int(@divTrunc(difference, rhs_size), comp); return overflowed != 0; - } else if (lhs_key == .global_var_offset) { - const rel = lhs_key.global_var_offset; + } else if (lhs_key == .pointer) { + const rel = lhs_key.pointer; const elem_size = try int(ty.elemType().sizeof(comp) orelse 1, comp); var total_offset: Value = undefined; @@ -628,7 +627,7 @@ pub fn sub(res: *Value, lhs: Value, rhs: Value, ty: Type, rhs_ty: Type, comp: *C const old_offset = try int(rel.offset, comp); const add_overflow = try total_offset.sub(old_offset, total_offset, comp.types.ptrdiff, undefined, comp); _ = try total_offset.intCast(comp.types.ptrdiff, comp); - res.* = try reloc(.{ .name = rel.name, .offset = total_offset.toInt(i64, comp).? }, comp); + res.* = try reloc(.{ .decl = rel.decl, .offset = total_offset.toInt(i64, comp).? }, comp); return mul_overflow or add_overflow; } @@ -1001,13 +1000,13 @@ pub fn comparePointers(lhs: Value, op: std.math.CompareOperator, rhs: Value, com const lhs_key = comp.interner.get(lhs.ref()); const rhs_key = comp.interner.get(rhs.ref()); - if (lhs_key == .global_var_offset and rhs_key == .global_var_offset) { - const lhs_reloc = lhs_key.global_var_offset; - const rhs_reloc = rhs_key.global_var_offset; + if (lhs_key == .pointer and rhs_key == .pointer) { + const lhs_reloc = lhs_key.pointer; + const rhs_reloc = rhs_key.pointer; switch (op) { - .eq => if (lhs_reloc.name != rhs_reloc.name) return false, - .neq => if (lhs_reloc.name != rhs_reloc.name) return true, - else => if (lhs_reloc.name != rhs_reloc.name) return null, + .eq => if (lhs_reloc.decl != rhs_reloc.decl) return false, + .neq => if (lhs_reloc.decl != rhs_reloc.decl) return true, + else => if (lhs_reloc.decl != rhs_reloc.decl) return null, } return std.math.compare(lhs_reloc.offset, op, rhs_reloc.offset); @@ -1051,7 +1050,7 @@ pub fn maxInt(ty: Type, comp: *Compilation) !Value { return twosCompIntLimit(.max, ty, comp); } -pub fn print(v: Value, ty: Type, comp: *const Compilation, mapper: StringInterner.TypeMapper, w: anytype) @TypeOf(w).Error!void { +pub fn print(v: Value, ty: Type, comp: *const Compilation, w: anytype) @TypeOf(w).Error!void { if (ty.is(.bool)) { return w.writeAll(if (v.isZero(comp)) "false" else "true"); } @@ -1071,16 +1070,7 @@ pub fn print(v: Value, ty: Type, comp: *const Compilation, mapper: StringInterne .cf32 => |components| return w.print("{d} + {d}i", .{ @round(@as(f64, @floatCast(components[0])) * 1000000) / 1000000, @round(@as(f64, @floatCast(components[1])) * 1000000) / 1000000 }), inline else => |components| return w.print("{d} + {d}i", .{ @as(f64, @floatCast(components[0])), @as(f64, @floatCast(components[1])) }), }, - .global_var_offset => |rel| { - const name = mapper.lookup(rel.name); - try w.print("&{s}", .{name}); - if (rel.offset == 0) return; - if (rel.offset == std.math.minInt(i64)) { - return w.print(" - {d}", .{std.math.maxInt(i64) + 1}); - } - const sign: u8 = if (rel.offset < 0) '-' else '+'; - return w.print(" {c} {d}", .{ sign, @abs(rel.offset) }); - }, + .pointer => {}, else => unreachable, // not a value } } diff --git a/src/backend/Interner.zig b/src/backend/Interner.zig index 531f8191..6c35e3b3 100644 --- a/src/backend/Interner.zig +++ b/src/backend/Interner.zig @@ -1,5 +1,4 @@ const std = @import("std"); -const StringId = @import("StringInterner.zig").StringId; const Allocator = std.mem.Allocator; const assert = std.debug.assert; const BigIntConst = std.math.big.int.Const; @@ -66,7 +65,7 @@ pub const Key = union(enum) { float: Float, complex: Complex, bytes: []const u8, - global_var_offset: GlobalVarOffset, + pointer: Pointer, pub const Float = union(enum) { f16: f16, @@ -82,8 +81,9 @@ pub const Key = union(enum) { cf80: [2]f80, cf128: [2]f128, }; - pub const GlobalVarOffset = struct { - name: StringId, + pub const Pointer = struct { + /// NodeIndex of decl whose address we are offsetting from + decl: u32, /// Offset in bytes offset: i64, }; @@ -310,8 +310,8 @@ pub const Tag = enum(u8) { bytes, /// `data` is `Record` record_ty, - /// `data` is GlobalVarOffset - global_var_offset, + /// `data` is Pointer + pointer, pub const Array = struct { len0: u32, @@ -547,23 +547,23 @@ pub const Tag = enum(u8) { // [elements_len]Ref }; - pub const GlobalVarOffset = struct { - name: u32, + pub const Pointer = struct { + decl: u32, piece0: u32, piece1: u32, - pub fn get(self: GlobalVarOffset) Key.GlobalVarOffset { + pub fn get(self: Pointer) Key.Pointer { const offset = @as(u64, self.piece0) | (@as(u64, self.piece1) << 32); return .{ - .name = @enumFromInt(self.name), + .decl = self.decl, .offset = @bitCast(offset), }; } - fn pack(val: Key.GlobalVarOffset) GlobalVarOffset { + fn pack(val: Key.Pointer) Pointer { const bits: u64 = @bitCast(val.offset); return .{ - .name = @intFromEnum(val.name), + .decl = val.decl, .piece0 = @truncate(bits), .piece1 = @truncate(bits >> 32), }; @@ -748,10 +748,10 @@ pub fn put(i: *Interner, gpa: Allocator, key: Key) !Ref { }); i.extra.appendSliceAssumeCapacity(@ptrCast(elems)); }, - .global_var_offset => |reloc| { + .pointer => |reloc| { i.items.appendAssumeCapacity(.{ - .tag = .global_var_offset, - .data = try i.addExtra(gpa, Tag.GlobalVarOffset.pack(reloc)), + .tag = .pointer, + .data = try i.addExtra(gpa, Tag.Pointer.pack(reloc)), }); }, .ptr_ty, @@ -886,9 +886,9 @@ pub fn get(i: *const Interner, ref: Ref) Key { .record_ty = @ptrCast(i.extra.items[extra.end..][0..extra.data.elements_len]), }; }, - .global_var_offset => { - const components = i.extraData(Tag.GlobalVarOffset, data); - return .{ .global_var_offset = components.get() }; + .pointer => { + const components = i.extraData(Tag.Pointer, data); + return .{ .pointer = components.get() }; }, }; }