diff --git a/src/Compilation.zig b/src/Compilation.zig index ce7f204dd6..b07761e7cb 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -992,6 +992,12 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { } else if (options.target.os.tag == .windows and link_libcpp) { // https://github.com/ziglang/zig/issues/8531 break :blk false; + } else if (options.target.cpu.arch.isRISCV()) { + // Clang and LLVM currently don't support RISC-V target-abi for LTO. + // Compiling with LTO may fail or produce undesired results. + // See https://reviews.llvm.org/D71387 + // See https://reviews.llvm.org/D102582 + break :blk false; } else switch (options.output_mode) { .Lib, .Obj => break :blk false, .Exe => switch (options.optimize_mode) { @@ -1780,8 +1786,8 @@ pub fn getTarget(self: Compilation) Target { /// Detect changes to source files, perform semantic analysis, and update the output files. pub fn update(self: *Compilation) !void { - const t = trace(@src()); - defer t.end(); + const tracy_trace = trace(@src()); + defer tracy_trace.end(); self.clearMiscFailures(); @@ -2822,8 +2828,8 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult { if (!build_options.have_llvm) return error.ZigCompilerNotBuiltWithLLVMExtensions; - const t = trace(@src()); - defer t.end(); + const tracy_trace = trace(@src()); + defer tracy_trace.end(); const cimport_zig_basename = "cimport.zig"; @@ -3077,8 +3083,8 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P const self_exe_path = comp.self_exe_path orelse return comp.failCObj(c_object, "clang compilation disabled", .{}); - const t = trace(@src()); - defer t.end(); + const tracy_trace = trace(@src()); + defer tracy_trace.end(); log.debug("updating C object: {s}", .{c_object.src.src_path}); @@ -3590,6 +3596,11 @@ pub fn addCCArgs( } }, } + + if (target_util.llvmMachineAbi(target)) |mabi| { + try argv.append(try std.fmt.allocPrint(arena, "-mabi={s}", .{mabi})); + } + if (out_dep_path) |p| { try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p }); } @@ -4036,8 +4047,8 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool { } fn updateBuiltinZigFile(comp: *Compilation, mod: *Module) Allocator.Error!void { - const t = trace(@src()); - defer t.end(); + const tracy_trace = trace(@src()); + defer tracy_trace.end(); const source = try comp.generateBuiltinZigSource(comp.gpa); defer comp.gpa.free(source); @@ -4074,8 +4085,8 @@ pub fn dump_argv(argv: []const []const u8) void { } pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Allocator.Error![]u8 { - const t = trace(@src()); - defer t.end(); + const tracy_trace = trace(@src()); + defer tracy_trace.end(); var buffer = std.ArrayList(u8).init(allocator); defer buffer.deinit(); @@ -4320,8 +4331,8 @@ fn buildOutputFromZig( out: *?CRTFile, misc_task_tag: MiscTask, ) !void { - const t = trace(@src()); - defer t.end(); + const tracy_trace = trace(@src()); + defer tracy_trace.end(); std.debug.assert(output_mode != .Exe); const special_sub = "std" ++ std.fs.path.sep_str ++ "special"; @@ -4419,8 +4430,8 @@ fn buildOutputFromZig( } fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node) !void { - const t = trace(@src()); - defer t.end(); + const tracy_trace = trace(@src()); + defer tracy_trace.end(); var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); defer arena_allocator.deinit(); @@ -4566,6 +4577,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node .is_native_cpu = false, // Only true when bootstrapping the compiler. .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null, .llvm_cpu_features = comp.bin_file.options.llvm_cpu_features.?, + .llvm_target_abi = if (target_util.llvmMachineAbi(target)) |s| s.ptr else null, }; comp.stage1_cache_manifest = &man; @@ -4773,8 +4785,8 @@ pub fn build_crt_file( output_mode: std.builtin.OutputMode, c_source_files: []const Compilation.CSourceFile, ) !void { - const t = trace(@src()); - defer t.end(); + const tracy_trace = trace(@src()); + defer tracy_trace.end(); const target = comp.getTarget(); const basename = try std.zig.binNameAlloc(comp.gpa, .{ diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 4600c2e07e..58239fdaea 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -15,6 +15,7 @@ const TypedValue = @import("../TypedValue.zig"); const Zir = @import("../Zir.zig"); const Air = @import("../Air.zig"); const Liveness = @import("../Liveness.zig"); +const target_util = @import("../target.zig"); const Value = @import("../value.zig").Value; const Type = @import("../type.zig").Type; @@ -244,19 +245,6 @@ pub const Object = struct { // TODO handle float ABI better- it should depend on the ABI portion of std.Target const float_abi: llvm.ABIType = .Default; - // TODO a way to override this as part of std.Target ABI? - const abi_name: ?[*:0]const u8 = switch (options.target.cpu.arch) { - .riscv32 => switch (options.target.os.tag) { - .linux => "ilp32d", - else => "ilp32", - }, - .riscv64 => switch (options.target.os.tag) { - .linux => "lp64d", - else => "lp64", - }, - else => null, - }; - const target_machine = llvm.TargetMachine.create( target, llvm_target_triple.ptr, @@ -267,7 +255,7 @@ pub const Object = struct { code_model, options.function_sections, float_abi, - abi_name, + if (target_util.llvmMachineAbi(options.target)) |s| s.ptr else null, ); errdefer target_machine.dispose(); diff --git a/src/stage1.zig b/src/stage1.zig index 8e6090af0b..8263427fbe 100644 --- a/src/stage1.zig +++ b/src/stage1.zig @@ -364,6 +364,7 @@ pub const Stage2Target = extern struct { llvm_cpu_name: ?[*:0]const u8, llvm_cpu_features: ?[*:0]const u8, + llvm_target_abi: ?[*:0]const u8, }; // ABI warning diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 8faebbe148..cba820037e 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -9487,9 +9487,8 @@ static void init(CodeGen *g) { // TODO handle float ABI better- it should depend on the ABI portion of std.Target ZigLLVMABIType float_abi = ZigLLVMABITypeDefault; - // TODO a way to override this as part of std.Target ABI? - const char *abi_name = nullptr; - if (target_is_riscv(g->zig_target)) { + const char *abi_name = g->zig_target->llvm_target_abi; + if (abi_name == nullptr && target_is_riscv(g->zig_target)) { // RISC-V Linux defaults to ilp32d/lp64d if (g->zig_target->os == OsLinux) { abi_name = (g->zig_target->arch == ZigLLVM_riscv32) ? "ilp32d" : "lp64d"; diff --git a/src/stage1/stage1.h b/src/stage1/stage1.h index ce8254eaef..2b2e5a85b0 100644 --- a/src/stage1/stage1.h +++ b/src/stage1/stage1.h @@ -112,6 +112,7 @@ struct ZigTarget { const char *llvm_cpu_name; const char *llvm_cpu_features; + const char *llvm_target_abi; }; // ABI warning diff --git a/src/target.zig b/src/target.zig index 9d22feff66..5b2f6f5978 100644 --- a/src/target.zig +++ b/src/target.zig @@ -599,3 +599,38 @@ pub fn defaultAddressSpace( _ = context; return .generic; } + +pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 { + const have_float = switch (target.abi) { + .gnuilp32 => return "ilp32", + .gnueabihf, .musleabihf, .eabihf => true, + else => false, + }; + + switch (target.cpu.arch) { + .riscv64 => { + const featureSetHas = std.Target.riscv.featureSetHas; + if (featureSetHas(target.cpu.features, .d)) { + return "lp64d"; + } else if (have_float) { + return "lp64f"; + } else { + return "lp64"; + } + }, + .riscv32 => { + const featureSetHas = std.Target.riscv.featureSetHas; + if (featureSetHas(target.cpu.features, .d)) { + return "ilp32d"; + } else if (have_float) { + return "ilp32f"; + } else if (featureSetHas(target.cpu.features, .e)) { + return "ilp32e"; + } else { + return "ilp32"; + } + }, + //TODO add ARM, Mips, and PowerPC + else => return null, + } +}