Commit 14aa08fcd3

Andrew Kelley <andrew@ziglang.org>
2020-06-24 09:46:32
self-hosted: restore ZIR functionality
1 parent b1b7708
Changed files (4)
src-self-hosted
test
stage2
src-self-hosted/main.zig
@@ -504,7 +504,7 @@ fn updateModule(gpa: *Allocator, module: *Module, zir_out_path: ?[]const u8) !vo
             });
         }
     } else {
-        std.debug.print("Update completed in {} ms\n", .{update_nanos / std.time.ns_per_ms});
+        std.log.info(.compiler, "Update completed in {} ms\n", .{update_nanos / std.time.ns_per_ms});
     }
 
     if (zir_out_path) |zop| {
src-self-hosted/Module.zig
@@ -1060,21 +1060,24 @@ fn ensureDeclAnalyzed(self: *Module, decl: *Decl) InnerError!void {
         .unreferenced => false,
     };
 
-    const type_changed = self.astGenAndAnalyzeDecl(decl) catch |err| switch (err) {
-        error.OutOfMemory => return error.OutOfMemory,
-        error.AnalysisFail => return error.AnalysisFail,
-        else => {
-            try self.failed_decls.ensureCapacity(self.failed_decls.size + 1);
-            self.failed_decls.putAssumeCapacityNoClobber(decl, try ErrorMsg.create(
-                self.allocator,
-                decl.src(),
-                "unable to analyze: {}",
-                .{@errorName(err)},
-            ));
-            decl.analysis = .sema_failure_retryable;
-            return error.AnalysisFail;
-        },
-    };
+    const type_changed = if (self.root_scope.cast(Scope.ZIRModule)) |zir_module|
+        try self.analyzeZirDecl(decl, zir_module.contents.module.decls[decl.src_index])
+    else
+        self.astGenAndAnalyzeDecl(decl) catch |err| switch (err) {
+            error.OutOfMemory => return error.OutOfMemory,
+            error.AnalysisFail => return error.AnalysisFail,
+            else => {
+                try self.failed_decls.ensureCapacity(self.failed_decls.size + 1);
+                self.failed_decls.putAssumeCapacityNoClobber(decl, try ErrorMsg.create(
+                    self.allocator,
+                    decl.src(),
+                    "unable to analyze: {}",
+                    .{@errorName(err)},
+                ));
+                decl.analysis = .sema_failure_retryable;
+                return error.AnalysisFail;
+            },
+        };
 
     if (subsequent_analysis) {
         // We may need to chase the dependants and re-analyze them.
@@ -1724,71 +1727,63 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void {
 }
 
 fn analyzeRootZIRModule(self: *Module, root_scope: *Scope.ZIRModule) !void {
-    switch (root_scope.status) {
-        .never_loaded => {
-            const src_module = try self.getSrcModule(root_scope);
+    // We may be analyzing it for the first time, or this may be
+    // an incremental update. This code handles both cases.
+    const src_module = try self.getSrcModule(root_scope);
 
-            // Here we ensure enough queue capacity to store all the decls, so that later we can use
-            // appendAssumeCapacity.
-            try self.work_queue.ensureUnusedCapacity(src_module.decls.len);
+    try self.work_queue.ensureUnusedCapacity(src_module.decls.len);
+    try root_scope.decls.ensureCapacity(self.allocator, src_module.decls.len);
 
-            for (src_module.decls) |src_decl| {
-                if (src_decl.inst.cast(zir.Inst.Export)) |export_inst| {
-                    _ = try self.resolveDecl(&root_scope.base, src_decl);
-                }
-            }
-        },
+    var exports_to_resolve = std.ArrayList(*zir.Decl).init(self.allocator);
+    defer exports_to_resolve.deinit();
 
-        .unloaded_parse_failure,
-        .unloaded_sema_failure,
-        .unloaded_success,
-        .loaded_sema_failure,
-        .loaded_success,
-        => {
-            const src_module = try self.getSrcModule(root_scope);
-
-            var exports_to_resolve = std.ArrayList(*zir.Decl).init(self.allocator);
-            defer exports_to_resolve.deinit();
-
-            // Keep track of the decls that we expect to see in this file so that
-            // we know which ones have been deleted.
-            var deleted_decls = std.AutoHashMap(*Decl, void).init(self.allocator);
-            defer deleted_decls.deinit();
-            try deleted_decls.ensureCapacity(self.decl_table.size);
-            {
-                var it = self.decl_table.iterator();
-                while (it.next()) |kv| {
-                    deleted_decls.putAssumeCapacityNoClobber(kv.value, {});
-                }
-            }
+    // Keep track of the decls that we expect to see in this file so that
+    // we know which ones have been deleted.
+    var deleted_decls = std.AutoHashMap(*Decl, void).init(self.allocator);
+    defer deleted_decls.deinit();
+    try deleted_decls.ensureCapacity(self.decl_table.size);
+    {
+        var it = self.decl_table.iterator();
+        while (it.next()) |kv| {
+            deleted_decls.putAssumeCapacityNoClobber(kv.value, {});
+        }
+    }
 
-            for (src_module.decls) |src_decl| {
-                const name_hash = root_scope.fullyQualifiedNameHash(src_decl.name);
-                if (self.decl_table.get(name_hash)) |kv| {
-                    const decl = kv.value;
-                    deleted_decls.removeAssertDiscard(decl);
-                    //std.debug.warn("'{}' contents: '{}'\n", .{ src_decl.name, src_decl.contents });
-                    if (!srcHashEql(src_decl.contents_hash, decl.contents_hash)) {
-                        try self.markOutdatedDecl(decl);
-                        decl.contents_hash = src_decl.contents_hash;
-                    }
-                } else if (src_decl.inst.cast(zir.Inst.Export)) |export_inst| {
-                    try exports_to_resolve.append(src_decl);
-                }
+    for (src_module.decls) |src_decl, decl_i| {
+        const name_hash = root_scope.fullyQualifiedNameHash(src_decl.name);
+        if (self.decl_table.get(name_hash)) |kv| {
+            const decl = kv.value;
+            deleted_decls.removeAssertDiscard(decl);
+            //std.debug.warn("'{}' contents: '{}'\n", .{ src_decl.name, src_decl.contents });
+            if (!srcHashEql(src_decl.contents_hash, decl.contents_hash)) {
+                try self.markOutdatedDecl(decl);
+                decl.contents_hash = src_decl.contents_hash;
             }
-            {
-                // Handle explicitly deleted decls from the source code. Not to be confused
-                // with when we delete decls because they are no longer referenced.
-                var it = deleted_decls.iterator();
-                while (it.next()) |kv| {
-                    //std.debug.warn("noticed '{}' deleted from source\n", .{kv.key.name});
-                    try self.deleteDecl(kv.key);
-                }
-            }
-            for (exports_to_resolve.items) |export_decl| {
-                _ = try self.resolveDecl(&root_scope.base, export_decl);
+        } else {
+            const new_decl = try self.createNewDecl(
+                &root_scope.base,
+                src_decl.name,
+                decl_i,
+                name_hash,
+                src_decl.contents_hash,
+            );
+            root_scope.decls.appendAssumeCapacity(new_decl);
+            if (src_decl.inst.cast(zir.Inst.Export)) |export_inst| {
+                try exports_to_resolve.append(src_decl);
             }
-        },
+        }
+    }
+    {
+        // Handle explicitly deleted decls from the source code. Not to be confused
+        // with when we delete decls because they are no longer referenced.
+        var it = deleted_decls.iterator();
+        while (it.next()) |kv| {
+            //std.debug.warn("noticed '{}' deleted from source\n", .{kv.key.name});
+            try self.deleteDecl(kv.key);
+        }
+    }
+    for (exports_to_resolve.items) |export_decl| {
+        _ = try self.resolveZirDecl(&root_scope.base, export_decl);
     }
 }
 
@@ -1933,73 +1928,67 @@ fn createNewDecl(
     return new_decl;
 }
 
-fn analyzeNewDecl(self: *Module, new_decl: *Decl, src_decl: *zir.Decl) InnerError!void {
+fn analyzeZirDecl(self: *Module, decl: *Decl, src_decl: *zir.Decl) InnerError!bool {
     var decl_scope: Scope.DeclAnalysis = .{
-        .decl = new_decl,
+        .decl = decl,
         .arena = std.heap.ArenaAllocator.init(self.allocator),
     };
     errdefer decl_scope.arena.deinit();
 
-    new_decl.analysis = .in_progress;
+    decl.analysis = .in_progress;
 
-    const typed_value = self.analyzeConstInst(&decl_scope.base, src_decl.inst) catch |err| switch (err) {
-        error.OutOfMemory => return error.OutOfMemory,
-        error.AnalysisFail => {
-            switch (new_decl.analysis) {
-                .in_progress => new_decl.analysis = .dependency_failure,
-                else => {},
-            }
-            new_decl.generation = self.generation;
-            return error.AnalysisFail;
-        },
-    };
+    const typed_value = try self.analyzeConstInst(&decl_scope.base, src_decl.inst);
     const arena_state = try decl_scope.arena.allocator.create(std.heap.ArenaAllocator.State);
 
-    arena_state.* = decl_scope.arena.state;
+    var prev_type_has_bits = false;
+    var type_changed = true;
 
-    new_decl.typed_value = .{
+    if (decl.typedValueManaged()) |tvm| {
+        prev_type_has_bits = tvm.typed_value.ty.hasCodeGenBits();
+        type_changed = !tvm.typed_value.ty.eql(typed_value.ty);
+
+        tvm.deinit(self.allocator);
+    }
+
+    arena_state.* = decl_scope.arena.state;
+    decl.typed_value = .{
         .most_recent = .{
             .typed_value = typed_value,
             .arena = arena_state,
         },
     };
-    new_decl.analysis = .complete;
-    new_decl.generation = self.generation;
+    decl.analysis = .complete;
+    decl.generation = self.generation;
     if (typed_value.ty.hasCodeGenBits()) {
         // We don't fully codegen the decl until later, but we do need to reserve a global
         // offset table index for it. This allows us to codegen decls out of dependency order,
         // increasing how many computations can be done in parallel.
-        try self.bin_file.allocateDeclIndexes(new_decl);
-        try self.work_queue.writeItem(.{ .codegen_decl = new_decl });
+        try self.bin_file.allocateDeclIndexes(decl);
+        try self.work_queue.writeItem(.{ .codegen_decl = decl });
+    } else if (prev_type_has_bits) {
+        self.bin_file.freeDecl(decl);
     }
+
+    return type_changed;
 }
 
-fn resolveDecl(self: *Module, scope: *Scope, src_decl: *zir.Decl) InnerError!*Decl {
-    // If the name is empty, then we make this an anonymous Decl.
-    const scope_decl = scope.decl().?;
-    const new_decl = try self.allocateNewDecl(scope, scope_decl.src_index, src_decl.contents_hash);
-    try self.analyzeNewDecl(new_decl, src_decl);
-    return new_decl;
-    //const name_hash = Decl.hashSimpleName(src_decl.name);
-    //if (self.decl_table.get(name_hash)) |kv| {
-    //    const decl = kv.value;
-    //    decl.src = src_decl.src;
-    //    try self.reAnalyzeDecl(decl, src_decl);
-    //    return decl;
-    //} else if (src_decl.cast(zir.Inst.DeclVal)) |decl_val| {
-    //    // This is just a named reference to another decl.
-    //    return self.analyzeDeclVal(scope, decl_val);
-    //} else {
-    //    const new_decl = try self.createNewDecl(scope, src_decl.name, src_decl.src, name_hash, src_decl.contents_hash);
-    //    try self.analyzeNewDecl(new_decl, src_decl);
-
-    //    return new_decl;
-    //}
+fn resolveZirDecl(self: *Module, scope: *Scope, src_decl: *zir.Decl) InnerError!*Decl {
+    const zir_module = self.root_scope.cast(Scope.ZIRModule).?;
+    const entry = zir_module.contents.module.findDecl(src_decl.name).?;
+    return self.resolveZirDeclHavingIndex(scope, src_decl, entry.index);
+}
+
+fn resolveZirDeclHavingIndex(self: *Module, scope: *Scope, src_decl: *zir.Decl, src_index: usize) InnerError!*Decl {
+    const name_hash = scope.namespace().fullyQualifiedNameHash(src_decl.name);
+    const decl = self.decl_table.getValue(name_hash).?;
+    decl.src_index = src_index;
+    try self.ensureDeclAnalyzed(decl);
+    return decl;
 }
 
 /// Declares a dependency on the decl.
-fn resolveCompleteDecl(self: *Module, scope: *Scope, src_decl: *zir.Decl) InnerError!*Decl {
-    const decl = try self.resolveDecl(scope, src_decl);
+fn resolveCompleteZirDecl(self: *Module, scope: *Scope, src_decl: *zir.Decl) InnerError!*Decl {
+    const decl = try self.resolveZirDecl(scope, src_decl);
     switch (decl.analysis) {
         .unreferenced => unreachable,
         .in_progress => unreachable,
@@ -2014,15 +2003,32 @@ fn resolveCompleteDecl(self: *Module, scope: *Scope, src_decl: *zir.Decl) InnerE
 
         .complete => {},
     }
-    if (scope.decl()) |scope_decl| {
-        try self.declareDeclDependency(scope_decl, decl);
-    }
     return decl;
 }
 
-/// TODO look into removing this function
+/// TODO Look into removing this function. The body is only needed for .zir files, not .zig files.
 fn resolveInst(self: *Module, scope: *Scope, old_inst: *zir.Inst) InnerError!*Inst {
-    return old_inst.analyzed_inst;
+    if (old_inst.analyzed_inst) |inst| return inst;
+
+    // If this assert trips, the instruction that was referenced did not get properly
+    // analyzed before it was referenced.
+    const zir_module = scope.namespace().cast(Scope.ZIRModule).?;
+    const entry = if (old_inst.cast(zir.Inst.DeclVal)) |declval| blk: {
+        const decl_name = declval.positionals.name;
+        const entry = zir_module.contents.module.findDecl(decl_name) orelse
+            return self.fail(scope, old_inst.src, "decl '{}' not found", .{decl_name});
+        break :blk entry;
+    } else blk: {
+        // If this assert trips, the instruction that was referenced did not get
+        // properly analyzed by a previous instruction analysis before it was
+        // referenced by the current one.
+        break :blk zir_module.contents.module.findInstDecl(old_inst).?;
+    };
+    const decl = try self.resolveCompleteZirDecl(scope, entry.decl);
+    const decl_ref = try self.analyzeDeclRef(scope, old_inst.src, decl);
+    const result = try self.analyzeDeref(scope, old_inst.src, decl_ref, old_inst.src);
+    old_inst.analyzed_inst = result;
+    return result;
 }
 
 fn requireRuntimeBlock(self: *Module, scope: *Scope, src: usize) !*Scope.Block {
@@ -2071,6 +2077,7 @@ fn resolveType(self: *Module, scope: *Scope, old_inst: *zir.Inst) !Type {
 }
 
 fn analyzeExport(self: *Module, scope: *Scope, src: usize, symbol_name: []const u8, exported_decl: *Decl) !void {
+    try self.ensureDeclAnalyzed(exported_decl);
     const typed_value = exported_decl.typed_value.most_recent.typed_value;
     switch (typed_value.ty.zigTypeTag()) {
         .Fn => {},
@@ -2439,7 +2446,7 @@ fn analyzeDeclVal(self: *Module, scope: *Scope, inst: *zir.Inst.DeclVal) InnerEr
     const src_decl = zir_module.contents.module.findDecl(decl_name) orelse
         return self.fail(scope, inst.base.src, "use of undeclared identifier '{}'", .{decl_name});
 
-    const decl = try self.resolveCompleteDecl(scope, src_decl.decl);
+    const decl = try self.resolveCompleteZirDecl(scope, src_decl.decl);
 
     return decl;
 }
@@ -2555,19 +2562,31 @@ fn analyzeInstCall(self: *Module, scope: *Scope, inst: *zir.Inst.Call) InnerErro
 }
 
 fn analyzeInstFn(self: *Module, scope: *Scope, fn_inst: *zir.Inst.Fn) InnerError!*Inst {
-    return self.fail(scope, fn_inst.base.src, "TODO implement ZIR fn inst", .{});
-    //const fn_type = try self.resolveType(scope, fn_inst.positionals.fn_type);
-    //const new_func = try scope.arena().create(Fn);
-    //new_func.* = .{
-    //    .analysis = .{ .queued = fn_inst },
-    //    .owner_decl = scope.decl().?,
-    //};
-    //const fn_payload = try scope.arena().create(Value.Payload.Function);
-    //fn_payload.* = .{ .func = new_func };
-    //return self.constInst(scope, fn_inst.base.src, .{
-    //    .ty = fn_type,
-    //    .val = Value.initPayload(&fn_payload.base),
-    //});
+    const fn_type = try self.resolveType(scope, fn_inst.positionals.fn_type);
+    const fn_zir = blk: {
+        var fn_arena = std.heap.ArenaAllocator.init(self.allocator);
+        errdefer fn_arena.deinit();
+
+        const fn_zir = try scope.arena().create(Fn.ZIR);
+        fn_zir.* = .{
+            .body = .{
+                .instructions = fn_inst.positionals.body.instructions,
+            },
+            .arena = fn_arena.state,
+        };
+        break :blk fn_zir;
+    };
+    const new_func = try scope.arena().create(Fn);
+    new_func.* = .{
+        .analysis = .{ .queued = fn_zir },
+        .owner_decl = scope.decl().?,
+    };
+    const fn_payload = try scope.arena().create(Value.Payload.Function);
+    fn_payload.* = .{ .func = new_func };
+    return self.constInst(scope, fn_inst.base.src, .{
+        .ty = fn_type,
+        .val = Value.initPayload(&fn_payload.base),
+    });
 }
 
 fn analyzeInstFnType(self: *Module, scope: *Scope, fntype: *zir.Inst.FnType) InnerError!*Inst {
@@ -3277,6 +3296,7 @@ fn failWithOwnedErrorMsg(self: *Module, scope: *Scope, src: usize, err_msg: *Err
         .decl => {
             const decl = scope.cast(Scope.DeclAnalysis).?.decl;
             decl.analysis = .sema_failure;
+            decl.generation = self.generation;
             self.failed_decls.putAssumeCapacityNoClobber(decl, err_msg);
         },
         .block => {
@@ -3285,12 +3305,14 @@ fn failWithOwnedErrorMsg(self: *Module, scope: *Scope, src: usize, err_msg: *Err
                 func.analysis = .sema_failure;
             } else {
                 block.decl.analysis = .sema_failure;
+                block.decl.generation = self.generation;
             }
             self.failed_decls.putAssumeCapacityNoClobber(block.decl, err_msg);
         },
         .gen_zir => {
             const gen_zir = scope.cast(Scope.GenZIR).?;
             gen_zir.decl.analysis = .sema_failure;
+            gen_zir.decl.generation = self.generation;
             self.failed_decls.putAssumeCapacityNoClobber(gen_zir.decl, err_msg);
         },
         .zir_module => {
src-self-hosted/zir.zig
@@ -30,7 +30,7 @@ pub const Inst = struct {
     /// Byte offset into the source.
     src: usize,
     /// Pre-allocated field for mapping ZIR text instructions to post-analysis instructions.
-    analyzed_inst: *ir.Inst = undefined,
+    analyzed_inst: ?*ir.Inst = null,
 
     /// These names are used directly as the instruction names in the text format.
     pub const Tag = enum {
@@ -545,6 +545,18 @@ pub const Module = struct {
         return null;
     }
 
+    pub fn findInstDecl(self: Module, inst: *Inst) ?DeclAndIndex {
+        for (self.decls) |decl, i| {
+            if (decl.inst == inst) {
+                return DeclAndIndex{
+                    .decl = decl,
+                    .index = i,
+                };
+            }
+        }
+        return null;
+    }
+
     /// The allocator is used for temporary storage, but this function always returns
     /// with no resources allocated.
     pub fn writeToStream(self: Module, allocator: *Allocator, stream: var) !void {
test/stage2/zir.zig
@@ -228,17 +228,6 @@ pub fn addCases(ctx: *TestContext) void {
             \\@2 = int(2)
             \\@3 = int(3)
             \\
-            \\@syscall_array = str("syscall")
-            \\@sysoutreg_array = str("={rax}")
-            \\@rax_array = str("{rax}")
-            \\@rdi_array = str("{rdi}")
-            \\@rcx_array = str("rcx")
-            \\@r11_array = str("r11")
-            \\@rdx_array = str("{rdx}")
-            \\@rsi_array = str("{rsi}")
-            \\@memory_array = str("memory")
-            \\@len_array = str("len")
-            \\
             \\@msg = str("Hello, world!\n")
             \\
             \\@start_fnty = fntype([], @noreturn, cc=Naked)
@@ -246,24 +235,23 @@ pub fn addCases(ctx: *TestContext) void {
             \\  %SYS_exit_group = int(231)
             \\  %exit_code = as(@usize, @0)
             \\
-            \\  %syscall = ref(@syscall_array)
-            \\  %sysoutreg = ref(@sysoutreg_array)
-            \\  %rax = ref(@rax_array)
-            \\  %rdi = ref(@rdi_array)
-            \\  %rcx = ref(@rcx_array)
-            \\  %rdx = ref(@rdx_array)
-            \\  %rsi = ref(@rsi_array)
-            \\  %r11 = ref(@r11_array)
-            \\  %memory = ref(@memory_array)
+            \\  %syscall = str("syscall")
+            \\  %sysoutreg = str("={rax}")
+            \\  %rax = str("{rax}")
+            \\  %rdi = str("{rdi}")
+            \\  %rcx = str("rcx")
+            \\  %rdx = str("{rdx}")
+            \\  %rsi = str("{rsi}")
+            \\  %r11 = str("r11")
+            \\  %memory = str("memory")
             \\
             \\  %SYS_write = as(@usize, @1)
             \\  %STDOUT_FILENO = as(@usize, @1)
             \\
-            \\  %msg_ptr = ref(@msg)
-            \\  %msg_addr = ptrtoint(%msg_ptr)
+            \\  %msg_addr = ptrtoint(@msg)
             \\
-            \\  %len_name = ref(@len_array)
-            \\  %msg_len_ptr = fieldptr(%msg_ptr, %len_name)
+            \\  %len_name = str("len")
+            \\  %msg_len_ptr = fieldptr(@msg, %len_name)
             \\  %msg_len = deref(%msg_len_ptr)
             \\  %rc_write = asm(%syscall, @usize,
             \\    volatile=1,
@@ -283,8 +271,7 @@ pub fn addCases(ctx: *TestContext) void {
             \\});
             \\
             \\@9 = str("_start")
-            \\@10 = ref(@9)
-            \\@11 = export(@10, @start)
+            \\@11 = export(@9, "start")
         ,
             \\@noreturn = primitive(noreturn)
             \\@void = primitive(void)
@@ -294,17 +281,6 @@ pub fn addCases(ctx: *TestContext) void {
             \\@2 = int(2)
             \\@3 = int(3)
             \\
-            \\@syscall_array = str("syscall")
-            \\@sysoutreg_array = str("={rax}")
-            \\@rax_array = str("{rax}")
-            \\@rdi_array = str("{rdi}")
-            \\@rcx_array = str("rcx")
-            \\@r11_array = str("r11")
-            \\@rdx_array = str("{rdx}")
-            \\@rsi_array = str("{rsi}")
-            \\@memory_array = str("memory")
-            \\@len_array = str("len")
-            \\
             \\@msg = str("Hello, world!\n")
             \\@msg2 = str("HELL WORLD\n")
             \\
@@ -313,24 +289,23 @@ pub fn addCases(ctx: *TestContext) void {
             \\  %SYS_exit_group = int(231)
             \\  %exit_code = as(@usize, @0)
             \\
-            \\  %syscall = ref(@syscall_array)
-            \\  %sysoutreg = ref(@sysoutreg_array)
-            \\  %rax = ref(@rax_array)
-            \\  %rdi = ref(@rdi_array)
-            \\  %rcx = ref(@rcx_array)
-            \\  %rdx = ref(@rdx_array)
-            \\  %rsi = ref(@rsi_array)
-            \\  %r11 = ref(@r11_array)
-            \\  %memory = ref(@memory_array)
+            \\  %syscall = str("syscall")
+            \\  %sysoutreg = str("={rax}")
+            \\  %rax = str("{rax}")
+            \\  %rdi = str("{rdi}")
+            \\  %rcx = str("rcx")
+            \\  %rdx = str("{rdx}")
+            \\  %rsi = str("{rsi}")
+            \\  %r11 = str("r11")
+            \\  %memory = str("memory")
             \\
             \\  %SYS_write = as(@usize, @1)
             \\  %STDOUT_FILENO = as(@usize, @1)
             \\
-            \\  %msg_ptr = ref(@msg2)
-            \\  %msg_addr = ptrtoint(%msg_ptr)
+            \\  %msg_addr = ptrtoint(@msg2)
             \\
-            \\  %len_name = ref(@len_array)
-            \\  %msg_len_ptr = fieldptr(%msg_ptr, %len_name)
+            \\  %len_name = str("len")
+            \\  %msg_len_ptr = fieldptr(@msg2, %len_name)
             \\  %msg_len = deref(%msg_len_ptr)
             \\  %rc_write = asm(%syscall, @usize,
             \\    volatile=1,
@@ -350,8 +325,7 @@ pub fn addCases(ctx: *TestContext) void {
             \\});
             \\
             \\@9 = str("_start")
-            \\@10 = ref(@9)
-            \\@11 = export(@10, @start)
+            \\@11 = export(@9, "start")
         ,
             \\@noreturn = primitive(noreturn)
             \\@void = primitive(void)
@@ -361,17 +335,6 @@ pub fn addCases(ctx: *TestContext) void {
             \\@2 = int(2)
             \\@3 = int(3)
             \\
-            \\@syscall_array = str("syscall")
-            \\@sysoutreg_array = str("={rax}")
-            \\@rax_array = str("{rax}")
-            \\@rdi_array = str("{rdi}")
-            \\@rcx_array = str("rcx")
-            \\@r11_array = str("r11")
-            \\@rdx_array = str("{rdx}")
-            \\@rsi_array = str("{rsi}")
-            \\@memory_array = str("memory")
-            \\@len_array = str("len")
-            \\
             \\@msg = str("Hello, world!\n")
             \\@msg2 = str("Editing the same msg2 decl but this time with a much longer message which will\ncause the data to need to be relocated in virtual address space.\n")
             \\
@@ -380,24 +343,23 @@ pub fn addCases(ctx: *TestContext) void {
             \\  %SYS_exit_group = int(231)
             \\  %exit_code = as(@usize, @0)
             \\
-            \\  %syscall = ref(@syscall_array)
-            \\  %sysoutreg = ref(@sysoutreg_array)
-            \\  %rax = ref(@rax_array)
-            \\  %rdi = ref(@rdi_array)
-            \\  %rcx = ref(@rcx_array)
-            \\  %rdx = ref(@rdx_array)
-            \\  %rsi = ref(@rsi_array)
-            \\  %r11 = ref(@r11_array)
-            \\  %memory = ref(@memory_array)
+            \\  %syscall = str("syscall")
+            \\  %sysoutreg = str("={rax}")
+            \\  %rax = str("{rax}")
+            \\  %rdi = str("{rdi}")
+            \\  %rcx = str("rcx")
+            \\  %rdx = str("{rdx}")
+            \\  %rsi = str("{rsi}")
+            \\  %r11 = str("r11")
+            \\  %memory = str("memory")
             \\
             \\  %SYS_write = as(@usize, @1)
             \\  %STDOUT_FILENO = as(@usize, @1)
             \\
-            \\  %msg_ptr = ref(@msg2)
-            \\  %msg_addr = ptrtoint(%msg_ptr)
+            \\  %msg_addr = ptrtoint(@msg2)
             \\
-            \\  %len_name = ref(@len_array)
-            \\  %msg_len_ptr = fieldptr(%msg_ptr, %len_name)
+            \\  %len_name = str("len")
+            \\  %msg_len_ptr = fieldptr(@msg2, %len_name)
             \\  %msg_len = deref(%msg_len_ptr)
             \\  %rc_write = asm(%syscall, @usize,
             \\    volatile=1,
@@ -417,8 +379,7 @@ pub fn addCases(ctx: *TestContext) void {
             \\});
             \\
             \\@9 = str("_start")
-            \\@10 = ref(@9)
-            \\@11 = export(@10, @start)
+            \\@11 = export(@9, "start")
         },
         &[_][]const u8{
             \\Hello, world!