llvm: Pass EmitOptions to libzigcpp by pointer.

Passing it by value means that bringup on new architectures is harder for no
real benefit. Passing it by pointer allows to get the compiler running without
needing to figure out the C calling convention details first. This manifested in
practice on LoongArch, for example.
This commit is contained in:
Alex Rønne Petersen 2024-08-30 12:18:37 +02:00 committed by Andrew Kelley
parent aaca4ff74d
commit 5723fcaac1
4 changed files with 31 additions and 31 deletions

View File

@ -1325,7 +1325,7 @@ pub const Object = struct {
},
};
if (options.asm_path != null and options.bin_path != null) {
if (target_machine.emitToFile(module, &error_message, lowered_options)) {
if (target_machine.emitToFile(module, &error_message, &lowered_options)) {
defer llvm.disposeMessage(error_message);
log.err("LLVM failed to emit bin={s} ir={s}: {s}", .{
emit_bin_msg, post_llvm_ir_msg, error_message,
@ -1337,7 +1337,7 @@ pub const Object = struct {
}
lowered_options.asm_filename = options.asm_path;
if (target_machine.emitToFile(module, &error_message, lowered_options)) {
if (target_machine.emitToFile(module, &error_message, &lowered_options)) {
defer llvm.disposeMessage(error_message);
log.err("LLVM failed to emit asm={s} bin={s} ir={s} bc={s}: {s}", .{
emit_asm_msg, emit_bin_msg, post_llvm_ir_msg, post_llvm_bc_msg,

View File

@ -130,7 +130,7 @@ pub const TargetMachine = opaque {
T: *TargetMachine,
M: *Module,
ErrorMessage: *[*:0]const u8,
options: EmitOptions,
options: *const EmitOptions,
) bool;
pub const createTargetDataLayout = LLVMCreateTargetDataLayout;

View File

@ -213,33 +213,33 @@ static SanitizerCoverageOptions getSanCovOptions(ZigLLVMCoverageOptions z) {
}
ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
char **error_message, struct ZigLLVMEmitOptions options)
char **error_message, const struct ZigLLVMEmitOptions *options)
{
TimePassesIsEnabled = options.time_report;
TimePassesIsEnabled = options->time_report;
raw_fd_ostream *dest_asm_ptr = nullptr;
raw_fd_ostream *dest_bin_ptr = nullptr;
raw_fd_ostream *dest_bitcode_ptr = nullptr;
if (options.asm_filename) {
if (options->asm_filename) {
std::error_code EC;
dest_asm_ptr = new(std::nothrow) raw_fd_ostream(options.asm_filename, EC, sys::fs::OF_None);
dest_asm_ptr = new(std::nothrow) raw_fd_ostream(options->asm_filename, EC, sys::fs::OF_None);
if (EC) {
*error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
return true;
}
}
if (options.bin_filename) {
if (options->bin_filename) {
std::error_code EC;
dest_bin_ptr = new(std::nothrow) raw_fd_ostream(options.bin_filename, EC, sys::fs::OF_None);
dest_bin_ptr = new(std::nothrow) raw_fd_ostream(options->bin_filename, EC, sys::fs::OF_None);
if (EC) {
*error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
return true;
}
}
if (options.bitcode_filename) {
if (options->bitcode_filename) {
std::error_code EC;
dest_bitcode_ptr = new(std::nothrow) raw_fd_ostream(options.bitcode_filename, EC, sys::fs::OF_None);
dest_bitcode_ptr = new(std::nothrow) raw_fd_ostream(options->bitcode_filename, EC, sys::fs::OF_None);
if (EC) {
*error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
return true;
@ -255,7 +255,7 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi
std::string ProcName = "zig-";
ProcName += std::to_string(PID);
TimeTracerRAII TimeTracer(ProcName,
options.bin_filename? options.bin_filename : options.asm_filename);
options->bin_filename? options->bin_filename : options->asm_filename);
TargetMachine &target_machine = *reinterpret_cast<TargetMachine*>(targ_machine_ref);
target_machine.setO0WantsFastISel(true);
@ -264,11 +264,11 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi
// Pipeline configurations
PipelineTuningOptions pipeline_opts;
pipeline_opts.LoopUnrolling = !options.is_debug;
pipeline_opts.SLPVectorization = !options.is_debug;
pipeline_opts.LoopVectorization = !options.is_debug;
pipeline_opts.LoopInterleaving = !options.is_debug;
pipeline_opts.MergeFunctions = !options.is_debug;
pipeline_opts.LoopUnrolling = !options->is_debug;
pipeline_opts.SLPVectorization = !options->is_debug;
pipeline_opts.LoopVectorization = !options->is_debug;
pipeline_opts.LoopInterleaving = !options->is_debug;
pipeline_opts.MergeFunctions = !options->is_debug;
// Instrumentations
PassInstrumentationCallbacks instr_callbacks;
@ -306,7 +306,7 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi
module_pm.addPass(VerifierPass());
}
if (!options.is_debug) {
if (!options->is_debug) {
module_pm.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass()));
}
});
@ -316,12 +316,12 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi
pass_builder.registerOptimizerLastEPCallback([&](ModulePassManager &module_pm, OptimizationLevel level) {
// Code coverage instrumentation.
if (options.sancov) {
module_pm.addPass(SanitizerCoveragePass(getSanCovOptions(options.coverage)));
if (options->sancov) {
module_pm.addPass(SanitizerCoveragePass(getSanCovOptions(options->coverage)));
}
// Thread sanitizer
if (options.tsan) {
if (options->tsan) {
module_pm.addPass(ModuleThreadSanitizerPass());
module_pm.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
}
@ -335,17 +335,17 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi
ModulePassManager module_pm;
OptimizationLevel opt_level;
// Setting up the optimization level
if (options.is_debug)
if (options->is_debug)
opt_level = OptimizationLevel::O0;
else if (options.is_small)
else if (options->is_small)
opt_level = OptimizationLevel::Oz;
else
opt_level = OptimizationLevel::O3;
// Initialize the PassManager
if (opt_level == OptimizationLevel::O0) {
module_pm = pass_builder.buildO0DefaultPipeline(opt_level, options.lto);
} else if (options.lto) {
module_pm = pass_builder.buildO0DefaultPipeline(opt_level, options->lto);
} else if (options->lto) {
module_pm = pass_builder.buildLTOPreLinkDefaultPipeline(opt_level);
} else {
module_pm = pass_builder.buildPerModuleDefaultPipeline(opt_level);
@ -356,7 +356,7 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi
codegen_pm.add(
createTargetTransformInfoWrapperPass(target_machine.getTargetIRAnalysis()));
if (dest_bin && !options.lto) {
if (dest_bin && !options->lto) {
if (target_machine.addPassesToEmitFile(codegen_pm, *dest_bin, nullptr, CodeGenFileType::ObjectFile)) {
*error_message = strdup("TargetMachine can't emit an object file");
return true;
@ -375,20 +375,20 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi
// Code generation phase
codegen_pm.run(llvm_module);
if (options.llvm_ir_filename) {
if (LLVMPrintModuleToFile(module_ref, options.llvm_ir_filename, error_message)) {
if (options->llvm_ir_filename) {
if (LLVMPrintModuleToFile(module_ref, options->llvm_ir_filename, error_message)) {
return true;
}
}
if (dest_bin && options.lto) {
if (dest_bin && options->lto) {
WriteBitcodeToFile(llvm_module, *dest_bin);
}
if (dest_bitcode) {
WriteBitcodeToFile(llvm_module, *dest_bitcode);
}
if (options.time_report) {
if (options->time_report) {
TimerGroup::printAll(errs());
}

View File

@ -67,7 +67,7 @@ struct ZigLLVMEmitOptions {
};
ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
char **error_message, struct ZigLLVMEmitOptions options);
char **error_message, const struct ZigLLVMEmitOptions *options);
enum ZigLLVMABIType {
ZigLLVMABITypeDefault, // Target-specific (either soft or hard depending on triple, etc).