| ... | ... | @@ -189,59 +189,56 @@ struct TimeTracerRAII { |
| 189 | 189 | }; |
| 190 | 190 | } // end anonymous namespace |
| 191 | 191 | |
| 192 | | static SanitizerCoverageOptions getSanCovOptions(void) { |
| 192 | static SanitizerCoverageOptions getSanCovOptions(ZigLLVMCoverageOptions z) { |
| 193 | 193 | SanitizerCoverageOptions o; |
| 194 | | o.CoverageType = SanitizerCoverageOptions::SCK_Edge; |
| 195 | | o.IndirectCalls = true; |
| 196 | | o.TraceBB = false; |
| 197 | | o.TraceCmp = true; |
| 198 | | o.TraceDiv = false; |
| 199 | | o.TraceGep = false; |
| 200 | | o.Use8bitCounters = false; |
| 201 | | o.TracePC = false; |
| 202 | | o.TracePCGuard = false; |
| 203 | | o.Inline8bitCounters = true; |
| 204 | | o.InlineBoolFlag = false; |
| 205 | | o.PCTable = true; |
| 206 | | o.NoPrune = false; |
| 207 | | o.StackDepth = true; |
| 208 | | o.TraceLoads = false; |
| 209 | | o.TraceStores = false; |
| 210 | | o.CollectControlFlow = false; |
| 194 | o.CoverageType = (SanitizerCoverageOptions::Type)z.CoverageType; |
| 195 | o.IndirectCalls = z.IndirectCalls; |
| 196 | o.TraceBB = z.TraceBB; |
| 197 | o.TraceCmp = z.TraceCmp; |
| 198 | o.TraceDiv = z.TraceDiv; |
| 199 | o.TraceGep = z.TraceGep; |
| 200 | o.Use8bitCounters = z.Use8bitCounters; |
| 201 | o.TracePC = z.TracePC; |
| 202 | o.TracePCGuard = z.TracePCGuard; |
| 203 | o.Inline8bitCounters = z.Inline8bitCounters; |
| 204 | o.InlineBoolFlag = z.InlineBoolFlag; |
| 205 | o.PCTable = z.PCTable; |
| 206 | o.NoPrune = z.NoPrune; |
| 207 | o.StackDepth = z.StackDepth; |
| 208 | o.TraceLoads = z.TraceLoads; |
| 209 | o.TraceStores = z.TraceStores; |
| 210 | o.CollectControlFlow = z.CollectControlFlow; |
| 211 | 211 | return o; |
| 212 | 212 | } |
| 213 | 213 | |
| 214 | | bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, |
| 215 | | char **error_message, bool is_debug, |
| 216 | | bool is_small, bool time_report, bool tsan, bool sancov, bool lto, |
| 217 | | const char *asm_filename, const char *bin_filename, |
| 218 | | const char *llvm_ir_filename, const char *bitcode_filename) |
| 214 | ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, |
| 215 | char **error_message, struct ZigLLVMEmitOptions options) |
| 219 | 216 | { |
| 220 | | TimePassesIsEnabled = time_report; |
| 217 | TimePassesIsEnabled = options.time_report; |
| 221 | 218 | |
| 222 | 219 | raw_fd_ostream *dest_asm_ptr = nullptr; |
| 223 | 220 | raw_fd_ostream *dest_bin_ptr = nullptr; |
| 224 | 221 | raw_fd_ostream *dest_bitcode_ptr = nullptr; |
| 225 | 222 | |
| 226 | | if (asm_filename) { |
| 223 | if (options.asm_filename) { |
| 227 | 224 | std::error_code EC; |
| 228 | | dest_asm_ptr = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::OF_None); |
| 225 | dest_asm_ptr = new(std::nothrow) raw_fd_ostream(options.asm_filename, EC, sys::fs::OF_None); |
| 229 | 226 | if (EC) { |
| 230 | 227 | *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); |
| 231 | 228 | return true; |
| 232 | 229 | } |
| 233 | 230 | } |
| 234 | | if (bin_filename) { |
| 231 | if (options.bin_filename) { |
| 235 | 232 | std::error_code EC; |
| 236 | | dest_bin_ptr = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::OF_None); |
| 233 | dest_bin_ptr = new(std::nothrow) raw_fd_ostream(options.bin_filename, EC, sys::fs::OF_None); |
| 237 | 234 | if (EC) { |
| 238 | 235 | *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); |
| 239 | 236 | return true; |
| 240 | 237 | } |
| 241 | 238 | } |
| 242 | | if (bitcode_filename) { |
| 239 | if (options.bitcode_filename) { |
| 243 | 240 | std::error_code EC; |
| 244 | | dest_bitcode_ptr = new(std::nothrow) raw_fd_ostream(bitcode_filename, EC, sys::fs::OF_None); |
| 241 | dest_bitcode_ptr = new(std::nothrow) raw_fd_ostream(options.bitcode_filename, EC, sys::fs::OF_None); |
| 245 | 242 | if (EC) { |
| 246 | 243 | *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); |
| 247 | 244 | return true; |
| ... | ... | @@ -257,7 +254,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 257 | 254 | std::string ProcName = "zig-"; |
| 258 | 255 | ProcName += std::to_string(PID); |
| 259 | 256 | TimeTracerRAII TimeTracer(ProcName, |
| 260 | | bin_filename? bin_filename : asm_filename); |
| 257 | options.bin_filename? options.bin_filename : options.asm_filename); |
| 261 | 258 | |
| 262 | 259 | TargetMachine &target_machine = *reinterpret_cast<TargetMachine*>(targ_machine_ref); |
| 263 | 260 | target_machine.setO0WantsFastISel(true); |
| ... | ... | @@ -266,11 +263,11 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 266 | 263 | |
| 267 | 264 | // Pipeline configurations |
| 268 | 265 | PipelineTuningOptions pipeline_opts; |
| 269 | | pipeline_opts.LoopUnrolling = !is_debug; |
| 270 | | pipeline_opts.SLPVectorization = !is_debug; |
| 271 | | pipeline_opts.LoopVectorization = !is_debug; |
| 272 | | pipeline_opts.LoopInterleaving = !is_debug; |
| 273 | | pipeline_opts.MergeFunctions = !is_debug; |
| 266 | pipeline_opts.LoopUnrolling = !options.is_debug; |
| 267 | pipeline_opts.SLPVectorization = !options.is_debug; |
| 268 | pipeline_opts.LoopVectorization = !options.is_debug; |
| 269 | pipeline_opts.LoopInterleaving = !options.is_debug; |
| 270 | pipeline_opts.MergeFunctions = !options.is_debug; |
| 274 | 271 | |
| 275 | 272 | // Instrumentations |
| 276 | 273 | PassInstrumentationCallbacks instr_callbacks; |
| ... | ... | @@ -308,19 +305,19 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 308 | 305 | module_pm.addPass(VerifierPass()); |
| 309 | 306 | } |
| 310 | 307 | |
| 311 | | if (!is_debug) { |
| 308 | if (!options.is_debug) { |
| 312 | 309 | module_pm.addPass(createModuleToFunctionPassAdaptor(AddDiscriminatorsPass())); |
| 313 | 310 | } |
| 314 | 311 | }); |
| 315 | 312 | |
| 316 | 313 | pass_builder.registerOptimizerEarlyEPCallback([&](ModulePassManager &module_pm, OptimizationLevel OL) { |
| 317 | 314 | // Code coverage instrumentation. |
| 318 | | if (sancov) { |
| 319 | | module_pm.addPass(SanitizerCoveragePass(getSanCovOptions())); |
| 315 | if (options.sancov) { |
| 316 | module_pm.addPass(SanitizerCoveragePass(getSanCovOptions(options.coverage))); |
| 320 | 317 | } |
| 321 | 318 | |
| 322 | 319 | // Thread sanitizer |
| 323 | | if (tsan) { |
| 320 | if (options.tsan) { |
| 324 | 321 | module_pm.addPass(ModuleThreadSanitizerPass()); |
| 325 | 322 | module_pm.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass())); |
| 326 | 323 | } |
| ... | ... | @@ -336,17 +333,17 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 336 | 333 | ModulePassManager module_pm; |
| 337 | 334 | OptimizationLevel opt_level; |
| 338 | 335 | // Setting up the optimization level |
| 339 | | if (is_debug) |
| 336 | if (options.is_debug) |
| 340 | 337 | opt_level = OptimizationLevel::O0; |
| 341 | | else if (is_small) |
| 338 | else if (options.is_small) |
| 342 | 339 | opt_level = OptimizationLevel::Oz; |
| 343 | 340 | else |
| 344 | 341 | opt_level = OptimizationLevel::O3; |
| 345 | 342 | |
| 346 | 343 | // Initialize the PassManager |
| 347 | 344 | if (opt_level == OptimizationLevel::O0) { |
| 348 | | module_pm = pass_builder.buildO0DefaultPipeline(opt_level, lto); |
| 349 | | } else if (lto) { |
| 345 | module_pm = pass_builder.buildO0DefaultPipeline(opt_level, options.lto); |
| 346 | } else if (options.lto) { |
| 350 | 347 | module_pm = pass_builder.buildLTOPreLinkDefaultPipeline(opt_level); |
| 351 | 348 | } else { |
| 352 | 349 | module_pm = pass_builder.buildPerModuleDefaultPipeline(opt_level); |
| ... | ... | @@ -357,7 +354,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 357 | 354 | codegen_pm.add( |
| 358 | 355 | createTargetTransformInfoWrapperPass(target_machine.getTargetIRAnalysis())); |
| 359 | 356 | |
| 360 | | if (dest_bin && !lto) { |
| 357 | if (dest_bin && !options.lto) { |
| 361 | 358 | if (target_machine.addPassesToEmitFile(codegen_pm, *dest_bin, nullptr, CodeGenFileType::ObjectFile)) { |
| 362 | 359 | *error_message = strdup("TargetMachine can't emit an object file"); |
| 363 | 360 | return true; |
| ... | ... | @@ -376,20 +373,20 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 376 | 373 | // Code generation phase |
| 377 | 374 | codegen_pm.run(llvm_module); |
| 378 | 375 | |
| 379 | | if (llvm_ir_filename) { |
| 380 | | if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) { |
| 376 | if (options.llvm_ir_filename) { |
| 377 | if (LLVMPrintModuleToFile(module_ref, options.llvm_ir_filename, error_message)) { |
| 381 | 378 | return true; |
| 382 | 379 | } |
| 383 | 380 | } |
| 384 | 381 | |
| 385 | | if (dest_bin && lto) { |
| 382 | if (dest_bin && options.lto) { |
| 386 | 383 | WriteBitcodeToFile(llvm_module, *dest_bin); |
| 387 | 384 | } |
| 388 | 385 | if (dest_bitcode) { |
| 389 | 386 | WriteBitcodeToFile(llvm_module, *dest_bitcode); |
| 390 | 387 | } |
| 391 | 388 | |
| 392 | | if (time_report) { |
| 389 | if (options.time_report) { |
| 393 | 390 | TimerGroup::printAll(errs()); |
| 394 | 391 | } |
| 395 | 392 | |