diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-04-29 12:23:46 +0300 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-04-30 01:06:01 +0300 |
| commit | 596f7df02e78adf334eed4a1f14eafa31ca611b9 (patch) | |
| tree | c2e3dc7082a0b0c8d870506820d10c708c906934 /src | |
| parent | 1d455896cb24165c5a3e0b3e10934c60a285589d (diff) | |
| download | zig-596f7df02e78adf334eed4a1f14eafa31ca611b9.tar.gz zig-596f7df02e78adf334eed4a1f14eafa31ca611b9.zip | |
Zir: turn extended func into func_extended
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 29 | ||||
| -rw-r--r-- | src/Module.zig | 8 | ||||
| -rw-r--r-- | src/Sema.zig | 32 | ||||
| -rw-r--r-- | src/Zir.zig | 62 | ||||
| -rw-r--r-- | src/print_zir.zig | 24 |
5 files changed, 75 insertions, 80 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index b0cd976b00..f74a2b2d39 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -72,6 +72,7 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void { i32 => @bitCast(u32, @field(extra, field.name)), Zir.Inst.Call.Flags => @bitCast(u32, @field(extra, field.name)), Zir.Inst.SwitchBlock.Bits => @bitCast(u32, @field(extra, field.name)), + Zir.Inst.ExtendedFunc.Bits => @bitCast(u32, @field(extra, field.name)), else => @compileError("bad field type"), }; i += 1; @@ -2245,6 +2246,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .field_val_named, .func, .func_inferred, + .func_extended, .int, .int_big, .float, @@ -10023,10 +10025,18 @@ const GenZir = struct { @boolToInt(args.cc != .none), ); const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedFunc{ - .src_node = gz.nodeIndexToRelative(args.src_node), .param_block = args.param_block, .ret_body_len = @intCast(u32, ret_ty.len), .body_len = @intCast(u32, body.len), + .bits = .{ + .is_var_args = args.is_var_args, + .is_inferred_error = args.is_inferred_error, + .has_lib_name = args.lib_name != 0, + .has_cc = args.cc != .none, + .has_align = args.align_inst != .none, + .is_test = args.is_test, + .is_extern = args.is_extern, + }, }); if (args.lib_name != 0) { astgen.extra.appendAssumeCapacity(args.lib_name); @@ -10050,19 +10060,10 @@ const GenZir = struct { astgen.instructions.items(.data)[args.ret_br].@"break".block_inst = new_index; } astgen.instructions.appendAssumeCapacity(.{ - .tag = .extended, - .data = .{ .extended = .{ - .opcode = .func, - .small = @bitCast(u16, Zir.Inst.ExtendedFunc.Small{ - .is_var_args = args.is_var_args, - .is_inferred_error = args.is_inferred_error, - .has_lib_name = args.lib_name != 0, - .has_cc = args.cc != .none, - .has_align = args.align_inst != .none, - .is_test = args.is_test, - .is_extern = args.is_extern, - }), - .operand = payload_index, + .tag = .func_extended, + .data = .{ .pl_node = .{ + .src_node = gz.nodeIndexToRelative(args.src_node), + .payload_index = payload_index, } }, }); gz.instructions.appendAssumeCapacity(new_index); diff --git a/src/Module.zig b/src/Module.zig index 1119d73ab0..55ec1fdd2c 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1532,10 +1532,10 @@ pub const Fn = struct { switch (zir_tags[func.zir_body_inst]) { .func => return false, .func_inferred => return true, - .extended => { - const extended = zir.instructions.items(.data)[func.zir_body_inst].extended; - const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small); - return small.is_inferred_error; + .func_extended => { + const inst_data = zir.instructions.items(.data)[func.zir_body_inst].pl_node; + const extra = zir.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index); + return extra.data.bits.is_inferred_error; }, else => unreachable, } diff --git a/src/Sema.zig b/src/Sema.zig index 40b9698d49..ccfb11e639 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -745,6 +745,7 @@ fn analyzeBodyInner( .field_call_bind => try sema.zirFieldCallBind(block, inst), .func => try sema.zirFunc(block, inst, false), .func_inferred => try sema.zirFunc(block, inst, true), + .func_extended => try sema.zirFuncExtended(block, inst), .import => try sema.zirImport(block, inst), .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst), .int => try sema.zirInt(block, inst), @@ -911,7 +912,6 @@ fn analyzeBodyInner( const extended = datas[inst].extended; break :ext switch (extended.opcode) { // zig fmt: off - .func => try sema.zirFuncExtended( block, extended, inst), .variable => try sema.zirVarExtended( block, extended), .struct_decl => try sema.zirStructDecl( block, extended, inst), .enum_decl => try sema.zirEnumDecl( block, extended), @@ -16099,37 +16099,33 @@ fn zirVarExtended( return result; } -fn zirFuncExtended( - sema: *Sema, - block: *Block, - extended: Zir.Inst.Extended.InstData, - inst: Zir.Inst.Index, -) CompileError!Air.Inst.Ref { +fn zirFuncExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); - const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, extended.operand); - const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; - const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = extra.data.src_node }; + const inst_data = sema.code.instructions.items(.data)[inst].pl_node; + const src = inst_data.src(); + const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index); + + const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = inst_data.src_node }; const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align - const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small); var extra_index: usize = extra.end; - const lib_name: ?[]const u8 = if (small.has_lib_name) blk: { + const lib_name: ?[]const u8 = if (extra.data.bits.has_lib_name) blk: { const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]); extra_index += 1; break :blk lib_name; } else null; - const cc: std.builtin.CallingConvention = if (small.has_cc) blk: { + const cc: std.builtin.CallingConvention = if (extra.data.bits.has_cc) blk: { const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); extra_index += 1; const cc_tv = try sema.resolveInstConst(block, cc_src, cc_ref); break :blk cc_tv.val.toEnum(std.builtin.CallingConvention); } else .Unspecified; - const align_val: Value = if (small.has_align) blk: { + const align_val: Value = if (extra.data.bits.has_align) blk: { const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]); extra_index += 1; const align_tv = try sema.resolveInstConst(block, align_src, align_ref); @@ -16146,13 +16142,13 @@ fn zirFuncExtended( src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data; } - const is_var_args = small.is_var_args; - const is_inferred_error = small.is_inferred_error; - const is_extern = small.is_extern; + const is_var_args = extra.data.bits.is_var_args; + const is_inferred_error = extra.data.bits.is_inferred_error; + const is_extern = extra.data.bits.is_extern; return sema.funcCommon( block, - extra.data.src_node, + inst_data.src_node, inst, ret_ty_body, cc, diff --git a/src/Zir.zig b/src/Zir.zig index 29732d7907..9ef6d33b86 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -73,6 +73,7 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) struct { data: T, en i32 => @bitCast(i32, code.extra[i]), Inst.Call.Flags => @bitCast(Inst.Call.Flags, code.extra[i]), Inst.SwitchBlock.Bits => @bitCast(Inst.SwitchBlock.Bits, code.extra[i]), + Inst.ExtendedFunc.Bits => @bitCast(Inst.ExtendedFunc.Bits, code.extra[i]), else => @compileError("bad field type"), }; i += 1; @@ -415,6 +416,10 @@ pub const Inst = struct { func, /// Same as `func` but has an inferred error set. func_inferred, + /// Represents a function declaration or function prototype, depending on + /// whether body_len is 0. + /// Uses the `pl_node` union field. `payload_index` points to a `ExtendedFunc`. + func_extended, /// Implements the `@import` builtin. /// Uses the `str_tok` field. import, @@ -1062,6 +1067,7 @@ pub const Inst = struct { .field_val_named, .func, .func_inferred, + .func_extended, .has_decl, .int, .int_big, @@ -1347,6 +1353,7 @@ pub const Inst = struct { .field_val_named, .func, .func_inferred, + .func_extended, .has_decl, .int, .int_big, @@ -1601,6 +1608,7 @@ pub const Inst = struct { .field_call_bind = .pl_node, .func = .pl_node, .func_inferred = .pl_node, + .func_extended = .pl_node, .import = .str_tok, .int = .int, .int_big = .str, @@ -1802,11 +1810,6 @@ pub const Inst = struct { /// Rarer instructions are here; ones that do not fit in the 8-bit `Tag` enum. /// `noreturn` instructions may not go here; they must be part of the main `Tag` enum. pub const Extended = enum(u16) { - /// Represents a function declaration or function prototype, depending on - /// whether body_len is 0. - /// `operand` is payload index to `ExtendedFunc`. - /// `small` is `ExtendedFunc.Small`. - func, /// Declares a global variable. /// `operand` is payload index to `ExtendedVar`. /// `small` is `ExtendedVar.Small`. @@ -2621,14 +2624,14 @@ pub const Inst = struct { /// 4. body: Index // for each body_len /// 5. src_locs: Func.SrcLocs // if body_len != 0 pub const ExtendedFunc = struct { - src_node: i32, /// If this is 0 it means a void return type. ret_body_len: u32, /// Points to the block that contains the param instructions for this function. param_block: Index, body_len: u32, + bits: Bits, - pub const Small = packed struct { + pub const Bits = packed struct { is_var_args: bool, is_inferred_error: bool, has_lib_name: bool, @@ -2636,7 +2639,7 @@ pub const Inst = struct { has_align: bool, is_test: bool, is_extern: bool, - _: u9 = undefined, + _: u25 = undefined, }; }; @@ -3460,14 +3463,11 @@ pub fn declIterator(zir: Zir, decl_inst: u32) DeclIterator { switch (tags[decl_inst]) { // Functions are allowed and yield no iterations. // There is one case matching this in the extended instruction set below. - .func, - .func_inferred, - => return declIteratorInner(zir, 0, 0), + .func, .func_inferred, .func_extended => return declIteratorInner(zir, 0, 0), .extended => { const extended = datas[decl_inst].extended; switch (extended.opcode) { - .func => return declIteratorInner(zir, 0, 0), .struct_decl => { const small = @bitCast(Inst.StructDecl.Small, extended.small); var extra_index: usize = extended.operand; @@ -3572,21 +3572,21 @@ fn findDeclsInner( const body = zir.extra[extra.end..][0..extra.data.body_len]; return zir.findDeclsBody(list, body); }, + .func_extended => { + try list.append(inst); + + const inst_data = datas[inst].pl_node; + const extra = zir.extraData(Inst.ExtendedFunc, inst_data.payload_index); + var extra_index: usize = extra.end; + extra_index += @boolToInt(extra.data.bits.has_lib_name); + extra_index += @boolToInt(extra.data.bits.has_cc); + extra_index += @boolToInt(extra.data.bits.has_align); + const body = zir.extra[extra_index..][0..extra.data.body_len]; + return zir.findDeclsBody(list, body); + }, .extended => { const extended = datas[inst].extended; switch (extended.opcode) { - .func => { - try list.append(inst); - - const extra = zir.extraData(Inst.ExtendedFunc, extended.operand); - const small = @bitCast(Inst.ExtendedFunc.Small, extended.small); - var extra_index: usize = extra.end; - extra_index += @boolToInt(small.has_lib_name); - extra_index += @boolToInt(small.has_cc); - extra_index += @boolToInt(small.has_align); - const body = zir.extra[extra_index..][0..extra.data.body_len]; - return zir.findDeclsBody(list, body); - }, // Decl instructions are interesting but have no body. // TODO yes they do have a body actually. recurse over them just like block instructions. @@ -3733,15 +3733,13 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo { .body = body, }; }, - .extended => blk: { - const extended = datas[fn_inst].extended; - assert(extended.opcode == .func); - const extra = zir.extraData(Inst.ExtendedFunc, extended.operand); - const small = @bitCast(Inst.ExtendedFunc.Small, extended.small); + .func_extended => blk: { + const inst_data = datas[fn_inst].pl_node; + const extra = zir.extraData(Inst.ExtendedFunc, inst_data.payload_index); var extra_index: usize = extra.end; - extra_index += @boolToInt(small.has_lib_name); - extra_index += @boolToInt(small.has_cc); - extra_index += @boolToInt(small.has_align); + extra_index += @boolToInt(extra.data.bits.has_lib_name); + extra_index += @boolToInt(extra.data.bits.has_cc); + extra_index += @boolToInt(extra.data.bits.has_align); const ret_ty_body = zir.extra[extra_index..][0..extra.data.ret_body_len]; extra_index += ret_ty_body.len; const body = zir.extra[extra_index..][0..extra.data.body_len]; diff --git a/src/print_zir.zig b/src/print_zir.zig index a65361652d..ac90c26cf6 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -429,6 +429,7 @@ const Writer = struct { .func => try self.writeFunc(stream, inst, false), .func_inferred => try self.writeFunc(stream, inst, true), + .func_extended => try self.writeFuncExtended(stream, inst), .@"unreachable" => try self.writeUnreachable(stream, inst), @@ -469,7 +470,6 @@ const Writer = struct { }, .@"asm" => try self.writeAsm(stream, extended), - .func => try self.writeFuncExtended(stream, extended), .variable => try self.writeVarExtended(stream, extended), .alloc => try self.writeAllocExtended(stream, extended), @@ -1920,24 +1920,24 @@ const Writer = struct { ); } - fn writeFuncExtended(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { - const extra = self.code.extraData(Zir.Inst.ExtendedFunc, extended.operand); - const src: LazySrcLoc = .{ .node_offset = extra.data.src_node }; - const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small); + fn writeFuncExtended(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { + const inst_data = self.code.instructions.items(.data)[inst].pl_node; + const extra = self.code.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index); + const src = inst_data.src(); var extra_index: usize = extra.end; - if (small.has_lib_name) { + if (extra.data.bits.has_lib_name) { const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]); extra_index += 1; try stream.print("lib_name=\"{}\", ", .{std.zig.fmtEscapes(lib_name)}); } - try self.writeFlag(stream, "test, ", small.is_test); - const cc: Zir.Inst.Ref = if (!small.has_cc) .none else blk: { + try self.writeFlag(stream, "test, ", extra.data.bits.is_test); + const cc: Zir.Inst.Ref = if (!extra.data.bits.has_cc) .none else blk: { const cc = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); extra_index += 1; break :blk cc; }; - const align_inst: Zir.Inst.Ref = if (!small.has_align) .none else blk: { + const align_inst: Zir.Inst.Ref = if (!extra.data.bits.has_align) .none else blk: { const align_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]); extra_index += 1; break :blk align_inst; @@ -1956,9 +1956,9 @@ const Writer = struct { return self.writeFuncCommon( stream, ret_ty_body, - small.is_inferred_error, - small.is_var_args, - small.is_extern, + extra.data.bits.is_inferred_error, + extra.data.bits.is_var_args, + extra.data.bits.is_extern, cc, align_inst, body, |
