authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-15 19:12:06-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 17:51:19-07:00
logb54ad9317591873159594e673953088a21d66e7b
tree3f460d89248d9764a2543a4ec0ae57edc99ff384
parent92b54e50c85488459df0c6579086494e31d9d52a

update codegen.llvm references to bin_file.options


8 files changed, 354 insertions(+), 304 deletions(-)

src/codegen/llvm.zig+246-248
...@@ -822,7 +822,7 @@ pub const Object = struct {...@@ -822,7 +822,7 @@ pub const Object = struct {
822 type_map: TypeMap,822 type_map: TypeMap,
823 di_type_map: DITypeMap,823 di_type_map: DITypeMap,
824 /// The LLVM global table which holds the names corresponding to Zig errors.824 /// The LLVM global table which holds the names corresponding to Zig errors.
825 /// Note that the values are not added until flushModule, when all errors in825 /// Note that the values are not added until `emit`, when all errors in
826 /// the compilation are known.826 /// the compilation are known.
827 error_name_table: Builder.Variable.Index,827 error_name_table: Builder.Variable.Index,
828 /// This map is usually very close to empty. It tracks only the cases when a828 /// This map is usually very close to empty. It tracks only the cases when a
...@@ -850,7 +850,7 @@ pub const Object = struct {...@@ -850,7 +850,7 @@ pub const Object = struct {
850850
851 pub const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, Builder.Type);851 pub const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, Builder.Type);
852852
853 /// This is an ArrayHashMap as opposed to a HashMap because in `flushModule` we853 /// This is an ArrayHashMap as opposed to a HashMap because in `emit` we
854 /// want to iterate over it while adding entries to it.854 /// want to iterate over it while adding entries to it.
855 pub const DITypeMap = std.AutoArrayHashMapUnmanaged(InternPool.Index, AnnotatedDITypePtr);855 pub const DITypeMap = std.AutoArrayHashMapUnmanaged(InternPool.Index, AnnotatedDITypePtr);
856856
...@@ -1026,17 +1026,6 @@ pub const Object = struct {...@@ -1026,17 +1026,6 @@ pub const Object = struct {
1026 self.* = undefined;1026 self.* = undefined;
1027 }1027 }
10281028
1029 fn locPath(
1030 arena: Allocator,
1031 opt_loc: ?Compilation.EmitLoc,
1032 cache_directory: Compilation.Directory,
1033 ) !?[*:0]u8 {
1034 const loc = opt_loc orelse return null;
1035 const directory = loc.directory orelse cache_directory;
1036 const slice = try directory.joinZ(arena, &[_][]const u8{loc.basename});
1037 return slice.ptr;
1038 }
1039
1040 fn genErrorNameTable(o: *Object) Allocator.Error!void {1029 fn genErrorNameTable(o: *Object) Allocator.Error!void {
1041 // If o.error_name_table is null, then it was not referenced by any instructions.1030 // If o.error_name_table is null, then it was not referenced by any instructions.
1042 if (o.error_name_table == .none) return;1031 if (o.error_name_table == .none) return;
...@@ -1175,12 +1164,22 @@ pub const Object = struct {...@@ -1175,12 +1164,22 @@ pub const Object = struct {
1175 }1164 }
1176 }1165 }
11771166
1178 pub fn flushModule(self: *Object, comp: *Compilation, prog_node: *std.Progress.Node) !void {1167 pub const EmitOptions = struct {
1179 var sub_prog_node = prog_node.start("LLVM Emit Object", 0);1168 pre_ir_path: ?[]const u8,
1180 sub_prog_node.activate();1169 pre_bc_path: ?[]const u8,
1181 sub_prog_node.context.refresh();1170 bin_path: ?[*:0]const u8,
1182 defer sub_prog_node.end();1171 emit_asm: ?[*:0]const u8,
1172 post_ir_path: ?[*:0]const u8,
1173 post_bc_path: ?[*:0]const u8,
1174
1175 is_debug: bool,
1176 is_small: bool,
1177 time_report: bool,
1178 sanitize_thread: bool,
1179 lto: bool,
1180 };
11831181
1182 pub fn emit(self: *Object, options: EmitOptions) !void {
1184 try self.resolveExportExternCollisions();1183 try self.resolveExportExternCollisions();
1185 try self.genErrorNameTable();1184 try self.genErrorNameTable();
1186 try self.genCmpLtErrorsLenFunction();1185 try self.genCmpLtErrorsLenFunction();
...@@ -1206,7 +1205,7 @@ pub const Object = struct {...@@ -1206,7 +1205,7 @@ pub const Object = struct {
1206 dib.finalize();1205 dib.finalize();
1207 }1206 }
12081207
1209 if (comp.verbose_llvm_ir) |path| {1208 if (options.pre_ir_path) |path| {
1210 if (std.mem.eql(u8, path, "-")) {1209 if (std.mem.eql(u8, path, "-")) {
1211 self.builder.dump();1210 self.builder.dump();
1212 } else {1211 } else {
...@@ -1214,91 +1213,72 @@ pub const Object = struct {...@@ -1214,91 +1213,72 @@ pub const Object = struct {
1214 }1213 }
1215 }1214 }
12161215
1217 if (comp.verbose_llvm_bc) |path| _ = try self.builder.writeBitcodeToFile(path);1216 if (options.pre_bc_path) |path| _ = try self.builder.writeBitcodeToFile(path);
1218
1219 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
1220 defer arena_allocator.deinit();
1221 const arena = arena_allocator.allocator();
1222
1223 const mod = comp.module.?;
1224 const cache_dir = mod.zig_cache_artifact_directory;
12251217
1226 if (std.debug.runtime_safety and !try self.builder.verify()) {1218 if (std.debug.runtime_safety and !try self.builder.verify()) {
1227 if (try locPath(arena, comp.emit_llvm_ir, cache_dir)) |emit_llvm_ir_path|
1228 _ = self.builder.printToFileZ(emit_llvm_ir_path);
1229 @panic("LLVM module verification failed");1219 @panic("LLVM module verification failed");
1230 }1220 }
12311221
1232 var emit_bin_path: ?[*:0]const u8 = if (comp.bin_file.options.emit) |emit|1222 const emit_asm_msg = options.asm_path orelse "(none)";
1233 try emit.basenamePath(arena, try arena.dupeZ(u8, comp.bin_file.intermediary_basename.?))1223 const emit_bin_msg = options.bin_path orelse "(none)";
1234 else1224 const post_llvm_ir_msg = options.post_ir_path orelse "(none)";
1235 null;1225 const post_llvm_bc_msg = options.post_bc_path orelse "(none)";
1236
1237 const emit_asm_path = try locPath(arena, comp.emit_asm, cache_dir);
1238 var emit_llvm_ir_path = try locPath(arena, comp.emit_llvm_ir, cache_dir);
1239 const emit_llvm_bc_path = try locPath(arena, comp.emit_llvm_bc, cache_dir);
1240
1241 const emit_asm_msg = emit_asm_path orelse "(none)";
1242 const emit_bin_msg = emit_bin_path orelse "(none)";
1243 const emit_llvm_ir_msg = emit_llvm_ir_path orelse "(none)";
1244 const emit_llvm_bc_msg = emit_llvm_bc_path orelse "(none)";
1245 log.debug("emit LLVM object asm={s} bin={s} ir={s} bc={s}", .{1226 log.debug("emit LLVM object asm={s} bin={s} ir={s} bc={s}", .{
1246 emit_asm_msg, emit_bin_msg, emit_llvm_ir_msg, emit_llvm_bc_msg,1227 emit_asm_msg, emit_bin_msg, post_llvm_ir_msg, post_llvm_bc_msg,
1247 });1228 });
12481229
1249 if (emit_asm_path == null and emit_bin_path == null and1230 if (options.asm_path == null and options.bin_path == null and
1250 emit_llvm_ir_path == null and emit_llvm_bc_path == null) return;1231 options.post_ir_path == null and options.post_bc_path == null) return;
12511232
1252 if (!self.builder.useLibLlvm()) {1233 if (!self.builder.useLibLlvm()) unreachable; // caught in Compilation.Config.resolve
1253 log.err("emitting without libllvm not implemented", .{});
1254 return error.FailedToEmit;
1255 }
12561234
1257 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly.1235 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly.
1258 // So we call the entire pipeline multiple times if this is requested.1236 // So we call the entire pipeline multiple times if this is requested.
1259 var error_message: [*:0]const u8 = undefined;1237 var error_message: [*:0]const u8 = undefined;
1260 if (emit_asm_path != null and emit_bin_path != null) {1238 var emit_bin_path = options.bin_path;
1239 var post_ir_path = options.post_ir_path;
1240 if (options.asm_path != null and options.bin_path != null) {
1261 if (self.target_machine.emitToFile(1241 if (self.target_machine.emitToFile(
1262 self.builder.llvm.module.?,1242 self.builder.llvm.module.?,
1263 &error_message,1243 &error_message,
1264 comp.bin_file.options.optimize_mode == .Debug,1244 options.is_debug,
1265 comp.bin_file.options.optimize_mode == .ReleaseSmall,1245 options.is_small,
1266 comp.time_report,1246 options.time_report,
1267 comp.bin_file.options.tsan,1247 options.sanitize_thread,
1268 comp.bin_file.options.lto,1248 options.lto,
1269 null,1249 null,
1270 emit_bin_path,1250 emit_bin_path,
1271 emit_llvm_ir_path,1251 post_ir_path,
1272 null,1252 null,
1273 )) {1253 )) {
1274 defer llvm.disposeMessage(error_message);1254 defer llvm.disposeMessage(error_message);
12751255
1276 log.err("LLVM failed to emit bin={s} ir={s}: {s}", .{1256 log.err("LLVM failed to emit bin={s} ir={s}: {s}", .{
1277 emit_bin_msg, emit_llvm_ir_msg, error_message,1257 emit_bin_msg, post_llvm_ir_msg, error_message,
1278 });1258 });
1279 return error.FailedToEmit;1259 return error.FailedToEmit;
1280 }1260 }
1281 emit_bin_path = null;1261 emit_bin_path = null;
1282 emit_llvm_ir_path = null;1262 post_ir_path = null;
1283 }1263 }
12841264
1285 if (self.target_machine.emitToFile(1265 if (self.target_machine.emitToFile(
1286 self.builder.llvm.module.?,1266 self.builder.llvm.module.?,
1287 &error_message,1267 &error_message,
1288 comp.bin_file.options.optimize_mode == .Debug,1268 options.is_debug,
1289 comp.bin_file.options.optimize_mode == .ReleaseSmall,1269 options.is_small,
1290 comp.time_report,1270 options.time_report,
1291 comp.bin_file.options.tsan,1271 options.sanitize_thread,
1292 comp.bin_file.options.lto,1272 options.lto,
1293 emit_asm_path,1273 options.asm_path,
1294 emit_bin_path,1274 emit_bin_path,
1295 emit_llvm_ir_path,1275 post_ir_path,
1296 emit_llvm_bc_path,1276 options.post_bc_path,
1297 )) {1277 )) {
1298 defer llvm.disposeMessage(error_message);1278 defer llvm.disposeMessage(error_message);
12991279
1300 log.err("LLVM failed to emit asm={s} bin={s} ir={s} bc={s}: {s}", .{1280 log.err("LLVM failed to emit asm={s} bin={s} ir={s} bc={s}: {s}", .{
1301 emit_asm_msg, emit_bin_msg, emit_llvm_ir_msg, emit_llvm_bc_msg,1281 emit_asm_msg, emit_bin_msg, post_llvm_ir_msg, post_llvm_bc_msg,
1302 error_message,1282 error_message,
1303 });1283 });
1304 return error.FailedToEmit;1284 return error.FailedToEmit;
...@@ -1307,17 +1287,19 @@ pub const Object = struct {...@@ -1307,17 +1287,19 @@ pub const Object = struct {
13071287
1308 pub fn updateFunc(1288 pub fn updateFunc(
1309 o: *Object,1289 o: *Object,
1310 mod: *Module,1290 zcu: *Module,
1311 func_index: InternPool.Index,1291 func_index: InternPool.Index,
1312 air: Air,1292 air: Air,
1313 liveness: Liveness,1293 liveness: Liveness,
1314 ) !void {1294 ) !void {
1315 const func = mod.funcInfo(func_index);1295 const func = zcu.funcInfo(func_index);
1316 const decl_index = func.owner_decl;1296 const decl_index = func.owner_decl;
1317 const decl = mod.declPtr(decl_index);1297 const decl = zcu.declPtr(decl_index);
1318 const fn_info = mod.typeToFunc(decl.ty).?;1298 const namespace = zcu.namespacePtr(decl.src_namespace);
1319 const target = mod.getTarget();1299 const owner_mod = namespace.file_scope.mod;
1320 const ip = &mod.intern_pool;1300 const fn_info = zcu.typeToFunc(decl.ty).?;
1301 const target = zcu.getTarget();
1302 const ip = &zcu.intern_pool;
13211303
1322 var dg: DeclGen = .{1304 var dg: DeclGen = .{
1323 .object = o,1305 .object = o,
...@@ -1352,7 +1334,7 @@ pub const Object = struct {...@@ -1352,7 +1334,7 @@ pub const Object = struct {
1352 }1334 }
13531335
1354 // TODO: disable this if safety is off for the function scope1336 // TODO: disable this if safety is off for the function scope
1355 const ssp_buf_size = mod.comp.bin_file.options.stack_protector;1337 const ssp_buf_size = owner_mod.stack_protector;
1356 if (ssp_buf_size != 0) {1338 if (ssp_buf_size != 0) {
1357 try attributes.addFnAttr(.sspstrong, &o.builder);1339 try attributes.addFnAttr(.sspstrong, &o.builder);
1358 try attributes.addFnAttr(.{ .string = .{1340 try attributes.addFnAttr(.{ .string = .{
...@@ -1362,7 +1344,7 @@ pub const Object = struct {...@@ -1362,7 +1344,7 @@ pub const Object = struct {
1362 }1344 }
13631345
1364 // TODO: disable this if safety is off for the function scope1346 // TODO: disable this if safety is off for the function scope
1365 if (mod.comp.bin_file.options.stack_check) {1347 if (owner_mod.stack_check) {
1366 try attributes.addFnAttr(.{ .string = .{1348 try attributes.addFnAttr(.{ .string = .{
1367 .kind = try o.builder.string("probe-stack"),1349 .kind = try o.builder.string("probe-stack"),
1368 .value = try o.builder.string("__zig_probe_stack"),1350 .value = try o.builder.string("__zig_probe_stack"),
...@@ -1385,20 +1367,22 @@ pub const Object = struct {...@@ -1385,20 +1367,22 @@ pub const Object = struct {
1385 var llvm_arg_i: u32 = 0;1367 var llvm_arg_i: u32 = 0;
13861368
1387 // This gets the LLVM values from the function and stores them in `dg.args`.1369 // This gets the LLVM values from the function and stores them in `dg.args`.
1388 const sret = firstParamSRet(fn_info, mod);1370 const sret = firstParamSRet(fn_info, zcu);
1389 const ret_ptr: Builder.Value = if (sret) param: {1371 const ret_ptr: Builder.Value = if (sret) param: {
1390 const param = wip.arg(llvm_arg_i);1372 const param = wip.arg(llvm_arg_i);
1391 llvm_arg_i += 1;1373 llvm_arg_i += 1;
1392 break :param param;1374 break :param param;
1393 } else .none;1375 } else .none;
13941376
1395 if (ccAbiPromoteInt(fn_info.cc, mod, Type.fromInterned(fn_info.return_type))) |s| switch (s) {1377 if (ccAbiPromoteInt(fn_info.cc, zcu, Type.fromInterned(fn_info.return_type))) |s| switch (s) {
1396 .signed => try attributes.addRetAttr(.signext, &o.builder),1378 .signed => try attributes.addRetAttr(.signext, &o.builder),
1397 .unsigned => try attributes.addRetAttr(.zeroext, &o.builder),1379 .unsigned => try attributes.addRetAttr(.zeroext, &o.builder),
1398 };1380 };
13991381
1400 const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(mod) and1382 const comp = zcu.comp;
1401 mod.comp.config.any_error_tracing;1383
1384 const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(zcu) and
1385 comp.config.any_error_tracing;
14021386
1403 const err_ret_trace: Builder.Value = if (err_return_tracing) param: {1387 const err_ret_trace: Builder.Value = if (err_return_tracing) param: {
1404 const param = wip.arg(llvm_arg_i);1388 const param = wip.arg(llvm_arg_i);
...@@ -1426,8 +1410,8 @@ pub const Object = struct {...@@ -1426,8 +1410,8 @@ pub const Object = struct {
1426 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);1410 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
1427 const param = wip.arg(llvm_arg_i);1411 const param = wip.arg(llvm_arg_i);
14281412
1429 if (isByRef(param_ty, mod)) {1413 if (isByRef(param_ty, zcu)) {
1430 const alignment = param_ty.abiAlignment(mod).toLlvm();1414 const alignment = param_ty.abiAlignment(zcu).toLlvm();
1431 const param_llvm_ty = param.typeOfWip(&wip);1415 const param_llvm_ty = param.typeOfWip(&wip);
1432 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);1416 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
1433 _ = try wip.store(.normal, param, arg_ptr, alignment);1417 _ = try wip.store(.normal, param, arg_ptr, alignment);
...@@ -1443,12 +1427,12 @@ pub const Object = struct {...@@ -1443,12 +1427,12 @@ pub const Object = struct {
1443 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);1427 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
1444 const param_llvm_ty = try o.lowerType(param_ty);1428 const param_llvm_ty = try o.lowerType(param_ty);
1445 const param = wip.arg(llvm_arg_i);1429 const param = wip.arg(llvm_arg_i);
1446 const alignment = param_ty.abiAlignment(mod).toLlvm();1430 const alignment = param_ty.abiAlignment(zcu).toLlvm();
14471431
1448 try o.addByRefParamAttrs(&attributes, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);1432 try o.addByRefParamAttrs(&attributes, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);
1449 llvm_arg_i += 1;1433 llvm_arg_i += 1;
14501434
1451 if (isByRef(param_ty, mod)) {1435 if (isByRef(param_ty, zcu)) {
1452 args.appendAssumeCapacity(param);1436 args.appendAssumeCapacity(param);
1453 } else {1437 } else {
1454 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, ""));1438 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, ""));
...@@ -1458,12 +1442,12 @@ pub const Object = struct {...@@ -1458,12 +1442,12 @@ pub const Object = struct {
1458 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);1442 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
1459 const param_llvm_ty = try o.lowerType(param_ty);1443 const param_llvm_ty = try o.lowerType(param_ty);
1460 const param = wip.arg(llvm_arg_i);1444 const param = wip.arg(llvm_arg_i);
1461 const alignment = param_ty.abiAlignment(mod).toLlvm();1445 const alignment = param_ty.abiAlignment(zcu).toLlvm();
14621446
1463 try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder);1447 try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder);
1464 llvm_arg_i += 1;1448 llvm_arg_i += 1;
14651449
1466 if (isByRef(param_ty, mod)) {1450 if (isByRef(param_ty, zcu)) {
1467 args.appendAssumeCapacity(param);1451 args.appendAssumeCapacity(param);
1468 } else {1452 } else {
1469 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, ""));1453 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, ""));
...@@ -1476,11 +1460,11 @@ pub const Object = struct {...@@ -1476,11 +1460,11 @@ pub const Object = struct {
1476 llvm_arg_i += 1;1460 llvm_arg_i += 1;
14771461
1478 const param_llvm_ty = try o.lowerType(param_ty);1462 const param_llvm_ty = try o.lowerType(param_ty);
1479 const alignment = param_ty.abiAlignment(mod).toLlvm();1463 const alignment = param_ty.abiAlignment(zcu).toLlvm();
1480 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);1464 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
1481 _ = try wip.store(.normal, param, arg_ptr, alignment);1465 _ = try wip.store(.normal, param, arg_ptr, alignment);
14821466
1483 args.appendAssumeCapacity(if (isByRef(param_ty, mod))1467 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))
1484 arg_ptr1468 arg_ptr
1485 else1469 else
1486 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));1470 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));
...@@ -1488,14 +1472,14 @@ pub const Object = struct {...@@ -1488,14 +1472,14 @@ pub const Object = struct {
1488 .slice => {1472 .slice => {
1489 assert(!it.byval_attr);1473 assert(!it.byval_attr);
1490 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);1474 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
1491 const ptr_info = param_ty.ptrInfo(mod);1475 const ptr_info = param_ty.ptrInfo(zcu);
14921476
1493 if (math.cast(u5, it.zig_index - 1)) |i| {1477 if (math.cast(u5, it.zig_index - 1)) |i| {
1494 if (@as(u1, @truncate(fn_info.noalias_bits >> i)) != 0) {1478 if (@as(u1, @truncate(fn_info.noalias_bits >> i)) != 0) {
1495 try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder);1479 try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder);
1496 }1480 }
1497 }1481 }
1498 if (param_ty.zigTypeTag(mod) != .Optional) {1482 if (param_ty.zigTypeTag(zcu) != .Optional) {
1499 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);1483 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
1500 }1484 }
1501 if (ptr_info.flags.is_const) {1485 if (ptr_info.flags.is_const) {
...@@ -1504,7 +1488,7 @@ pub const Object = struct {...@@ -1504,7 +1488,7 @@ pub const Object = struct {
1504 const elem_align = (if (ptr_info.flags.alignment != .none)1488 const elem_align = (if (ptr_info.flags.alignment != .none)
1505 @as(InternPool.Alignment, ptr_info.flags.alignment)1489 @as(InternPool.Alignment, ptr_info.flags.alignment)
1506 else1490 else
1507 Type.fromInterned(ptr_info.child).abiAlignment(mod).max(.@"1")).toLlvm();1491 Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm();
1508 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);1492 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
1509 const ptr_param = wip.arg(llvm_arg_i);1493 const ptr_param = wip.arg(llvm_arg_i);
1510 llvm_arg_i += 1;1494 llvm_arg_i += 1;
...@@ -1521,7 +1505,7 @@ pub const Object = struct {...@@ -1521,7 +1505,7 @@ pub const Object = struct {
1521 const field_types = it.types_buffer[0..it.types_len];1505 const field_types = it.types_buffer[0..it.types_len];
1522 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);1506 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
1523 const param_llvm_ty = try o.lowerType(param_ty);1507 const param_llvm_ty = try o.lowerType(param_ty);
1524 const param_alignment = param_ty.abiAlignment(mod).toLlvm();1508 const param_alignment = param_ty.abiAlignment(zcu).toLlvm();
1525 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, param_alignment, target);1509 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, param_alignment, target);
1526 const llvm_ty = try o.builder.structType(.normal, field_types);1510 const llvm_ty = try o.builder.structType(.normal, field_types);
1527 for (0..field_types.len) |field_i| {1511 for (0..field_types.len) |field_i| {
...@@ -1533,7 +1517,7 @@ pub const Object = struct {...@@ -1533,7 +1517,7 @@ pub const Object = struct {
1533 _ = try wip.store(.normal, param, field_ptr, alignment);1517 _ = try wip.store(.normal, param, field_ptr, alignment);
1534 }1518 }
15351519
1536 const is_by_ref = isByRef(param_ty, mod);1520 const is_by_ref = isByRef(param_ty, zcu);
1537 args.appendAssumeCapacity(if (is_by_ref)1521 args.appendAssumeCapacity(if (is_by_ref)
1538 arg_ptr1522 arg_ptr
1539 else1523 else
...@@ -1551,11 +1535,11 @@ pub const Object = struct {...@@ -1551,11 +1535,11 @@ pub const Object = struct {
1551 const param = wip.arg(llvm_arg_i);1535 const param = wip.arg(llvm_arg_i);
1552 llvm_arg_i += 1;1536 llvm_arg_i += 1;
15531537
1554 const alignment = param_ty.abiAlignment(mod).toLlvm();1538 const alignment = param_ty.abiAlignment(zcu).toLlvm();
1555 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);1539 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
1556 _ = try wip.store(.normal, param, arg_ptr, alignment);1540 _ = try wip.store(.normal, param, arg_ptr, alignment);
15571541
1558 args.appendAssumeCapacity(if (isByRef(param_ty, mod))1542 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))
1559 arg_ptr1543 arg_ptr
1560 else1544 else
1561 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));1545 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));
...@@ -1566,11 +1550,11 @@ pub const Object = struct {...@@ -1566,11 +1550,11 @@ pub const Object = struct {
1566 const param = wip.arg(llvm_arg_i);1550 const param = wip.arg(llvm_arg_i);
1567 llvm_arg_i += 1;1551 llvm_arg_i += 1;
15681552
1569 const alignment = param_ty.abiAlignment(mod).toLlvm();1553 const alignment = param_ty.abiAlignment(zcu).toLlvm();
1570 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);1554 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
1571 _ = try wip.store(.normal, param, arg_ptr, alignment);1555 _ = try wip.store(.normal, param, arg_ptr, alignment);
15721556
1573 args.appendAssumeCapacity(if (isByRef(param_ty, mod))1557 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))
1574 arg_ptr1558 arg_ptr
1575 else1559 else
1576 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));1560 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));
...@@ -1584,14 +1568,12 @@ pub const Object = struct {...@@ -1584,14 +1568,12 @@ pub const Object = struct {
1584 var di_file: ?if (build_options.have_llvm) *llvm.DIFile else noreturn = null;1568 var di_file: ?if (build_options.have_llvm) *llvm.DIFile else noreturn = null;
1585 var di_scope: ?if (build_options.have_llvm) *llvm.DIScope else noreturn = null;1569 var di_scope: ?if (build_options.have_llvm) *llvm.DIScope else noreturn = null;
15861570
1587 const namespace = mod.namespacePtr(decl.src_namespace);
1588
1589 if (o.di_builder) |dib| {1571 if (o.di_builder) |dib| {
1590 di_file = try o.getDIFile(gpa, namespace.file_scope);1572 di_file = try o.getDIFile(gpa, namespace.file_scope);
15911573
1592 const line_number = decl.src_line + 1;1574 const line_number = decl.src_line + 1;
1593 const is_internal_linkage = decl.val.getExternFunc(mod) == null and1575 const is_internal_linkage = decl.val.getExternFunc(zcu) == null and
1594 !mod.decl_exports.contains(decl_index);1576 !zcu.decl_exports.contains(decl_index);
1595 const noret_bit: c_uint = if (fn_info.return_type == .noreturn_type)1577 const noret_bit: c_uint = if (fn_info.return_type == .noreturn_type)
1596 llvm.DIFlags.NoReturn1578 llvm.DIFlags.NoReturn
1597 else1579 else
...@@ -1608,7 +1590,7 @@ pub const Object = struct {...@@ -1608,7 +1590,7 @@ pub const Object = struct {
1608 true, // is definition1590 true, // is definition
1609 line_number + func.lbrace_line, // scope line1591 line_number + func.lbrace_line, // scope line
1610 llvm.DIFlags.StaticMember | noret_bit,1592 llvm.DIFlags.StaticMember | noret_bit,
1611 mod.comp.bin_file.options.optimize_mode != .Debug,1593 owner_mod.optimize_mode != .Debug,
1612 null, // decl_subprogram1594 null, // decl_subprogram
1613 );1595 );
1614 try o.di_map.put(gpa, decl, subprogram.toNode());1596 try o.di_map.put(gpa, decl, subprogram.toNode());
...@@ -1618,8 +1600,6 @@ pub const Object = struct {...@@ -1618,8 +1600,6 @@ pub const Object = struct {
1618 di_scope = subprogram.toScope();1600 di_scope = subprogram.toScope();
1619 }1601 }
16201602
1621 const single_threaded = namespace.file_scope.mod.single_threaded;
1622
1623 var fg: FuncGen = .{1603 var fg: FuncGen = .{
1624 .gpa = gpa,1604 .gpa = gpa,
1625 .air = air,1605 .air = air,
...@@ -1631,7 +1611,7 @@ pub const Object = struct {...@@ -1631,7 +1611,7 @@ pub const Object = struct {
1631 .arg_index = 0,1611 .arg_index = 0,
1632 .func_inst_table = .{},1612 .func_inst_table = .{},
1633 .blocks = .{},1613 .blocks = .{},
1634 .sync_scope = if (single_threaded) .singlethread else .system,1614 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,
1635 .di_scope = di_scope,1615 .di_scope = di_scope,
1636 .di_file = di_file,1616 .di_file = di_file,
1637 .base_line = dg.decl.src_line,1617 .base_line = dg.decl.src_line,
...@@ -1645,7 +1625,7 @@ pub const Object = struct {...@@ -1645,7 +1625,7 @@ pub const Object = struct {
1645 fg.genBody(air.getMainBody()) catch |err| switch (err) {1625 fg.genBody(air.getMainBody()) catch |err| switch (err) {
1646 error.CodegenFail => {1626 error.CodegenFail => {
1647 decl.analysis = .codegen_failure;1627 decl.analysis = .codegen_failure;
1648 try mod.failed_decls.put(mod.gpa, decl_index, dg.err_msg.?);1628 try zcu.failed_decls.put(zcu.gpa, decl_index, dg.err_msg.?);
1649 dg.err_msg = null;1629 dg.err_msg = null;
1650 return;1630 return;
1651 },1631 },
...@@ -1654,7 +1634,7 @@ pub const Object = struct {...@@ -1654,7 +1634,7 @@ pub const Object = struct {
16541634
1655 try fg.wip.finish();1635 try fg.wip.finish();
16561636
1657 try o.updateExports(mod, .{ .decl_index = decl_index }, mod.getDeclExports(decl_index));1637 try o.updateExports(zcu, .{ .decl_index = decl_index }, zcu.getDeclExports(decl_index));
1658 }1638 }
16591639
1660 pub fn updateDecl(self: *Object, module: *Module, decl_index: InternPool.DeclIndex) !void {1640 pub fn updateDecl(self: *Object, module: *Module, decl_index: InternPool.DeclIndex) !void {
...@@ -2933,22 +2913,24 @@ pub const Object = struct {...@@ -2933,22 +2913,24 @@ pub const Object = struct {
2933 o: *Object,2913 o: *Object,
2934 decl_index: InternPool.DeclIndex,2914 decl_index: InternPool.DeclIndex,
2935 ) Allocator.Error!Builder.Function.Index {2915 ) Allocator.Error!Builder.Function.Index {
2936 const mod = o.module;2916 const zcu = o.module;
2937 const ip = &mod.intern_pool;2917 const ip = &zcu.intern_pool;
2938 const gpa = o.gpa;2918 const gpa = o.gpa;
2939 const decl = mod.declPtr(decl_index);2919 const decl = zcu.declPtr(decl_index);
2920 const namespace = zcu.namespacePtr(decl.src_namespace);
2921 const owner_mod = namespace.file_scope.mod;
2940 const zig_fn_type = decl.ty;2922 const zig_fn_type = decl.ty;
2941 const gop = try o.decl_map.getOrPut(gpa, decl_index);2923 const gop = try o.decl_map.getOrPut(gpa, decl_index);
2942 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function;2924 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function;
29432925
2944 assert(decl.has_tv);2926 assert(decl.has_tv);
2945 const fn_info = mod.typeToFunc(zig_fn_type).?;2927 const fn_info = zcu.typeToFunc(zig_fn_type).?;
2946 const target = mod.getTarget();2928 const target = owner_mod.resolved_target.result;
2947 const sret = firstParamSRet(fn_info, mod);2929 const sret = firstParamSRet(fn_info, zcu);
29482930
2949 const function_index = try o.builder.addFunction(2931 const function_index = try o.builder.addFunction(
2950 try o.lowerType(zig_fn_type),2932 try o.lowerType(zig_fn_type),
2951 try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(mod))),2933 try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(zcu))),
2952 toLlvmAddressSpace(decl.@"addrspace", target),2934 toLlvmAddressSpace(decl.@"addrspace", target),
2953 );2935 );
2954 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;2936 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
...@@ -2956,7 +2938,7 @@ pub const Object = struct {...@@ -2956,7 +2938,7 @@ pub const Object = struct {
2956 var attributes: Builder.FunctionAttributes.Wip = .{};2938 var attributes: Builder.FunctionAttributes.Wip = .{};
2957 defer attributes.deinit(&o.builder);2939 defer attributes.deinit(&o.builder);
29582940
2959 const is_extern = decl.isExtern(mod);2941 const is_extern = decl.isExtern(zcu);
2960 if (!is_extern) {2942 if (!is_extern) {
2961 function_index.setLinkage(.internal, &o.builder);2943 function_index.setLinkage(.internal, &o.builder);
2962 function_index.setUnnamedAddr(.unnamed_addr, &o.builder);2944 function_index.setUnnamedAddr(.unnamed_addr, &o.builder);
...@@ -2966,7 +2948,7 @@ pub const Object = struct {...@@ -2966,7 +2948,7 @@ pub const Object = struct {
2966 .kind = try o.builder.string("wasm-import-name"),2948 .kind = try o.builder.string("wasm-import-name"),
2967 .value = try o.builder.string(ip.stringToSlice(decl.name)),2949 .value = try o.builder.string(ip.stringToSlice(decl.name)),
2968 } }, &o.builder);2950 } }, &o.builder);
2969 if (ip.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {2951 if (ip.stringToSliceUnwrap(decl.getOwnedExternFunc(zcu).?.lib_name)) |lib_name| {
2970 if (!std.mem.eql(u8, lib_name, "c")) try attributes.addFnAttr(.{ .string = .{2952 if (!std.mem.eql(u8, lib_name, "c")) try attributes.addFnAttr(.{ .string = .{
2971 .kind = try o.builder.string("wasm-import-module"),2953 .kind = try o.builder.string("wasm-import-module"),
2972 .value = try o.builder.string(lib_name),2954 .value = try o.builder.string(lib_name),
...@@ -2987,8 +2969,8 @@ pub const Object = struct {...@@ -2987,8 +2969,8 @@ pub const Object = struct {
2987 llvm_arg_i += 1;2969 llvm_arg_i += 1;
2988 }2970 }
29892971
2990 const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(mod) and2972 const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(zcu) and
2991 mod.comp.config.any_error_tracing;2973 zcu.comp.config.any_error_tracing;
29922974
2993 if (err_return_tracing) {2975 if (err_return_tracing) {
2994 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);2976 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
...@@ -3009,7 +2991,7 @@ pub const Object = struct {...@@ -3009,7 +2991,7 @@ pub const Object = struct {
3009 function_index.setAlignment(fn_info.alignment.toLlvm(), &o.builder);2991 function_index.setAlignment(fn_info.alignment.toLlvm(), &o.builder);
30102992
3011 // Function attributes that are independent of analysis results of the function body.2993 // Function attributes that are independent of analysis results of the function body.
3012 try o.addCommonFnAttributes(&attributes);2994 try o.addCommonFnAttributes(&attributes, owner_mod);
30132995
3014 if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder);2996 if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder);
30152997
...@@ -3022,14 +3004,14 @@ pub const Object = struct {...@@ -3022,14 +3004,14 @@ pub const Object = struct {
3022 .byval => {3004 .byval => {
3023 const param_index = it.zig_index - 1;3005 const param_index = it.zig_index - 1;
3024 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);3006 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
3025 if (!isByRef(param_ty, mod)) {3007 if (!isByRef(param_ty, zcu)) {
3026 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);3008 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
3027 }3009 }
3028 },3010 },
3029 .byref => {3011 .byref => {
3030 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);3012 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
3031 const param_llvm_ty = try o.lowerType(param_ty);3013 const param_llvm_ty = try o.lowerType(param_ty);
3032 const alignment = param_ty.abiAlignment(mod);3014 const alignment = param_ty.abiAlignment(zcu);
3033 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty);3015 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty);
3034 },3016 },
3035 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),3017 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),
...@@ -3055,13 +3037,14 @@ pub const Object = struct {...@@ -3055,13 +3037,14 @@ pub const Object = struct {
3055 fn addCommonFnAttributes(3037 fn addCommonFnAttributes(
3056 o: *Object,3038 o: *Object,
3057 attributes: *Builder.FunctionAttributes.Wip,3039 attributes: *Builder.FunctionAttributes.Wip,
3040 owner_mod: *Package.Module,
3058 ) Allocator.Error!void {3041 ) Allocator.Error!void {
3059 const comp = o.module.comp;3042 const comp = o.module.comp;
30603043
3061 if (!comp.bin_file.options.red_zone) {3044 if (!owner_mod.red_zone) {
3062 try attributes.addFnAttr(.noredzone, &o.builder);3045 try attributes.addFnAttr(.noredzone, &o.builder);
3063 }3046 }
3064 if (comp.bin_file.options.omit_frame_pointer) {3047 if (owner_mod.omit_frame_pointer) {
3065 try attributes.addFnAttr(.{ .string = .{3048 try attributes.addFnAttr(.{ .string = .{
3066 .kind = try o.builder.string("frame-pointer"),3049 .kind = try o.builder.string("frame-pointer"),
3067 .value = try o.builder.string("none"),3050 .value = try o.builder.string("none"),
...@@ -3073,7 +3056,7 @@ pub const Object = struct {...@@ -3073,7 +3056,7 @@ pub const Object = struct {
3073 } }, &o.builder);3056 } }, &o.builder);
3074 }3057 }
3075 try attributes.addFnAttr(.nounwind, &o.builder);3058 try attributes.addFnAttr(.nounwind, &o.builder);
3076 if (comp.unwind_tables) {3059 if (owner_mod.unwind_tables) {
3077 try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);3060 try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);
3078 }3061 }
3079 if (comp.skip_linker_dependencies or comp.no_builtin) {3062 if (comp.skip_linker_dependencies or comp.no_builtin) {
...@@ -3084,26 +3067,27 @@ pub const Object = struct {...@@ -3084,26 +3067,27 @@ pub const Object = struct {
3084 // overflow instead of performing memcpy.3067 // overflow instead of performing memcpy.
3085 try attributes.addFnAttr(.nobuiltin, &o.builder);3068 try attributes.addFnAttr(.nobuiltin, &o.builder);
3086 }3069 }
3087 if (comp.bin_file.options.optimize_mode == .ReleaseSmall) {3070 if (owner_mod.optimize_mode == .ReleaseSmall) {
3088 try attributes.addFnAttr(.minsize, &o.builder);3071 try attributes.addFnAttr(.minsize, &o.builder);
3089 try attributes.addFnAttr(.optsize, &o.builder);3072 try attributes.addFnAttr(.optsize, &o.builder);
3090 }3073 }
3091 if (comp.bin_file.options.tsan) {3074 if (owner_mod.sanitize_thread) {
3092 try attributes.addFnAttr(.sanitize_thread, &o.builder);3075 try attributes.addFnAttr(.sanitize_thread, &o.builder);
3093 }3076 }
3094 if (comp.getTarget().cpu.model.llvm_name) |s| {3077 const target = owner_mod.resolved_target.result;
3078 if (target.cpu.model.llvm_name) |s| {
3095 try attributes.addFnAttr(.{ .string = .{3079 try attributes.addFnAttr(.{ .string = .{
3096 .kind = try o.builder.string("target-cpu"),3080 .kind = try o.builder.string("target-cpu"),
3097 .value = try o.builder.string(s),3081 .value = try o.builder.string(s),
3098 } }, &o.builder);3082 } }, &o.builder);
3099 }3083 }
3100 if (comp.bin_file.options.llvm_cpu_features) |s| {3084 if (owner_mod.resolved_target.llvm_cpu_features) |s| {
3101 try attributes.addFnAttr(.{ .string = .{3085 try attributes.addFnAttr(.{ .string = .{
3102 .kind = try o.builder.string("target-features"),3086 .kind = try o.builder.string("target-features"),
3103 .value = try o.builder.string(std.mem.span(s)),3087 .value = try o.builder.string(std.mem.span(s)),
3104 } }, &o.builder);3088 } }, &o.builder);
3105 }3089 }
3106 if (comp.getTarget().cpu.arch.isBpf()) {3090 if (target.cpu.arch.isBpf()) {
3107 try attributes.addFnAttr(.{ .string = .{3091 try attributes.addFnAttr(.{ .string = .{
3108 .kind = try o.builder.string("no-builtins"),3092 .kind = try o.builder.string("no-builtins"),
3109 .value = .empty,3093 .value = .empty,
...@@ -4646,6 +4630,100 @@ pub const Object = struct {...@@ -4646,6 +4630,100 @@ pub const Object = struct {
4646 .field_index = @intCast(field_index),4630 .field_index = @intCast(field_index),
4647 });4631 });
4648 }4632 }
4633
4634 fn getCmpLtErrorsLenFunction(o: *Object) !Builder.Function.Index {
4635 const name = try o.builder.string(lt_errors_fn_name);
4636 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;
4637
4638 const zcu = o.module;
4639 const target = zcu.root_mod.resolved_target.result;
4640 const function_index = try o.builder.addFunction(
4641 try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal),
4642 name,
4643 toLlvmAddressSpace(.generic, target),
4644 );
4645
4646 var attributes: Builder.FunctionAttributes.Wip = .{};
4647 defer attributes.deinit(&o.builder);
4648 try o.addCommonFnAttributes(&attributes, zcu.root_mod);
4649
4650 function_index.setLinkage(.internal, &o.builder);
4651 function_index.setCallConv(.fastcc, &o.builder);
4652 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
4653 return function_index;
4654 }
4655
4656 fn getEnumTagNameFunction(o: *Object, enum_ty: Type) !Builder.Function.Index {
4657 const zcu = o.module;
4658 const ip = &zcu.intern_pool;
4659 const enum_type = ip.indexToKey(enum_ty.toIntern()).enum_type;
4660
4661 // TODO: detect when the type changes and re-emit this function.
4662 const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl);
4663 if (gop.found_existing) return gop.value_ptr.ptrConst(&o.builder).kind.function;
4664 errdefer assert(o.decl_map.remove(enum_type.decl));
4665
4666 const usize_ty = try o.lowerType(Type.usize);
4667 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
4668 const fqn = try zcu.declPtr(enum_type.decl).getFullyQualifiedName(zcu);
4669 const target = zcu.root_mod.resolved_target.result;
4670 const function_index = try o.builder.addFunction(
4671 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
4672 try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(ip)}),
4673 toLlvmAddressSpace(.generic, target),
4674 );
4675
4676 var attributes: Builder.FunctionAttributes.Wip = .{};
4677 defer attributes.deinit(&o.builder);
4678 try o.addCommonFnAttributes(&attributes, zcu.root_mod);
4679
4680 function_index.setLinkage(.internal, &o.builder);
4681 function_index.setCallConv(.fastcc, &o.builder);
4682 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
4683 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
4684
4685 var wip = try Builder.WipFunction.init(&o.builder, function_index);
4686 defer wip.deinit();
4687 wip.cursor = .{ .block = try wip.block(0, "Entry") };
4688
4689 const bad_value_block = try wip.block(1, "BadValue");
4690 const tag_int_value = wip.arg(0);
4691 var wip_switch =
4692 try wip.@"switch"(tag_int_value, bad_value_block, @intCast(enum_type.names.len));
4693 defer wip_switch.finish(&wip);
4694
4695 for (0..enum_type.names.len) |field_index| {
4696 const name = try o.builder.string(ip.stringToSlice(enum_type.names.get(ip)[field_index]));
4697 const name_init = try o.builder.stringNullConst(name);
4698 const name_variable_index =
4699 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
4700 try name_variable_index.setInitializer(name_init, &o.builder);
4701 name_variable_index.setLinkage(.private, &o.builder);
4702 name_variable_index.setMutability(.constant, &o.builder);
4703 name_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
4704 name_variable_index.setAlignment(comptime Builder.Alignment.fromByteUnits(1), &o.builder);
4705
4706 const name_val = try o.builder.structValue(ret_ty, &.{
4707 name_variable_index.toConst(&o.builder),
4708 try o.builder.intConst(usize_ty, name.slice(&o.builder).?.len),
4709 });
4710
4711 const return_block = try wip.block(1, "Name");
4712 const this_tag_int_value = try o.lowerValue(
4713 (try zcu.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
4714 );
4715 try wip_switch.addCase(this_tag_int_value, return_block, &wip);
4716
4717 wip.cursor = .{ .block = return_block };
4718 _ = try wip.ret(name_val);
4719 }
4720
4721 wip.cursor = .{ .block = bad_value_block };
4722 _ = try wip.@"unreachable"();
4723
4724 try wip.finish();
4725 return function_index;
4726 }
4649};4727};
46504728
4651pub const DeclGen = struct {4729pub const DeclGen = struct {
...@@ -4654,6 +4732,13 @@ pub const DeclGen = struct {...@@ -4654,6 +4732,13 @@ pub const DeclGen = struct {
4654 decl_index: InternPool.DeclIndex,4732 decl_index: InternPool.DeclIndex,
4655 err_msg: ?*Module.ErrorMsg,4733 err_msg: ?*Module.ErrorMsg,
46564734
4735 fn ownerModule(dg: DeclGen) *Package.Module {
4736 const o = dg.object;
4737 const zcu = o.module;
4738 const namespace = zcu.namespacePtr(dg.decl.src_namespace);
4739 return namespace.file_scope.mod;
4740 }
4741
4657 fn todo(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {4742 fn todo(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {
4658 @setCold(true);4743 @setCold(true);
4659 assert(dg.err_msg == null);4744 assert(dg.err_msg == null);
...@@ -5614,7 +5699,7 @@ pub const FuncGen = struct {...@@ -5614,7 +5699,7 @@ pub const FuncGen = struct {
5614 const o = self.dg.object;5699 const o = self.dg.object;
5615 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;5700 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
5616 const operand = try self.resolveInst(un_op);5701 const operand = try self.resolveInst(un_op);
5617 const llvm_fn = try self.getCmpLtErrorsLenFunction();5702 const llvm_fn = try o.getCmpLtErrorsLenFunction();
5618 return self.wip.call(5703 return self.wip.call(
5619 .normal,5704 .normal,
5620 .fastcc,5705 .fastcc,
...@@ -6547,11 +6632,13 @@ pub const FuncGen = struct {...@@ -6547,11 +6632,13 @@ pub const FuncGen = struct {
6547 const dib = o.di_builder orelse return .none;6632 const dib = o.di_builder orelse return .none;
6548 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;6633 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
65496634
6550 const mod = o.module;6635 const zcu = o.module;
6551 const func = mod.funcInfo(ty_fn.func);6636 const func = zcu.funcInfo(ty_fn.func);
6552 const decl_index = func.owner_decl;6637 const decl_index = func.owner_decl;
6553 const decl = mod.declPtr(decl_index);6638 const decl = zcu.declPtr(decl_index);
6554 const di_file = try o.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);6639 const namespace = zcu.namespacePtr(decl.src_namespace);
6640 const owner_mod = namespace.file_scope.mod;
6641 const di_file = try o.getDIFile(self.gpa, zcu.namespacePtr(decl.src_namespace).file_scope);
6555 self.di_file = di_file;6642 self.di_file = di_file;
6556 const line_number = decl.src_line + 1;6643 const line_number = decl.src_line + 1;
6557 const cur_debug_location = self.wip.llvm.builder.getCurrentDebugLocation2();6644 const cur_debug_location = self.wip.llvm.builder.getCurrentDebugLocation2();
...@@ -6562,18 +6649,18 @@ pub const FuncGen = struct {...@@ -6562,18 +6649,18 @@ pub const FuncGen = struct {
6562 .base_line = self.base_line,6649 .base_line = self.base_line,
6563 });6650 });
65646651
6565 const fqn = try decl.getFullyQualifiedName(mod);6652 const fqn = try decl.getFullyQualifiedName(zcu);
65666653
6567 const is_internal_linkage = !mod.decl_exports.contains(decl_index);6654 const is_internal_linkage = !zcu.decl_exports.contains(decl_index);
6568 const fn_ty = try mod.funcType(.{6655 const fn_ty = try zcu.funcType(.{
6569 .param_types = &.{},6656 .param_types = &.{},
6570 .return_type = .void_type,6657 .return_type = .void_type,
6571 });6658 });
6572 const fn_di_ty = try o.lowerDebugType(fn_ty, .full);6659 const fn_di_ty = try o.lowerDebugType(fn_ty, .full);
6573 const subprogram = dib.createFunction(6660 const subprogram = dib.createFunction(
6574 di_file.toScope(),6661 di_file.toScope(),
6575 mod.intern_pool.stringToSlice(decl.name),6662 zcu.intern_pool.stringToSlice(decl.name),
6576 mod.intern_pool.stringToSlice(fqn),6663 zcu.intern_pool.stringToSlice(fqn),
6577 di_file,6664 di_file,
6578 line_number,6665 line_number,
6579 fn_di_ty,6666 fn_di_ty,
...@@ -6581,7 +6668,7 @@ pub const FuncGen = struct {...@@ -6581,7 +6668,7 @@ pub const FuncGen = struct {
6581 true, // is definition6668 true, // is definition
6582 line_number + func.lbrace_line, // scope line6669 line_number + func.lbrace_line, // scope line
6583 llvm.DIFlags.StaticMember,6670 llvm.DIFlags.StaticMember,
6584 mod.comp.bin_file.options.optimize_mode != .Debug,6671 owner_mod.optimize_mode != .Debug,
6585 null, // decl_subprogram6672 null, // decl_subprogram
6586 );6673 );
65876674
...@@ -6676,11 +6763,12 @@ pub const FuncGen = struct {...@@ -6676,11 +6763,12 @@ pub const FuncGen = struct {
6676 null;6763 null;
6677 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);6764 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);
6678 const insert_block = self.wip.cursor.block.toLlvm(&self.wip);6765 const insert_block = self.wip.cursor.block.toLlvm(&self.wip);
6679 const mod = o.module;6766 const zcu = o.module;
6680 if (isByRef(operand_ty, mod)) {6767 const owner_mod = self.dg.ownerModule();
6768 if (isByRef(operand_ty, zcu)) {
6681 _ = dib.insertDeclareAtEnd(operand.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);6769 _ = dib.insertDeclareAtEnd(operand.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
6682 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {6770 } else if (owner_mod.optimize_mode == .Debug) {
6683 const alignment = operand_ty.abiAlignment(mod).toLlvm();6771 const alignment = operand_ty.abiAlignment(zcu).toLlvm();
6684 const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment);6772 const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment);
6685 _ = try self.wip.store(.normal, operand, alloca, alignment);6773 _ = try self.wip.store(.normal, operand, alloca, alignment);
6686 _ = dib.insertDeclareAtEnd(alloca.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);6774 _ = dib.insertDeclareAtEnd(alloca.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
...@@ -8729,9 +8817,10 @@ pub const FuncGen = struct {...@@ -8729,9 +8817,10 @@ pub const FuncGen = struct {
87298817
8730 const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null);8818 const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null);
8731 const insert_block = self.wip.cursor.block.toLlvm(&self.wip);8819 const insert_block = self.wip.cursor.block.toLlvm(&self.wip);
8820 const owner_mod = self.dg.ownerModule();
8732 if (isByRef(inst_ty, mod)) {8821 if (isByRef(inst_ty, mod)) {
8733 _ = dib.insertDeclareAtEnd(arg_val.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);8822 _ = dib.insertDeclareAtEnd(arg_val.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
8734 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {8823 } else if (owner_mod.optimize_mode == .Debug) {
8735 const alignment = inst_ty.abiAlignment(mod).toLlvm();8824 const alignment = inst_ty.abiAlignment(mod).toLlvm();
8736 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);8825 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);
8737 _ = try self.wip.store(.normal, arg_val, alloca, alignment);8826 _ = try self.wip.store(.normal, arg_val, alloca, alignment);
...@@ -8821,7 +8910,8 @@ pub const FuncGen = struct {...@@ -8821,7 +8910,8 @@ pub const FuncGen = struct {
8821 len,8910 len,
8822 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,8911 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
8823 );8912 );
8824 if (safety and mod.comp.bin_file.options.valgrind) {8913 const owner_mod = self.dg.ownerModule();
8914 if (safety and owner_mod.valgrind) {
8825 try self.valgrindMarkUndef(dest_ptr, len);8915 try self.valgrindMarkUndef(dest_ptr, len);
8826 }8916 }
8827 return .none;8917 return .none;
...@@ -9137,7 +9227,8 @@ pub const FuncGen = struct {...@@ -9137,7 +9227,8 @@ pub const FuncGen = struct {
9137 } else {9227 } else {
9138 _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);9228 _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
9139 }9229 }
9140 if (safety and mod.comp.bin_file.options.valgrind) {9230 const owner_mod = self.dg.ownerModule();
9231 if (safety and owner_mod.valgrind) {
9141 try self.valgrindMarkUndef(dest_ptr, len);9232 try self.valgrindMarkUndef(dest_ptr, len);
9142 }9233 }
9143 return .none;9234 return .none;
...@@ -9488,24 +9579,25 @@ pub const FuncGen = struct {...@@ -9488,24 +9579,25 @@ pub const FuncGen = struct {
94889579
9489 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {9580 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {
9490 const o = self.dg.object;9581 const o = self.dg.object;
9491 const mod = o.module;9582 const zcu = o.module;
9492 const enum_type = mod.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;9583 const enum_type = zcu.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;
94939584
9494 // TODO: detect when the type changes and re-emit this function.9585 // TODO: detect when the type changes and re-emit this function.
9495 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);9586 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);
9496 if (gop.found_existing) return gop.value_ptr.*;9587 if (gop.found_existing) return gop.value_ptr.*;
9497 errdefer assert(o.named_enum_map.remove(enum_type.decl));9588 errdefer assert(o.named_enum_map.remove(enum_type.decl));
94989589
9499 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);9590 const fqn = try zcu.declPtr(enum_type.decl).getFullyQualifiedName(zcu);
9591 const target = zcu.root_mod.resolved_target.result;
9500 const function_index = try o.builder.addFunction(9592 const function_index = try o.builder.addFunction(
9501 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),9593 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
9502 try o.builder.fmt("__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)}),9594 try o.builder.fmt("__zig_is_named_enum_value_{}", .{fqn.fmt(&zcu.intern_pool)}),
9503 toLlvmAddressSpace(.generic, mod.getTarget()),9595 toLlvmAddressSpace(.generic, target),
9504 );9596 );
95059597
9506 var attributes: Builder.FunctionAttributes.Wip = .{};9598 var attributes: Builder.FunctionAttributes.Wip = .{};
9507 defer attributes.deinit(&o.builder);9599 defer attributes.deinit(&o.builder);
9508 try o.addCommonFnAttributes(&attributes);9600 try o.addCommonFnAttributes(&attributes, zcu.root_mod);
95099601
9510 function_index.setLinkage(.internal, &o.builder);9602 function_index.setLinkage(.internal, &o.builder);
9511 function_index.setCallConv(.fastcc, &o.builder);9603 function_index.setCallConv(.fastcc, &o.builder);
...@@ -9524,7 +9616,7 @@ pub const FuncGen = struct {...@@ -9524,7 +9616,7 @@ pub const FuncGen = struct {
95249616
9525 for (0..enum_type.names.len) |field_index| {9617 for (0..enum_type.names.len) |field_index| {
9526 const this_tag_int_value = try o.lowerValue(9618 const this_tag_int_value = try o.lowerValue(
9527 (try mod.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),9619 (try zcu.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
9528 );9620 );
9529 try wip_switch.addCase(this_tag_int_value, named_block, &wip);9621 try wip_switch.addCase(this_tag_int_value, named_block, &wip);
9530 }9622 }
...@@ -9544,7 +9636,7 @@ pub const FuncGen = struct {...@@ -9544,7 +9636,7 @@ pub const FuncGen = struct {
9544 const operand = try self.resolveInst(un_op);9636 const operand = try self.resolveInst(un_op);
9545 const enum_ty = self.typeOf(un_op);9637 const enum_ty = self.typeOf(un_op);
95469638
9547 const llvm_fn = try self.getEnumTagNameFunction(enum_ty);9639 const llvm_fn = try o.getEnumTagNameFunction(enum_ty);
9548 return self.wip.call(9640 return self.wip.call(
9549 .normal,9641 .normal,
9550 .fastcc,9642 .fastcc,
...@@ -9556,100 +9648,6 @@ pub const FuncGen = struct {...@@ -9556,100 +9648,6 @@ pub const FuncGen = struct {
9556 );9648 );
9557 }9649 }
95589650
9559 fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {
9560 const o = self.dg.object;
9561 const mod = o.module;
9562 const ip = &mod.intern_pool;
9563 const enum_type = ip.indexToKey(enum_ty.toIntern()).enum_type;
9564
9565 // TODO: detect when the type changes and re-emit this function.
9566 const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl);
9567 if (gop.found_existing) return gop.value_ptr.ptrConst(&o.builder).kind.function;
9568 errdefer assert(o.decl_map.remove(enum_type.decl));
9569
9570 const usize_ty = try o.lowerType(Type.usize);
9571 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
9572 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
9573 const function_index = try o.builder.addFunction(
9574 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
9575 try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(ip)}),
9576 toLlvmAddressSpace(.generic, mod.getTarget()),
9577 );
9578
9579 var attributes: Builder.FunctionAttributes.Wip = .{};
9580 defer attributes.deinit(&o.builder);
9581 try o.addCommonFnAttributes(&attributes);
9582
9583 function_index.setLinkage(.internal, &o.builder);
9584 function_index.setCallConv(.fastcc, &o.builder);
9585 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
9586 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
9587
9588 var wip = try Builder.WipFunction.init(&o.builder, function_index);
9589 defer wip.deinit();
9590 wip.cursor = .{ .block = try wip.block(0, "Entry") };
9591
9592 const bad_value_block = try wip.block(1, "BadValue");
9593 const tag_int_value = wip.arg(0);
9594 var wip_switch =
9595 try wip.@"switch"(tag_int_value, bad_value_block, @intCast(enum_type.names.len));
9596 defer wip_switch.finish(&wip);
9597
9598 for (0..enum_type.names.len) |field_index| {
9599 const name = try o.builder.string(ip.stringToSlice(enum_type.names.get(ip)[field_index]));
9600 const name_init = try o.builder.stringNullConst(name);
9601 const name_variable_index =
9602 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
9603 try name_variable_index.setInitializer(name_init, &o.builder);
9604 name_variable_index.setLinkage(.private, &o.builder);
9605 name_variable_index.setMutability(.constant, &o.builder);
9606 name_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
9607 name_variable_index.setAlignment(comptime Builder.Alignment.fromByteUnits(1), &o.builder);
9608
9609 const name_val = try o.builder.structValue(ret_ty, &.{
9610 name_variable_index.toConst(&o.builder),
9611 try o.builder.intConst(usize_ty, name.slice(&o.builder).?.len),
9612 });
9613
9614 const return_block = try wip.block(1, "Name");
9615 const this_tag_int_value = try o.lowerValue(
9616 (try mod.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
9617 );
9618 try wip_switch.addCase(this_tag_int_value, return_block, &wip);
9619
9620 wip.cursor = .{ .block = return_block };
9621 _ = try wip.ret(name_val);
9622 }
9623
9624 wip.cursor = .{ .block = bad_value_block };
9625 _ = try wip.@"unreachable"();
9626
9627 try wip.finish();
9628 return function_index;
9629 }
9630
9631 fn getCmpLtErrorsLenFunction(self: *FuncGen) !Builder.Function.Index {
9632 const o = self.dg.object;
9633
9634 const name = try o.builder.string(lt_errors_fn_name);
9635 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;
9636
9637 const function_index = try o.builder.addFunction(
9638 try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal),
9639 name,
9640 toLlvmAddressSpace(.generic, o.module.getTarget()),
9641 );
9642
9643 var attributes: Builder.FunctionAttributes.Wip = .{};
9644 defer attributes.deinit(&o.builder);
9645 try o.addCommonFnAttributes(&attributes);
9646
9647 function_index.setLinkage(.internal, &o.builder);
9648 function_index.setCallConv(.fastcc, &o.builder);
9649 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
9650 return function_index;
9651 }
9652
9653 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {9651 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
9654 const o = self.dg.object;9652 const o = self.dg.object;
9655 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;9653 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
src/link.zig+46
...@@ -18,6 +18,7 @@ const Module = @import("Module.zig");...@@ -18,6 +18,7 @@ const Module = @import("Module.zig");
18const InternPool = @import("InternPool.zig");18const InternPool = @import("InternPool.zig");
19const Type = @import("type.zig").Type;19const Type = @import("type.zig").Type;
20const TypedValue = @import("TypedValue.zig");20const TypedValue = @import("TypedValue.zig");
21const LlvmObject = @import("codegen/llvm.zig").Object;
2122
22/// When adding a new field, remember to update `hashAddSystemLibs`.23/// When adding a new field, remember to update `hashAddSystemLibs`.
23/// These are *always* dynamically linked. Static libraries will be24/// These are *always* dynamically linked. Static libraries will be
...@@ -1046,6 +1047,51 @@ pub const File = struct {...@@ -1046,6 +1047,51 @@ pub const File = struct {
1046 return output_mode == .Lib and !self.isStatic();1047 return output_mode == .Lib and !self.isStatic();
1047 }1048 }
10481049
1050 pub fn resolveEmitLoc(
1051 base: File,
1052 arena: Allocator,
1053 opt_loc: ?Compilation.EmitLoc,
1054 ) Allocator.Error!?[*:0]u8 {
1055 const loc = opt_loc orelse return null;
1056 const slice = if (loc.directory) |directory|
1057 try directory.joinZ(arena, &.{loc.basename})
1058 else
1059 try base.emit.basenamePath(arena, loc.basename);
1060 return slice.ptr;
1061 }
1062
1063 pub fn emitLlvmObject(
1064 base: File,
1065 arena: Allocator,
1066 llvm_object: *LlvmObject,
1067 prog_node: *std.Progress.Node,
1068 ) !void {
1069 const comp = base.comp;
1070
1071 var sub_prog_node = prog_node.start("LLVM Emit Object", 0);
1072 sub_prog_node.activate();
1073 sub_prog_node.context.refresh();
1074 defer sub_prog_node.end();
1075
1076 try llvm_object.emit(comp, .{
1077 .pre_ir_path = comp.verbose_llvm_ir,
1078 .pre_bc_path = comp.verbose_llvm_bc,
1079 .bin_path = try base.resolveEmitLoc(arena, .{
1080 .directory = null,
1081 .basename = base.intermediary_basename.?,
1082 }),
1083 .asm_path = try base.resolveEmitLoc(arena, comp.emit_asm),
1084 .post_llvm_ir_path = try base.resolveEmitLoc(arena, comp.emit_llvm_ir),
1085 .post_llvm_bc_path = try base.resolveEmitLoc(arena, comp.emit_llvm_bc),
1086
1087 .is_debug = comp.root_mod.optimize_mode == .Debug,
1088 .is_small = comp.root_mod.optimize_mode == .ReleaseSmall,
1089 .time_report = comp.time_report,
1090 .sanitize_thread = comp.config.any_sanitize_thread,
1091 .lto = comp.config.lto,
1092 });
1093 }
1094
1049 pub const C = @import("link/C.zig");1095 pub const C = @import("link/C.zig");
1050 pub const Coff = @import("link/Coff.zig");1096 pub const Coff = @import("link/Coff.zig");
1051 pub const Plan9 = @import("link/Plan9.zig");1097 pub const Plan9 = @import("link/Plan9.zig");
src/link/Coff.zig+11-6
...@@ -3,7 +3,7 @@...@@ -3,7 +3,7 @@
3//! LLD for traditional linking (linking relocatable object files).3//! LLD for traditional linking (linking relocatable object files).
4//! LLD is also the default linker for LLVM.4//! LLD is also the default linker for LLVM.
55
6/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.6/// If this is not null, an object file is created by LLVM and emitted to intermediary_basename.
7llvm_object: ?*LlvmObject = null,7llvm_object: ?*LlvmObject = null,
88
9base: link.File,9base: link.File,
...@@ -1711,17 +1711,22 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -1711,17 +1711,22 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
1711 const tracy = trace(@src());1711 const tracy = trace(@src());
1712 defer tracy.end();1712 defer tracy.end();
17131713
1714 const gpa = comp.gpa;
1715
1714 if (self.llvm_object) |llvm_object| {1716 if (self.llvm_object) |llvm_object| {
1715 return try llvm_object.flushModule(comp, prog_node);1717 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
1718 defer arena_allocator.deinit();
1719 const arena = arena_allocator.allocator();
1720
1721 try self.base.emitLlvmObject(arena, llvm_object, prog_node);
1722 return;
1716 }1723 }
17171724
1718 var sub_prog_node = prog_node.start("COFF Flush", 0);1725 var sub_prog_node = prog_node.start("COFF Flush", 0);
1719 sub_prog_node.activate();1726 sub_prog_node.activate();
1720 defer sub_prog_node.end();1727 defer sub_prog_node.end();
17211728
1722 const gpa = self.base.comp.gpa;1729 const module = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;
1723
1724 const module = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;
17251730
1726 if (self.lazy_syms.getPtr(.none)) |metadata| {1731 if (self.lazy_syms.getPtr(.none)) |metadata| {
1727 // Most lazy symbols can be updated on first use, but1732 // Most lazy symbols can be updated on first use, but
...@@ -1822,7 +1827,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -1822,7 +1827,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
1822 try self.writeDataDirectoriesHeaders();1827 try self.writeDataDirectoriesHeaders();
1823 try self.writeSectionHeaders();1828 try self.writeSectionHeaders();
18241829
1825 if (self.entry_addr == null and self.base.comp.config.output_mode == .Exe) {1830 if (self.entry_addr == null and comp.config.output_mode == .Exe) {
1826 log.debug("flushing. no_entry_point_found = true\n", .{});1831 log.debug("flushing. no_entry_point_found = true\n", .{});
1827 self.base.error_flags.no_entry_point_found = true;1832 self.base.error_flags.no_entry_point_found = true;
1828 } else {1833 } else {
src/link/Elf.zig+23-24
...@@ -27,7 +27,7 @@ version_script: ?[]const u8,...@@ -27,7 +27,7 @@ version_script: ?[]const u8,
2727
28ptr_width: PtrWidth,28ptr_width: PtrWidth,
2929
30/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.30/// If this is not null, an object file is created by LLVM and emitted to intermediary_basename.
31llvm_object: ?*LlvmObject = null,31llvm_object: ?*LlvmObject = null,
3232
33/// A list of all input files.33/// A list of all input files.
...@@ -1031,24 +1031,23 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1031,24 +1031,23 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1031 const tracy = trace(@src());1031 const tracy = trace(@src());
1032 defer tracy.end();1032 defer tracy.end();
10331033
1034 if (self.llvm_object) |llvm_object| {1034 const gpa = comp.gpa;
1035 try llvm_object.flushModule(comp, prog_node);1035 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
1036 defer arena_allocator.deinit();
1037 const arena = arena_allocator.allocator();
10361038
1037 const use_lld = build_options.have_llvm and self.base.comp.config.use_lld;1039 if (self.llvm_object) |llvm_object| {
1040 try self.base.emitLlvmObject(arena, llvm_object, prog_node);
1041 const use_lld = build_options.have_llvm and comp.config.use_lld;
1038 if (use_lld) return;1042 if (use_lld) return;
1039 }1043 }
10401044
1041 const gpa = self.base.comp.gpa;
1042 var sub_prog_node = prog_node.start("ELF Flush", 0);1045 var sub_prog_node = prog_node.start("ELF Flush", 0);
1043 sub_prog_node.activate();1046 sub_prog_node.activate();
1044 defer sub_prog_node.end();1047 defer sub_prog_node.end();
10451048
1046 var arena_allocator = std.heap.ArenaAllocator.init(gpa);1049 const target = comp.root_mod.resolved_target.result;
1047 defer arena_allocator.deinit();1050 const link_mode = comp.config.link_mode;
1048 const arena = arena_allocator.allocator();
1049
1050 const target = self.base.comp.root_mod.resolved_target.result;
1051 const link_mode = self.base.comp.config.link_mode;
1052 const directory = self.base.emit.directory; // Just an alias to make it shorter to type.1051 const directory = self.base.emit.directory; // Just an alias to make it shorter to type.
1053 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});1052 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
1054 const module_obj_path: ?[]const u8 = if (self.base.intermediary_basename) |path| blk: {1053 const module_obj_path: ?[]const u8 = if (self.base.intermediary_basename) |path| blk: {
...@@ -1060,7 +1059,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1060,7 +1059,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1060 } else null;1059 } else null;
10611060
1062 // --verbose-link1061 // --verbose-link
1063 if (self.base.comp.verbose_link) try self.dumpArgv(comp);1062 if (comp.verbose_link) try self.dumpArgv(comp);
10641063
1065 const csu = try CsuObjects.init(arena, comp);1064 const csu = try CsuObjects.init(arena, comp);
1066 const compiler_rt_path: ?[]const u8 = blk: {1065 const compiler_rt_path: ?[]const u8 = blk: {
...@@ -1082,8 +1081,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1082,8 +1081,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1082 if (csu.crti) |v| try positionals.append(.{ .path = v });1081 if (csu.crti) |v| try positionals.append(.{ .path = v });
1083 if (csu.crtbegin) |v| try positionals.append(.{ .path = v });1082 if (csu.crtbegin) |v| try positionals.append(.{ .path = v });
10841083
1085 try positionals.ensureUnusedCapacity(self.base.comp.objects.len);1084 try positionals.ensureUnusedCapacity(comp.objects.len);
1086 positionals.appendSliceAssumeCapacity(self.base.comp.objects);1085 positionals.appendSliceAssumeCapacity(comp.objects);
10871086
1088 // This is a set of object files emitted by clang in a single `build-exe` invocation.1087 // This is a set of object files emitted by clang in a single `build-exe` invocation.
1089 // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up1088 // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up
...@@ -1106,13 +1105,13 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1106,13 +1105,13 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1106 var test_path = std.ArrayList(u8).init(gpa);1105 var test_path = std.ArrayList(u8).init(gpa);
1107 defer test_path.deinit();1106 defer test_path.deinit();
1108 for (self.lib_dirs) |lib_dir_path| {1107 for (self.lib_dirs) |lib_dir_path| {
1109 for (self.base.comp.system_libs.keys()) |link_lib| {1108 for (comp.system_libs.keys()) |link_lib| {
1110 if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic)))1109 if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic)))
1111 continue;1110 continue;
1112 _ = try rpath_table.put(lib_dir_path, {});1111 _ = try rpath_table.put(lib_dir_path, {});
1113 }1112 }
1114 }1113 }
1115 for (self.base.comp.objects) |obj| {1114 for (comp.objects) |obj| {
1116 if (Compilation.classifyFileExt(obj.path) == .shared_library) {1115 if (Compilation.classifyFileExt(obj.path) == .shared_library) {
1117 const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue;1116 const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue;
1118 if (obj.loption) continue;1117 if (obj.loption) continue;
...@@ -1122,7 +1121,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1122,7 +1121,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1122 }1121 }
11231122
1124 // TSAN1123 // TSAN
1125 if (self.base.comp.config.any_sanitize_thread) {1124 if (comp.config.any_sanitize_thread) {
1126 try positionals.append(.{ .path = comp.tsan_static_lib.?.full_object_path });1125 try positionals.append(.{ .path = comp.tsan_static_lib.?.full_object_path });
1127 }1126 }
11281127
...@@ -1146,27 +1145,27 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1146,27 +1145,27 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
11461145
1147 var system_libs = std.ArrayList(SystemLib).init(arena);1146 var system_libs = std.ArrayList(SystemLib).init(arena);
11481147
1149 try system_libs.ensureUnusedCapacity(self.base.comp.system_libs.values().len);1148 try system_libs.ensureUnusedCapacity(comp.system_libs.values().len);
1150 for (self.base.comp.system_libs.values()) |lib_info| {1149 for (comp.system_libs.values()) |lib_info| {
1151 system_libs.appendAssumeCapacity(.{ .needed = lib_info.needed, .path = lib_info.path.? });1150 system_libs.appendAssumeCapacity(.{ .needed = lib_info.needed, .path = lib_info.path.? });
1152 }1151 }
11531152
1154 // libc++ dep1153 // libc++ dep
1155 if (self.base.comp.config.link_libcpp) {1154 if (comp.config.link_libcpp) {
1156 try system_libs.ensureUnusedCapacity(2);1155 try system_libs.ensureUnusedCapacity(2);
1157 system_libs.appendAssumeCapacity(.{ .path = comp.libcxxabi_static_lib.?.full_object_path });1156 system_libs.appendAssumeCapacity(.{ .path = comp.libcxxabi_static_lib.?.full_object_path });
1158 system_libs.appendAssumeCapacity(.{ .path = comp.libcxx_static_lib.?.full_object_path });1157 system_libs.appendAssumeCapacity(.{ .path = comp.libcxx_static_lib.?.full_object_path });
1159 }1158 }
11601159
1161 // libunwind dep1160 // libunwind dep
1162 if (self.base.comp.config.link_libunwind) {1161 if (comp.config.link_libunwind) {
1163 try system_libs.append(.{ .path = comp.libunwind_static_lib.?.full_object_path });1162 try system_libs.append(.{ .path = comp.libunwind_static_lib.?.full_object_path });
1164 }1163 }
11651164
1166 // libc dep1165 // libc dep
1167 self.base.error_flags.missing_libc = false;1166 self.base.error_flags.missing_libc = false;
1168 if (self.base.comp.config.link_libc) {1167 if (comp.config.link_libc) {
1169 if (self.base.comp.libc_installation) |lc| {1168 if (comp.libc_installation) |lc| {
1170 const flags = target_util.libcFullLinkFlags(target);1169 const flags = target_util.libcFullLinkFlags(target);
1171 try system_libs.ensureUnusedCapacity(flags.len);1170 try system_libs.ensureUnusedCapacity(flags.len);
11721171
...@@ -1305,7 +1304,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1305,7 +1304,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1305 // Look for entry address in objects if not set by the incremental compiler.1304 // Look for entry address in objects if not set by the incremental compiler.
1306 if (self.entry_index == null) {1305 if (self.entry_index == null) {
1307 const entry: ?[]const u8 = entry: {1306 const entry: ?[]const u8 = entry: {
1308 if (self.base.comp.config.entry) |entry| break :entry entry;1307 if (comp.config.entry) |entry| break :entry entry;
1309 if (!self.base.isDynLib()) break :entry "_start";1308 if (!self.base.isDynLib()) break :entry "_start";
1310 break :entry null;1309 break :entry null;
1311 };1310 };
src/link/Elf/Symbol.zig+3-3
...@@ -43,7 +43,7 @@ pub fn outputShndx(symbol: Symbol) ?u16 {...@@ -43,7 +43,7 @@ pub fn outputShndx(symbol: Symbol) ?u16 {
43}43}
4444
45pub fn isLocal(symbol: Symbol, elf_file: *Elf) bool {45pub fn isLocal(symbol: Symbol, elf_file: *Elf) bool {
46 if (elf_file.isRelocatable()) return symbol.elfSym(elf_file).st_bind() == elf.STB_LOCAL;46 if (elf_file.base.isRelocatable()) return symbol.elfSym(elf_file).st_bind() == elf.STB_LOCAL;
47 return !(symbol.flags.import or symbol.flags.@"export");47 return !(symbol.flags.import or symbol.flags.@"export");
48}48}
4949
...@@ -186,7 +186,7 @@ const GetOrCreateZigGotEntryResult = struct {...@@ -186,7 +186,7 @@ const GetOrCreateZigGotEntryResult = struct {
186};186};
187187
188pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult {188pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult {
189 assert(!elf_file.isRelocatable());189 assert(!elf_file.base.isRelocatable());
190 assert(symbol.flags.needs_zig_got);190 assert(symbol.flags.needs_zig_got);
191 if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).?.zig_got };191 if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).?.zig_got };
192 const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file);192 const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file);
...@@ -237,7 +237,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {...@@ -237,7 +237,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
237 const st_shndx = blk: {237 const st_shndx = blk: {
238 if (symbol.flags.has_copy_rel) break :blk elf_file.copy_rel_section_index.?;238 if (symbol.flags.has_copy_rel) break :blk elf_file.copy_rel_section_index.?;
239 if (file_ptr == .shared_object or esym.st_shndx == elf.SHN_UNDEF) break :blk elf.SHN_UNDEF;239 if (file_ptr == .shared_object or esym.st_shndx == elf.SHN_UNDEF) break :blk elf.SHN_UNDEF;
240 if (elf_file.isRelocatable() and esym.st_shndx == elf.SHN_COMMON) break :blk elf.SHN_COMMON;240 if (elf_file.base.isRelocatable() and esym.st_shndx == elf.SHN_COMMON) break :blk elf.SHN_COMMON;
241 if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) break :blk elf.SHN_ABS;241 if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) break :blk elf.SHN_ABS;
242 break :blk symbol.outputShndx() orelse elf.SHN_UNDEF;242 break :blk symbol.outputShndx() orelse elf.SHN_UNDEF;
243 };243 };
src/link/Elf/ZigObject.zig+3-3
...@@ -926,7 +926,7 @@ fn updateDeclCode(...@@ -926,7 +926,7 @@ fn updateDeclCode(
926 sym.value = atom_ptr.value;926 sym.value = atom_ptr.value;
927 esym.st_value = atom_ptr.value;927 esym.st_value = atom_ptr.value;
928928
929 if (!elf_file.isRelocatable()) {929 if (!elf_file.base.isRelocatable()) {
930 log.debug(" (writing new offset table entry)", .{});930 log.debug(" (writing new offset table entry)", .{});
931 assert(sym.flags.has_zig_got);931 assert(sym.flags.has_zig_got);
932 const extra = sym.extra(elf_file).?;932 const extra = sym.extra(elf_file).?;
...@@ -944,7 +944,7 @@ fn updateDeclCode(...@@ -944,7 +944,7 @@ fn updateDeclCode(
944 sym.flags.needs_zig_got = true;944 sym.flags.needs_zig_got = true;
945 esym.st_value = atom_ptr.value;945 esym.st_value = atom_ptr.value;
946946
947 if (!elf_file.isRelocatable()) {947 if (!elf_file.base.isRelocatable()) {
948 const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);948 const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
949 try elf_file.zig_got.writeOne(elf_file, gop.index);949 try elf_file.zig_got.writeOne(elf_file, gop.index);
950 }950 }
...@@ -1262,7 +1262,7 @@ fn updateLazySymbol(...@@ -1262,7 +1262,7 @@ fn updateLazySymbol(
1262 local_sym.flags.needs_zig_got = true;1262 local_sym.flags.needs_zig_got = true;
1263 local_esym.st_value = atom_ptr.value;1263 local_esym.st_value = atom_ptr.value;
12641264
1265 if (!elf_file.isRelocatable()) {1265 if (!elf_file.base.isRelocatable()) {
1266 const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file);1266 const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file);
1267 try elf_file.zig_got.writeOne(elf_file, gop.index);1267 try elf_file.zig_got.writeOne(elf_file, gop.index);
1268 }1268 }
src/link/MachO.zig+11-10
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1base: File,1base: File,
22
3/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.3/// If this is not null, an object file is created by LLVM and emitted to intermediary_basename.
4llvm_object: ?*LlvmObject = null,4llvm_object: ?*LlvmObject = null,
55
6/// Debug symbols bundle (or dSym).6/// Debug symbols bundle (or dSym).
...@@ -352,22 +352,23 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -352,22 +352,23 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
352 const tracy = trace(@src());352 const tracy = trace(@src());
353 defer tracy.end();353 defer tracy.end();
354354
355 if (self.llvm_object) |llvm_object| {355 const gpa = comp.gpa;
356 return try llvm_object.flushModule(comp, prog_node);
357 }
358
359 const gpa = self.base.comp.gpa;
360 var arena_allocator = std.heap.ArenaAllocator.init(gpa);356 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
361 defer arena_allocator.deinit();357 defer arena_allocator.deinit();
362 const arena = arena_allocator.allocator();358 const arena = arena_allocator.allocator();
363359
360 if (self.llvm_object) |llvm_object| {
361 try self.base.emitLlvmObject(arena, llvm_object, prog_node);
362 return;
363 }
364
364 var sub_prog_node = prog_node.start("MachO Flush", 0);365 var sub_prog_node = prog_node.start("MachO Flush", 0);
365 sub_prog_node.activate();366 sub_prog_node.activate();
366 defer sub_prog_node.end();367 defer sub_prog_node.end();
367368
368 const output_mode = self.base.comp.config.output_mode;369 const output_mode = comp.config.output_mode;
369 const module = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;370 const module = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;
370 const target = self.base.comp.root_mod.resolved_target.result;371 const target = comp.root_mod.resolved_target.result;
371372
372 if (self.lazy_syms.getPtr(.none)) |metadata| {373 if (self.lazy_syms.getPtr(.none)) |metadata| {
373 // Most lazy symbols can be updated on first use, but374 // Most lazy symbols can be updated on first use, but
...@@ -619,7 +620,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No...@@ -619,7 +620,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
619 .stacksize = self.base.stack_size,620 .stacksize = self.base.stack_size,
620 });621 });
621 },622 },
622 .Lib => if (self.base.comp.config.link_mode == .Dynamic) {623 .Lib => if (comp.config.link_mode == .Dynamic) {
623 try load_commands.writeDylibIdLC(self, lc_writer);624 try load_commands.writeDylibIdLC(self, lc_writer);
624 },625 },
625 else => {},626 else => {},
src/link/Wasm.zig+11-10
...@@ -3700,8 +3700,15 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -3700,8 +3700,15 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
3700 const tracy = trace(@src());3700 const tracy = trace(@src());
3701 defer tracy.end();3701 defer tracy.end();
37023702
3703 const gpa = comp.gpa;
3704 // Used for all temporary memory allocated during flushin
3705 var arena_instance = std.heap.ArenaAllocator.init(gpa);
3706 defer arena_instance.deinit();
3707 const arena = arena_instance.allocator();
3708
3703 if (wasm.llvm_object) |llvm_object| {3709 if (wasm.llvm_object) |llvm_object| {
3704 return try llvm_object.flushModule(comp, prog_node);3710 try wasm.base.emitLlvmObject(arena, llvm_object, prog_node);
3711 return;
3705 }3712 }
37063713
3707 var sub_prog_node = prog_node.start("Wasm Flush", 0);3714 var sub_prog_node = prog_node.start("Wasm Flush", 0);
...@@ -3711,13 +3718,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -3711,13 +3718,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
3711 // ensure the error names table is populated when an error name is referenced3718 // ensure the error names table is populated when an error name is referenced
3712 try wasm.populateErrorNameTable();3719 try wasm.populateErrorNameTable();
37133720
3714 // Used for all temporary memory allocated during flushin3721 const objects = comp.objects;
3715 const gpa = wasm.base.comp.gpa;
3716 var arena_instance = std.heap.ArenaAllocator.init(gpa);
3717 defer arena_instance.deinit();
3718 const arena = arena_instance.allocator();
3719
3720 const objects = wasm.base.comp.objects;
37213722
3722 // Positional arguments to the linker such as object files and static archives.3723 // Positional arguments to the linker such as object files and static archives.
3723 var positionals = std.ArrayList([]const u8).init(arena);3724 var positionals = std.ArrayList([]const u8).init(arena);
...@@ -3755,7 +3756,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -3755,7 +3756,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
3755 try wasm.markReferences();3756 try wasm.markReferences();
3756 try wasm.setupErrorsLen();3757 try wasm.setupErrorsLen();
3757 try wasm.setupImports();3758 try wasm.setupImports();
3758 if (wasm.base.comp.module) |mod| {3759 if (comp.module) |mod| {
3759 var decl_it = wasm.decls.iterator();3760 var decl_it = wasm.decls.iterator();
3760 while (decl_it.next()) |entry| {3761 while (decl_it.next()) |entry| {
3761 const decl = mod.declPtr(entry.key_ptr.*);3762 const decl = mod.declPtr(entry.key_ptr.*);
...@@ -3810,7 +3811,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -3810,7 +3811,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
3810 }3811 }
38113812
3812 if (wasm.dwarf) |*dwarf| {3813 if (wasm.dwarf) |*dwarf| {
3813 try dwarf.flushModule(wasm.base.comp.module.?);3814 try dwarf.flushModule(comp.module.?);
3814 }3815 }
3815 }3816 }
38163817