authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-06 02:52:25-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-19 23:38:40-04:00
logd195173ba2c06b56c1bf5554ebf0736795798c91
treee358fa6f170400ce6a07ba00a032548a4f1263e8
parent996eb01746498e0ec5e162ed40d1f3c913891150

llvm: start tracking more things without relying on the llvm api


6 files changed, 1324 insertions(+), 331 deletions(-)

src/Compilation.zig+5-1
......@@ -538,6 +538,7 @@ pub const InitOptions = struct {
538538 want_lto: ?bool = null,
539539 want_unwind_tables: ?bool = null,
540540 use_llvm: ?bool = null,
541 use_lib_llvm: ?bool = null,
541542 use_lld: ?bool = null,
542543 use_clang: ?bool = null,
543544 single_threaded: ?bool = null,
......@@ -753,7 +754,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
753754 const root_name = try arena.dupeZ(u8, options.root_name);
754755
755756 // Make a decision on whether to use LLVM or our own backend.
756 const use_llvm = build_options.have_llvm and blk: {
757 const use_lib_llvm = options.use_lib_llvm orelse build_options.have_llvm;
758 const use_llvm = blk: {
757759 if (options.use_llvm) |explicit|
758760 break :blk explicit;
759761
......@@ -1161,6 +1163,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
11611163 hash.add(valgrind);
11621164 hash.add(single_threaded);
11631165 hash.add(use_llvm);
1166 hash.add(use_lib_llvm);
11641167 hash.add(dll_export_fns);
11651168 hash.add(options.is_test);
11661169 hash.add(options.test_evented_io);
......@@ -1444,6 +1447,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
14441447 .optimize_mode = options.optimize_mode,
14451448 .use_lld = use_lld,
14461449 .use_llvm = use_llvm,
1450 .use_lib_llvm = use_lib_llvm,
14471451 .link_libc = link_libc,
14481452 .link_libcpp = link_libcpp,
14491453 .link_libunwind = link_libunwind,
src/codegen/llvm.zig+438-327
......@@ -7,6 +7,7 @@ const math = std.math;
77const native_endian = builtin.cpu.arch.endian();
88const DW = std.dwarf;
99
10const Builder = @import("llvm/Builder.zig");
1011const llvm = @import("llvm/bindings.zig");
1112const link = @import("../link.zig");
1213const Compilation = @import("../Compilation.zig");
......@@ -338,6 +339,8 @@ fn deleteLlvmGlobal(llvm_global: *llvm.Value) void {
338339
339340pub const Object = struct {
340341 gpa: Allocator,
342 builder: Builder,
343
341344 module: *Module,
342345 llvm_module: *llvm.Module,
343346 di_builder: ?*llvm.DIBuilder,
......@@ -359,7 +362,7 @@ pub const Object = struct {
359362 /// version of the name and incorrectly get function not found in the llvm module.
360363 /// * it works for functions not all globals.
361364 /// Therefore, this table keeps track of the mapping.
362 decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value),
365 decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, Builder.Global.Index),
363366 /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction.
364367 named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value),
365368 /// Maps Zig types to LLVM types. The table memory is backed by the GPA of
......@@ -394,13 +397,19 @@ pub const Object = struct {
394397 }
395398
396399 pub fn init(gpa: Allocator, options: link.Options) !Object {
397 const context = llvm.Context.create();
398 errdefer context.dispose();
400 var builder = Builder{
401 .gpa = gpa,
402 .use_lib_llvm = options.use_lib_llvm,
403
404 .llvm_context = llvm.Context.create(),
405 .llvm_module = undefined,
406 };
407 errdefer builder.llvm_context.dispose();
399408
400409 initializeLLVMTarget(options.target.cpu.arch);
401410
402 const llvm_module = llvm.Module.createWithName(options.root_name.ptr, context);
403 errdefer llvm_module.dispose();
411 builder.llvm_module = llvm.Module.createWithName(options.root_name.ptr, builder.llvm_context);
412 errdefer builder.llvm_module.dispose();
404413
405414 const llvm_target_triple = try targetTriple(gpa, options.target);
406415 defer gpa.free(llvm_target_triple);
......@@ -414,7 +423,7 @@ pub const Object = struct {
414423 return error.InvalidLlvmTriple;
415424 }
416425
417 llvm_module.setTarget(llvm_target_triple.ptr);
426 builder.llvm_module.setTarget(llvm_target_triple.ptr);
418427 var opt_di_builder: ?*llvm.DIBuilder = null;
419428 errdefer if (opt_di_builder) |di_builder| di_builder.dispose();
420429
......@@ -422,10 +431,10 @@ pub const Object = struct {
422431
423432 if (!options.strip) {
424433 switch (options.target.ofmt) {
425 .coff => llvm_module.addModuleCodeViewFlag(),
426 else => llvm_module.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"),
434 .coff => builder.llvm_module.addModuleCodeViewFlag(),
435 else => builder.llvm_module.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"),
427436 }
428 const di_builder = llvm_module.createDIBuilder(true);
437 const di_builder = builder.llvm_module.createDIBuilder(true);
429438 opt_di_builder = di_builder;
430439
431440 // Don't use the version string here; LLVM misparses it when it
......@@ -508,24 +517,35 @@ pub const Object = struct {
508517 const target_data = target_machine.createTargetDataLayout();
509518 errdefer target_data.dispose();
510519
511 llvm_module.setModuleDataLayout(target_data);
520 builder.llvm_module.setModuleDataLayout(target_data);
512521
513 if (options.pic) llvm_module.setModulePICLevel();
514 if (options.pie) llvm_module.setModulePIELevel();
515 if (code_model != .Default) llvm_module.setModuleCodeModel(code_model);
522 if (options.pic) builder.llvm_module.setModulePICLevel();
523 if (options.pie) builder.llvm_module.setModulePIELevel();
524 if (code_model != .Default) builder.llvm_module.setModuleCodeModel(code_model);
516525
517526 if (options.opt_bisect_limit >= 0) {
518 context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit));
527 builder.llvm_context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit));
519528 }
520529
530 try builder.init();
531 errdefer builder.deinit();
532 builder.source_filename = try builder.string(options.root_name);
533 builder.data_layout = rep: {
534 const rep = target_data.stringRep();
535 defer llvm.disposeMessage(rep);
536 break :rep try builder.string(std.mem.span(rep));
537 };
538 builder.target_triple = try builder.string(llvm_target_triple);
539
521540 return Object{
522541 .gpa = gpa,
542 .builder = builder,
523543 .module = options.module.?,
524 .llvm_module = llvm_module,
544 .llvm_module = builder.llvm_module,
525545 .di_map = .{},
526546 .di_builder = opt_di_builder,
527547 .di_compile_unit = di_compile_unit,
528 .context = context,
548 .context = builder.llvm_context,
529549 .target_machine = target_machine,
530550 .target_data = target_data,
531551 .target = options.target,
......@@ -553,6 +573,7 @@ pub const Object = struct {
553573 self.named_enum_map.deinit(gpa);
554574 self.type_map.deinit(gpa);
555575 self.extern_collisions.deinit(gpa);
576 self.builder.deinit();
556577 self.* = undefined;
557578 }
558579
......@@ -671,34 +692,36 @@ pub const Object = struct {
671692
672693 // This map has externs with incorrect symbol names.
673694 for (object.extern_collisions.keys()) |decl_index| {
674 const entry = object.decl_map.getEntry(decl_index) orelse continue;
675 const llvm_global = entry.value_ptr.*;
695 const global = object.decl_map.get(decl_index) orelse continue;
696 const llvm_global = global.toLlvm(&object.builder);
676697 // Same logic as below but for externs instead of exports.
677 const decl = mod.declPtr(decl_index);
678 const other_global = object.getLlvmGlobal(mod.intern_pool.stringToSlice(decl.name)) orelse continue;
679 if (other_global == llvm_global) continue;
698 const decl_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(mod.declPtr(decl_index).name)) orelse continue;
699 const other_global = object.builder.getGlobal(decl_name) orelse continue;
700 const other_llvm_global = other_global.toLlvm(&object.builder);
701 if (other_llvm_global == llvm_global) continue;
680702
681 llvm_global.replaceAllUsesWith(other_global);
703 llvm_global.replaceAllUsesWith(other_llvm_global);
682704 deleteLlvmGlobal(llvm_global);
683 entry.value_ptr.* = other_global;
705 object.builder.llvm_globals.items[@intFromEnum(global)] = other_llvm_global;
684706 }
685707 object.extern_collisions.clearRetainingCapacity();
686708
687 const export_keys = mod.decl_exports.keys();
688 for (mod.decl_exports.values(), 0..) |export_list, i| {
689 const decl_index = export_keys[i];
690 const llvm_global = object.decl_map.get(decl_index) orelse continue;
709 for (mod.decl_exports.keys(), mod.decl_exports.values()) |decl_index, export_list| {
710 const global = object.decl_map.get(decl_index) orelse continue;
711 const llvm_global = global.toLlvm(&object.builder);
691712 for (export_list.items) |exp| {
692713 // Detect if the LLVM global has already been created as an extern. In such
693714 // case, we need to replace all uses of it with this exported global.
694 const exp_name = mod.intern_pool.stringToSlice(exp.opts.name);
715 const exp_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(exp.opts.name)) orelse continue;
695716
696 const other_global = object.getLlvmGlobal(exp_name.ptr) orelse continue;
697 if (other_global == llvm_global) continue;
717 const other_global = object.builder.getGlobal(exp_name) orelse continue;
718 const other_llvm_global = other_global.toLlvm(&object.builder);
719 if (other_llvm_global == llvm_global) continue;
698720
699 other_global.replaceAllUsesWith(llvm_global);
700 llvm_global.takeName(other_global);
701 deleteLlvmGlobal(other_global);
721 other_llvm_global.replaceAllUsesWith(llvm_global);
722 try global.takeName(&object.builder, other_global);
723 deleteLlvmGlobal(other_llvm_global);
724 object.builder.llvm_globals.items[@intFromEnum(other_global)] = llvm_global;
702725 // Problem: now we need to replace in the decl_map that
703726 // the extern decl index points to this new global. However we don't
704727 // know the decl index.
......@@ -813,6 +836,12 @@ pub const Object = struct {
813836 emit_asm_msg, emit_bin_msg, emit_llvm_ir_msg, emit_llvm_bc_msg,
814837 });
815838
839 {
840 const writer = std.io.getStdErr().writer();
841 try writer.writeAll("\n" ++ "-" ** 200 ++ "\n\n");
842 try self.builder.dump(writer);
843 }
844
816845 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly.
817846 // So we call the entire pipeline multiple times if this is requested.
818847 var error_message: [*:0]const u8 = undefined;
......@@ -884,7 +913,9 @@ pub const Object = struct {
884913 .err_msg = null,
885914 };
886915
887 const llvm_func = try o.resolveLlvmFunction(decl_index);
916 const function_index = try o.resolveLlvmFunction(decl_index);
917 const function = function_index.ptr(&o.builder);
918 const llvm_func = function.global.toLlvm(&o.builder);
888919
889920 if (func.analysis(ip).is_noinline) {
890921 o.addFnAttr(llvm_func, "noinline");
......@@ -932,6 +963,7 @@ pub const Object = struct {
932963
933964 const builder = o.context.createBuilder();
934965
966 function.body = {};
935967 const entry_block = o.context.appendBasicBlock(llvm_func, "Entry");
936968 builder.positionBuilderAtEnd(entry_block);
937969
......@@ -988,7 +1020,7 @@ pub const Object = struct {
9881020 },
9891021 .byref => {
9901022 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
991 const param_llvm_ty = try o.lowerType(param_ty);
1023 const param_llvm_ty = try o.lowerLlvmType(param_ty);
9921024 const param = llvm_func.getParam(llvm_arg_i);
9931025 const alignment = param_ty.abiAlignment(mod);
9941026
......@@ -1007,7 +1039,7 @@ pub const Object = struct {
10071039 },
10081040 .byref_mut => {
10091041 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
1010 const param_llvm_ty = try o.lowerType(param_ty);
1042 const param_llvm_ty = try o.lowerLlvmType(param_ty);
10111043 const param = llvm_func.getParam(llvm_arg_i);
10121044 const alignment = param_ty.abiAlignment(mod);
10131045
......@@ -1030,7 +1062,7 @@ pub const Object = struct {
10301062 const param = llvm_func.getParam(llvm_arg_i);
10311063 llvm_arg_i += 1;
10321064
1033 const param_llvm_ty = try o.lowerType(param_ty);
1065 const param_llvm_ty = try o.lowerLlvmType(param_ty);
10341066 const abi_size = @as(c_uint, @intCast(param_ty.abiSize(mod)));
10351067 const int_llvm_ty = o.context.intType(abi_size * 8);
10361068 const alignment = @max(
......@@ -1075,7 +1107,7 @@ pub const Object = struct {
10751107 const len_param = llvm_func.getParam(llvm_arg_i);
10761108 llvm_arg_i += 1;
10771109
1078 const slice_llvm_ty = try o.lowerType(param_ty);
1110 const slice_llvm_ty = try o.lowerLlvmType(param_ty);
10791111 const partial = builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr_param, 0, "");
10801112 const aggregate = builder.buildInsertValue(partial, len_param, 1, "");
10811113 try args.append(aggregate);
......@@ -1084,7 +1116,7 @@ pub const Object = struct {
10841116 assert(!it.byval_attr);
10851117 const field_types = it.llvm_types_buffer[0..it.llvm_types_len];
10861118 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
1087 const param_llvm_ty = try o.lowerType(param_ty);
1119 const param_llvm_ty = try o.lowerLlvmType(param_ty);
10881120 const param_alignment = param_ty.abiAlignment(mod);
10891121 const arg_ptr = buildAllocaInner(o.context, builder, llvm_func, false, param_llvm_ty, param_alignment, target);
10901122 const llvm_ty = o.context.structType(field_types.ptr, @as(c_uint, @intCast(field_types.len)), .False);
......@@ -1115,7 +1147,7 @@ pub const Object = struct {
11151147 },
11161148 .float_array => {
11171149 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
1118 const param_llvm_ty = try o.lowerType(param_ty);
1150 const param_llvm_ty = try o.lowerLlvmType(param_ty);
11191151 const param = llvm_func.getParam(llvm_arg_i);
11201152 llvm_arg_i += 1;
11211153
......@@ -1133,7 +1165,7 @@ pub const Object = struct {
11331165 },
11341166 .i32_array, .i64_array => {
11351167 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
1136 const param_llvm_ty = try o.lowerType(param_ty);
1168 const param_llvm_ty = try o.lowerLlvmType(param_ty);
11371169 const param = llvm_func.getParam(llvm_arg_i);
11381170 llvm_arg_i += 1;
11391171
......@@ -1243,14 +1275,6 @@ pub const Object = struct {
12431275 try self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index));
12441276 }
12451277
1246 /// TODO replace this with a call to `Module::getNamedValue`. This will require adding
1247 /// a new wrapper in zig_llvm.h/zig_llvm.cpp.
1248 fn getLlvmGlobal(o: Object, name: [*:0]const u8) ?*llvm.Value {
1249 if (o.llvm_module.getNamedFunction(name)) |x| return x;
1250 if (o.llvm_module.getNamedGlobal(name)) |x| return x;
1251 return null;
1252 }
1253
12541278 pub fn updateDeclExports(
12551279 self: *Object,
12561280 mod: *Module,
......@@ -1260,45 +1284,49 @@ pub const Object = struct {
12601284 const gpa = mod.gpa;
12611285 // If the module does not already have the function, we ignore this function call
12621286 // because we call `updateDeclExports` at the end of `updateFunc` and `updateDecl`.
1263 const llvm_global = self.decl_map.get(decl_index) orelse return;
1287 const global_index = self.decl_map.get(decl_index) orelse return;
1288 const llvm_global = global_index.toLlvm(&self.builder);
12641289 const decl = mod.declPtr(decl_index);
12651290 if (decl.isExtern(mod)) {
1266 var free_decl_name = false;
12671291 const decl_name = decl_name: {
12681292 const decl_name = mod.intern_pool.stringToSlice(decl.name);
12691293
12701294 if (mod.getTarget().isWasm() and try decl.isFunction(mod)) {
12711295 if (mod.intern_pool.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
12721296 if (!std.mem.eql(u8, lib_name, "c")) {
1273 free_decl_name = true;
1274 break :decl_name try std.fmt.allocPrintZ(gpa, "{s}|{s}", .{
1275 decl_name, lib_name,
1276 });
1297 break :decl_name try self.builder.fmt("{s}|{s}", .{ decl_name, lib_name });
12771298 }
12781299 }
12791300 }
12801301
1281 break :decl_name decl_name;
1302 break :decl_name try self.builder.string(decl_name);
12821303 };
1283 defer if (free_decl_name) gpa.free(decl_name);
12841304
1285 llvm_global.setValueName(decl_name);
1286 if (self.getLlvmGlobal(decl_name)) |other_global| {
1287 if (other_global != llvm_global) {
1305 if (self.builder.getGlobal(decl_name)) |other_global| {
1306 if (other_global.toLlvm(&self.builder) != llvm_global) {
12881307 try self.extern_collisions.put(gpa, decl_index, {});
12891308 }
12901309 }
1310
1311 try global_index.rename(&self.builder, decl_name);
1312 const decl_name_slice = decl_name.toSlice(&self.builder).?;
1313 const global = global_index.ptr(&self.builder);
1314 global.unnamed_addr = .none;
12911315 llvm_global.setUnnamedAddr(.False);
1316 global.linkage = .external;
12921317 llvm_global.setLinkage(.External);
1293 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
1318 if (mod.wantDllExports()) {
1319 global.dll_storage_class = .default;
1320 llvm_global.setDLLStorageClass(.Default);
1321 }
12941322 if (self.di_map.get(decl)) |di_node| {
12951323 if (try decl.isFunction(mod)) {
12961324 const di_func = @as(*llvm.DISubprogram, @ptrCast(di_node));
1297 const linkage_name = llvm.MDString.get(self.context, decl_name.ptr, decl_name.len);
1325 const linkage_name = llvm.MDString.get(self.context, decl_name_slice.ptr, decl_name_slice.len);
12981326 di_func.replaceLinkageName(linkage_name);
12991327 } else {
13001328 const di_global = @as(*llvm.DIGlobalVariable, @ptrCast(di_node));
1301 const linkage_name = llvm.MDString.get(self.context, decl_name.ptr, decl_name.len);
1329 const linkage_name = llvm.MDString.get(self.context, decl_name_slice.ptr, decl_name_slice.len);
13021330 di_global.replaceLinkageName(linkage_name);
13031331 }
13041332 }
......@@ -1313,18 +1341,19 @@ pub const Object = struct {
13131341 }
13141342 }
13151343 } else if (exports.len != 0) {
1316 const exp_name = mod.intern_pool.stringToSlice(exports[0].opts.name);
1317 llvm_global.setValueName2(exp_name.ptr, exp_name.len);
1344 const exp_name = try self.builder.string(mod.intern_pool.stringToSlice(exports[0].opts.name));
1345 try global_index.rename(&self.builder, exp_name);
13181346 llvm_global.setUnnamedAddr(.False);
13191347 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.DLLExport);
13201348 if (self.di_map.get(decl)) |di_node| {
1349 const exp_name_slice = exp_name.toSlice(&self.builder).?;
13211350 if (try decl.isFunction(mod)) {
13221351 const di_func = @as(*llvm.DISubprogram, @ptrCast(di_node));
1323 const linkage_name = llvm.MDString.get(self.context, exp_name.ptr, exp_name.len);
1352 const linkage_name = llvm.MDString.get(self.context, exp_name_slice.ptr, exp_name_slice.len);
13241353 di_func.replaceLinkageName(linkage_name);
13251354 } else {
13261355 const di_global = @as(*llvm.DIGlobalVariable, @ptrCast(di_node));
1327 const linkage_name = llvm.MDString.get(self.context, exp_name.ptr, exp_name.len);
1356 const linkage_name = llvm.MDString.get(self.context, exp_name_slice.ptr, exp_name_slice.len);
13281357 di_global.replaceLinkageName(linkage_name);
13291358 }
13301359 }
......@@ -1369,8 +1398,8 @@ pub const Object = struct {
13691398 }
13701399 }
13711400 } else {
1372 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1373 llvm_global.setValueName2(fqn.ptr, fqn.len);
1401 const fqn = try self.builder.string(mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)));
1402 try global_index.rename(&self.builder, fqn);
13741403 llvm_global.setLinkage(.Internal);
13751404 if (mod.wantDllExports()) llvm_global.setDLLStorageClass(.Default);
13761405 llvm_global.setUnnamedAddr(.True);
......@@ -1386,8 +1415,8 @@ pub const Object = struct {
13861415 }
13871416
13881417 pub fn freeDecl(self: *Object, decl_index: Module.Decl.Index) void {
1389 const llvm_value = self.decl_map.get(decl_index) orelse return;
1390 llvm_value.deleteGlobal();
1418 const global = self.decl_map.get(decl_index) orelse return;
1419 global.toLlvm(&self.builder).deleteGlobal();
13911420 }
13921421
13931422 fn getDIFile(o: *Object, gpa: Allocator, file: *const Module.File) !*llvm.DIFile {
......@@ -2459,27 +2488,34 @@ pub const Object = struct {
24592488 /// If the llvm function does not exist, create it.
24602489 /// Note that this can be called before the function's semantic analysis has
24612490 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.
2462 fn resolveLlvmFunction(o: *Object, decl_index: Module.Decl.Index) !*llvm.Value {
2491 fn resolveLlvmFunction(o: *Object, decl_index: Module.Decl.Index) !Builder.Function.Index {
24632492 const mod = o.module;
24642493 const gpa = o.gpa;
24652494 const decl = mod.declPtr(decl_index);
24662495 const zig_fn_type = decl.ty;
24672496 const gop = try o.decl_map.getOrPut(gpa, decl_index);
2468 if (gop.found_existing) return gop.value_ptr.*;
2497 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function;
24692498
24702499 assert(decl.has_tv);
24712500 const fn_info = mod.typeToFunc(zig_fn_type).?;
24722501 const target = mod.getTarget();
24732502 const sret = firstParamSRet(fn_info, mod);
24742503
2475 const fn_type = try o.lowerType(zig_fn_type);
2504 const fn_type = try o.lowerLlvmType(zig_fn_type);
24762505
2477 const fqn = try decl.getFullyQualifiedName(mod);
24782506 const ip = &mod.intern_pool;
2507 const fqn = try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(mod)));
24792508
24802509 const llvm_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
2481 const llvm_fn = o.llvm_module.addFunctionInAddressSpace(ip.stringToSlice(fqn), fn_type, llvm_addrspace);
2482 gop.value_ptr.* = llvm_fn;
2510 const llvm_fn = o.llvm_module.addFunctionInAddressSpace(fqn.toSlice(&o.builder).?, fn_type, llvm_addrspace);
2511
2512 var global = Builder.Global{
2513 .type = .void,
2514 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
2515 };
2516 var function = Builder.Function{
2517 .global = @enumFromInt(o.builder.globals.count()),
2518 };
24832519
24842520 const is_extern = decl.isExtern(mod);
24852521 if (!is_extern) {
......@@ -2500,7 +2536,7 @@ pub const Object = struct {
25002536 o.addArgAttr(llvm_fn, 0, "nonnull"); // Sret pointers must not be address 0
25012537 o.addArgAttr(llvm_fn, 0, "noalias");
25022538
2503 const raw_llvm_ret_ty = try o.lowerType(fn_info.return_type.toType());
2539 const raw_llvm_ret_ty = try o.lowerLlvmType(fn_info.return_type.toType());
25042540 llvm_fn.addSretAttr(raw_llvm_ret_ty);
25052541 }
25062542
......@@ -2554,7 +2590,7 @@ pub const Object = struct {
25542590 },
25552591 .byref => {
25562592 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1];
2557 const param_llvm_ty = try o.lowerType(param_ty.toType());
2593 const param_llvm_ty = try o.lowerLlvmType(param_ty.toType());
25582594 const alignment = param_ty.toType().abiAlignment(mod);
25592595 o.addByRefParamAttrs(llvm_fn, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
25602596 },
......@@ -2576,7 +2612,10 @@ pub const Object = struct {
25762612 };
25772613 }
25782614
2579 return llvm_fn;
2615 try o.builder.llvm_globals.append(o.gpa, llvm_fn);
2616 gop.value_ptr.* = try o.builder.addGlobal(fqn, global);
2617 try o.builder.functions.append(o.gpa, function);
2618 return global.kind.function;
25802619 }
25812620
25822621 fn addCommonFnAttributes(o: *Object, llvm_fn: *llvm.Value) void {
......@@ -2622,60 +2661,89 @@ pub const Object = struct {
26222661 }
26232662 }
26242663
2625 fn resolveGlobalDecl(o: *Object, decl_index: Module.Decl.Index) Error!*llvm.Value {
2664 fn resolveGlobalDecl(o: *Object, decl_index: Module.Decl.Index) Error!Builder.Object.Index {
26262665 const gop = try o.decl_map.getOrPut(o.gpa, decl_index);
2627 if (gop.found_existing) return gop.value_ptr.*;
2666 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.object;
26282667 errdefer assert(o.decl_map.remove(decl_index));
26292668
26302669 const mod = o.module;
26312670 const decl = mod.declPtr(decl_index);
2632 const fqn = try decl.getFullyQualifiedName(mod);
2671 const fqn = try o.builder.string(mod.intern_pool.stringToSlice(
2672 try decl.getFullyQualifiedName(mod),
2673 ));
26332674
26342675 const target = mod.getTarget();
26352676
2636 const llvm_type = try o.lowerType(decl.ty);
2677 const llvm_type = try o.lowerLlvmType(decl.ty);
26372678 const llvm_actual_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
26382679
2680 var global = Builder.Global{
2681 .type = .void,
2682 .kind = .{ .object = @enumFromInt(o.builder.objects.items.len) },
2683 };
2684 var object = Builder.Object{
2685 .global = @enumFromInt(o.builder.globals.count()),
2686 };
2687
2688 const is_extern = decl.isExtern(mod);
2689 const name = if (is_extern)
2690 try o.builder.string(mod.intern_pool.stringToSlice(decl.name))
2691 else
2692 fqn;
26392693 const llvm_global = o.llvm_module.addGlobalInAddressSpace(
26402694 llvm_type,
2641 mod.intern_pool.stringToSlice(fqn),
2695 fqn.toSlice(&o.builder).?,
26422696 llvm_actual_addrspace,
26432697 );
2644 gop.value_ptr.* = llvm_global;
26452698
26462699 // This is needed for declarations created by `@extern`.
2647 if (decl.isExtern(mod)) {
2648 llvm_global.setValueName(mod.intern_pool.stringToSlice(decl.name));
2700 if (is_extern) {
2701 global.unnamed_addr = .none;
26492702 llvm_global.setUnnamedAddr(.False);
2703 global.linkage = .external;
26502704 llvm_global.setLinkage(.External);
26512705 if (decl.val.getVariable(mod)) |variable| {
26522706 const single_threaded = mod.comp.bin_file.options.single_threaded;
26532707 if (variable.is_threadlocal and !single_threaded) {
2708 object.thread_local = .generaldynamic;
26542709 llvm_global.setThreadLocalMode(.GeneralDynamicTLSModel);
26552710 } else {
2711 object.thread_local = .none;
26562712 llvm_global.setThreadLocalMode(.NotThreadLocal);
26572713 }
2658 if (variable.is_weak_linkage) llvm_global.setLinkage(.ExternalWeak);
2714 if (variable.is_weak_linkage) {
2715 global.linkage = .extern_weak;
2716 llvm_global.setLinkage(.ExternalWeak);
2717 }
26592718 }
26602719 } else {
2720 global.linkage = .internal;
26612721 llvm_global.setLinkage(.Internal);
2722 global.unnamed_addr = .unnamed_addr;
26622723 llvm_global.setUnnamedAddr(.True);
26632724 }
26642725
2665 return llvm_global;
2726 try o.builder.llvm_globals.append(o.gpa, llvm_global);
2727 gop.value_ptr.* = try o.builder.addGlobal(name, global);
2728 try o.builder.objects.append(o.gpa, object);
2729 return global.kind.object;
26662730 }
26672731
26682732 fn isUnnamedType(o: *Object, ty: Type, val: *llvm.Value) bool {
2669 // Once `lowerType` succeeds, successive calls to it with the same Zig type
2670 // are guaranteed to succeed. So if a call to `lowerType` fails here it means
2733 // Once `lowerLlvmType` succeeds, successive calls to it with the same Zig type
2734 // are guaranteed to succeed. So if a call to `lowerLlvmType` fails here it means
26712735 // it is the first time lowering the type, which means the value can't possible
26722736 // have that type.
2673 const llvm_ty = o.lowerType(ty) catch return true;
2737 const llvm_ty = o.lowerLlvmType(ty) catch return true;
26742738 return val.typeOf() != llvm_ty;
26752739 }
26762740
2677 fn lowerType(o: *Object, t: Type) Allocator.Error!*llvm.Type {
2678 const llvm_ty = try lowerTypeInner(o, t);
2741 fn lowerLlvmType(o: *Object, t: Type) Allocator.Error!*llvm.Type {
2742 const ty = try o.lowerType(t);
2743 const llvm_ty = if (ty != .none)
2744 o.builder.llvm_types.items[@intFromEnum(ty)]
2745 else
2746 try o.lowerLlvmTypeInner(t);
26792747 const mod = o.module;
26802748 if (std.debug.runtime_safety and false) check: {
26812749 if (t.zigTypeTag(mod) == .Opaque) break :check;
......@@ -2693,7 +2761,7 @@ pub const Object = struct {
26932761 return llvm_ty;
26942762 }
26952763
2696 fn lowerTypeInner(o: *Object, t: Type) Allocator.Error!*llvm.Type {
2764 fn lowerLlvmTypeInner(o: *Object, t: Type) Allocator.Error!*llvm.Type {
26972765 const gpa = o.gpa;
26982766 const mod = o.module;
26992767 const target = mod.getTarget();
......@@ -2714,7 +2782,7 @@ pub const Object = struct {
27142782 16 => return if (backendSupportsF16(target)) o.context.halfType() else o.context.intType(16),
27152783 32 => return o.context.floatType(),
27162784 64 => return o.context.doubleType(),
2717 80 => return if (backendSupportsF80(target)) o.context.x86FP80Type() else o.context.intType(80),
2785 80 => return if (backendSupportsF80(target)) o.context.x86_fp80Type() else o.context.intType(80),
27182786 128 => return o.context.fp128Type(),
27192787 else => unreachable,
27202788 },
......@@ -2724,8 +2792,8 @@ pub const Object = struct {
27242792 const ptr_type = t.slicePtrFieldType(mod);
27252793
27262794 const fields: [2]*llvm.Type = .{
2727 try o.lowerType(ptr_type),
2728 try o.lowerType(Type.usize),
2795 try o.lowerLlvmType(ptr_type),
2796 try o.lowerLlvmType(Type.usize),
27292797 };
27302798 return o.context.structType(&fields, fields.len, .False);
27312799 }
......@@ -2749,12 +2817,12 @@ pub const Object = struct {
27492817 .Array => {
27502818 const elem_ty = t.childType(mod);
27512819 if (std.debug.runtime_safety) assert((try elem_ty.onePossibleValue(mod)) == null);
2752 const elem_llvm_ty = try o.lowerType(elem_ty);
2820 const elem_llvm_ty = try o.lowerLlvmType(elem_ty);
27532821 const total_len = t.arrayLen(mod) + @intFromBool(t.sentinel(mod) != null);
27542822 return elem_llvm_ty.arrayType(@as(c_uint, @intCast(total_len)));
27552823 },
27562824 .Vector => {
2757 const elem_type = try o.lowerType(t.childType(mod));
2825 const elem_type = try o.lowerLlvmType(t.childType(mod));
27582826 return elem_type.vectorType(t.vectorLen(mod));
27592827 },
27602828 .Optional => {
......@@ -2762,7 +2830,7 @@ pub const Object = struct {
27622830 if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) {
27632831 return o.context.intType(8);
27642832 }
2765 const payload_llvm_ty = try o.lowerType(child_ty);
2833 const payload_llvm_ty = try o.lowerLlvmType(child_ty);
27662834 if (t.optionalReprIsPayload(mod)) {
27672835 return payload_llvm_ty;
27682836 }
......@@ -2783,10 +2851,10 @@ pub const Object = struct {
27832851 .ErrorUnion => {
27842852 const payload_ty = t.errorUnionPayload(mod);
27852853 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
2786 return try o.lowerType(Type.anyerror);
2854 return try o.lowerLlvmType(Type.anyerror);
27872855 }
2788 const llvm_error_type = try o.lowerType(Type.anyerror);
2789 const llvm_payload_type = try o.lowerType(payload_ty);
2856 const llvm_error_type = try o.lowerLlvmType(Type.anyerror);
2857 const llvm_payload_type = try o.lowerLlvmType(payload_ty);
27902858
27912859 const payload_align = payload_ty.abiAlignment(mod);
27922860 const error_align = Type.anyerror.abiAlignment(mod);
......@@ -2855,7 +2923,7 @@ pub const Object = struct {
28552923 const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len)));
28562924 try llvm_field_types.append(gpa, llvm_array_ty);
28572925 }
2858 const field_llvm_ty = try o.lowerType(field_ty.toType());
2926 const field_llvm_ty = try o.lowerLlvmType(field_ty.toType());
28592927 try llvm_field_types.append(gpa, field_llvm_ty);
28602928
28612929 offset += field_ty.toType().abiSize(mod);
......@@ -2886,14 +2954,17 @@ pub const Object = struct {
28862954
28872955 if (struct_obj.layout == .Packed) {
28882956 assert(struct_obj.haveLayout());
2889 const int_llvm_ty = try o.lowerType(struct_obj.backing_int_ty);
2957 const int_llvm_ty = try o.lowerLlvmType(struct_obj.backing_int_ty);
28902958 gop.value_ptr.* = int_llvm_ty;
28912959 return int_llvm_ty;
28922960 }
28932961
2894 const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(mod));
2962 const name = try o.builder.string(mod.intern_pool.stringToSlice(
2963 try struct_obj.getFullyQualifiedName(mod),
2964 ));
2965 _ = try o.builder.opaqueType(name);
28952966
2896 const llvm_struct_ty = o.context.structCreateNamed(name);
2967 const llvm_struct_ty = o.context.structCreateNamed(name.toSlice(&o.builder).?);
28972968 gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls
28982969
28992970 assert(struct_obj.haveFieldTypes());
......@@ -2924,7 +2995,7 @@ pub const Object = struct {
29242995 const llvm_array_ty = o.context.intType(8).arrayType(@as(c_uint, @intCast(padding_len)));
29252996 try llvm_field_types.append(gpa, llvm_array_ty);
29262997 }
2927 const field_llvm_ty = try o.lowerType(field.ty);
2998 const field_llvm_ty = try o.lowerLlvmType(field.ty);
29282999 try llvm_field_types.append(gpa, field_llvm_ty);
29293000
29303001 offset += field.ty.abiSize(mod);
......@@ -2962,7 +3033,7 @@ pub const Object = struct {
29623033 }
29633034
29643035 if (layout.payload_size == 0) {
2965 const enum_tag_llvm_ty = try o.lowerType(union_obj.tag_ty);
3036 const enum_tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty);
29663037 gop.value_ptr.* = enum_tag_llvm_ty;
29673038 return enum_tag_llvm_ty;
29683039 }
......@@ -2973,7 +3044,7 @@ pub const Object = struct {
29733044 gop.value_ptr.* = llvm_union_ty; // must be done before any recursive calls
29743045
29753046 const aligned_field = union_obj.fields.values()[layout.most_aligned_field];
2976 const llvm_aligned_field_ty = try o.lowerType(aligned_field.ty);
3047 const llvm_aligned_field_ty = try o.lowerLlvmType(aligned_field.ty);
29773048
29783049 const llvm_payload_ty = t: {
29793050 if (layout.most_aligned_field_size == layout.payload_size) {
......@@ -2995,7 +3066,7 @@ pub const Object = struct {
29953066 llvm_union_ty.structSetBody(&llvm_fields, llvm_fields.len, .False);
29963067 return llvm_union_ty;
29973068 }
2998 const enum_tag_llvm_ty = try o.lowerType(union_obj.tag_ty);
3069 const enum_tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty);
29993070
30003071 // Put the tag before or after the payload depending on which one's
30013072 // alignment is greater.
......@@ -3017,7 +3088,7 @@ pub const Object = struct {
30173088 llvm_union_ty.structSetBody(&llvm_fields, llvm_fields_len, .False);
30183089 return llvm_union_ty;
30193090 },
3020 .Fn => return lowerTypeFn(o, t),
3091 .Fn => return lowerLlvmTypeFn(o, t),
30213092 .ComptimeInt => unreachable,
30223093 .ComptimeFloat => unreachable,
30233094 .Type => unreachable,
......@@ -3030,7 +3101,17 @@ pub const Object = struct {
30303101 }
30313102 }
30323103
3033 fn lowerTypeFn(o: *Object, fn_ty: Type) Allocator.Error!*llvm.Type {
3104 fn lowerType(o: *Object, t: Type) Allocator.Error!Builder.Type {
3105 const mod = o.module;
3106 switch (t.toIntern()) {
3107 .void_type, .noreturn_type => return .void,
3108 else => switch (mod.intern_pool.indexToKey(t.toIntern())) {
3109 else => return .none,
3110 },
3111 }
3112 }
3113
3114 fn lowerLlvmTypeFn(o: *Object, fn_ty: Type) Allocator.Error!*llvm.Type {
30343115 const mod = o.module;
30353116 const ip = &mod.intern_pool;
30363117 const fn_info = mod.typeToFunc(fn_ty).?;
......@@ -3047,7 +3128,7 @@ pub const Object = struct {
30473128 mod.comp.bin_file.options.error_return_tracing)
30483129 {
30493130 const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
3050 try llvm_params.append(try o.lowerType(ptr_ty));
3131 try llvm_params.append(try o.lowerLlvmType(ptr_ty));
30513132 }
30523133
30533134 var it = iterateParamTypes(o, fn_info);
......@@ -3055,7 +3136,7 @@ pub const Object = struct {
30553136 .no_bits => continue,
30563137 .byval => {
30573138 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
3058 try llvm_params.append(try o.lowerType(param_ty));
3139 try llvm_params.append(try o.lowerLlvmType(param_ty));
30593140 },
30603141 .byref, .byref_mut => {
30613142 try llvm_params.append(o.context.pointerType(0));
......@@ -3071,8 +3152,8 @@ pub const Object = struct {
30713152 param_ty.optionalChild(mod).slicePtrFieldType(mod)
30723153 else
30733154 param_ty.slicePtrFieldType(mod);
3074 const ptr_llvm_ty = try o.lowerType(ptr_ty);
3075 const len_llvm_ty = try o.lowerType(Type.usize);
3155 const ptr_llvm_ty = try o.lowerLlvmType(ptr_ty);
3156 const len_llvm_ty = try o.lowerLlvmType(Type.usize);
30763157
30773158 try llvm_params.ensureUnusedCapacity(2);
30783159 llvm_params.appendAssumeCapacity(ptr_llvm_ty);
......@@ -3086,7 +3167,7 @@ pub const Object = struct {
30863167 },
30873168 .float_array => |count| {
30883169 const param_ty = fn_info.param_types.get(ip)[it.zig_index - 1].toType();
3089 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?);
3170 const float_ty = try o.lowerLlvmType(aarch64_c_abi.getFloatArrayType(param_ty, mod).?);
30903171 const field_count = @as(c_uint, @intCast(count));
30913172 const arr_ty = float_ty.arrayType(field_count);
30923173 try llvm_params.append(arr_ty);
......@@ -3106,7 +3187,7 @@ pub const Object = struct {
31063187 );
31073188 }
31083189
3109 /// Use this instead of lowerType when you want to handle correctly the case of elem_ty
3190 /// Use this instead of lowerLlvmType when you want to handle correctly the case of elem_ty
31103191 /// being a zero bit type, but it should still be lowered as an i8 in such case.
31113192 /// There are other similar cases handled here as well.
31123193 fn lowerPtrElemTy(o: *Object, elem_ty: Type) Allocator.Error!*llvm.Type {
......@@ -3118,7 +3199,7 @@ pub const Object = struct {
31183199 else => elem_ty.hasRuntimeBitsIgnoreComptime(mod),
31193200 };
31203201 const llvm_elem_ty = if (lower_elem_ty)
3121 try o.lowerType(elem_ty)
3202 try o.lowerLlvmType(elem_ty)
31223203 else
31233204 o.context.intType(8);
31243205
......@@ -3135,7 +3216,7 @@ pub const Object = struct {
31353216 else => {},
31363217 }
31373218 if (tv.val.isUndefDeep(mod)) {
3138 const llvm_type = try o.lowerType(tv.ty);
3219 const llvm_type = try o.lowerLlvmType(tv.ty);
31393220 return llvm_type.getUndef();
31403221 }
31413222
......@@ -3168,7 +3249,7 @@ pub const Object = struct {
31683249 .generic_poison,
31693250 => unreachable, // non-runtime values
31703251 .false, .true => {
3171 const llvm_type = try o.lowerType(tv.ty);
3252 const llvm_type = try o.lowerLlvmType(tv.ty);
31723253 return if (tv.val.toBool()) llvm_type.constAllOnes() else llvm_type.constNull();
31733254 },
31743255 },
......@@ -3180,13 +3261,15 @@ pub const Object = struct {
31803261 const fn_decl_index = extern_func.decl;
31813262 const fn_decl = mod.declPtr(fn_decl_index);
31823263 try mod.markDeclAlive(fn_decl);
3183 return o.resolveLlvmFunction(fn_decl_index);
3264 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3265 return function_index.toLlvm(&o.builder);
31843266 },
31853267 .func => |func| {
31863268 const fn_decl_index = func.owner_decl;
31873269 const fn_decl = mod.declPtr(fn_decl_index);
31883270 try mod.markDeclAlive(fn_decl);
3189 return o.resolveLlvmFunction(fn_decl_index);
3271 const function_index = try o.resolveLlvmFunction(fn_decl_index);
3272 return function_index.toLlvm(&o.builder);
31903273 },
31913274 .int => {
31923275 var bigint_space: Value.BigIntSpace = undefined;
......@@ -3194,7 +3277,7 @@ pub const Object = struct {
31943277 return lowerBigInt(o, tv.ty, bigint);
31953278 },
31963279 .err => |err| {
3197 const llvm_ty = try o.lowerType(Type.anyerror);
3280 const llvm_ty = try o.lowerLlvmType(Type.anyerror);
31983281 const int = try mod.getErrorValue(err.name);
31993282 return llvm_ty.constInt(int, .False);
32003283 },
......@@ -3230,7 +3313,7 @@ pub const Object = struct {
32303313 });
32313314 var fields_buf: [3]*llvm.Value = undefined;
32323315
3233 const llvm_ty = try o.lowerType(tv.ty);
3316 const llvm_ty = try o.lowerLlvmType(tv.ty);
32343317 const llvm_field_count = llvm_ty.countStructElementTypes();
32353318 if (llvm_field_count > 2) {
32363319 assert(llvm_field_count == 3);
......@@ -3274,7 +3357,7 @@ pub const Object = struct {
32743357 return unsigned_val;
32753358 },
32763359 .float => {
3277 const llvm_ty = try o.lowerType(tv.ty);
3360 const llvm_ty = try o.lowerLlvmType(tv.ty);
32783361 switch (tv.ty.floatBits(target)) {
32793362 16 => {
32803363 const repr = @as(u16, @bitCast(tv.val.toFloat(f16, mod)));
......@@ -3359,7 +3442,7 @@ pub const Object = struct {
33593442 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
33603443 return non_null_bit;
33613444 }
3362 const llvm_ty = try o.lowerType(tv.ty);
3445 const llvm_ty = try o.lowerLlvmType(tv.ty);
33633446 if (tv.ty.optionalReprIsPayload(mod)) return switch (opt.val) {
33643447 .none => llvm_ty.constNull(),
33653448 else => |payload| o.lowerValue(.{ .ty = payload_ty, .val = payload.toValue() }),
......@@ -3405,7 +3488,7 @@ pub const Object = struct {
34053488 .True,
34063489 );
34073490 } else {
3408 const llvm_elem_ty = try o.lowerType(elem_ty);
3491 const llvm_elem_ty = try o.lowerLlvmType(elem_ty);
34093492 return llvm_elem_ty.constArray(
34103493 llvm_elems.ptr,
34113494 @as(c_uint, @intCast(llvm_elems.len)),
......@@ -3440,7 +3523,7 @@ pub const Object = struct {
34403523 .True,
34413524 );
34423525 } else {
3443 const llvm_elem_ty = try o.lowerType(elem_ty);
3526 const llvm_elem_ty = try o.lowerLlvmType(elem_ty);
34443527 return llvm_elem_ty.constArray(
34453528 llvm_elems.ptr,
34463529 @as(c_uint, @intCast(llvm_elems.len)),
......@@ -3527,7 +3610,7 @@ pub const Object = struct {
35273610 .False,
35283611 );
35293612 } else {
3530 const llvm_struct_ty = try o.lowerType(tv.ty);
3613 const llvm_struct_ty = try o.lowerLlvmType(tv.ty);
35313614 return llvm_struct_ty.constNamedStruct(
35323615 llvm_fields.items.ptr,
35333616 @as(c_uint, @intCast(llvm_fields.items.len)),
......@@ -3536,7 +3619,7 @@ pub const Object = struct {
35363619 },
35373620 .struct_type => |struct_type| {
35383621 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3539 const llvm_struct_ty = try o.lowerType(tv.ty);
3622 const llvm_struct_ty = try o.lowerLlvmType(tv.ty);
35403623
35413624 if (struct_obj.layout == .Packed) {
35423625 assert(struct_obj.haveLayout());
......@@ -3633,7 +3716,7 @@ pub const Object = struct {
36333716 else => unreachable,
36343717 },
36353718 .un => {
3636 const llvm_union_ty = try o.lowerType(tv.ty);
3719 const llvm_union_ty = try o.lowerLlvmType(tv.ty);
36373720 const tag_and_val: Value.Payload.Union.Data = switch (tv.val.toIntern()) {
36383721 .none => tv.val.castTag(.@"union").?.data,
36393722 else => switch (mod.intern_pool.indexToKey(tv.val.toIntern())) {
......@@ -3803,7 +3886,7 @@ pub const Object = struct {
38033886 llvm_u32.constInt(0, .False),
38043887 llvm_u32.constInt(payload_offset, .False),
38053888 };
3806 const eu_llvm_ty = try o.lowerType(eu_ty);
3889 const eu_llvm_ty = try o.lowerLlvmType(eu_ty);
38073890 return eu_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
38083891 },
38093892 .opt_payload => |opt_ptr| {
......@@ -3824,19 +3907,19 @@ pub const Object = struct {
38243907 llvm_u32.constInt(0, .False),
38253908 llvm_u32.constInt(0, .False),
38263909 };
3827 const opt_llvm_ty = try o.lowerType(opt_ty);
3910 const opt_llvm_ty = try o.lowerLlvmType(opt_ty);
38283911 return opt_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
38293912 },
38303913 .comptime_field => unreachable,
38313914 .elem => |elem_ptr| {
38323915 const parent_llvm_ptr = try o.lowerParentPtr(elem_ptr.base.toValue(), true);
38333916
3834 const llvm_usize = try o.lowerType(Type.usize);
3917 const llvm_usize = try o.lowerLlvmType(Type.usize);
38353918 const indices: [1]*llvm.Value = .{
38363919 llvm_usize.constInt(elem_ptr.index, .False),
38373920 };
38383921 const elem_ty = mod.intern_pool.typeOf(elem_ptr.base).toType().elemType2(mod);
3839 const elem_llvm_ty = try o.lowerType(elem_ty);
3922 const elem_llvm_ty = try o.lowerLlvmType(elem_ty);
38403923 return elem_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
38413924 },
38423925 .field => |field_ptr| {
......@@ -3865,7 +3948,7 @@ pub const Object = struct {
38653948 llvm_u32.constInt(0, .False),
38663949 llvm_u32.constInt(llvm_pl_index, .False),
38673950 };
3868 const parent_llvm_ty = try o.lowerType(parent_ty);
3951 const parent_llvm_ty = try o.lowerLlvmType(parent_ty);
38693952 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
38703953 },
38713954 .Struct => {
......@@ -3888,7 +3971,7 @@ pub const Object = struct {
38883971 return field_addr.constIntToPtr(final_llvm_ty);
38893972 }
38903973
3891 const parent_llvm_ty = try o.lowerType(parent_ty);
3974 const parent_llvm_ty = try o.lowerLlvmType(parent_ty);
38923975 if (llvmField(parent_ty, field_index, mod)) |llvm_field| {
38933976 const indices: [2]*llvm.Value = .{
38943977 llvm_u32.constInt(0, .False),
......@@ -3907,7 +3990,7 @@ pub const Object = struct {
39073990 llvm_u32.constInt(0, .False),
39083991 llvm_u32.constInt(field_index, .False),
39093992 };
3910 const parent_llvm_ty = try o.lowerType(parent_ty);
3993 const parent_llvm_ty = try o.lowerLlvmType(parent_ty);
39113994 return parent_llvm_ty.constInBoundsGEP(parent_llvm_ptr, &indices, indices.len);
39123995 },
39133996 else => unreachable,
......@@ -3949,9 +4032,9 @@ pub const Object = struct {
39494032 try mod.markDeclAlive(decl);
39504033
39514034 const llvm_decl_val = if (is_fn_body)
3952 try o.resolveLlvmFunction(decl_index)
4035 (try o.resolveLlvmFunction(decl_index)).toLlvm(&o.builder)
39534036 else
3954 try o.resolveGlobalDecl(decl_index);
4037 (try o.resolveGlobalDecl(decl_index)).toLlvm(&o.builder);
39554038
39564039 const target = mod.getTarget();
39574040 const llvm_wanted_addrspace = toLlvmAddressSpace(decl.@"addrspace", target);
......@@ -3961,7 +4044,7 @@ pub const Object = struct {
39614044 break :blk llvm_decl_val.constAddrSpaceCast(llvm_decl_wanted_ptr_ty);
39624045 } else llvm_decl_val;
39634046
3964 const llvm_type = try o.lowerType(tv.ty);
4047 const llvm_type = try o.lowerLlvmType(tv.ty);
39654048 if (tv.ty.zigTypeTag(mod) == .Int) {
39664049 return llvm_val.constPtrToInt(llvm_type);
39674050 } else {
......@@ -3976,8 +4059,8 @@ pub const Object = struct {
39764059 // The value cannot be undefined, because we use the `nonnull` annotation
39774060 // for non-optional pointers. We also need to respect the alignment, even though
39784061 // the address will never be dereferenced.
3979 const llvm_usize = try o.lowerType(Type.usize);
3980 const llvm_ptr_ty = try o.lowerType(ptr_ty);
4062 const llvm_usize = try o.lowerLlvmType(Type.usize);
4063 const llvm_ptr_ty = try o.lowerLlvmType(ptr_ty);
39814064 if (ptr_ty.ptrInfo(mod).flags.alignment.toByteUnitsOptional()) |alignment| {
39824065 return llvm_usize.constInt(alignment, .False).constIntToPtr(llvm_ptr_ty);
39834066 }
......@@ -4159,20 +4242,26 @@ pub const DeclGen = struct {
41594242 _ = try o.resolveLlvmFunction(extern_func.decl);
41604243 } else {
41614244 const target = mod.getTarget();
4162 var global = try o.resolveGlobalDecl(decl_index);
4163 global.setAlignment(decl.getAlignment(mod));
4164 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| global.setSection(s);
4245 const object_index = try o.resolveGlobalDecl(decl_index);
4246 const object = object_index.ptr(&o.builder);
4247 const global = object.global.ptr(&o.builder);
4248 var llvm_global = object.global.toLlvm(&o.builder);
4249 global.alignment = Builder.Alignment.fromByteUnits(decl.getAlignment(mod));
4250 llvm_global.setAlignment(decl.getAlignment(mod));
4251 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s| llvm_global.setSection(s);
41654252 assert(decl.has_tv);
41664253 const init_val = if (decl.val.getVariable(mod)) |variable| init_val: {
4254 object.mutability = .global;
41674255 break :init_val variable.init;
41684256 } else init_val: {
4169 global.setGlobalConstant(.True);
4257 object.mutability = .constant;
4258 llvm_global.setGlobalConstant(.True);
41704259 break :init_val decl.val.toIntern();
41714260 };
41724261 if (init_val != .none) {
41734262 const llvm_init = try o.lowerValue(.{ .ty = decl.ty, .val = init_val.toValue() });
4174 if (global.globalGetValueType() == llvm_init.typeOf()) {
4175 global.setInitializer(llvm_init);
4263 if (llvm_global.globalGetValueType() == llvm_init.typeOf()) {
4264 llvm_global.setInitializer(llvm_init);
41764265 } else {
41774266 // LLVM does not allow us to change the type of globals. So we must
41784267 // create a new global with the correct type, copy all its attributes,
......@@ -4193,18 +4282,18 @@ pub const DeclGen = struct {
41934282 "",
41944283 llvm_global_addrspace,
41954284 );
4196 new_global.setLinkage(global.getLinkage());
4197 new_global.setUnnamedAddr(global.getUnnamedAddress());
4198 new_global.setAlignment(global.getAlignment());
4285 new_global.setLinkage(llvm_global.getLinkage());
4286 new_global.setUnnamedAddr(llvm_global.getUnnamedAddress());
4287 new_global.setAlignment(llvm_global.getAlignment());
41994288 if (mod.intern_pool.stringToSliceUnwrap(decl.@"linksection")) |s|
42004289 new_global.setSection(s);
42014290 new_global.setInitializer(llvm_init);
42024291 // TODO: How should this work then the address space of a global changed?
4203 global.replaceAllUsesWith(new_global);
4204 o.decl_map.putAssumeCapacity(decl_index, new_global);
4205 new_global.takeName(global);
4206 global.deleteGlobal();
4207 global = new_global;
4292 llvm_global.replaceAllUsesWith(new_global);
4293 new_global.takeName(llvm_global);
4294 o.builder.llvm_globals.items[@intFromEnum(object.global)] = new_global;
4295 llvm_global.deleteGlobal();
4296 llvm_global = new_global;
42084297 }
42094298 }
42104299
......@@ -4216,7 +4305,7 @@ pub const DeclGen = struct {
42164305 const di_global = dib.createGlobalVariableExpression(
42174306 di_file.toScope(),
42184307 mod.intern_pool.stringToSlice(decl.name),
4219 global.getValueName(),
4308 llvm_global.getValueName(),
42204309 di_file,
42214310 line_number,
42224311 try o.lowerDebugType(decl.ty, .full),
......@@ -4224,7 +4313,7 @@ pub const DeclGen = struct {
42244313 );
42254314
42264315 try o.di_map.put(o.gpa, dg.decl, di_global.getVariable().toNode());
4227 if (!is_internal_linkage or decl.isExtern(mod)) global.attachMetaData(di_global);
4316 if (!is_internal_linkage or decl.isExtern(mod)) llvm_global.attachMetaData(di_global);
42284317 }
42294318 }
42304319 }
......@@ -4618,7 +4707,7 @@ pub const FuncGen = struct {
46184707 defer llvm_args.deinit();
46194708
46204709 const ret_ptr = if (!sret) null else blk: {
4621 const llvm_ret_ty = try o.lowerType(return_type);
4710 const llvm_ret_ty = try o.lowerLlvmType(return_type);
46224711 const ret_ptr = self.buildAlloca(llvm_ret_ty, return_type.abiAlignment(mod));
46234712 try llvm_args.append(ret_ptr);
46244713 break :blk ret_ptr;
......@@ -4637,7 +4726,7 @@ pub const FuncGen = struct {
46374726 const arg = args[it.zig_index - 1];
46384727 const param_ty = self.typeOf(arg);
46394728 const llvm_arg = try self.resolveInst(arg);
4640 const llvm_param_ty = try o.lowerType(param_ty);
4729 const llvm_param_ty = try o.lowerLlvmType(param_ty);
46414730 if (isByRef(param_ty, mod)) {
46424731 const alignment = param_ty.abiAlignment(mod);
46434732 const load_inst = self.builder.buildLoad(llvm_param_ty, llvm_arg, "");
......@@ -4668,7 +4757,7 @@ pub const FuncGen = struct {
46684757 const llvm_arg = try self.resolveInst(arg);
46694758
46704759 const alignment = param_ty.abiAlignment(mod);
4671 const param_llvm_ty = try o.lowerType(param_ty);
4760 const param_llvm_ty = try o.lowerLlvmType(param_ty);
46724761 const arg_ptr = self.buildAlloca(param_llvm_ty, alignment);
46734762 if (isByRef(param_ty, mod)) {
46744763 const load_inst = self.builder.buildLoad(param_llvm_ty, llvm_arg, "");
......@@ -4759,7 +4848,7 @@ pub const FuncGen = struct {
47594848 llvm_arg = store_inst;
47604849 }
47614850
4762 const float_ty = try o.lowerType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?);
4851 const float_ty = try o.lowerLlvmType(aarch64_c_abi.getFloatArrayType(arg_ty, mod).?);
47634852 const array_llvm_ty = float_ty.arrayType(count);
47644853
47654854 const alignment = arg_ty.abiAlignment(mod);
......@@ -4788,7 +4877,7 @@ pub const FuncGen = struct {
47884877 };
47894878
47904879 const call = self.builder.buildCall(
4791 try o.lowerType(zig_fn_ty),
4880 try o.lowerLlvmType(zig_fn_ty),
47924881 llvm_fn,
47934882 llvm_args.items.ptr,
47944883 @as(c_uint, @intCast(llvm_args.items.len)),
......@@ -4813,7 +4902,7 @@ pub const FuncGen = struct {
48134902 .byref => {
48144903 const param_index = it.zig_index - 1;
48154904 const param_ty = fn_info.param_types.get(ip)[param_index].toType();
4816 const param_llvm_ty = try o.lowerType(param_ty);
4905 const param_llvm_ty = try o.lowerLlvmType(param_ty);
48174906 const alignment = param_ty.abiAlignment(mod);
48184907 o.addByRefParamAttrs(call, it.llvm_index - 1, alignment, it.byval_attr, param_llvm_ty);
48194908 },
......@@ -4862,7 +4951,7 @@ pub const FuncGen = struct {
48624951 return null;
48634952 }
48644953
4865 const llvm_ret_ty = try o.lowerType(return_type);
4954 const llvm_ret_ty = try o.lowerLlvmType(return_type);
48664955
48674956 if (ret_ptr) |rp| {
48684957 call.setCallSret(llvm_ret_ty);
......@@ -4939,8 +5028,8 @@ pub const FuncGen = struct {
49395028 const fn_info = mod.typeToFunc(panic_decl.ty).?;
49405029 const panic_global = try o.resolveLlvmFunction(panic_func.owner_decl);
49415030 _ = fg.builder.buildCall(
4942 try o.lowerType(panic_decl.ty),
4943 panic_global,
5031 try o.lowerLlvmType(panic_decl.ty),
5032 panic_global.toLlvm(&o.builder),
49445033 &args,
49455034 args.len,
49465035 toLlvmCallConv(fn_info.cc, target),
......@@ -4968,7 +5057,7 @@ pub const FuncGen = struct {
49685057 // Functions with an empty error set are emitted with an error code
49695058 // return type and return zero so they can be function pointers coerced
49705059 // to functions that return anyerror.
4971 const err_int = try o.lowerType(Type.anyerror);
5060 const err_int = try o.lowerLlvmType(Type.anyerror);
49725061 _ = self.builder.buildRet(err_int.constInt(0, .False));
49735062 } else {
49745063 _ = self.builder.buildRetVoid();
......@@ -5016,7 +5105,7 @@ pub const FuncGen = struct {
50165105 // Functions with an empty error set are emitted with an error code
50175106 // return type and return zero so they can be function pointers coerced
50185107 // to functions that return anyerror.
5019 const err_int = try o.lowerType(Type.anyerror);
5108 const err_int = try o.lowerLlvmType(Type.anyerror);
50205109 _ = self.builder.buildRet(err_int.constInt(0, .False));
50215110 } else {
50225111 _ = self.builder.buildRetVoid();
......@@ -5040,7 +5129,7 @@ pub const FuncGen = struct {
50405129 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
50415130 const list = try self.resolveInst(ty_op.operand);
50425131 const arg_ty = self.air.getRefType(ty_op.ty);
5043 const llvm_arg_ty = try o.lowerType(arg_ty);
5132 const llvm_arg_ty = try o.lowerLlvmType(arg_ty);
50445133
50455134 return self.builder.buildVAArg(list, llvm_arg_ty, "");
50465135 }
......@@ -5050,7 +5139,7 @@ pub const FuncGen = struct {
50505139 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
50515140 const src_list = try self.resolveInst(ty_op.operand);
50525141 const va_list_ty = self.air.getRefType(ty_op.ty);
5053 const llvm_va_list_ty = try o.lowerType(va_list_ty);
5142 const llvm_va_list_ty = try o.lowerLlvmType(va_list_ty);
50545143 const mod = o.module;
50555144
50565145 const result_alignment = va_list_ty.abiAlignment(mod);
......@@ -5098,7 +5187,7 @@ pub const FuncGen = struct {
50985187 const o = self.dg.object;
50995188 const mod = o.module;
51005189 const va_list_ty = self.typeOfIndex(inst);
5101 const llvm_va_list_ty = try o.lowerType(va_list_ty);
5190 const llvm_va_list_ty = try o.lowerLlvmType(va_list_ty);
51025191
51035192 const result_alignment = va_list_ty.abiAlignment(mod);
51045193 const list = self.buildAlloca(llvm_va_list_ty, result_alignment);
......@@ -5177,7 +5266,7 @@ pub const FuncGen = struct {
51775266 // We need to emit instructions to check for equality/inequality
51785267 // of optionals that are not pointers.
51795268 const is_by_ref = isByRef(scalar_ty, mod);
5180 const opt_llvm_ty = try o.lowerType(scalar_ty);
5269 const opt_llvm_ty = try o.lowerLlvmType(scalar_ty);
51815270 const lhs_non_null = self.optIsNonNull(opt_llvm_ty, lhs, is_by_ref);
51825271 const rhs_non_null = self.optIsNonNull(opt_llvm_ty, rhs, is_by_ref);
51835272 const llvm_i2 = self.context.intType(2);
......@@ -5287,7 +5376,7 @@ pub const FuncGen = struct {
52875376 const is_body = inst_ty.zigTypeTag(mod) == .Fn;
52885377 if (!is_body and !inst_ty.hasRuntimeBitsIgnoreComptime(mod)) return null;
52895378
5290 const raw_llvm_ty = try o.lowerType(inst_ty);
5379 const raw_llvm_ty = try o.lowerLlvmType(inst_ty);
52915380
52925381 const llvm_ty = ty: {
52935382 // If the zig tag type is a function, this represents an actual function body; not
......@@ -5392,11 +5481,11 @@ pub const FuncGen = struct {
53925481 const mod = o.module;
53935482 const payload_ty = err_union_ty.errorUnionPayload(mod);
53945483 const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(mod);
5395 const err_union_llvm_ty = try o.lowerType(err_union_ty);
5484 const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty);
53965485
53975486 if (!err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
53985487 const is_err = err: {
5399 const err_set_ty = try o.lowerType(Type.anyerror);
5488 const err_set_ty = try o.lowerLlvmType(Type.anyerror);
54005489 const zero = err_set_ty.constNull();
54015490 if (!payload_has_bits) {
54025491 // TODO add alignment to this load
......@@ -5531,9 +5620,9 @@ pub const FuncGen = struct {
55315620 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
55325621 const operand_ty = self.typeOf(ty_op.operand);
55335622 const array_ty = operand_ty.childType(mod);
5534 const llvm_usize = try o.lowerType(Type.usize);
5623 const llvm_usize = try o.lowerLlvmType(Type.usize);
55355624 const len = llvm_usize.constInt(array_ty.arrayLen(mod), .False);
5536 const slice_llvm_ty = try o.lowerType(self.typeOfIndex(inst));
5625 const slice_llvm_ty = try o.lowerLlvmType(self.typeOfIndex(inst));
55375626 const operand = try self.resolveInst(ty_op.operand);
55385627 if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
55395628 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), operand, 0, "");
......@@ -5542,7 +5631,7 @@ pub const FuncGen = struct {
55425631 const indices: [2]*llvm.Value = .{
55435632 llvm_usize.constNull(), llvm_usize.constNull(),
55445633 };
5545 const array_llvm_ty = try o.lowerType(array_ty);
5634 const array_llvm_ty = try o.lowerLlvmType(array_ty);
55465635 const ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indices, indices.len, "");
55475636 const partial = self.builder.buildInsertValue(slice_llvm_ty.getUndef(), ptr, 0, "");
55485637 return self.builder.buildInsertValue(partial, len, 1, "");
......@@ -5559,7 +5648,7 @@ pub const FuncGen = struct {
55595648
55605649 const dest_ty = self.typeOfIndex(inst);
55615650 const dest_scalar_ty = dest_ty.scalarType(mod);
5562 const dest_llvm_ty = try o.lowerType(dest_ty);
5651 const dest_llvm_ty = try o.lowerLlvmType(dest_ty);
55635652 const target = mod.getTarget();
55645653
55655654 if (intrinsicsAllowed(dest_scalar_ty, target)) {
......@@ -5600,7 +5689,7 @@ pub const FuncGen = struct {
56005689 param_types = [1]*llvm.Type{v2i64};
56015690 }
56025691
5603 const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
5692 const libc_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
56045693 const params = [1]*llvm.Value{extended};
56055694
56065695 return self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, "");
......@@ -5620,7 +5709,7 @@ pub const FuncGen = struct {
56205709
56215710 const dest_ty = self.typeOfIndex(inst);
56225711 const dest_scalar_ty = dest_ty.scalarType(mod);
5623 const dest_llvm_ty = try o.lowerType(dest_ty);
5712 const dest_llvm_ty = try o.lowerLlvmType(dest_ty);
56245713
56255714 if (intrinsicsAllowed(operand_scalar_ty, target)) {
56265715 // TODO set fast math flag
......@@ -5652,9 +5741,9 @@ pub const FuncGen = struct {
56525741 compiler_rt_dest_abbrev,
56535742 }) catch unreachable;
56545743
5655 const operand_llvm_ty = try o.lowerType(operand_ty);
5744 const operand_llvm_ty = try o.lowerLlvmType(operand_ty);
56565745 const param_types = [1]*llvm.Type{operand_llvm_ty};
5657 const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty);
5746 const libc_fn = try self.getLibcFunction(fn_name, &param_types, libc_ret_ty);
56585747 const params = [1]*llvm.Value{operand};
56595748
56605749 var result = self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, "");
......@@ -5762,7 +5851,7 @@ pub const FuncGen = struct {
57625851 const array_ty = self.typeOf(bin_op.lhs);
57635852 const array_llvm_val = try self.resolveInst(bin_op.lhs);
57645853 const rhs = try self.resolveInst(bin_op.rhs);
5765 const array_llvm_ty = try o.lowerType(array_ty);
5854 const array_llvm_ty = try o.lowerLlvmType(array_ty);
57665855 const elem_ty = array_ty.childType(mod);
57675856 if (isByRef(array_ty, mod)) {
57685857 const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs };
......@@ -5773,7 +5862,7 @@ pub const FuncGen = struct {
57735862
57745863 return self.loadByRef(elem_ptr, elem_ty, elem_ty.abiAlignment(mod), false);
57755864 } else {
5776 const elem_llvm_ty = try o.lowerType(elem_ty);
5865 const elem_llvm_ty = try o.lowerLlvmType(elem_ty);
57775866 if (Air.refToIndex(bin_op.lhs)) |lhs_index| {
57785867 if (self.air.instructions.items(.tag)[lhs_index] == .load) {
57795868 const load_data = self.air.instructions.items(.data)[lhs_index];
......@@ -5898,7 +5987,7 @@ pub const FuncGen = struct {
58985987 const containing_int = struct_llvm_val;
58995988 const shift_amt = containing_int.typeOf().constInt(bit_offset, .False);
59005989 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
5901 const elem_llvm_ty = try o.lowerType(field_ty);
5990 const elem_llvm_ty = try o.lowerLlvmType(field_ty);
59025991 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
59035992 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));
59045993 const same_size_int = self.context.intType(elem_bits);
......@@ -5920,7 +6009,7 @@ pub const FuncGen = struct {
59206009 .Union => {
59216010 assert(struct_ty.containerLayout(mod) == .Packed);
59226011 const containing_int = struct_llvm_val;
5923 const elem_llvm_ty = try o.lowerType(field_ty);
6012 const elem_llvm_ty = try o.lowerLlvmType(field_ty);
59246013 if (field_ty.zigTypeTag(mod) == .Float or field_ty.zigTypeTag(mod) == .Vector) {
59256014 const elem_bits = @as(c_uint, @intCast(field_ty.bitSize(mod)));
59266015 const same_size_int = self.context.intType(elem_bits);
......@@ -5942,7 +6031,7 @@ pub const FuncGen = struct {
59426031 .Struct => {
59436032 assert(struct_ty.containerLayout(mod) != .Packed);
59446033 const llvm_field = llvmField(struct_ty, field_index, mod).?;
5945 const struct_llvm_ty = try o.lowerType(struct_ty);
6034 const struct_llvm_ty = try o.lowerLlvmType(struct_ty);
59466035 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field.index, "");
59476036 const field_ptr_ty = try mod.ptrType(.{
59486037 .child = llvm_field.ty.toIntern(),
......@@ -5961,11 +6050,11 @@ pub const FuncGen = struct {
59616050 }
59626051 },
59636052 .Union => {
5964 const union_llvm_ty = try o.lowerType(struct_ty);
6053 const union_llvm_ty = try o.lowerLlvmType(struct_ty);
59656054 const layout = struct_ty.unionGetLayout(mod);
59666055 const payload_index = @intFromBool(layout.tag_align >= layout.payload_align);
59676056 const field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_llvm_val, payload_index, "");
5968 const llvm_field_ty = try o.lowerType(field_ty);
6057 const llvm_field_ty = try o.lowerLlvmType(field_ty);
59696058 if (isByRef(field_ty, mod)) {
59706059 if (canElideLoad(self, body_tail))
59716060 return field_ptr;
......@@ -5991,7 +6080,7 @@ pub const FuncGen = struct {
59916080 const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod);
59926081 const field_offset = parent_ty.structFieldOffset(extra.field_index, mod);
59936082
5994 const res_ty = try o.lowerType(self.air.getRefType(ty_pl.ty));
6083 const res_ty = try o.lowerLlvmType(self.air.getRefType(ty_pl.ty));
59956084 if (field_offset == 0) {
59966085 return field_ptr;
59976086 }
......@@ -6273,7 +6362,7 @@ pub const FuncGen = struct {
62736362 }
62746363 } else {
62756364 const ret_ty = self.typeOfIndex(inst);
6276 llvm_ret_types[llvm_ret_i] = try o.lowerType(ret_ty);
6365 llvm_ret_types[llvm_ret_i] = try o.lowerLlvmType(ret_ty);
62776366 llvm_ret_i += 1;
62786367 }
62796368
......@@ -6316,7 +6405,7 @@ pub const FuncGen = struct {
63166405 llvm_param_types[llvm_param_i] = arg_llvm_value.typeOf();
63176406 } else {
63186407 const alignment = arg_ty.abiAlignment(mod);
6319 const arg_llvm_ty = try o.lowerType(arg_ty);
6408 const arg_llvm_ty = try o.lowerLlvmType(arg_ty);
63206409 const load_inst = self.builder.buildLoad(arg_llvm_ty, arg_llvm_value, "");
63216410 load_inst.setAlignment(alignment);
63226411 llvm_param_values[llvm_param_i] = load_inst;
......@@ -6554,7 +6643,7 @@ pub const FuncGen = struct {
65546643 const operand = try self.resolveInst(un_op);
65556644 const operand_ty = self.typeOf(un_op);
65566645 const optional_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
6557 const optional_llvm_ty = try o.lowerType(optional_ty);
6646 const optional_llvm_ty = try o.lowerLlvmType(optional_ty);
65586647 const payload_ty = optional_ty.optionalChild(mod);
65596648 if (optional_ty.optionalReprIsPayload(mod)) {
65606649 const loaded = if (operand_is_ptr)
......@@ -6563,7 +6652,7 @@ pub const FuncGen = struct {
65636652 operand;
65646653 if (payload_ty.isSlice(mod)) {
65656654 const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");
6566 const ptr_ty = try o.lowerType(payload_ty.slicePtrFieldType(mod));
6655 const ptr_ty = try o.lowerLlvmType(payload_ty.slicePtrFieldType(mod));
65676656 return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");
65686657 }
65696658 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
......@@ -6602,7 +6691,7 @@ pub const FuncGen = struct {
66026691 const operand_ty = self.typeOf(un_op);
66036692 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
66046693 const payload_ty = err_union_ty.errorUnionPayload(mod);
6605 const err_set_ty = try o.lowerType(Type.anyerror);
6694 const err_set_ty = try o.lowerLlvmType(Type.anyerror);
66066695 const zero = err_set_ty.constNull();
66076696
66086697 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
......@@ -6616,7 +6705,7 @@ pub const FuncGen = struct {
66166705
66176706 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
66186707 const loaded = if (operand_is_ptr)
6619 self.builder.buildLoad(try o.lowerType(err_union_ty), operand, "")
6708 self.builder.buildLoad(try o.lowerLlvmType(err_union_ty), operand, "")
66206709 else
66216710 operand;
66226711 return self.builder.buildICmp(op, loaded, zero, "");
......@@ -6625,7 +6714,7 @@ pub const FuncGen = struct {
66256714 const err_field_index = errUnionErrorOffset(payload_ty, mod);
66266715
66276716 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
6628 const err_union_llvm_ty = try o.lowerType(err_union_ty);
6717 const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty);
66296718 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, err_field_index, "");
66306719 const loaded = self.builder.buildLoad(err_set_ty, err_field_ptr, "");
66316720 return self.builder.buildICmp(op, loaded, zero, "");
......@@ -6651,7 +6740,7 @@ pub const FuncGen = struct {
66516740 // The payload and the optional are the same value.
66526741 return operand;
66536742 }
6654 const optional_llvm_ty = try o.lowerType(optional_ty);
6743 const optional_llvm_ty = try o.lowerLlvmType(optional_ty);
66556744 return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, "");
66566745 }
66576746
......@@ -6677,7 +6766,7 @@ pub const FuncGen = struct {
66776766 }
66786767
66796768 // First set the non-null bit.
6680 const optional_llvm_ty = try o.lowerType(optional_ty);
6769 const optional_llvm_ty = try o.lowerLlvmType(optional_ty);
66816770 const non_null_ptr = self.builder.buildStructGEP(optional_llvm_ty, operand, 1, "");
66826771 // TODO set alignment on this store
66836772 _ = self.builder.buildStore(non_null_bit, non_null_ptr);
......@@ -6704,7 +6793,7 @@ pub const FuncGen = struct {
67046793 return operand;
67056794 }
67066795
6707 const opt_llvm_ty = try o.lowerType(optional_ty);
6796 const opt_llvm_ty = try o.lowerLlvmType(optional_ty);
67086797 const can_elide_load = if (isByRef(payload_ty, mod)) self.canElideLoad(body_tail) else false;
67096798 return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load);
67106799 }
......@@ -6728,7 +6817,7 @@ pub const FuncGen = struct {
67286817 return if (operand_is_ptr) operand else null;
67296818 }
67306819 const offset = errUnionPayloadOffset(payload_ty, mod);
6731 const err_union_llvm_ty = try o.lowerType(err_union_ty);
6820 const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty);
67326821 if (operand_is_ptr) {
67336822 return self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
67346823 } else if (isByRef(err_union_ty, mod)) {
......@@ -6758,7 +6847,7 @@ pub const FuncGen = struct {
67586847 const operand_ty = self.typeOf(ty_op.operand);
67596848 const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty;
67606849 if (err_union_ty.errorUnionSet(mod).errorSetIsEmpty(mod)) {
6761 const err_llvm_ty = try o.lowerType(Type.anyerror);
6850 const err_llvm_ty = try o.lowerLlvmType(Type.anyerror);
67626851 if (operand_is_ptr) {
67636852 return operand;
67646853 } else {
......@@ -6766,7 +6855,7 @@ pub const FuncGen = struct {
67666855 }
67676856 }
67686857
6769 const err_set_llvm_ty = try o.lowerType(Type.anyerror);
6858 const err_set_llvm_ty = try o.lowerLlvmType(Type.anyerror);
67706859
67716860 const payload_ty = err_union_ty.errorUnionPayload(mod);
67726861 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -6777,7 +6866,7 @@ pub const FuncGen = struct {
67776866 const offset = errUnionErrorOffset(payload_ty, mod);
67786867
67796868 if (operand_is_ptr or isByRef(err_union_ty, mod)) {
6780 const err_union_llvm_ty = try o.lowerType(err_union_ty);
6869 const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty);
67816870 const err_field_ptr = self.builder.buildStructGEP(err_union_llvm_ty, operand, offset, "");
67826871 return self.builder.buildLoad(err_set_llvm_ty, err_field_ptr, "");
67836872 }
......@@ -6798,7 +6887,7 @@ pub const FuncGen = struct {
67986887 _ = self.builder.buildStore(non_error_val, operand);
67996888 return operand;
68006889 }
6801 const err_union_llvm_ty = try o.lowerType(err_union_ty);
6890 const err_union_llvm_ty = try o.lowerLlvmType(err_union_ty);
68026891 {
68036892 const error_offset = errUnionErrorOffset(payload_ty, mod);
68046893 // First set the non-error value.
......@@ -6834,7 +6923,7 @@ pub const FuncGen = struct {
68346923
68356924 const mod = o.module;
68366925 const llvm_field = llvmField(struct_ty, field_index, mod).?;
6837 const struct_llvm_ty = try o.lowerType(struct_ty);
6926 const struct_llvm_ty = try o.lowerLlvmType(struct_ty);
68386927 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, self.err_ret_trace.?, llvm_field.index, "");
68396928 const field_ptr_ty = try mod.ptrType(.{
68406929 .child = llvm_field.ty.toIntern(),
......@@ -6858,7 +6947,7 @@ pub const FuncGen = struct {
68586947 if (optional_ty.optionalReprIsPayload(mod)) {
68596948 return operand;
68606949 }
6861 const llvm_optional_ty = try o.lowerType(optional_ty);
6950 const llvm_optional_ty = try o.lowerLlvmType(optional_ty);
68626951 if (isByRef(optional_ty, mod)) {
68636952 const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod));
68646953 const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, "");
......@@ -6882,8 +6971,8 @@ pub const FuncGen = struct {
68826971 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
68836972 return operand;
68846973 }
6885 const ok_err_code = (try o.lowerType(Type.anyerror)).constNull();
6886 const err_un_llvm_ty = try o.lowerType(err_un_ty);
6974 const ok_err_code = (try o.lowerLlvmType(Type.anyerror)).constNull();
6975 const err_un_llvm_ty = try o.lowerLlvmType(err_un_ty);
68876976
68886977 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
68896978 const error_offset = errUnionErrorOffset(payload_ty, mod);
......@@ -6912,7 +7001,7 @@ pub const FuncGen = struct {
69127001 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
69137002 return operand;
69147003 }
6915 const err_un_llvm_ty = try o.lowerType(err_un_ty);
7004 const err_un_llvm_ty = try o.lowerLlvmType(err_un_ty);
69167005
69177006 const payload_offset = errUnionPayloadOffset(payload_ty, mod);
69187007 const error_offset = errUnionErrorOffset(payload_ty, mod);
......@@ -6968,7 +7057,7 @@ pub const FuncGen = struct {
69687057 const operand = try self.resolveInst(extra.rhs);
69697058
69707059 const loaded_vector = blk: {
6971 const elem_llvm_ty = try o.lowerType(vector_ptr_ty.childType(mod));
7060 const elem_llvm_ty = try o.lowerLlvmType(vector_ptr_ty.childType(mod));
69727061 const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, "");
69737062 load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod));
69747063 load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod)));
......@@ -7012,7 +7101,7 @@ pub const FuncGen = struct {
70127101 const ptr = try self.resolveInst(bin_op.lhs);
70137102 const len = try self.resolveInst(bin_op.rhs);
70147103 const inst_ty = self.typeOfIndex(inst);
7015 const llvm_slice_ty = try o.lowerType(inst_ty);
7104 const llvm_slice_ty = try o.lowerLlvmType(inst_ty);
70167105
70177106 // In case of slicing a global, the result type looks something like `{ i8*, i64 }`
70187107 // but `ptr` is pointing to the global directly.
......@@ -7056,7 +7145,7 @@ pub const FuncGen = struct {
70567145 true => signed_intrinsic,
70577146 false => unsigned_intrinsic,
70587147 };
7059 const llvm_inst_ty = try o.lowerType(inst_ty);
7148 const llvm_inst_ty = try o.lowerLlvmType(inst_ty);
70607149 const llvm_fn = fg.getIntrinsic(intrinsic_name, &.{llvm_inst_ty});
70617150 const result_struct = fg.builder.buildCall(
70627151 llvm_fn.globalGetValueType(),
......@@ -7229,11 +7318,11 @@ pub const FuncGen = struct {
72297318 return self.buildFloatOp(.floor, inst_ty, 1, .{result});
72307319 }
72317320 if (scalar_ty.isSignedInt(mod)) {
7232 const inst_llvm_ty = try o.lowerType(inst_ty);
7321 const inst_llvm_ty = try o.lowerLlvmType(inst_ty);
72337322 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
72347323 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
72357324 const vec_len = inst_ty.vectorLen(mod);
7236 const scalar_llvm_ty = try o.lowerType(scalar_ty);
7325 const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty);
72377326
72387327 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
72397328 defer self.gpa.free(shifts);
......@@ -7295,7 +7384,7 @@ pub const FuncGen = struct {
72957384 const lhs = try self.resolveInst(bin_op.lhs);
72967385 const rhs = try self.resolveInst(bin_op.rhs);
72977386 const inst_ty = self.typeOfIndex(inst);
7298 const inst_llvm_ty = try o.lowerType(inst_ty);
7387 const inst_llvm_ty = try o.lowerLlvmType(inst_ty);
72997388 const scalar_ty = inst_ty.scalarType(mod);
73007389
73017390 if (scalar_ty.isRuntimeFloat()) {
......@@ -7310,7 +7399,7 @@ pub const FuncGen = struct {
73107399 const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1;
73117400 const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: {
73127401 const vec_len = inst_ty.vectorLen(mod);
7313 const scalar_llvm_ty = try o.lowerType(scalar_ty);
7402 const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty);
73147403
73157404 const shifts = try self.gpa.alloc(*llvm.Value, vec_len);
73167405 defer self.gpa.free(shifts);
......@@ -7408,8 +7497,8 @@ pub const FuncGen = struct {
74087497
74097498 const intrinsic_name = if (scalar_ty.isSignedInt(mod)) signed_intrinsic else unsigned_intrinsic;
74107499
7411 const llvm_lhs_ty = try o.lowerType(lhs_ty);
7412 const llvm_dest_ty = try o.lowerType(dest_ty);
7500 const llvm_lhs_ty = try o.lowerLlvmType(lhs_ty);
7501 const llvm_dest_ty = try o.lowerLlvmType(dest_ty);
74137502
74147503 const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty});
74157504 const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, "");
......@@ -7472,15 +7561,30 @@ pub const FuncGen = struct {
74727561 fn_name: [:0]const u8,
74737562 param_types: []const *llvm.Type,
74747563 return_type: *llvm.Type,
7475 ) *llvm.Value {
7564 ) Allocator.Error!*llvm.Value {
74767565 const o = self.dg.object;
74777566 return o.llvm_module.getNamedFunction(fn_name.ptr) orelse b: {
74787567 const alias = o.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len);
74797568 break :b if (alias) |a| a.getAliasee() else null;
74807569 } orelse b: {
7570 const name = try o.builder.string(fn_name);
7571
74817572 const params_len = @as(c_uint, @intCast(param_types.len));
74827573 const fn_type = llvm.functionType(return_type, param_types.ptr, params_len, .False);
7483 const f = o.llvm_module.addFunction(fn_name, fn_type);
7574 const f = o.llvm_module.addFunction(name.toSlice(&o.builder).?, fn_type);
7575
7576 var global = Builder.Global{
7577 .type = .void,
7578 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
7579 };
7580 var function = Builder.Function{
7581 .global = @enumFromInt(o.builder.globals.count()),
7582 };
7583
7584 try o.builder.llvm_globals.append(self.gpa, f);
7585 _ = try o.builder.addGlobal(name, global);
7586 try o.builder.functions.append(self.gpa, function);
7587
74847588 break :b f;
74857589 };
74867590 }
......@@ -7497,7 +7601,7 @@ pub const FuncGen = struct {
74977601 const mod = o.module;
74987602 const target = o.module.getTarget();
74997603 const scalar_ty = ty.scalarType(mod);
7500 const scalar_llvm_ty = try o.lowerType(scalar_ty);
7604 const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty);
75017605
75027606 if (intrinsicsAllowed(scalar_ty, target)) {
75037607 const llvm_predicate: llvm.RealPredicate = switch (pred) {
......@@ -7528,7 +7632,7 @@ pub const FuncGen = struct {
75287632
75297633 const param_types = [2]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty };
75307634 const llvm_i32 = self.context.intType(32);
7531 const libc_fn = self.getLibcFunction(fn_name, param_types[0..], llvm_i32);
7635 const libc_fn = try self.getLibcFunction(fn_name, param_types[0..], llvm_i32);
75327636
75337637 const zero = llvm_i32.constInt(0, .False);
75347638 const int_pred: llvm.IntPredicate = switch (pred) {
......@@ -7600,8 +7704,8 @@ pub const FuncGen = struct {
76007704 const mod = o.module;
76017705 const target = mod.getTarget();
76027706 const scalar_ty = ty.scalarType(mod);
7603 const llvm_ty = try o.lowerType(ty);
7604 const scalar_llvm_ty = try o.lowerType(scalar_ty);
7707 const llvm_ty = try o.lowerLlvmType(ty);
7708 const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty);
76057709
76067710 const intrinsics_allowed = op != .tan and intrinsicsAllowed(scalar_ty, target);
76077711 var fn_name_buf: [64]u8 = undefined;
......@@ -7672,7 +7776,7 @@ pub const FuncGen = struct {
76727776 .intrinsic => |fn_name| self.getIntrinsic(fn_name, &.{llvm_ty}),
76737777 .libc => |fn_name| b: {
76747778 const param_types = [3]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty, scalar_llvm_ty };
7675 const libc_fn = self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty);
7779 const libc_fn = try self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty);
76767780 if (ty.zigTypeTag(mod) == .Vector) {
76777781 const result = llvm_ty.getUndef();
76787782 return self.buildElementwiseCall(libc_fn, &params, result, ty.vectorLen(mod));
......@@ -7711,10 +7815,10 @@ pub const FuncGen = struct {
77117815 const rhs_scalar_ty = rhs_ty.scalarType(mod);
77127816
77137817 const dest_ty = self.typeOfIndex(inst);
7714 const llvm_dest_ty = try o.lowerType(dest_ty);
7818 const llvm_dest_ty = try o.lowerLlvmType(dest_ty);
77157819
77167820 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
7717 self.builder.buildZExt(rhs, try o.lowerType(lhs_ty), "")
7821 self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_ty), "")
77187822 else
77197823 rhs;
77207824
......@@ -7785,7 +7889,7 @@ pub const FuncGen = struct {
77857889 const rhs_scalar_ty = rhs_ty.scalarType(mod);
77867890
77877891 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
7788 self.builder.buildZExt(rhs, try o.lowerType(lhs_ty), "")
7892 self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_ty), "")
77897893 else
77907894 rhs;
77917895 if (lhs_scalar_ty.isSignedInt(mod)) return self.builder.buildNSWShl(lhs, casted_rhs, "");
......@@ -7806,7 +7910,7 @@ pub const FuncGen = struct {
78067910 const rhs_scalar_ty = rhs_type.scalarType(mod);
78077911
78087912 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
7809 self.builder.buildZExt(rhs, try o.lowerType(lhs_type), "")
7913 self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_type), "")
78107914 else
78117915 rhs;
78127916 return self.builder.buildShl(lhs, casted_rhs, "");
......@@ -7841,7 +7945,7 @@ pub const FuncGen = struct {
78417945 // poison value."
78427946 // However Zig semantics says that saturating shift left can never produce
78437947 // undefined; instead it saturates.
7844 const lhs_scalar_llvm_ty = try o.lowerType(lhs_scalar_ty);
7948 const lhs_scalar_llvm_ty = try o.lowerLlvmType(lhs_scalar_ty);
78457949 const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False);
78467950 const lhs_max = lhs_scalar_llvm_ty.constAllOnes();
78477951 if (rhs_ty.zigTypeTag(mod) == .Vector) {
......@@ -7870,7 +7974,7 @@ pub const FuncGen = struct {
78707974 const rhs_scalar_ty = rhs_ty.scalarType(mod);
78717975
78727976 const casted_rhs = if (rhs_scalar_ty.bitSize(mod) < lhs_scalar_ty.bitSize(mod))
7873 self.builder.buildZExt(rhs, try o.lowerType(lhs_ty), "")
7977 self.builder.buildZExt(rhs, try o.lowerLlvmType(lhs_ty), "")
78747978 else
78757979 rhs;
78767980 const is_signed_int = lhs_scalar_ty.isSignedInt(mod);
......@@ -7896,7 +8000,7 @@ pub const FuncGen = struct {
78968000 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
78978001 const dest_ty = self.typeOfIndex(inst);
78988002 const dest_info = dest_ty.intInfo(mod);
7899 const dest_llvm_ty = try o.lowerType(dest_ty);
8003 const dest_llvm_ty = try o.lowerLlvmType(dest_ty);
79008004 const operand = try self.resolveInst(ty_op.operand);
79018005 const operand_ty = self.typeOf(ty_op.operand);
79028006 const operand_info = operand_ty.intInfo(mod);
......@@ -7917,7 +8021,7 @@ pub const FuncGen = struct {
79178021 const o = self.dg.object;
79188022 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
79198023 const operand = try self.resolveInst(ty_op.operand);
7920 const dest_llvm_ty = try o.lowerType(self.typeOfIndex(inst));
8024 const dest_llvm_ty = try o.lowerLlvmType(self.typeOfIndex(inst));
79218025 return self.builder.buildTrunc(operand, dest_llvm_ty, "");
79228026 }
79238027
......@@ -7933,11 +8037,11 @@ pub const FuncGen = struct {
79338037 const src_bits = operand_ty.floatBits(target);
79348038
79358039 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {
7936 const dest_llvm_ty = try o.lowerType(dest_ty);
8040 const dest_llvm_ty = try o.lowerLlvmType(dest_ty);
79378041 return self.builder.buildFPTrunc(operand, dest_llvm_ty, "");
79388042 } else {
7939 const operand_llvm_ty = try o.lowerType(operand_ty);
7940 const dest_llvm_ty = try o.lowerType(dest_ty);
8043 const operand_llvm_ty = try o.lowerLlvmType(operand_ty);
8044 const dest_llvm_ty = try o.lowerLlvmType(dest_ty);
79418045
79428046 var fn_name_buf: [64]u8 = undefined;
79438047 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__trunc{s}f{s}f2", .{
......@@ -7946,7 +8050,7 @@ pub const FuncGen = struct {
79468050
79478051 const params = [1]*llvm.Value{operand};
79488052 const param_types = [1]*llvm.Type{operand_llvm_ty};
7949 const llvm_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
8053 const llvm_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
79508054
79518055 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, "");
79528056 }
......@@ -7964,11 +8068,11 @@ pub const FuncGen = struct {
79648068 const src_bits = operand_ty.floatBits(target);
79658069
79668070 if (intrinsicsAllowed(dest_ty, target) and intrinsicsAllowed(operand_ty, target)) {
7967 const dest_llvm_ty = try o.lowerType(dest_ty);
8071 const dest_llvm_ty = try o.lowerLlvmType(dest_ty);
79688072 return self.builder.buildFPExt(operand, dest_llvm_ty, "");
79698073 } else {
7970 const operand_llvm_ty = try o.lowerType(operand_ty);
7971 const dest_llvm_ty = try o.lowerType(dest_ty);
8074 const operand_llvm_ty = try o.lowerLlvmType(operand_ty);
8075 const dest_llvm_ty = try o.lowerLlvmType(dest_ty);
79728076
79738077 var fn_name_buf: [64]u8 = undefined;
79748078 const fn_name = std.fmt.bufPrintZ(&fn_name_buf, "__extend{s}f{s}f2", .{
......@@ -7977,7 +8081,7 @@ pub const FuncGen = struct {
79778081
79788082 const params = [1]*llvm.Value{operand};
79798083 const param_types = [1]*llvm.Type{operand_llvm_ty};
7980 const llvm_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
8084 const llvm_fn = try self.getLibcFunction(fn_name, &param_types, dest_llvm_ty);
79818085
79828086 return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .C, .Auto, "");
79838087 }
......@@ -7989,7 +8093,7 @@ pub const FuncGen = struct {
79898093 const operand = try self.resolveInst(un_op);
79908094 const ptr_ty = self.typeOf(un_op);
79918095 const operand_ptr = self.sliceOrArrayPtr(operand, ptr_ty);
7992 const dest_llvm_ty = try o.lowerType(self.typeOfIndex(inst));
8096 const dest_llvm_ty = try o.lowerLlvmType(self.typeOfIndex(inst));
79938097 return self.builder.buildPtrToInt(operand_ptr, dest_llvm_ty, "");
79948098 }
79958099
......@@ -8006,7 +8110,7 @@ pub const FuncGen = struct {
80068110 const mod = o.module;
80078111 const operand_is_ref = isByRef(operand_ty, mod);
80088112 const result_is_ref = isByRef(inst_ty, mod);
8009 const llvm_dest_ty = try o.lowerType(inst_ty);
8113 const llvm_dest_ty = try o.lowerLlvmType(inst_ty);
80108114
80118115 if (operand_is_ref and result_is_ref) {
80128116 // They are both pointers, so just return the same opaque pointer :)
......@@ -8036,7 +8140,7 @@ pub const FuncGen = struct {
80368140 } else {
80378141 // If the ABI size of the element type is not evenly divisible by size in bits;
80388142 // a simple bitcast will not work, and we fall back to extractelement.
8039 const llvm_usize = try o.lowerType(Type.usize);
8143 const llvm_usize = try o.lowerLlvmType(Type.usize);
80408144 const llvm_u32 = self.context.intType(32);
80418145 const zero = llvm_usize.constNull();
80428146 const vector_len = operand_ty.arrayLen(mod);
......@@ -8053,7 +8157,7 @@ pub const FuncGen = struct {
80538157 return array_ptr;
80548158 } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) {
80558159 const elem_ty = operand_ty.childType(mod);
8056 const llvm_vector_ty = try o.lowerType(inst_ty);
8160 const llvm_vector_ty = try o.lowerLlvmType(inst_ty);
80578161 if (!operand_is_ref) {
80588162 return self.dg.todo("implement bitcast non-ref array to vector", .{});
80598163 }
......@@ -8068,9 +8172,9 @@ pub const FuncGen = struct {
80688172 } else {
80698173 // If the ABI size of the element type is not evenly divisible by size in bits;
80708174 // a simple bitcast will not work, and we fall back to extractelement.
8071 const array_llvm_ty = try o.lowerType(operand_ty);
8072 const elem_llvm_ty = try o.lowerType(elem_ty);
8073 const llvm_usize = try o.lowerType(Type.usize);
8175 const array_llvm_ty = try o.lowerLlvmType(operand_ty);
8176 const elem_llvm_ty = try o.lowerLlvmType(elem_ty);
8177 const llvm_usize = try o.lowerLlvmType(Type.usize);
80748178 const llvm_u32 = self.context.intType(32);
80758179 const zero = llvm_usize.constNull();
80768180 const vector_len = operand_ty.arrayLen(mod);
......@@ -8179,7 +8283,7 @@ pub const FuncGen = struct {
81798283 if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod))
81808284 return o.lowerPtrToVoid(ptr_ty);
81818285
8182 const pointee_llvm_ty = try o.lowerType(pointee_type);
8286 const pointee_llvm_ty = try o.lowerLlvmType(pointee_type);
81838287 const alignment = ptr_ty.ptrAlignment(mod);
81848288 return self.buildAlloca(pointee_llvm_ty, alignment);
81858289 }
......@@ -8191,7 +8295,7 @@ pub const FuncGen = struct {
81918295 const ret_ty = ptr_ty.childType(mod);
81928296 if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return o.lowerPtrToVoid(ptr_ty);
81938297 if (self.ret_ptr) |ret_ptr| return ret_ptr;
8194 const ret_llvm_ty = try o.lowerType(ret_ty);
8298 const ret_llvm_ty = try o.lowerLlvmType(ret_ty);
81958299 return self.buildAlloca(ret_llvm_ty, ptr_ty.ptrAlignment(mod));
81968300 }
81978301
......@@ -8223,7 +8327,7 @@ pub const FuncGen = struct {
82238327 else
82248328 u8_llvm_ty.getUndef();
82258329 const operand_size = operand_ty.abiSize(mod);
8226 const usize_llvm_ty = try o.lowerType(Type.usize);
8330 const usize_llvm_ty = try o.lowerLlvmType(Type.usize);
82278331 const len = usize_llvm_ty.constInt(operand_size, .False);
82288332 const dest_ptr_align = ptr_ty.ptrAlignment(mod);
82298333 _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod));
......@@ -8296,7 +8400,7 @@ pub const FuncGen = struct {
82968400 _ = inst;
82978401 const o = self.dg.object;
82988402 const mod = o.module;
8299 const llvm_usize = try o.lowerType(Type.usize);
8403 const llvm_usize = try o.lowerLlvmType(Type.usize);
83008404 const target = mod.getTarget();
83018405 if (!target_util.supportsReturnAddress(target)) {
83028406 // https://github.com/ziglang/zig/issues/11946
......@@ -8324,7 +8428,7 @@ pub const FuncGen = struct {
83248428
83258429 const params = [_]*llvm.Value{llvm_i32.constNull()};
83268430 const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, "");
8327 const llvm_usize = try o.lowerType(Type.usize);
8431 const llvm_usize = try o.lowerLlvmType(Type.usize);
83288432 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
83298433 }
83308434
......@@ -8370,7 +8474,7 @@ pub const FuncGen = struct {
83708474
83718475 var payload = self.builder.buildExtractValue(result, 0, "");
83728476 if (opt_abi_ty != null) {
8373 payload = self.builder.buildTrunc(payload, try o.lowerType(operand_ty), "");
8477 payload = self.builder.buildTrunc(payload, try o.lowerLlvmType(operand_ty), "");
83748478 }
83758479 const success_bit = self.builder.buildExtractValue(result, 1, "");
83768480
......@@ -8415,7 +8519,7 @@ pub const FuncGen = struct {
84158519 ordering,
84168520 single_threaded,
84178521 );
8418 const operand_llvm_ty = try o.lowerType(operand_ty);
8522 const operand_llvm_ty = try o.lowerLlvmType(operand_ty);
84198523 if (is_float) {
84208524 return self.builder.buildBitCast(uncasted_result, operand_llvm_ty, "");
84218525 } else {
......@@ -8428,7 +8532,7 @@ pub const FuncGen = struct {
84288532 }
84298533
84308534 // It's a pointer but we need to treat it as an int.
8431 const usize_llvm_ty = try o.lowerType(Type.usize);
8535 const usize_llvm_ty = try o.lowerLlvmType(Type.usize);
84328536 const casted_operand = self.builder.buildPtrToInt(operand, usize_llvm_ty, "");
84338537 const uncasted_result = self.builder.buildAtomicRmw(
84348538 op,
......@@ -8437,7 +8541,7 @@ pub const FuncGen = struct {
84378541 ordering,
84388542 single_threaded,
84398543 );
8440 const operand_llvm_ty = try o.lowerType(operand_ty);
8544 const operand_llvm_ty = try o.lowerLlvmType(operand_ty);
84418545 return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, "");
84428546 }
84438547
......@@ -8456,7 +8560,7 @@ pub const FuncGen = struct {
84568560 const ptr_alignment = @as(u32, @intCast(ptr_info.flags.alignment.toByteUnitsOptional() orelse
84578561 ptr_info.child.toType().abiAlignment(mod)));
84588562 const ptr_volatile = llvm.Bool.fromBool(ptr_info.flags.is_volatile);
8459 const elem_llvm_ty = try o.lowerType(elem_ty);
8563 const elem_llvm_ty = try o.lowerLlvmType(elem_ty);
84608564
84618565 if (opt_abi_llvm_ty) |abi_llvm_ty| {
84628566 // operand needs widening and truncating
......@@ -8606,7 +8710,7 @@ pub const FuncGen = struct {
86068710 .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False),
86078711 .Many, .C => unreachable,
86088712 };
8609 const elem_llvm_ty = try o.lowerType(elem_ty);
8713 const elem_llvm_ty = try o.lowerLlvmType(elem_ty);
86108714 const len_gep = [_]*llvm.Value{len};
86118715 const end_ptr = self.builder.buildInBoundsGEP(elem_llvm_ty, dest_ptr, &len_gep, len_gep.len, "");
86128716 _ = self.builder.buildBr(loop_block);
......@@ -8731,7 +8835,7 @@ pub const FuncGen = struct {
87318835 _ = self.builder.buildStore(new_tag, union_ptr);
87328836 return null;
87338837 }
8734 const un_llvm_ty = try o.lowerType(un_ty);
8838 const un_llvm_ty = try o.lowerLlvmType(un_ty);
87358839 const tag_index = @intFromBool(layout.tag_align < layout.payload_align);
87368840 const tag_field_ptr = self.builder.buildStructGEP(un_llvm_ty, union_ptr, tag_index, "");
87378841 // TODO alignment on this store
......@@ -8748,7 +8852,7 @@ pub const FuncGen = struct {
87488852 if (layout.tag_size == 0) return null;
87498853 const union_handle = try self.resolveInst(ty_op.operand);
87508854 if (isByRef(un_ty, mod)) {
8751 const llvm_un_ty = try o.lowerType(un_ty);
8855 const llvm_un_ty = try o.lowerLlvmType(un_ty);
87528856 if (layout.payload_size == 0) {
87538857 return self.builder.buildLoad(llvm_un_ty, union_handle, "");
87548858 }
......@@ -8790,13 +8894,13 @@ pub const FuncGen = struct {
87908894 const operand = try self.resolveInst(ty_op.operand);
87918895
87928896 const llvm_i1 = self.context.intType(1);
8793 const operand_llvm_ty = try o.lowerType(operand_ty);
8897 const operand_llvm_ty = try o.lowerLlvmType(operand_ty);
87948898 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
87958899
87968900 const params = [_]*llvm.Value{ operand, llvm_i1.constNull() };
87978901 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
87988902 const result_ty = self.typeOfIndex(inst);
8799 const result_llvm_ty = try o.lowerType(result_ty);
8903 const result_llvm_ty = try o.lowerLlvmType(result_ty);
88008904
88018905 const bits = operand_ty.intInfo(mod).bits;
88028906 const result_bits = result_ty.intInfo(mod).bits;
......@@ -8817,12 +8921,12 @@ pub const FuncGen = struct {
88178921 const operand = try self.resolveInst(ty_op.operand);
88188922
88198923 const params = [_]*llvm.Value{operand};
8820 const operand_llvm_ty = try o.lowerType(operand_ty);
8924 const operand_llvm_ty = try o.lowerLlvmType(operand_ty);
88218925 const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty});
88228926
88238927 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
88248928 const result_ty = self.typeOfIndex(inst);
8825 const result_llvm_ty = try o.lowerType(result_ty);
8929 const result_llvm_ty = try o.lowerLlvmType(result_ty);
88268930
88278931 const bits = operand_ty.intInfo(mod).bits;
88288932 const result_bits = result_ty.intInfo(mod).bits;
......@@ -8844,7 +8948,7 @@ pub const FuncGen = struct {
88448948 assert(bits % 8 == 0);
88458949
88468950 var operand = try self.resolveInst(ty_op.operand);
8847 var operand_llvm_ty = try o.lowerType(operand_ty);
8951 var operand_llvm_ty = try o.lowerLlvmType(operand_ty);
88488952
88498953 if (bits % 16 == 8) {
88508954 // If not an even byte-multiple, we need zero-extend + shift-left 1 byte
......@@ -8878,7 +8982,7 @@ pub const FuncGen = struct {
88788982 const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, "");
88798983
88808984 const result_ty = self.typeOfIndex(inst);
8881 const result_llvm_ty = try o.lowerType(result_ty);
8985 const result_llvm_ty = try o.lowerLlvmType(result_ty);
88828986 const result_bits = result_ty.intInfo(mod).bits;
88838987 if (bits > result_bits) {
88848988 return self.builder.buildTrunc(wrong_size_result, result_llvm_ty, "");
......@@ -8957,9 +9061,9 @@ pub const FuncGen = struct {
89579061 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
89589062 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)});
89599063
8960 const param_types = [_]*llvm.Type{try o.lowerType(enum_type.tag_ty.toType())};
9064 const param_types = [_]*llvm.Type{try o.lowerLlvmType(enum_type.tag_ty.toType())};
89619065
8962 const llvm_ret_ty = try o.lowerType(Type.bool);
9066 const llvm_ret_ty = try o.lowerLlvmType(Type.bool);
89639067 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);
89649068 const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type);
89659069 fn_val.setLinkage(.Internal);
......@@ -9020,29 +9124,32 @@ pub const FuncGen = struct {
90209124
90219125 // TODO: detect when the type changes and re-emit this function.
90229126 const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl);
9023 if (gop.found_existing) return gop.value_ptr.*;
9127 if (gop.found_existing) return gop.value_ptr.toLlvm(&o.builder);
90249128 errdefer assert(o.decl_map.remove(enum_type.decl));
90259129
9026 var arena_allocator = std.heap.ArenaAllocator.init(self.gpa);
9027 defer arena_allocator.deinit();
9028 const arena = arena_allocator.allocator();
9029
90309130 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
9031 const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)});
9131 const llvm_fn_name = try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(&mod.intern_pool)});
90329132
90339133 const slice_ty = Type.slice_const_u8_sentinel_0;
9034 const llvm_ret_ty = try o.lowerType(slice_ty);
9035 const usize_llvm_ty = try o.lowerType(Type.usize);
9134 const llvm_ret_ty = try o.lowerLlvmType(slice_ty);
9135 const usize_llvm_ty = try o.lowerLlvmType(Type.usize);
90369136 const slice_alignment = slice_ty.abiAlignment(mod);
90379137
9038 const param_types = [_]*llvm.Type{try o.lowerType(enum_type.tag_ty.toType())};
9138 const param_types = [_]*llvm.Type{try o.lowerLlvmType(enum_type.tag_ty.toType())};
90399139
90409140 const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False);
9041 const fn_val = o.llvm_module.addFunction(llvm_fn_name, fn_type);
9141 const fn_val = o.llvm_module.addFunction(llvm_fn_name.toSlice(&o.builder).?, fn_type);
90429142 fn_val.setLinkage(.Internal);
90439143 fn_val.setFunctionCallConv(.Fast);
90449144 o.addCommonFnAttributes(fn_val);
9045 gop.value_ptr.* = fn_val;
9145
9146 var global = Builder.Global{
9147 .type = .void,
9148 .kind = .{ .function = @enumFromInt(o.builder.functions.items.len) },
9149 };
9150 var function = Builder.Function{
9151 .global = @enumFromInt(o.builder.globals.count()),
9152 };
90469153
90479154 const prev_block = self.builder.getInsertBlock();
90489155 const prev_debug_location = self.builder.getCurrentDebugLocation2();
......@@ -9104,6 +9211,10 @@ pub const FuncGen = struct {
91049211
91059212 self.builder.positionBuilderAtEnd(bad_value_block);
91069213 _ = self.builder.buildUnreachable();
9214
9215 try o.builder.llvm_globals.append(self.gpa, fn_val);
9216 gop.value_ptr.* = try o.builder.addGlobal(llvm_fn_name, global);
9217 try o.builder.functions.append(self.gpa, function);
91079218 return fn_val;
91089219 }
91099220
......@@ -9116,8 +9227,8 @@ pub const FuncGen = struct {
91169227
91179228 // Function signature: fn (anyerror) bool
91189229
9119 const ret_llvm_ty = try o.lowerType(Type.bool);
9120 const anyerror_llvm_ty = try o.lowerType(Type.anyerror);
9230 const ret_llvm_ty = try o.lowerLlvmType(Type.bool);
9231 const anyerror_llvm_ty = try o.lowerLlvmType(Type.anyerror);
91219232 const param_types = [_]*llvm.Type{anyerror_llvm_ty};
91229233
91239234 const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False);
......@@ -9133,7 +9244,7 @@ pub const FuncGen = struct {
91339244 const un_op = self.air.instructions.items(.data)[inst].un_op;
91349245 const operand = try self.resolveInst(un_op);
91359246 const slice_ty = self.typeOfIndex(inst);
9136 const slice_llvm_ty = try o.lowerType(slice_ty);
9247 const slice_llvm_ty = try o.lowerLlvmType(slice_ty);
91379248
91389249 const error_name_table_ptr = try self.getErrorNameTable();
91399250 const ptr_slice_llvm_ty = self.context.pointerType(0);
......@@ -9219,7 +9330,7 @@ pub const FuncGen = struct {
92199330 accum_init: *llvm.Value,
92209331 ) !*llvm.Value {
92219332 const o = self.dg.object;
9222 const llvm_usize_ty = try o.lowerType(Type.usize);
9333 const llvm_usize_ty = try o.lowerLlvmType(Type.usize);
92239334 const llvm_vector_len = llvm_usize_ty.constInt(vector_len, .False);
92249335 const llvm_result_ty = accum_init.typeOf();
92259336
......@@ -9296,7 +9407,7 @@ pub const FuncGen = struct {
92969407 .Add => switch (scalar_ty.zigTypeTag(mod)) {
92979408 .Int => return self.builder.buildAddReduce(operand),
92989409 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
9299 const scalar_llvm_ty = try o.lowerType(scalar_ty);
9410 const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty);
93009411 const neutral_value = scalar_llvm_ty.constReal(-0.0);
93019412 return self.builder.buildFPAddReduce(neutral_value, operand);
93029413 },
......@@ -9305,7 +9416,7 @@ pub const FuncGen = struct {
93059416 .Mul => switch (scalar_ty.zigTypeTag(mod)) {
93069417 .Int => return self.builder.buildMulReduce(operand),
93079418 .Float => if (intrinsicsAllowed(scalar_ty, target)) {
9308 const scalar_llvm_ty = try o.lowerType(scalar_ty);
9419 const scalar_llvm_ty = try o.lowerLlvmType(scalar_ty);
93099420 const neutral_value = scalar_llvm_ty.constReal(1.0);
93109421 return self.builder.buildFPMulReduce(neutral_value, operand);
93119422 },
......@@ -9333,9 +9444,9 @@ pub const FuncGen = struct {
93339444 else => unreachable,
93349445 };
93359446
9336 const param_llvm_ty = try o.lowerType(scalar_ty);
9447 const param_llvm_ty = try o.lowerLlvmType(scalar_ty);
93379448 const param_types = [2]*llvm.Type{ param_llvm_ty, param_llvm_ty };
9338 const libc_fn = self.getLibcFunction(fn_name, &param_types, param_llvm_ty);
9449 const libc_fn = try self.getLibcFunction(fn_name, &param_types, param_llvm_ty);
93399450 const init_value = try o.lowerValue(.{
93409451 .ty = scalar_ty,
93419452 .val = try mod.floatValue(scalar_ty, switch (reduce.operation) {
......@@ -9356,7 +9467,7 @@ pub const FuncGen = struct {
93569467 const result_ty = self.typeOfIndex(inst);
93579468 const len = @as(usize, @intCast(result_ty.arrayLen(mod)));
93589469 const elements = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[ty_pl.payload..][0..len]));
9359 const llvm_result_ty = try o.lowerType(result_ty);
9470 const llvm_result_ty = try o.lowerLlvmType(result_ty);
93609471
93619472 switch (result_ty.zigTypeTag(mod)) {
93629473 .Vector => {
......@@ -9444,7 +9555,7 @@ pub const FuncGen = struct {
94449555 .Array => {
94459556 assert(isByRef(result_ty, mod));
94469557
9447 const llvm_usize = try o.lowerType(Type.usize);
9558 const llvm_usize = try o.lowerLlvmType(Type.usize);
94489559 const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod));
94499560
94509561 const array_info = result_ty.arrayInfo(mod);
......@@ -9487,7 +9598,7 @@ pub const FuncGen = struct {
94879598 const ty_pl = self.air.instructions.items(.data)[inst].ty_pl;
94889599 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
94899600 const union_ty = self.typeOfIndex(inst);
9490 const union_llvm_ty = try o.lowerType(union_ty);
9601 const union_llvm_ty = try o.lowerLlvmType(union_ty);
94919602 const layout = union_ty.unionGetLayout(mod);
94929603 const union_obj = mod.typeToUnion(union_ty).?;
94939604
......@@ -9529,7 +9640,7 @@ pub const FuncGen = struct {
95299640 const llvm_payload = try self.resolveInst(extra.init);
95309641 assert(union_obj.haveFieldTypes());
95319642 const field = union_obj.fields.values()[extra.field_index];
9532 const field_llvm_ty = try o.lowerType(field.ty);
9643 const field_llvm_ty = try o.lowerLlvmType(field.ty);
95339644 const field_size = field.ty.abiSize(mod);
95349645 const field_align = field.normalAlignment(mod);
95359646
......@@ -9552,7 +9663,7 @@ pub const FuncGen = struct {
95529663 const fields: [1]*llvm.Type = .{payload};
95539664 break :t self.context.structType(&fields, fields.len, .False);
95549665 }
9555 const tag_llvm_ty = try o.lowerType(union_obj.tag_ty);
9666 const tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty);
95569667 var fields: [3]*llvm.Type = undefined;
95579668 var fields_len: c_uint = 2;
95589669 if (layout.tag_align >= layout.payload_align) {
......@@ -9605,7 +9716,7 @@ pub const FuncGen = struct {
96059716 index_type.constInt(@intFromBool(layout.tag_align < layout.payload_align), .False),
96069717 };
96079718 const field_ptr = self.builder.buildInBoundsGEP(llvm_union_ty, result_ptr, &indices, indices.len, "");
9608 const tag_llvm_ty = try o.lowerType(union_obj.tag_ty);
9719 const tag_llvm_ty = try o.lowerLlvmType(union_obj.tag_ty);
96099720 const llvm_tag = tag_llvm_ty.constInt(tag_int, .False);
96109721 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
96119722 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(mod));
......@@ -9687,7 +9798,7 @@ pub const FuncGen = struct {
96879798 const inst_ty = self.typeOfIndex(inst);
96889799 const operand = try self.resolveInst(ty_op.operand);
96899800
9690 const llvm_dest_ty = try o.lowerType(inst_ty);
9801 const llvm_dest_ty = try o.lowerLlvmType(inst_ty);
96919802 return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, "");
96929803 }
96939804
......@@ -9821,7 +9932,7 @@ pub const FuncGen = struct {
98219932
98229933 return fg.loadByRef(payload_ptr, payload_ty, payload_alignment, false);
98239934 }
9824 const payload_llvm_ty = try o.lowerType(payload_ty);
9935 const payload_llvm_ty = try o.lowerLlvmType(payload_ty);
98259936 const load_inst = fg.builder.buildLoad(payload_llvm_ty, payload_ptr, "");
98269937 load_inst.setAlignment(payload_alignment);
98279938 return load_inst;
......@@ -9838,7 +9949,7 @@ pub const FuncGen = struct {
98389949 non_null_bit: *llvm.Value,
98399950 ) !?*llvm.Value {
98409951 const o = self.dg.object;
9841 const optional_llvm_ty = try o.lowerType(optional_ty);
9952 const optional_llvm_ty = try o.lowerLlvmType(optional_ty);
98429953 const non_null_field = self.builder.buildZExt(non_null_bit, self.context.intType(8), "");
98439954 const mod = o.module;
98449955
......@@ -9893,7 +10004,7 @@ pub const FuncGen = struct {
989310004 const byte_offset = struct_ty.packedStructFieldByteOffset(field_index, mod);
989410005 if (byte_offset == 0) return struct_ptr;
989510006 const byte_llvm_ty = self.context.intType(8);
9896 const llvm_usize = try o.lowerType(Type.usize);
10007 const llvm_usize = try o.lowerLlvmType(Type.usize);
989710008 const llvm_index = llvm_usize.constInt(byte_offset, .False);
989810009 const indices: [1]*llvm.Value = .{llvm_index};
989910010 return self.builder.buildInBoundsGEP(byte_llvm_ty, struct_ptr, &indices, indices.len, "");
......@@ -9919,7 +10030,7 @@ pub const FuncGen = struct {
991910030 const layout = struct_ty.unionGetLayout(mod);
992010031 if (layout.payload_size == 0 or struct_ty.containerLayout(mod) == .Packed) return struct_ptr;
992110032 const payload_index = @intFromBool(layout.tag_align >= layout.payload_align);
9922 const union_llvm_ty = try o.lowerType(struct_ty);
10033 const union_llvm_ty = try o.lowerLlvmType(struct_ty);
992310034 const union_field_ptr = self.builder.buildStructGEP(union_llvm_ty, struct_ptr, payload_index, "");
992410035 return union_field_ptr;
992510036 },
......@@ -9944,7 +10055,7 @@ pub const FuncGen = struct {
994410055 ) !*llvm.Value {
994510056 const o = fg.dg.object;
994610057 const mod = o.module;
9947 const pointee_llvm_ty = try o.lowerType(pointee_type);
10058 const pointee_llvm_ty = try o.lowerLlvmType(pointee_type);
994810059 const result_align = @max(ptr_alignment, pointee_type.abiAlignment(mod));
994910060 const result_ptr = fg.buildAlloca(pointee_llvm_ty, result_align);
995010061 const llvm_usize = fg.context.intType(Type.usize.intInfo(mod).bits);
......@@ -9977,7 +10088,7 @@ pub const FuncGen = struct {
997710088 assert(info.flags.vector_index != .runtime);
997810089 if (info.flags.vector_index != .none) {
997910090 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);
9980 const vec_elem_ty = try o.lowerType(elem_ty);
10091 const vec_elem_ty = try o.lowerLlvmType(elem_ty);
998110092 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
998210093
998310094 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
......@@ -9991,7 +10102,7 @@ pub const FuncGen = struct {
999110102 if (isByRef(elem_ty, mod)) {
999210103 return self.loadByRef(ptr, elem_ty, ptr_alignment, info.flags.is_volatile);
999310104 }
9994 const elem_llvm_ty = try o.lowerType(elem_ty);
10105 const elem_llvm_ty = try o.lowerLlvmType(elem_ty);
999510106 const llvm_inst = self.builder.buildLoad(elem_llvm_ty, ptr, "");
999610107 llvm_inst.setAlignment(ptr_alignment);
999710108 llvm_inst.setVolatile(ptr_volatile);
......@@ -10006,7 +10117,7 @@ pub const FuncGen = struct {
1000610117 const elem_bits = @as(c_uint, @intCast(ptr_ty.childType(mod).bitSize(mod)));
1000710118 const shift_amt = containing_int.typeOf().constInt(info.packed_offset.bit_offset, .False);
1000810119 const shifted_value = self.builder.buildLShr(containing_int, shift_amt, "");
10009 const elem_llvm_ty = try o.lowerType(elem_ty);
10120 const elem_llvm_ty = try o.lowerLlvmType(elem_ty);
1001010121
1001110122 if (isByRef(elem_ty, mod)) {
1001210123 const result_align = elem_ty.abiAlignment(mod);
......@@ -10054,7 +10165,7 @@ pub const FuncGen = struct {
1005410165 assert(info.flags.vector_index != .runtime);
1005510166 if (info.flags.vector_index != .none) {
1005610167 const index_u32 = self.context.intType(32).constInt(@intFromEnum(info.flags.vector_index), .False);
10057 const vec_elem_ty = try o.lowerType(elem_ty);
10168 const vec_elem_ty = try o.lowerLlvmType(elem_ty);
1005810169 const vec_ty = vec_elem_ty.vectorType(info.packed_offset.host_size);
1005910170
1006010171 const loaded_vector = self.builder.buildLoad(vec_ty, ptr, "");
......@@ -10702,7 +10813,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
1070210813 // anyerror return type instead, so that it can be coerced into a function
1070310814 // pointer type which has anyerror as the return type.
1070410815 if (return_type.isError(mod)) {
10705 return o.lowerType(Type.anyerror);
10816 return o.lowerLlvmType(Type.anyerror);
1070610817 } else {
1070710818 return o.context.voidType();
1070810819 }
......@@ -10713,19 +10824,19 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
1071310824 if (isByRef(return_type, mod)) {
1071410825 return o.context.voidType();
1071510826 } else {
10716 return o.lowerType(return_type);
10827 return o.lowerLlvmType(return_type);
1071710828 }
1071810829 },
1071910830 .C => {
1072010831 switch (target.cpu.arch) {
10721 .mips, .mipsel => return o.lowerType(return_type),
10832 .mips, .mipsel => return o.lowerLlvmType(return_type),
1072210833 .x86_64 => switch (target.os.tag) {
1072310834 .windows => return lowerWin64FnRetTy(o, fn_info),
1072410835 else => return lowerSystemVFnRetTy(o, fn_info),
1072510836 },
1072610837 .wasm32 => {
1072710838 if (isScalar(mod, return_type)) {
10728 return o.lowerType(return_type);
10839 return o.lowerLlvmType(return_type);
1072910840 }
1073010841 const classes = wasm_c_abi.classifyType(return_type, mod);
1073110842 if (classes[0] == .indirect or classes[0] == .none) {
......@@ -10740,8 +10851,8 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
1074010851 .aarch64, .aarch64_be => {
1074110852 switch (aarch64_c_abi.classifyType(return_type, mod)) {
1074210853 .memory => return o.context.voidType(),
10743 .float_array => return o.lowerType(return_type),
10744 .byval => return o.lowerType(return_type),
10854 .float_array => return o.lowerLlvmType(return_type),
10855 .byval => return o.lowerLlvmType(return_type),
1074510856 .integer => {
1074610857 const bit_size = return_type.bitSize(mod);
1074710858 return o.context.intType(@as(c_uint, @intCast(bit_size)));
......@@ -10757,7 +10868,7 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
1075710868 } else {
1075810869 return o.context.voidType();
1075910870 },
10760 .byval => return o.lowerType(return_type),
10871 .byval => return o.lowerLlvmType(return_type),
1076110872 }
1076210873 },
1076310874 .riscv32, .riscv64 => {
......@@ -10774,23 +10885,23 @@ fn lowerFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
1077410885 };
1077510886 return o.context.structType(&llvm_types_buffer, 2, .False);
1077610887 },
10777 .byval => return o.lowerType(return_type),
10888 .byval => return o.lowerLlvmType(return_type),
1077810889 }
1077910890 },
1078010891 // TODO investigate C ABI for other architectures
10781 else => return o.lowerType(return_type),
10892 else => return o.lowerLlvmType(return_type),
1078210893 }
1078310894 },
1078410895 .Win64 => return lowerWin64FnRetTy(o, fn_info),
1078510896 .SysV => return lowerSystemVFnRetTy(o, fn_info),
1078610897 .Stdcall => {
1078710898 if (isScalar(mod, return_type)) {
10788 return o.lowerType(return_type);
10899 return o.lowerLlvmType(return_type);
1078910900 } else {
1079010901 return o.context.voidType();
1079110902 }
1079210903 },
10793 else => return o.lowerType(return_type),
10904 else => return o.lowerLlvmType(return_type),
1079410905 }
1079510906}
1079610907
......@@ -10800,7 +10911,7 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
1080010911 switch (x86_64_abi.classifyWindows(return_type, mod)) {
1080110912 .integer => {
1080210913 if (isScalar(mod, return_type)) {
10803 return o.lowerType(return_type);
10914 return o.lowerLlvmType(return_type);
1080410915 } else {
1080510916 const abi_size = return_type.abiSize(mod);
1080610917 return o.context.intType(@as(c_uint, @intCast(abi_size * 8)));
......@@ -10808,7 +10919,7 @@ fn lowerWin64FnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type {
1080810919 },
1080910920 .win_i128 => return o.context.intType(64).vectorType(2),
1081010921 .memory => return o.context.voidType(),
10811 .sse => return o.lowerType(return_type),
10922 .sse => return o.lowerLlvmType(return_type),
1081210923 else => unreachable,
1081310924 }
1081410925}
......@@ -10817,7 +10928,7 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type
1081710928 const mod = o.module;
1081810929 const return_type = fn_info.return_type.toType();
1081910930 if (isScalar(mod, return_type)) {
10820 return o.lowerType(return_type);
10931 return o.lowerLlvmType(return_type);
1082110932 }
1082210933 const classes = x86_64_abi.classifySystemV(return_type, mod, .ret);
1082310934 if (classes[0] == .memory) {
......@@ -10847,7 +10958,7 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) !*llvm.Type
1084710958 if (llvm_types_index != 0 or classes[2] != .none) {
1084810959 return o.context.voidType();
1084910960 }
10850 llvm_types_buffer[llvm_types_index] = o.context.x86FP80Type();
10961 llvm_types_buffer[llvm_types_index] = o.context.x86_fp80Type();
1085110962 llvm_types_index += 1;
1085210963 },
1085310964 .x87up => continue,
src/codegen/llvm/Builder.zig created+845
......@@ -0,0 +1,845 @@
1gpa: Allocator,
2use_lib_llvm: bool,
3
4llvm_context: *llvm.Context,
5llvm_module: *llvm.Module,
6di_builder: ?*llvm.DIBuilder = null,
7llvm_types: std.ArrayListUnmanaged(*llvm.Type) = .{},
8llvm_globals: std.ArrayListUnmanaged(*llvm.Value) = .{},
9
10source_filename: String = .none,
11data_layout: String = .none,
12target_triple: String = .none,
13
14string_map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
15string_bytes: std.ArrayListUnmanaged(u8) = .{},
16string_indices: std.ArrayListUnmanaged(u32) = .{},
17
18types: std.AutoArrayHashMapUnmanaged(String, Type) = .{},
19next_unnamed_type: String = @enumFromInt(0),
20type_map: std.AutoArrayHashMapUnmanaged(void, void) = .{},
21type_data: std.ArrayListUnmanaged(Type.Data) = .{},
22type_extra: std.ArrayListUnmanaged(u32) = .{},
23
24globals: std.AutoArrayHashMapUnmanaged(String, Global) = .{},
25next_unnamed_global: String = @enumFromInt(0),
26next_unique_global_id: std.AutoHashMapUnmanaged(String, u32) = .{},
27aliases: std.ArrayListUnmanaged(Alias) = .{},
28objects: std.ArrayListUnmanaged(Object) = .{},
29functions: std.ArrayListUnmanaged(Function) = .{},
30
31pub const String = enum(u32) {
32 none = std.math.maxInt(u31),
33 empty,
34 debugme,
35 _,
36
37 pub fn toSlice(self: String, b: *const Builder) ?[:0]const u8 {
38 const index = self.toIndex() orelse return null;
39 const start = b.string_indices.items[index];
40 const end = b.string_indices.items[index + 1];
41 return b.string_bytes.items[start .. end - 1 :0];
42 }
43
44 const FormatData = struct {
45 string: String,
46 builder: *const Builder,
47 };
48 fn format(
49 data: FormatData,
50 comptime fmt_str: []const u8,
51 _: std.fmt.FormatOptions,
52 writer: anytype,
53 ) @TypeOf(writer).Error!void {
54 assert(data.string != .none);
55 const slice = data.string.toSlice(data.builder) orelse
56 return writer.print("{d}", .{@intFromEnum(data.string)});
57 const need_quotes = if (comptime std.mem.eql(u8, fmt_str, ""))
58 !isValidIdentifier(slice)
59 else if (comptime std.mem.eql(u8, fmt_str, "\""))
60 true
61 else
62 @compileError("invalid format string: '" ++ fmt_str ++ "'");
63 if (need_quotes) try writer.writeByte('\"');
64 for (slice) |c| switch (c) {
65 '\\' => try writer.writeAll("\\\\"),
66 ' '...'"' - 1, '"' + 1...'\\' - 1, '\\' + 1...'~' => try writer.writeByte(c),
67 else => try writer.print("\\{X:0>2}", .{c}),
68 };
69 if (need_quotes) try writer.writeByte('\"');
70 }
71 pub fn fmt(self: String, builder: *const Builder) std.fmt.Formatter(format) {
72 return .{ .data = .{ .string = self, .builder = builder } };
73 }
74
75 fn fromIndex(index: ?usize) String {
76 return @enumFromInt(@as(u32, @intCast((index orelse return .none) +
77 @intFromEnum(String.empty))));
78 }
79 fn toIndex(self: String) ?usize {
80 return std.math.sub(u32, @intFromEnum(self), @intFromEnum(String.empty)) catch null;
81 }
82
83 const Adapter = struct {
84 builder: *const Builder,
85 pub fn hash(_: Adapter, key: []const u8) u32 {
86 return @truncate(std.hash.Wyhash.hash(0, key));
87 }
88 pub fn eql(ctx: Adapter, lhs: []const u8, _: void, rhs_index: usize) bool {
89 return std.mem.eql(u8, lhs, String.fromIndex(rhs_index).toSlice(ctx.builder).?);
90 }
91 };
92};
93
94pub const Type = enum(u32) {
95 void,
96 half,
97 bfloat,
98 float,
99 double,
100 fp128,
101 x86_fp80,
102 ppc_fp128,
103 x86_amx,
104 x86_mmx,
105 label,
106 token,
107 metadata,
108
109 i1,
110 i8,
111 i16,
112 i32,
113 i64,
114 i128,
115 ptr,
116
117 none = std.math.maxInt(u32),
118 _,
119
120 const Tag = enum(u4) {
121 simple,
122 function,
123 integer,
124 pointer,
125 target,
126 vector,
127 vscale_vector,
128 array,
129 structure,
130 packed_structure,
131 named_structure,
132 };
133
134 const Simple = enum {
135 void,
136 half,
137 bfloat,
138 float,
139 double,
140 fp128,
141 x86_fp80,
142 ppc_fp128,
143 x86_amx,
144 x86_mmx,
145 label,
146 token,
147 metadata,
148 };
149
150 const NamedStructure = struct {
151 id: String,
152 child: Type,
153 };
154
155 const Data = packed struct(u32) {
156 tag: Tag,
157 data: ExtraIndex,
158 };
159
160 const ExtraIndex = u28;
161
162 const FormatData = struct {
163 type: Type,
164 builder: *const Builder,
165 };
166 fn format(
167 data: FormatData,
168 comptime fmt_str: []const u8,
169 fmt_opts: std.fmt.FormatOptions,
170 writer: anytype,
171 ) @TypeOf(writer).Error!void {
172 assert(data.type != .none);
173 if (std.enums.tagName(Type, data.type)) |name| return writer.writeAll(name);
174 const type_data = data.builder.type_data.items[@intFromEnum(data.type)];
175 switch (type_data.tag) {
176 .named_structure => {
177 const extra = data.builder.typeExtraData(NamedStructure, type_data.data);
178 if (comptime std.mem.eql(u8, fmt_str, "")) try writer.print("%{}", .{
179 extra.id.fmt(data.builder),
180 }) else if (comptime std.mem.eql(u8, fmt_str, "+")) switch (extra.child) {
181 .none => try writer.writeAll("opaque"),
182 else => try format(.{
183 .type = extra.child,
184 .builder = data.builder,
185 }, fmt_str, fmt_opts, writer),
186 } else @compileError("invalid format string: '" ++ fmt_str ++ "'");
187 },
188 else => try writer.print("<type 0x{X}>", .{@intFromEnum(data.type)}),
189 }
190 }
191 pub fn fmt(self: Type, builder: *const Builder) std.fmt.Formatter(format) {
192 return .{ .data = .{ .type = self, .builder = builder } };
193 }
194};
195
196pub const Linkage = enum {
197 default,
198 private,
199 internal,
200 available_externally,
201 linkonce,
202 weak,
203 common,
204 appending,
205 extern_weak,
206 linkonce_odr,
207 weak_odr,
208 external,
209
210 pub fn format(
211 self: Linkage,
212 comptime _: []const u8,
213 _: std.fmt.FormatOptions,
214 writer: anytype,
215 ) @TypeOf(writer).Error!void {
216 if (self == .default) return;
217 try writer.writeAll(@tagName(self));
218 try writer.writeByte(' ');
219 }
220};
221
222pub const Preemption = enum {
223 none,
224 dso_preemptable,
225 dso_local,
226
227 pub fn format(
228 self: Preemption,
229 comptime _: []const u8,
230 _: std.fmt.FormatOptions,
231 writer: anytype,
232 ) @TypeOf(writer).Error!void {
233 if (self == .none) return;
234 try writer.writeAll(@tagName(self));
235 try writer.writeByte(' ');
236 }
237};
238
239pub const Visibility = enum {
240 default,
241 hidden,
242 protected,
243
244 pub fn format(
245 self: Visibility,
246 comptime _: []const u8,
247 _: std.fmt.FormatOptions,
248 writer: anytype,
249 ) @TypeOf(writer).Error!void {
250 if (self == .default) return;
251 try writer.writeAll(@tagName(self));
252 try writer.writeByte(' ');
253 }
254};
255
256pub const DllStorageClass = enum {
257 default,
258 dllimport,
259 dllexport,
260
261 pub fn format(
262 self: DllStorageClass,
263 comptime _: []const u8,
264 _: std.fmt.FormatOptions,
265 writer: anytype,
266 ) @TypeOf(writer).Error!void {
267 if (self == .default) return;
268 try writer.writeAll(@tagName(self));
269 try writer.writeByte(' ');
270 }
271};
272
273pub const ThreadLocal = enum {
274 none,
275 generaldynamic,
276 localdynamic,
277 initialexec,
278 localexec,
279
280 pub fn format(
281 self: ThreadLocal,
282 comptime _: []const u8,
283 _: std.fmt.FormatOptions,
284 writer: anytype,
285 ) @TypeOf(writer).Error!void {
286 if (self == .none) return;
287 try writer.writeAll("thread_local");
288 if (self != .generaldynamic) {
289 try writer.writeByte('(');
290 try writer.writeAll(@tagName(self));
291 try writer.writeByte(')');
292 }
293 try writer.writeByte(' ');
294 }
295};
296
297pub const UnnamedAddr = enum {
298 none,
299 unnamed_addr,
300 local_unnamed_addr,
301
302 pub fn format(
303 self: UnnamedAddr,
304 comptime _: []const u8,
305 _: std.fmt.FormatOptions,
306 writer: anytype,
307 ) @TypeOf(writer).Error!void {
308 if (self == .none) return;
309 try writer.writeAll(@tagName(self));
310 try writer.writeByte(' ');
311 }
312};
313
314pub const AddrSpace = enum(u24) {
315 none,
316 _,
317
318 pub fn format(
319 self: AddrSpace,
320 comptime _: []const u8,
321 _: std.fmt.FormatOptions,
322 writer: anytype,
323 ) @TypeOf(writer).Error!void {
324 if (self == .none) return;
325 try writer.print("addrspace({d}) ", .{@intFromEnum(self)});
326 }
327};
328
329pub const ExternallyInitialized = enum {
330 none,
331 externally_initialized,
332
333 pub fn format(
334 self: ExternallyInitialized,
335 comptime _: []const u8,
336 _: std.fmt.FormatOptions,
337 writer: anytype,
338 ) @TypeOf(writer).Error!void {
339 if (self == .none) return;
340 try writer.writeAll(@tagName(self));
341 try writer.writeByte(' ');
342 }
343};
344
345pub const Alignment = enum(u6) {
346 default = std.math.maxInt(u6),
347 _,
348
349 pub fn fromByteUnits(bytes: u64) Alignment {
350 if (bytes == 0) return .default;
351 assert(std.math.isPowerOfTwo(bytes));
352 assert(bytes <= 1 << 32);
353 return @enumFromInt(@ctz(bytes));
354 }
355
356 pub fn toByteUnits(self: Alignment) ?u64 {
357 return if (self == .default) null else @as(u64, 1) << @intFromEnum(self);
358 }
359
360 pub fn format(
361 self: Alignment,
362 comptime prefix: []const u8,
363 _: std.fmt.FormatOptions,
364 writer: anytype,
365 ) @TypeOf(writer).Error!void {
366 try writer.print("{s} align {d}", .{ prefix, self.toByteUnits() orelse return });
367 }
368};
369
370pub const Global = struct {
371 linkage: Linkage = .default,
372 preemption: Preemption = .none,
373 visibility: Visibility = .default,
374 dll_storage_class: DllStorageClass = .default,
375 unnamed_addr: UnnamedAddr = .none,
376 addr_space: AddrSpace = .none,
377 externally_initialized: ExternallyInitialized = .none,
378 type: Type,
379 alignment: Alignment = .default,
380 kind: union(enum) {
381 alias: Alias.Index,
382 object: Object.Index,
383 function: Function.Index,
384 },
385
386 pub const Index = enum(u32) {
387 _,
388
389 pub fn ptr(self: Index, builder: *Builder) *Global {
390 return &builder.globals.values()[@intFromEnum(self)];
391 }
392
393 pub fn ptrConst(self: Index, builder: *const Builder) *const Global {
394 return &builder.globals.values()[@intFromEnum(self)];
395 }
396
397 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
398 return builder.llvm_globals.items[@intFromEnum(self)];
399 }
400
401 pub fn rename(self: Index, builder: *Builder, name: String) Allocator.Error!void {
402 try builder.ensureUnusedCapacityGlobal(name);
403 self.renameAssumeCapacity(builder, name);
404 }
405
406 pub fn renameAssumeCapacity(self: Index, builder: *Builder, name: String) void {
407 const index = @intFromEnum(self);
408 if (builder.globals.keys()[index] == name) return;
409 if (builder.useLibLlvm()) builder.llvm_globals.appendAssumeCapacity(builder.llvm_globals.items[index]);
410 _ = builder.addGlobalAssumeCapacity(name, builder.globals.values()[index]);
411 if (builder.useLibLlvm()) _ = builder.llvm_globals.pop();
412 builder.globals.swapRemoveAt(index);
413 self.updateName(builder);
414 }
415
416 pub fn takeName(self: Index, builder: *Builder, other: Index) Allocator.Error!void {
417 try builder.ensureUnusedCapacityGlobal(.empty);
418 self.takeNameAssumeCapacity(builder, other);
419 }
420
421 pub fn takeNameAssumeCapacity(self: Index, builder: *Builder, other: Index) void {
422 const other_name = builder.globals.keys()[@intFromEnum(other)];
423 other.renameAssumeCapacity(builder, .none);
424 self.renameAssumeCapacity(builder, other_name);
425 }
426
427 fn updateName(self: Index, builder: *const Builder) void {
428 if (!builder.useLibLlvm()) return;
429 const index = @intFromEnum(self);
430 const slice = builder.globals.keys()[index].toSlice(builder) orelse "";
431 builder.llvm_globals.items[index].setValueName2(slice.ptr, slice.len);
432 }
433 };
434
435 fn deinit(self: *Global, _: Allocator) void {
436 self.* = undefined;
437 }
438};
439
440pub const Alias = struct {
441 global: Global.Index,
442
443 pub const Index = enum(u32) {
444 _,
445
446 pub fn ptr(self: Index, builder: *Builder) *Alias {
447 return &builder.aliases.items[@intFromEnum(self)];
448 }
449
450 pub fn ptrConst(self: Index, builder: *const Builder) *const Alias {
451 return &builder.aliases.items[@intFromEnum(self)];
452 }
453
454 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
455 return self.ptrConst(builder).global.toLlvm(builder);
456 }
457 };
458};
459
460pub const Object = struct {
461 global: Global.Index,
462 thread_local: ThreadLocal = .none,
463 mutability: enum { global, constant } = .global,
464 init: void = {},
465
466 pub const Index = enum(u32) {
467 _,
468
469 pub fn ptr(self: Index, builder: *Builder) *Object {
470 return &builder.objects.items[@intFromEnum(self)];
471 }
472
473 pub fn ptrConst(self: Index, builder: *const Builder) *const Object {
474 return &builder.objects.items[@intFromEnum(self)];
475 }
476
477 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
478 return self.ptrConst(builder).global.toLlvm(builder);
479 }
480 };
481};
482
483pub const Function = struct {
484 global: Global.Index,
485 body: ?void = null,
486
487 fn deinit(self: *Function, _: Allocator) void {
488 self.* = undefined;
489 }
490
491 pub const Index = enum(u32) {
492 _,
493
494 pub fn ptr(self: Index, builder: *Builder) *Function {
495 return &builder.functions.items[@intFromEnum(self)];
496 }
497
498 pub fn ptrConst(self: Index, builder: *const Builder) *const Function {
499 return &builder.functions.items[@intFromEnum(self)];
500 }
501
502 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
503 return self.ptrConst(builder).global.toLlvm(builder);
504 }
505 };
506};
507
508pub fn init(self: *Builder) Allocator.Error!void {
509 try self.string_indices.append(self.gpa, 0);
510 assert(try self.string("") == .empty);
511 assert(try self.string("debugme") == .debugme);
512
513 {
514 const static_len = @typeInfo(Type).Enum.fields.len - 1;
515 try self.type_map.ensureTotalCapacity(self.gpa, static_len);
516 try self.type_data.ensureTotalCapacity(self.gpa, static_len);
517 if (self.useLibLlvm()) try self.llvm_types.ensureTotalCapacity(self.gpa, static_len);
518 inline for (@typeInfo(Type.Simple).Enum.fields) |simple_field| {
519 const result = self.typeNoExtraAssumeCapacity(.{
520 .tag = .simple,
521 .data = simple_field.value,
522 });
523 assert(result.new and result.type == @field(Type, simple_field.name));
524 if (self.useLibLlvm()) self.llvm_types.appendAssumeCapacity(
525 @field(llvm.Context, simple_field.name ++ "Type")(self.llvm_context),
526 );
527 }
528 inline for (.{ 1, 8, 16, 32, 64, 128 }) |bits| assert(self.intTypeAssumeCapacity(bits) ==
529 @field(Type, std.fmt.comptimePrint("i{d}", .{bits})));
530 inline for (.{0}) |addr_space|
531 assert(self.pointerTypeAssumeCapacity(@enumFromInt(addr_space)) == .ptr);
532 }
533}
534
535pub fn deinit(self: *Builder) void {
536 self.llvm_types.deinit(self.gpa);
537 self.llvm_globals.deinit(self.gpa);
538
539 self.string_map.deinit(self.gpa);
540 self.string_bytes.deinit(self.gpa);
541 self.string_indices.deinit(self.gpa);
542
543 self.types.deinit(self.gpa);
544 self.type_map.deinit(self.gpa);
545 self.type_data.deinit(self.gpa);
546 self.type_extra.deinit(self.gpa);
547
548 self.globals.deinit(self.gpa);
549 self.next_unique_global_id.deinit(self.gpa);
550 self.aliases.deinit(self.gpa);
551 self.objects.deinit(self.gpa);
552 self.functions.deinit(self.gpa);
553
554 self.* = undefined;
555}
556
557pub fn string(self: *Builder, bytes: []const u8) Allocator.Error!String {
558 try self.string_bytes.ensureUnusedCapacity(self.gpa, bytes.len + 1);
559 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
560 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
561
562 const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self });
563 if (!gop.found_existing) {
564 self.string_bytes.appendSliceAssumeCapacity(bytes);
565 self.string_bytes.appendAssumeCapacity(0);
566 self.string_indices.appendAssumeCapacity(@intCast(self.string_bytes.items.len));
567 }
568 return String.fromIndex(gop.index);
569}
570
571pub fn stringIfExists(self: *const Builder, bytes: []const u8) ?String {
572 return String.fromIndex(
573 self.string_map.getIndexAdapted(bytes, String.Adapter{ .builder = self }) orelse return null,
574 );
575}
576
577pub fn fmt(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) Allocator.Error!String {
578 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
579 try self.string_bytes.ensureUnusedCapacity(self.gpa, std.fmt.count(fmt_str ++ .{0}, fmt_args));
580 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
581 return self.fmtAssumeCapacity(fmt_str, fmt_args);
582}
583
584pub fn fmtAssumeCapacity(self: *Builder, comptime fmt_str: []const u8, fmt_args: anytype) String {
585 const start = self.string_bytes.items.len;
586 self.string_bytes.writer(self.gpa).print(fmt_str ++ .{0}, fmt_args) catch unreachable;
587 const bytes: []const u8 = self.string_bytes.items[start .. self.string_bytes.items.len - 1];
588
589 const gop = self.string_map.getOrPutAssumeCapacityAdapted(bytes, String.Adapter{ .builder = self });
590 if (gop.found_existing) {
591 self.string_bytes.shrinkRetainingCapacity(start);
592 } else {
593 self.string_indices.appendAssumeCapacity(@intCast(self.string_bytes.items.len));
594 }
595 return String.fromIndex(gop.index);
596}
597
598pub fn opaqueType(self: *Builder, name: String) Allocator.Error!Type {
599 try self.types.ensureUnusedCapacity(self.gpa, 1);
600 try self.ensureUnusedCapacityTypes(1, Type.NamedStructure);
601 return self.opaqueTypeAssumeCapacity(name);
602}
603
604pub fn intType(self: *Builder, bits: u24) Allocator.Error!Type {
605 try self.ensureUnusedCapacityTypes(1);
606 return self.intTypeAssumeCapacity(bits);
607}
608
609pub fn pointerType(self: *Builder, addr_space: AddrSpace) Allocator.Error!Type {
610 try self.ensureUnusedCapacityTypes(1, null);
611 return self.pointerTypeAssumeCapacity(addr_space);
612}
613
614pub fn addGlobal(self: *Builder, name: String, global: Global) Allocator.Error!Global.Index {
615 try self.ensureUnusedCapacityGlobal(name);
616 return self.addGlobalAssumeCapacity(name, global);
617}
618
619pub fn addGlobalAssumeCapacity(self: *Builder, name: String, global: Global) Global.Index {
620 var id = name;
621 if (id == .none) {
622 id = self.next_unnamed_global;
623 self.next_unnamed_global = @enumFromInt(@intFromEnum(self.next_unnamed_global) + 1);
624 }
625 while (true) {
626 const global_gop = self.globals.getOrPutAssumeCapacity(id);
627 if (!global_gop.found_existing) {
628 global_gop.value_ptr.* = global;
629 const index: Global.Index = @enumFromInt(global_gop.index);
630 index.updateName(self);
631 return index;
632 }
633
634 const unique_gop = self.next_unique_global_id.getOrPutAssumeCapacity(name);
635 if (!unique_gop.found_existing) unique_gop.value_ptr.* = 2;
636 id = self.fmtAssumeCapacity("{s}.{d}", .{ name.toSlice(self).?, unique_gop.value_ptr.* });
637 unique_gop.value_ptr.* += 1;
638 }
639}
640
641pub fn getGlobal(self: *const Builder, name: String) ?Global.Index {
642 return @enumFromInt(self.globals.getIndex(name) orelse return null);
643}
644
645fn ensureUnusedCapacityGlobal(self: *Builder, name: String) Allocator.Error!void {
646 if (self.useLibLlvm()) try self.llvm_globals.ensureUnusedCapacity(self.gpa, 1);
647 try self.string_map.ensureUnusedCapacity(self.gpa, 1);
648 try self.string_bytes.ensureUnusedCapacity(self.gpa, name.toSlice(self).?.len +
649 comptime std.fmt.count("{d}" ++ .{0}, .{std.math.maxInt(u32)}));
650 try self.string_indices.ensureUnusedCapacity(self.gpa, 1);
651 try self.globals.ensureUnusedCapacity(self.gpa, 1);
652 try self.next_unique_global_id.ensureUnusedCapacity(self.gpa, 1);
653}
654
655fn addTypeExtraAssumeCapacity(self: *Builder, extra: anytype) Type.ExtraIndex {
656 const result: Type.ExtraIndex = @intCast(self.type_extra.items.len);
657 inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| {
658 const value = @field(extra, field.name);
659 self.type_extra.appendAssumeCapacity(switch (field.type) {
660 String, Type => @intFromEnum(value),
661 else => @compileError("bad field type: " ++ @typeName(field.type)),
662 });
663 }
664 return result;
665}
666
667fn typeExtraDataTrail(
668 self: *const Builder,
669 comptime T: type,
670 index: Type.ExtraIndex,
671) struct { data: T, end: Type.ExtraIndex } {
672 var result: T = undefined;
673 const fields = @typeInfo(T).Struct.fields;
674 inline for (fields, self.type_extra.items[index..][0..fields.len]) |field, data|
675 @field(result, field.name) = switch (field.type) {
676 String, Type => @enumFromInt(data),
677 else => @compileError("bad field type: " ++ @typeName(field.type)),
678 };
679 return .{ .data = result, .end = index + @as(Type.ExtraIndex, @intCast(fields.len)) };
680}
681
682fn typeExtraData(self: *const Builder, comptime T: type, index: Type.ExtraIndex) T {
683 return self.typeExtraDataTrail(T, index).data;
684}
685
686fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {
687 const Adapter = struct {
688 builder: *const Builder,
689 pub fn hash(_: @This(), key: String) u32 {
690 return std.hash.uint32(@intFromEnum(key));
691 }
692 pub fn eql(ctx: @This(), lhs: String, _: void, rhs_index: usize) bool {
693 const rhs_data = ctx.builder.type_data.items[rhs_index];
694 return rhs_data.tag == .named_structure and
695 lhs == ctx.builder.typeExtraData(Type.NamedStructure, rhs_data.data).id;
696 }
697 };
698 const id = if (name == .none) name: {
699 const next_name = self.next_unnamed_type;
700 assert(next_name != .none);
701 self.next_unnamed_type = @enumFromInt(@intFromEnum(next_name) + 1);
702 break :name next_name;
703 } else name: {
704 assert(name.toIndex() != null);
705 break :name name;
706 };
707 const gop = self.type_map.getOrPutAssumeCapacityAdapted(id, Adapter{ .builder = self });
708 if (!gop.found_existing) {
709 gop.key_ptr.* = {};
710 gop.value_ptr.* = {};
711 self.type_data.appendAssumeCapacity(.{
712 .tag = .named_structure,
713 .data = self.addTypeExtraAssumeCapacity(Type.NamedStructure{ .id = id, .child = .none }),
714 });
715 }
716 const result: Type = @enumFromInt(gop.index);
717 self.types.putAssumeCapacityNoClobber(id, result);
718 return result;
719}
720
721fn intTypeAssumeCapacity(self: *Builder, bits: u24) Type {
722 const result = self.typeNoExtraAssumeCapacity(.{ .tag = .integer, .data = bits });
723 if (self.useLibLlvm() and result.new)
724 self.llvm_types.appendAssumeCapacity(self.llvm_context.intType(bits));
725 return result.type;
726}
727
728fn pointerTypeAssumeCapacity(self: *Builder, addr_space: AddrSpace) Type {
729 const result = self.typeNoExtraAssumeCapacity(.{ .tag = .pointer, .data = @intFromEnum(addr_space) });
730 if (self.useLibLlvm() and result.new)
731 self.llvm_types.appendAssumeCapacity(self.llvm_context.pointerType(@intFromEnum(addr_space)));
732 return result.type;
733}
734
735fn ensureUnusedCapacityTypes(self: *Builder, count: usize, comptime Extra: ?type) Allocator.Error!void {
736 try self.type_map.ensureUnusedCapacity(self.gpa, count);
737 try self.type_data.ensureUnusedCapacity(self.gpa, count);
738 if (Extra) |E|
739 try self.type_extra.ensureUnusedCapacity(self.gpa, count * @typeInfo(E).Struct.fields.len);
740 if (self.useLibLlvm()) try self.llvm_types.ensureUnusedCapacity(self.gpa, count);
741}
742
743fn typeNoExtraAssumeCapacity(self: *Builder, data: Type.Data) struct { new: bool, type: Type } {
744 const Adapter = struct {
745 builder: *const Builder,
746 pub fn hash(_: @This(), key: Type.Data) u32 {
747 return std.hash.uint32(@bitCast(key));
748 }
749 pub fn eql(ctx: @This(), lhs: Type.Data, _: void, rhs_index: usize) bool {
750 const lhs_bits: u32 = @bitCast(lhs);
751 const rhs_bits: u32 = @bitCast(ctx.builder.type_data.items[rhs_index]);
752 return lhs_bits == rhs_bits;
753 }
754 };
755 const gop = self.type_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
756 if (!gop.found_existing) {
757 gop.key_ptr.* = {};
758 gop.value_ptr.* = {};
759 self.type_data.appendAssumeCapacity(data);
760 }
761 return .{ .new = !gop.found_existing, .type = @enumFromInt(gop.index) };
762}
763
764fn isValidIdentifier(id: []const u8) bool {
765 for (id, 0..) |c, i| switch (c) {
766 '$', '-', '.', 'A'...'Z', '_', 'a'...'z' => {},
767 '0'...'9' => if (i == 0) return false,
768 else => return false,
769 };
770 return true;
771}
772
773pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {
774 if (self.source_filename != .none) try writer.print(
775 \\; ModuleID = '{s}'
776 \\source_filename = {"}
777 \\
778 , .{ self.source_filename.toSlice(self).?, self.source_filename.fmt(self) });
779 if (self.data_layout != .none) try writer.print(
780 \\target datalayout = {"}
781 \\
782 , .{self.data_layout.fmt(self)});
783 if (self.target_triple != .none) try writer.print(
784 \\target triple = {"}
785 \\
786 , .{self.target_triple.fmt(self)});
787 try writer.writeByte('\n');
788 for (self.types.keys(), self.types.values()) |id, ty| try writer.print(
789 \\%{} = type {+}
790 \\
791 , .{ id.fmt(self), ty.fmt(self) });
792 try writer.writeByte('\n');
793 for (self.objects.items) |object| {
794 const global = self.globals.entries.get(@intFromEnum(object.global));
795 try writer.print(
796 \\@{} = {}{}{}{}{}{}{}{}{s} {}{,}
797 \\
798 , .{
799 global.key.fmt(self),
800 global.value.linkage,
801 global.value.preemption,
802 global.value.visibility,
803 global.value.dll_storage_class,
804 object.thread_local,
805 global.value.unnamed_addr,
806 global.value.addr_space,
807 global.value.externally_initialized,
808 @tagName(object.mutability),
809 global.value.type.fmt(self),
810 global.value.alignment,
811 });
812 }
813 try writer.writeByte('\n');
814 for (self.functions.items) |function| {
815 const global = self.globals.entries.get(@intFromEnum(function.global));
816 try writer.print(
817 \\{s} {}{}{}{}void @{}() {}{}{{
818 \\ ret void
819 \\}}
820 \\
821 , .{
822 if (function.body) |_| "define" else "declare",
823 global.value.linkage,
824 global.value.preemption,
825 global.value.visibility,
826 global.value.dll_storage_class,
827 global.key.fmt(self),
828 global.value.unnamed_addr,
829 global.value.alignment,
830 });
831 }
832 try writer.writeByte('\n');
833}
834
835inline fn useLibLlvm(self: *const Builder) bool {
836 return build_options.have_llvm and self.use_lib_llvm;
837}
838
839const assert = std.debug.assert;
840const build_options = @import("build_options");
841const llvm = @import("bindings.zig");
842const std = @import("std");
843
844const Allocator = std.mem.Allocator;
845const Builder = @This();
src/codegen/llvm/bindings.zig+27-3
......@@ -40,21 +40,42 @@ pub const Context = opaque {
4040 pub const halfType = LLVMHalfTypeInContext;
4141 extern fn LLVMHalfTypeInContext(C: *Context) *Type;
4242
43 pub const bfloatType = LLVMBFloatTypeInContext;
44 extern fn LLVMBFloatTypeInContext(C: *Context) *Type;
45
4346 pub const floatType = LLVMFloatTypeInContext;
4447 extern fn LLVMFloatTypeInContext(C: *Context) *Type;
4548
4649 pub const doubleType = LLVMDoubleTypeInContext;
4750 extern fn LLVMDoubleTypeInContext(C: *Context) *Type;
4851
49 pub const x86FP80Type = LLVMX86FP80TypeInContext;
50 extern fn LLVMX86FP80TypeInContext(C: *Context) *Type;
51
5252 pub const fp128Type = LLVMFP128TypeInContext;
5353 extern fn LLVMFP128TypeInContext(C: *Context) *Type;
5454
55 pub const x86_fp80Type = LLVMX86FP80TypeInContext;
56 extern fn LLVMX86FP80TypeInContext(C: *Context) *Type;
57
58 pub const ppc_fp128Type = LLVMPPCFP128TypeInContext;
59 extern fn LLVMPPCFP128TypeInContext(C: *Context) *Type;
60
61 pub const x86_amxType = LLVMX86AMXTypeInContext;
62 extern fn LLVMX86AMXTypeInContext(C: *Context) *Type;
63
64 pub const x86_mmxType = LLVMX86MMXTypeInContext;
65 extern fn LLVMX86MMXTypeInContext(C: *Context) *Type;
66
5567 pub const voidType = LLVMVoidTypeInContext;
5668 extern fn LLVMVoidTypeInContext(C: *Context) *Type;
5769
70 pub const labelType = LLVMLabelTypeInContext;
71 extern fn LLVMLabelTypeInContext(C: *Context) *Type;
72
73 pub const tokenType = LLVMTokenTypeInContext;
74 extern fn LLVMTokenTypeInContext(C: *Context) *Type;
75
76 pub const metadataType = LLVMMetadataTypeInContext;
77 extern fn LLVMMetadataTypeInContext(C: *Context) *Type;
78
5879 pub const structType = LLVMStructTypeInContext;
5980 extern fn LLVMStructTypeInContext(
6081 C: *Context,
......@@ -1071,6 +1092,9 @@ pub const TargetData = opaque {
10711092
10721093 pub const abiSizeOfType = LLVMABISizeOfType;
10731094 extern fn LLVMABISizeOfType(TD: *TargetData, Ty: *Type) c_ulonglong;
1095
1096 pub const stringRep = LLVMCopyStringRepOfTargetData;
1097 extern fn LLVMCopyStringRepOfTargetData(TD: *TargetData) [*:0]const u8;
10741098};
10751099
10761100pub const CodeModel = enum(c_int) {
src/link.zig+1
......@@ -110,6 +110,7 @@ pub const Options = struct {
110110 /// other objects.
111111 /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.
112112 use_llvm: bool,
113 use_lib_llvm: bool,
113114 link_libc: bool,
114115 link_libcpp: bool,
115116 link_libunwind: bool,
src/main.zig+8
......@@ -439,6 +439,8 @@ const usage_build_generic =
439439 \\ -fno-unwind-tables Never produce unwind table entries
440440 \\ -fLLVM Force using LLVM as the codegen backend
441441 \\ -fno-LLVM Prevent using LLVM as the codegen backend
442 \\ -flibLLVM Force using LLVM shared library apias the codegen backend
443 \\ -fno-libLLVM Prevent using LLVM as the codegen backend
442444 \\ -fClang Force using Clang as the C/C++ compilation backend
443445 \\ -fno-Clang Prevent using Clang as the C/C++ compilation backend
444446 \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
......@@ -821,6 +823,7 @@ fn buildOutputType(
821823 var stack_size_override: ?u64 = null;
822824 var image_base_override: ?u64 = null;
823825 var use_llvm: ?bool = null;
826 var use_lib_llvm: ?bool = null;
824827 var use_lld: ?bool = null;
825828 var use_clang: ?bool = null;
826829 var link_eh_frame_hdr = false;
......@@ -1261,6 +1264,10 @@ fn buildOutputType(
12611264 use_llvm = true;
12621265 } else if (mem.eql(u8, arg, "-fno-LLVM")) {
12631266 use_llvm = false;
1267 } else if (mem.eql(u8, arg, "-flibLLVM")) {
1268 use_lib_llvm = true;
1269 } else if (mem.eql(u8, arg, "-fno-libLLVM")) {
1270 use_lib_llvm = false;
12641271 } else if (mem.eql(u8, arg, "-fLLD")) {
12651272 use_lld = true;
12661273 } else if (mem.eql(u8, arg, "-fno-LLD")) {
......@@ -3119,6 +3126,7 @@ fn buildOutputType(
31193126 .want_tsan = want_tsan,
31203127 .want_compiler_rt = want_compiler_rt,
31213128 .use_llvm = use_llvm,
3129 .use_lib_llvm = use_lib_llvm,
31223130 .use_lld = use_lld,
31233131 .use_clang = use_clang,
31243132 .hash_style = hash_style,