Commit 33d4742456
Changed files (5)
src
src/codegen/llvm/bindings.zig
@@ -84,11 +84,7 @@ pub const TargetMachine = opaque {
pub const dispose = LLVMDisposeTargetMachine;
extern fn LLVMDisposeTargetMachine(T: *TargetMachine) void;
- pub const emitToFile = ZigLLVMTargetMachineEmitToFile;
- extern fn ZigLLVMTargetMachineEmitToFile(
- T: *TargetMachine,
- M: *Module,
- ErrorMessage: *[*:0]const u8,
+ pub const EmitOptions = extern struct {
is_debug: bool,
is_small: bool,
time_report: bool,
@@ -99,6 +95,42 @@ pub const TargetMachine = opaque {
bin_filename: ?[*:0]const u8,
llvm_ir_filename: ?[*:0]const u8,
bitcode_filename: ?[*:0]const u8,
+ coverage: Coverage,
+
+ pub const Coverage = extern struct {
+ CoverageType: Coverage.Type,
+ IndirectCalls: bool,
+ TraceBB: bool,
+ TraceCmp: bool,
+ TraceDiv: bool,
+ TraceGep: bool,
+ Use8bitCounters: bool,
+ TracePC: bool,
+ TracePCGuard: bool,
+ Inline8bitCounters: bool,
+ InlineBoolFlag: bool,
+ PCTable: bool,
+ NoPrune: bool,
+ StackDepth: bool,
+ TraceLoads: bool,
+ TraceStores: bool,
+ CollectControlFlow: bool,
+
+ pub const Type = enum(c_uint) {
+ None = 0,
+ Function,
+ BB,
+ Edge,
+ };
+ };
+ };
+
+ pub const emitToFile = ZigLLVMTargetMachineEmitToFile;
+ extern fn ZigLLVMTargetMachineEmitToFile(
+ T: *TargetMachine,
+ M: *Module,
+ ErrorMessage: *[*:0]const u8,
+ options: EmitOptions,
) bool;
pub const createTargetDataLayout = LLVMCreateTargetDataLayout;
src/codegen/llvm.zig
@@ -1278,50 +1278,52 @@ pub const Object = struct {
// Unfortunately, LLVM shits the bed when we ask for both binary and assembly.
// So we call the entire pipeline multiple times if this is requested.
// var error_message: [*:0]const u8 = undefined;
- var emit_bin_path = options.bin_path;
- var post_ir_path = options.post_ir_path;
+ var lowered_options: llvm.TargetMachine.EmitOptions = .{
+ .is_debug = options.is_debug,
+ .is_small = options.is_small,
+ .time_report = options.time_report,
+ .tsan = options.sanitize_thread,
+ .sancov = options.fuzz,
+ .lto = options.lto,
+ .asm_filename = null,
+ .bin_filename = options.bin_path,
+ .llvm_ir_filename = options.post_ir_path,
+ .bitcode_filename = null,
+ .coverage = .{
+ .CoverageType = .Edge,
+ .IndirectCalls = true,
+ .TraceBB = false,
+ .TraceCmp = true,
+ .TraceDiv = false,
+ .TraceGep = false,
+ .Use8bitCounters = false,
+ .TracePC = false,
+ .TracePCGuard = true,
+ .Inline8bitCounters = true,
+ .InlineBoolFlag = false,
+ .PCTable = true,
+ .NoPrune = false,
+ .StackDepth = true,
+ .TraceLoads = false,
+ .TraceStores = false,
+ .CollectControlFlow = false,
+ },
+ };
if (options.asm_path != null and options.bin_path != null) {
- if (target_machine.emitToFile(
- module,
- &error_message,
- options.is_debug,
- options.is_small,
- options.time_report,
- options.sanitize_thread,
- options.fuzz,
- options.lto,
- null,
- emit_bin_path,
- post_ir_path,
- null,
- )) {
+ 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,
});
return error.FailedToEmit;
}
- emit_bin_path = null;
- post_ir_path = null;
- }
-
- if (target_machine.emitToFile(
- module,
- &error_message,
- options.is_debug,
- options.is_small,
- options.time_report,
- options.sanitize_thread,
- options.fuzz,
- options.lto,
- options.asm_path,
- emit_bin_path,
- post_ir_path,
- null,
- )) {
- defer llvm.disposeMessage(error_message);
+ lowered_options.bin_filename = null;
+ lowered_options.llvm_ir_filename = null;
+ }
+ lowered_options.asm_filename = options.asm_path;
+ 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,
error_message,
src/Compilation.zig
@@ -5652,6 +5652,10 @@ pub fn addCCArgs(
// function was called.
try argv.append("-fno-sanitize=function");
}
+
+ if (mod.fuzz) {
+ try argv.appendSlice(&.{ "-Xclang", "-fsanitize-coverage-trace-pc-guard" });
+ }
}
}
src/zig_llvm.cpp
@@ -189,59 +189,56 @@ struct TimeTracerRAII {
};
} // end anonymous namespace
-static SanitizerCoverageOptions getSanCovOptions(void) {
+static SanitizerCoverageOptions getSanCovOptions(ZigLLVMCoverageOptions z) {
SanitizerCoverageOptions o;
- o.CoverageType = SanitizerCoverageOptions::SCK_Edge;
- o.IndirectCalls = true;
- o.TraceBB = false;
- o.TraceCmp = true;
- o.TraceDiv = false;
- o.TraceGep = false;
- o.Use8bitCounters = false;
- o.TracePC = false;
- o.TracePCGuard = false;
- o.Inline8bitCounters = true;
- o.InlineBoolFlag = false;
- o.PCTable = true;
- o.NoPrune = false;
- o.StackDepth = true;
- o.TraceLoads = false;
- o.TraceStores = false;
- o.CollectControlFlow = false;
+ o.CoverageType = (SanitizerCoverageOptions::Type)z.CoverageType;
+ o.IndirectCalls = z.IndirectCalls;
+ o.TraceBB = z.TraceBB;
+ o.TraceCmp = z.TraceCmp;
+ o.TraceDiv = z.TraceDiv;
+ o.TraceGep = z.TraceGep;
+ o.Use8bitCounters = z.Use8bitCounters;
+ o.TracePC = z.TracePC;
+ o.TracePCGuard = z.TracePCGuard;
+ o.Inline8bitCounters = z.Inline8bitCounters;
+ o.InlineBoolFlag = z.InlineBoolFlag;
+ o.PCTable = z.PCTable;
+ o.NoPrune = z.NoPrune;
+ o.StackDepth = z.StackDepth;
+ o.TraceLoads = z.TraceLoads;
+ o.TraceStores = z.TraceStores;
+ o.CollectControlFlow = z.CollectControlFlow;
return o;
}
-bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
- char **error_message, bool is_debug,
- bool is_small, bool time_report, bool tsan, bool sancov, bool lto,
- const char *asm_filename, const char *bin_filename,
- const char *llvm_ir_filename, const char *bitcode_filename)
+ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
+ char **error_message, struct ZigLLVMEmitOptions options)
{
- TimePassesIsEnabled = 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 (asm_filename) {
+ if (options.asm_filename) {
std::error_code EC;
- dest_asm_ptr = new(std::nothrow) raw_fd_ostream(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 (bin_filename) {
+ if (options.bin_filename) {
std::error_code EC;
- dest_bin_ptr = new(std::nothrow) raw_fd_ostream(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 (bitcode_filename) {
+ if (options.bitcode_filename) {
std::error_code EC;
- dest_bitcode_ptr = new(std::nothrow) raw_fd_ostream(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;
@@ -257,7 +254,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
std::string ProcName = "zig-";
ProcName += std::to_string(PID);
TimeTracerRAII TimeTracer(ProcName,
- bin_filename? bin_filename : asm_filename);
+ options.bin_filename? options.bin_filename : options.asm_filename);
TargetMachine &target_machine = *reinterpret_cast<TargetMachine*>(targ_machine_ref);
target_machine.setO0WantsFastISel(true);
@@ -266,11 +263,11 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
// Pipeline configurations
PipelineTuningOptions pipeline_opts;
- pipeline_opts.LoopUnrolling = !is_debug;
- pipeline_opts.SLPVectorization = !is_debug;
- pipeline_opts.LoopVectorization = !is_debug;
- pipeline_opts.LoopInterleaving = !is_debug;
- pipeline_opts.MergeFunctions = !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;
@@ -308,19 +305,19 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
module_pm.addPass(VerifierPass());
}
- if (!is_debug) {
+ if (!options.is_debug) {
module_pm.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass()));
}
});
pass_builder.registerOptimizerEarlyEPCallback([&](ModulePassManager &module_pm, OptimizationLevel OL) {
// Code coverage instrumentation.
- if (sancov) {
- module_pm.addPass(SanitizerCoveragePass(getSanCovOptions()));
+ if (options.sancov) {
+ module_pm.addPass(SanitizerCoveragePass(getSanCovOptions(options.coverage)));
}
// Thread sanitizer
- if (tsan) {
+ if (options.tsan) {
module_pm.addPass(ModuleThreadSanitizerPass());
module_pm.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
}
@@ -336,17 +333,17 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
ModulePassManager module_pm;
OptimizationLevel opt_level;
// Setting up the optimization level
- if (is_debug)
+ if (options.is_debug)
opt_level = OptimizationLevel::O0;
- else if (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, lto);
- } else if (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);
@@ -357,7 +354,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
codegen_pm.add(
createTargetTransformInfoWrapperPass(target_machine.getTargetIRAnalysis()));
- if (dest_bin && !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;
@@ -376,20 +373,20 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
// Code generation phase
codegen_pm.run(llvm_module);
- if (llvm_ir_filename) {
- if (LLVMPrintModuleToFile(module_ref, 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 && lto) {
+ if (dest_bin && options.lto) {
WriteBitcodeToFile(llvm_module, *dest_bin);
}
if (dest_bitcode) {
WriteBitcodeToFile(llvm_module, *dest_bitcode);
}
- if (time_report) {
+ if (options.time_report) {
TimerGroup::printAll(errs());
}
src/zig_llvm.h
@@ -24,12 +24,50 @@
// ATTENTION: If you modify this file, be sure to update the corresponding
// extern function declarations in the self-hosted compiler.
-ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
- char **error_message, bool is_debug,
- bool is_small, bool time_report, bool tsan, bool sancov, bool lto,
- const char *asm_filename, const char *bin_filename,
- const char *llvm_ir_filename, const char *bitcode_filename);
+enum ZigLLVMCoverageType {
+ ZigLLVMCoverageType_None = 0,
+ ZigLLVMCoverageType_Function,
+ ZigLLVMCoverageType_BB,
+ ZigLLVMCoverageType_Edge
+};
+
+struct ZigLLVMCoverageOptions {
+ ZigLLVMCoverageType CoverageType;
+ bool IndirectCalls;
+ bool TraceBB;
+ bool TraceCmp;
+ bool TraceDiv;
+ bool TraceGep;
+ bool Use8bitCounters;
+ bool TracePC;
+ bool TracePCGuard;
+ bool Inline8bitCounters;
+ bool InlineBoolFlag;
+ bool PCTable;
+ bool NoPrune;
+ bool StackDepth;
+ bool TraceLoads;
+ bool TraceStores;
+ bool CollectControlFlow;
+};
+
+struct ZigLLVMEmitOptions {
+ bool is_debug;
+ bool is_small;
+ bool time_report;
+ bool tsan;
+ bool sancov;
+ bool lto;
+ const char *asm_filename;
+ const char *bin_filename;
+ const char *llvm_ir_filename;
+ const char *bitcode_filename;
+ ZigLLVMCoverageOptions coverage;
+};
+
+ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
+ char **error_message, struct ZigLLVMEmitOptions options);
enum ZigLLVMABIType {
ZigLLVMABITypeDefault, // Target-specific (either soft or hard depending on triple, etc).