diff options
Diffstat (limited to 'src/link/C.zig')
| -rw-r--r-- | src/link/C.zig | 146 |
1 files changed, 53 insertions, 93 deletions
diff --git a/src/link/C.zig b/src/link/C.zig index c32d8ba80b..f3465055b8 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -17,7 +17,7 @@ const link = @import("../link.zig"); const trace = @import("../tracy.zig").trace; const Type = @import("../Type.zig"); const Value = @import("../Value.zig"); -const Air = @import("../Air.zig"); +const AnyMir = @import("../codegen.zig").AnyMir; pub const zig_h = "#include \"zig.h\"\n"; @@ -145,7 +145,6 @@ pub fn createEmpty( .stack_size = options.stack_size orelse 16777216, .allow_shlib_undefined = options.allow_shlib_undefined orelse false, .file = file, - .disable_lld_caching = options.disable_lld_caching, .build_id = options.build_id, }, }; @@ -167,6 +166,9 @@ pub fn deinit(self: *C) void { self.uavs.deinit(gpa); self.aligned_uavs.deinit(gpa); + self.exported_navs.deinit(gpa); + self.exported_uavs.deinit(gpa); + self.string_bytes.deinit(gpa); self.fwd_decl_buf.deinit(gpa); self.code_buf.deinit(gpa); @@ -178,73 +180,23 @@ pub fn updateFunc( self: *C, pt: Zcu.PerThread, func_index: InternPool.Index, - air: Air, - liveness: Air.Liveness, + mir: *AnyMir, ) link.File.UpdateNavError!void { const zcu = pt.zcu; const gpa = zcu.gpa; const func = zcu.funcInfo(func_index); - const gop = try self.navs.getOrPut(gpa, func.owner_nav); - if (!gop.found_existing) gop.value_ptr.* = .{}; - const ctype_pool = &gop.value_ptr.ctype_pool; - const lazy_fns = &gop.value_ptr.lazy_fns; - const fwd_decl = &self.fwd_decl_buf; - const code = &self.code_buf; - try ctype_pool.init(gpa); - ctype_pool.clearRetainingCapacity(); - lazy_fns.clearRetainingCapacity(); - fwd_decl.clearRetainingCapacity(); - code.clearRetainingCapacity(); - - var function: codegen.Function = .{ - .value_map = codegen.CValueMap.init(gpa), - .air = air, - .liveness = liveness, - .func_index = func_index, - .object = .{ - .dg = .{ - .gpa = gpa, - .pt = pt, - .mod = zcu.navFileScope(func.owner_nav).mod.?, - .error_msg = null, - .pass = .{ .nav = func.owner_nav }, - .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked, - .expected_block = null, - .fwd_decl = fwd_decl.toManaged(gpa), - .ctype_pool = ctype_pool.*, - .scratch = .{}, - .uav_deps = self.uavs, - .aligned_uavs = self.aligned_uavs, - }, - .code = code.toManaged(gpa), - .indent_writer = undefined, // set later so we can get a pointer to object.code - }, - .lazy_fns = lazy_fns.*, - }; - function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() }; - defer { - self.uavs = function.object.dg.uav_deps; - self.aligned_uavs = function.object.dg.aligned_uavs; - fwd_decl.* = function.object.dg.fwd_decl.moveToUnmanaged(); - ctype_pool.* = function.object.dg.ctype_pool.move(); - ctype_pool.freeUnusedCapacity(gpa); - function.object.dg.scratch.deinit(gpa); - lazy_fns.* = function.lazy_fns.move(); - lazy_fns.shrinkAndFree(gpa, lazy_fns.count()); - code.* = function.object.code.moveToUnmanaged(); - function.deinit(); - } - try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1); - codegen.genFunc(&function) catch |err| switch (err) { - error.AnalysisFail => { - zcu.failed_codegen.putAssumeCapacityNoClobber(func.owner_nav, function.object.dg.error_msg.?); - return; - }, - else => |e| return e, + const gop = try self.navs.getOrPut(gpa, func.owner_nav); + if (gop.found_existing) gop.value_ptr.deinit(gpa); + gop.value_ptr.* = .{ + .code = .empty, + .fwd_decl = .empty, + .ctype_pool = mir.c.ctype_pool.move(), + .lazy_fns = mir.c.lazy_fns.move(), }; - gop.value_ptr.fwd_decl = try self.addString(function.object.dg.fwd_decl.items); - gop.value_ptr.code = try self.addString(function.object.code.items); + gop.value_ptr.code = try self.addString(mir.c.code); + gop.value_ptr.fwd_decl = try self.addString(mir.c.fwd_decl); + try self.addUavsFromCodegen(&mir.c.uavs); } fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void { @@ -268,16 +220,14 @@ fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void { .fwd_decl = fwd_decl.toManaged(gpa), .ctype_pool = codegen.CType.Pool.empty, .scratch = .{}, - .uav_deps = self.uavs, - .aligned_uavs = self.aligned_uavs, + .uavs = .empty, }, .code = code.toManaged(gpa), .indent_writer = undefined, // set later so we can get a pointer to object.code }; object.indent_writer = .{ .underlying_writer = object.code.writer() }; defer { - self.uavs = object.dg.uav_deps; - self.aligned_uavs = object.dg.aligned_uavs; + object.dg.uavs.deinit(gpa); fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged(); object.dg.ctype_pool.deinit(object.dg.gpa); object.dg.scratch.deinit(gpa); @@ -296,8 +246,10 @@ fn updateUav(self: *C, pt: Zcu.PerThread, i: usize) !void { else => |e| return e, }; + try self.addUavsFromCodegen(&object.dg.uavs); + object.dg.ctype_pool.freeUnusedCapacity(gpa); - object.dg.uav_deps.values()[i] = .{ + self.uavs.values()[i] = .{ .code = try self.addString(object.code.items), .fwd_decl = try self.addString(object.dg.fwd_decl.items), .ctype_pool = object.dg.ctype_pool.move(), @@ -344,16 +296,14 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l .fwd_decl = fwd_decl.toManaged(gpa), .ctype_pool = ctype_pool.*, .scratch = .{}, - .uav_deps = self.uavs, - .aligned_uavs = self.aligned_uavs, + .uavs = .empty, }, .code = code.toManaged(gpa), .indent_writer = undefined, // set later so we can get a pointer to object.code }; object.indent_writer = .{ .underlying_writer = object.code.writer() }; defer { - self.uavs = object.dg.uav_deps; - self.aligned_uavs = object.dg.aligned_uavs; + object.dg.uavs.deinit(gpa); fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged(); ctype_pool.* = object.dg.ctype_pool.move(); ctype_pool.freeUnusedCapacity(gpa); @@ -361,16 +311,16 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) l code.* = object.code.moveToUnmanaged(); } - try zcu.failed_codegen.ensureUnusedCapacity(gpa, 1); codegen.genDecl(&object) catch |err| switch (err) { - error.AnalysisFail => { - zcu.failed_codegen.putAssumeCapacityNoClobber(nav_index, object.dg.error_msg.?); - return; + error.AnalysisFail => switch (zcu.codegenFailMsg(nav_index, object.dg.error_msg.?)) { + error.CodegenFail => return, + error.OutOfMemory => |e| return e, }, else => |e| return e, }; gop.value_ptr.code = try self.addString(object.code.items); gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items); + try self.addUavsFromCodegen(&object.dg.uavs); } pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void { @@ -381,10 +331,6 @@ pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedIn _ = ti_id; } -pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { - return self.flushModule(arena, tid, prog_node); -} - fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { const gpa = self.base.comp.gpa; var defines = std.ArrayList(u8).init(gpa); @@ -400,7 +346,7 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) { return defines; } -pub fn flushModule(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { +pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { _ = arena; // Has the same lifetime as the call to Compilation.update. const tracy = trace(@src()); @@ -676,16 +622,14 @@ fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) F .fwd_decl = fwd_decl.toManaged(gpa), .ctype_pool = ctype_pool.*, .scratch = .{}, - .uav_deps = self.uavs, - .aligned_uavs = self.aligned_uavs, + .uavs = .empty, }, .code = code.toManaged(gpa), .indent_writer = undefined, // set later so we can get a pointer to object.code }; object.indent_writer = .{ .underlying_writer = object.code.writer() }; defer { - self.uavs = object.dg.uav_deps; - self.aligned_uavs = object.dg.aligned_uavs; + object.dg.uavs.deinit(gpa); fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged(); ctype_pool.* = object.dg.ctype_pool.move(); ctype_pool.freeUnusedCapacity(gpa); @@ -697,6 +641,8 @@ fn flushErrDecls(self: *C, pt: Zcu.PerThread, ctype_pool: *codegen.CType.Pool) F error.AnalysisFail => unreachable, else => |e| return e, }; + + try self.addUavsFromCodegen(&object.dg.uavs); } fn flushLazyFn( @@ -724,8 +670,7 @@ fn flushLazyFn( .fwd_decl = fwd_decl.toManaged(gpa), .ctype_pool = ctype_pool.*, .scratch = .{}, - .uav_deps = .{}, - .aligned_uavs = .{}, + .uavs = .empty, }, .code = code.toManaged(gpa), .indent_writer = undefined, // set later so we can get a pointer to object.code @@ -734,8 +679,7 @@ fn flushLazyFn( defer { // If this assert trips just handle the anon_decl_deps the same as // `updateFunc()` does. - assert(object.dg.uav_deps.count() == 0); - assert(object.dg.aligned_uavs.count() == 0); + assert(object.dg.uavs.count() == 0); fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged(); ctype_pool.* = object.dg.ctype_pool.move(); ctype_pool.freeUnusedCapacity(gpa); @@ -871,12 +815,10 @@ pub fn updateExports( .fwd_decl = fwd_decl.toManaged(gpa), .ctype_pool = decl_block.ctype_pool, .scratch = .{}, - .uav_deps = .{}, - .aligned_uavs = .{}, + .uavs = .empty, }; defer { - assert(dg.uav_deps.count() == 0); - assert(dg.aligned_uavs.count() == 0); + assert(dg.uavs.count() == 0); fwd_decl.* = dg.fwd_decl.moveToUnmanaged(); ctype_pool.* = dg.ctype_pool.move(); ctype_pool.freeUnusedCapacity(gpa); @@ -896,3 +838,21 @@ pub fn deleteExport( .uav => |uav| _ = self.exported_uavs.swapRemove(uav), } } + +fn addUavsFromCodegen(c: *C, uavs: *const std.AutoArrayHashMapUnmanaged(InternPool.Index, Alignment)) Allocator.Error!void { + const gpa = c.base.comp.gpa; + try c.uavs.ensureUnusedCapacity(gpa, uavs.count()); + try c.aligned_uavs.ensureUnusedCapacity(gpa, uavs.count()); + for (uavs.keys(), uavs.values()) |uav_val, uav_align| { + { + const gop = c.uavs.getOrPutAssumeCapacity(uav_val); + if (!gop.found_existing) gop.value_ptr.* = .{}; + } + if (uav_align != .none) { + const gop = c.aligned_uavs.getOrPutAssumeCapacity(uav_val); + gop.value_ptr.* = if (gop.found_existing) max: { + break :max gop.value_ptr.*.maxStrict(uav_align); + } else uav_align; + } + } +} |
