From 97d7fddfb78d17132749cae59fea36fe661bf642 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 2 Apr 2021 19:11:51 -0700 Subject: stage2: progress towards basic structs Introduce `ResultLoc.none_or_ref` which is used by field access expressions to avoid unnecessary loads when the field access itself will do the load. This turns: ```zig p.y - p.x - p.x ``` from ```zir %14 = load(%4) node_offset:8:12 %15 = field_val(%14, "y") node_offset:8:13 %16 = load(%4) node_offset:8:18 %17 = field_val(%16, "x") node_offset:8:19 %18 = sub(%15, %17) node_offset:8:16 %19 = load(%4) node_offset:8:24 %20 = field_val(%19, "x") node_offset:8:25 ``` to ```zir %14 = field_val(%4, "y") node_offset:8:13 %15 = field_val(%4, "x") node_offset:8:19 %16 = sub(%14, %15) node_offset:8:16 %17 = field_val(%4, "x") node_offset:8:25 ``` Much more compact. This requires `Sema.zirFieldVal` to support both pointers and non-pointers. C backend: Implement typedefs for struct types, as well as the following TZIR instructions: * mul * mulwrap * addwrap * subwrap * ref * struct_field_ptr Note that add, addwrap, sub, subwrap, mul, mulwrap instructions are all incorrect currently and need to be updated to properly handle wrapping and non wrapping for signed and unsigned. C backend: change indentation delta to 1, to make the output smaller and to process fewer bytes. I promise I will add a test case as soon as I fix those warnings that are being printed for my test case. --- src/Sema.zig | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/Sema.zig') diff --git a/src/Sema.zig b/src/Sema.zig index 06ff3e445b..216544e1df 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -600,6 +600,7 @@ fn zirStructDecl( const struct_obj = try new_decl_arena.allocator.create(Module.Struct); const struct_ty = try Type.Tag.@"struct".create(&new_decl_arena.allocator, struct_obj); + const struct_val = try Value.Tag.ty.create(&new_decl_arena.allocator, struct_ty); struct_obj.* = .{ .owner_decl = sema.owner_decl, .fields = fields_map, @@ -611,7 +612,7 @@ fn zirStructDecl( }; const new_decl = try sema.mod.createAnonymousDecl(&block.base, &new_decl_arena, .{ .ty = Type.initTag(.type), - .val = try Value.Tag.ty.create(gpa, struct_ty), + .val = struct_val, }); return sema.analyzeDeclVal(block, src, new_decl); } @@ -2139,7 +2140,10 @@ fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro const extra = sema.code.extraData(zir.Inst.Field, inst_data.payload_index).data; const field_name = sema.code.nullTerminatedString(extra.field_name_start); const object = try sema.resolveInst(extra.lhs); - const object_ptr = try sema.analyzeRef(block, src, object); + const object_ptr = if (object.ty.zigTypeTag() == .Pointer) + object + else + try sema.analyzeRef(block, src, object); const result_ptr = try sema.namedFieldPtr(block, src, object_ptr, field_name, field_name_src); return sema.analyzeLoad(block, src, result_ptr, result_ptr.src); } -- cgit v1.2.3