diff options
| author | Jacob Young <jacobly0@users.noreply.github.com> | 2023-07-10 20:30:15 -0400 |
|---|---|---|
| committer | Jacob Young <jacobly0@users.noreply.github.com> | 2023-07-19 23:38:40 -0400 |
| commit | 7ec7fe53597a70a3f2c9f040d7da978ae3a52a6b (patch) | |
| tree | d5a50df9e0d541a0300967b3d1a02752f35b6054 /src/codegen/llvm.zig | |
| parent | ff8a49448c70ffe73826c7987522ed63fddd654f (diff) | |
| download | zig-7ec7fe53597a70a3f2c9f040d7da978ae3a52a6b.tar.gz zig-7ec7fe53597a70a3f2c9f040d7da978ae3a52a6b.zip | |
llvm: cleanup init
Diffstat (limited to 'src/codegen/llvm.zig')
| -rw-r--r-- | src/codegen/llvm.zig | 286 |
1 files changed, 129 insertions, 157 deletions
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 0ac30e00e7..c34e241fa4 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -35,7 +35,7 @@ const compilerRtIntAbbrev = target_util.compilerRtIntAbbrev; const Error = error{ OutOfMemory, CodegenFail }; -pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 { +pub fn targetTriple(allocator: Allocator, target: std.Target) ![]const u8 { var llvm_triple = std.ArrayList(u8).init(allocator); defer llvm_triple.deinit(); @@ -208,7 +208,7 @@ pub fn targetTriple(allocator: Allocator, target: std.Target) ![:0]u8 { }; try llvm_triple.appendSlice(llvm_abi); - return llvm_triple.toOwnedSliceSentinel(0); + return llvm_triple.toOwnedSlice(); } pub fn targetOs(os_tag: std.Target.Os.Tag) llvm.OSType { @@ -602,160 +602,137 @@ pub const Object = struct { } pub fn init(gpa: Allocator, options: link.Options) !Object { - var builder = Builder{ - .gpa = gpa, - .use_lib_llvm = options.use_lib_llvm, - - .llvm_context = llvm.Context.create(), - .llvm_module = undefined, - }; - errdefer builder.llvm_context.dispose(); - - builder.initializeLLVMTarget(options.target.cpu.arch); - - builder.llvm_module = llvm.Module.createWithName(options.root_name.ptr, builder.llvm_context); - errdefer builder.llvm_module.dispose(); - const llvm_target_triple = try targetTriple(gpa, options.target); defer gpa.free(llvm_target_triple); - var error_message: [*:0]const u8 = undefined; - var target: *llvm.Target = undefined; - if (llvm.Target.getFromTriple(llvm_target_triple.ptr, &target, &error_message).toBool()) { - defer llvm.disposeMessage(error_message); - - log.err("LLVM failed to parse '{s}': {s}", .{ llvm_target_triple, error_message }); - return error.InvalidLlvmTriple; - } - - builder.llvm_module.setTarget(llvm_target_triple.ptr); - var opt_di_builder: ?*llvm.DIBuilder = null; - errdefer if (opt_di_builder) |di_builder| di_builder.dispose(); + var builder = try Builder.init(.{ + .allocator = gpa, + .use_lib_llvm = options.use_lib_llvm, + .name = options.root_name, + .target = options.target, + .triple = llvm_target_triple, + }); + errdefer builder.deinit(); - var di_compile_unit: ?*llvm.DICompileUnit = null; + var target_machine: *llvm.TargetMachine = undefined; + var target_data: *llvm.TargetData = undefined; + if (builder.useLibLlvm()) { + if (!options.strip) { + switch (options.target.ofmt) { + .coff => builder.llvm.module.?.addModuleCodeViewFlag(), + else => builder.llvm.module.?.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"), + } + builder.llvm.di_builder = builder.llvm.module.?.createDIBuilder(true); + + // Don't use the version string here; LLVM misparses it when it + // includes the git revision. + const producer = try builder.fmt("zig {d}.{d}.{d}", .{ + build_options.semver.major, + build_options.semver.minor, + build_options.semver.patch, + }); - if (!options.strip) { - switch (options.target.ofmt) { - .coff => builder.llvm_module.addModuleCodeViewFlag(), - else => builder.llvm_module.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"), - } - const di_builder = builder.llvm_module.createDIBuilder(true); - opt_di_builder = di_builder; - - // Don't use the version string here; LLVM misparses it when it - // includes the git revision. - const producer = try std.fmt.allocPrintZ(gpa, "zig {d}.{d}.{d}", .{ - build_options.semver.major, - build_options.semver.minor, - build_options.semver.patch, - }); - defer gpa.free(producer); - - // We fully resolve all paths at this point to avoid lack of source line info in stack - // traces or lack of debugging information which, if relative paths were used, would - // be very location dependent. - // TODO: the only concern I have with this is WASI as either host or target, should - // we leave the paths as relative then? - var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; - const compile_unit_dir = blk: { - const path = d: { - const mod = options.module orelse break :d "."; - break :d mod.root_pkg.root_src_directory.path orelse "."; + // We fully resolve all paths at this point to avoid lack of source line info in stack + // traces or lack of debugging information which, if relative paths were used, would + // be very location dependent. + // TODO: the only concern I have with this is WASI as either host or target, should + // we leave the paths as relative then? + var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + const compile_unit_dir = blk: { + const path = d: { + const mod = options.module orelse break :d "."; + break :d mod.root_pkg.root_src_directory.path orelse "."; + }; + if (std.fs.path.isAbsolute(path)) break :blk path; + break :blk std.os.realpath(path, &buf) catch path; // If realpath fails, fallback to whatever path was }; - if (std.fs.path.isAbsolute(path)) break :blk path; - break :blk std.os.realpath(path, &buf) catch path; // If realpath fails, fallback to whatever path was - }; - const compile_unit_dir_z = try gpa.dupeZ(u8, compile_unit_dir); - defer gpa.free(compile_unit_dir_z); - - di_compile_unit = di_builder.createCompileUnit( - DW.LANG.C99, - di_builder.createFile(options.root_name, compile_unit_dir_z), - producer, - options.optimize_mode != .Debug, - "", // flags - 0, // runtime version - "", // split name - 0, // dwo id - true, // emit debug info - ); - } - - const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug) - .None - else - .Aggressive; + const compile_unit_dir_z = try builder.gpa.dupeZ(u8, compile_unit_dir); + defer builder.gpa.free(compile_unit_dir_z); + + builder.llvm.di_compile_unit = builder.llvm.di_builder.?.createCompileUnit( + DW.LANG.C99, + builder.llvm.di_builder.?.createFile(options.root_name, compile_unit_dir_z), + producer.toSlice(&builder).?, + options.optimize_mode != .Debug, + "", // flags + 0, // runtime version + "", // split name + 0, // dwo id + true, // emit debug info + ); + } - const reloc_mode: llvm.RelocMode = if (options.pic) - .PIC - else if (options.link_mode == .Dynamic) - llvm.RelocMode.DynamicNoPIC - else - .Static; - - const code_model: llvm.CodeModel = switch (options.machine_code_model) { - .default => .Default, - .tiny => .Tiny, - .small => .Small, - .kernel => .Kernel, - .medium => .Medium, - .large => .Large, - }; + const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug) + .None + else + .Aggressive; - // TODO handle float ABI better- it should depend on the ABI portion of std.Target - const float_abi: llvm.ABIType = .Default; - - const target_machine = llvm.TargetMachine.create( - target, - llvm_target_triple.ptr, - if (options.target.cpu.model.llvm_name) |s| s.ptr else null, - options.llvm_cpu_features, - opt_level, - reloc_mode, - code_model, - options.function_sections, - float_abi, - if (target_util.llvmMachineAbi(options.target)) |s| s.ptr else null, - ); - errdefer target_machine.dispose(); + const reloc_mode: llvm.RelocMode = if (options.pic) + .PIC + else if (options.link_mode == .Dynamic) + llvm.RelocMode.DynamicNoPIC + else + .Static; + + const code_model: llvm.CodeModel = switch (options.machine_code_model) { + .default => .Default, + .tiny => .Tiny, + .small => .Small, + .kernel => .Kernel, + .medium => .Medium, + .large => .Large, + }; - const target_data = target_machine.createTargetDataLayout(); - errdefer target_data.dispose(); + // TODO handle float ABI better- it should depend on the ABI portion of std.Target + const float_abi: llvm.ABIType = .Default; + + target_machine = llvm.TargetMachine.create( + builder.llvm.target.?, + builder.target_triple.toSlice(&builder).?.ptr, + if (options.target.cpu.model.llvm_name) |s| s.ptr else null, + options.llvm_cpu_features, + opt_level, + reloc_mode, + code_model, + options.function_sections, + float_abi, + if (target_util.llvmMachineAbi(options.target)) |s| s.ptr else null, + ); + errdefer target_machine.dispose(); - builder.llvm_module.setModuleDataLayout(target_data); + target_data = target_machine.createTargetDataLayout(); + errdefer target_data.dispose(); - if (options.pic) builder.llvm_module.setModulePICLevel(); - if (options.pie) builder.llvm_module.setModulePIELevel(); - if (code_model != .Default) builder.llvm_module.setModuleCodeModel(code_model); + builder.llvm.module.?.setModuleDataLayout(target_data); - if (options.opt_bisect_limit >= 0) { - builder.llvm_context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit)); - } + if (options.pic) builder.llvm.module.?.setModulePICLevel(); + if (options.pie) builder.llvm.module.?.setModulePIELevel(); + if (code_model != .Default) builder.llvm.module.?.setModuleCodeModel(code_model); - try builder.init(); - errdefer builder.deinit(); - builder.source_filename = try builder.string(options.root_name); - builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = options.target }}); - builder.target_triple = try builder.string(llvm_target_triple); + if (options.opt_bisect_limit >= 0) { + builder.llvm.context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit)); + } - if (std.debug.runtime_safety) { - const rep = target_data.stringRep(); - defer llvm.disposeMessage(rep); - std.testing.expectEqualStrings( - std.mem.span(rep), - builder.data_layout.toSlice(&builder).?, - ) catch unreachable; + builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = options.target }}); + if (std.debug.runtime_safety) { + const rep = target_data.stringRep(); + defer llvm.disposeMessage(rep); + std.testing.expectEqualStrings( + std.mem.span(rep), + builder.data_layout.toSlice(&builder).?, + ) catch unreachable; + } } - return Object{ + return .{ .gpa = gpa, .builder = builder, .module = options.module.?, - .llvm_module = builder.llvm_module, + .llvm_module = builder.llvm.module.?, .di_map = .{}, - .di_builder = opt_di_builder, - .di_compile_unit = di_compile_unit, - .context = builder.llvm_context, + .di_builder = builder.llvm.di_builder, + .di_compile_unit = builder.llvm.di_compile_unit, + .context = builder.llvm.context, .target_machine = target_machine, .target_data = target_data, .target = options.target, @@ -770,15 +747,10 @@ pub const Object = struct { } pub fn deinit(self: *Object, gpa: Allocator) void { - if (self.di_builder) |dib| { - dib.dispose(); - self.di_map.deinit(gpa); - self.di_type_map.deinit(gpa); - } + self.di_map.deinit(gpa); + self.di_type_map.deinit(gpa); self.target_data.dispose(); self.target_machine.dispose(); - self.llvm_module.dispose(); - self.context.dispose(); self.decl_map.deinit(gpa); self.named_enum_map.deinit(gpa); self.type_map.deinit(gpa); @@ -845,7 +817,7 @@ pub const Object = struct { .mutability = .constant, .init = str_init, }; - try o.builder.llvm_globals.append(o.gpa, str_global); + try o.builder.llvm.globals.append(o.gpa, str_global); const str_global_index = try o.builder.addGlobal(.none, global); try o.builder.variables.append(o.gpa, variable); @@ -875,7 +847,7 @@ pub const Object = struct { .mutability = .constant, .init = error_name_table_init, }; - try o.builder.llvm_globals.append(o.gpa, error_name_table_global); + try o.builder.llvm.globals.append(o.gpa, error_name_table_global); _ = try o.builder.addGlobal(.none, global); try o.builder.variables.append(o.gpa, variable); @@ -941,7 +913,7 @@ pub const Object = struct { llvm_global.replaceAllUsesWith(other_llvm_global); deleteLlvmGlobal(llvm_global); - object.builder.llvm_globals.items[@intFromEnum(global)] = other_llvm_global; + object.builder.llvm.globals.items[@intFromEnum(global)] = other_llvm_global; } object.extern_collisions.clearRetainingCapacity(); @@ -960,7 +932,7 @@ pub const Object = struct { other_llvm_global.replaceAllUsesWith(llvm_global); try global.takeName(&object.builder, other_global); deleteLlvmGlobal(other_llvm_global); - object.builder.llvm_globals.items[@intFromEnum(other_global)] = llvm_global; + object.builder.llvm.globals.items[@intFromEnum(other_global)] = llvm_global; // Problem: now we need to replace in the decl_map that // the extern decl index points to this new global. However we don't // know the decl index. @@ -2765,7 +2737,7 @@ pub const Object = struct { .global = @enumFromInt(o.builder.globals.count()), .init = llvm_init, }; - try o.builder.llvm_globals.append(o.gpa, llvm_global); + try o.builder.llvm.globals.append(o.gpa, llvm_global); _ = try o.builder.addGlobal(.none, global); try o.builder.variables.append(o.gpa, variable); @@ -2908,7 +2880,7 @@ pub const Object = struct { }; } - try o.builder.llvm_globals.append(o.gpa, llvm_fn); + try o.builder.llvm.globals.append(o.gpa, llvm_fn); gop.value_ptr.* = try o.builder.addGlobal(fqn, global); try o.builder.functions.append(o.gpa, function); return global.kind.function; @@ -3017,7 +2989,7 @@ pub const Object = struct { llvm_global.setUnnamedAddr(.True); } - try o.builder.llvm_globals.append(o.gpa, llvm_global); + try o.builder.llvm.globals.append(o.gpa, llvm_global); gop.value_ptr.* = try o.builder.addGlobal(name, global); try o.builder.variables.append(o.gpa, variable); return global.kind.variable; @@ -4553,7 +4525,7 @@ pub const DeclGen = struct { // TODO: How should this work then the address space of a global changed? llvm_global.replaceAllUsesWith(new_global); new_global.takeName(llvm_global); - o.builder.llvm_globals.items[@intFromEnum(object.ptrConst(&o.builder).global)] = + o.builder.llvm.globals.items[@intFromEnum(object.ptrConst(&o.builder).global)] = new_global; llvm_global.deleteGlobal(); llvm_global = new_global; @@ -4699,7 +4671,7 @@ pub const FuncGen = struct { .mutability = .constant, .init = llvm_val, }; - try o.builder.llvm_globals.append(o.gpa, llvm_global); + try o.builder.llvm.globals.append(o.gpa, llvm_global); _ = try o.builder.addGlobal(.none, global); try o.builder.variables.append(o.gpa, variable); @@ -7855,7 +7827,7 @@ pub const FuncGen = struct { .global = @enumFromInt(o.builder.globals.count()), }; - try o.builder.llvm_globals.append(self.gpa, f); + try o.builder.llvm.globals.append(self.gpa, f); _ = try o.builder.addGlobal(fn_name, global); try o.builder.functions.append(self.gpa, function); break :b f; @@ -9372,7 +9344,7 @@ pub const FuncGen = struct { self.builder.positionBuilderAtEnd(unnamed_block); _ = self.builder.buildRet(Builder.Constant.false.toLlvm(&o.builder)); - try o.builder.llvm_globals.append(self.gpa, fn_val); + try o.builder.llvm.globals.append(self.gpa, fn_val); _ = try o.builder.addGlobal(llvm_fn_name, global); try o.builder.functions.append(self.gpa, function); gop.value_ptr.* = global.kind.function; @@ -9484,7 +9456,7 @@ pub const FuncGen = struct { self.builder.positionBuilderAtEnd(bad_value_block); _ = self.builder.buildUnreachable(); - try o.builder.llvm_globals.append(self.gpa, fn_val); + try o.builder.llvm.globals.append(self.gpa, fn_val); gop.value_ptr.* = try o.builder.addGlobal(llvm_fn_name, global); try o.builder.functions.append(self.gpa, function); return fn_val; @@ -9515,7 +9487,7 @@ pub const FuncGen = struct { .global = @enumFromInt(o.builder.globals.count()), }; - try o.builder.llvm_globals.append(self.gpa, llvm_fn); + try o.builder.llvm.globals.append(self.gpa, llvm_fn); _ = try o.builder.addGlobal(try o.builder.string(lt_errors_fn_name), global); try o.builder.functions.append(self.gpa, function); return llvm_fn; @@ -10156,7 +10128,7 @@ pub const FuncGen = struct { .mutability = .constant, .init = undef_init, }; - try o.builder.llvm_globals.append(o.gpa, error_name_table_global); + try o.builder.llvm.globals.append(o.gpa, error_name_table_global); _ = try o.builder.addGlobal(name, global); try o.builder.variables.append(o.gpa, variable); |
