| ... | @@ -195,6 +195,8 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM | ... | @@ -195,6 +195,8 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 195 | bool is_small, bool time_report, bool tsan, bool lto, | 195 | bool is_small, bool time_report, bool tsan, bool lto, |
| 196 | const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename) | 196 | const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename) |
| 197 | { | 197 | { |
| | 198 | // TODO: Maybe we should collect time trace rather than using timer |
| | 199 | // to get a more hierarchical timeline view |
| 198 | TimePassesIsEnabled = time_report; | 200 | TimePassesIsEnabled = time_report; |
| 199 | | 201 | |
| 200 | raw_fd_ostream *dest_asm_ptr = nullptr; | 202 | raw_fd_ostream *dest_asm_ptr = nullptr; |
| ... | @@ -225,12 +227,15 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM | ... | @@ -225,12 +227,15 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 225 | | 227 | |
| 226 | Module &module = *unwrap(module_ref); | 228 | Module &module = *unwrap(module_ref); |
| 227 | | 229 | |
| | 230 | // Pipeline configurations |
| 228 | PipelineTuningOptions pipeline_opts; | 231 | PipelineTuningOptions pipeline_opts; |
| 229 | pipeline_opts.LoopUnrolling = !is_debug; | 232 | pipeline_opts.LoopUnrolling = !is_debug; |
| 230 | pipeline_opts.SLPVectorization = !is_debug; | 233 | pipeline_opts.SLPVectorization = !is_debug; |
| 231 | pipeline_opts.LoopVectorization = !is_debug; | 234 | pipeline_opts.LoopVectorization = !is_debug; |
| 232 | pipeline_opts.LoopInterleaving = !is_debug; | 235 | pipeline_opts.LoopInterleaving = !is_debug; |
| | 236 | pipeline_opts.MergeFunctions = !is_debug; |
| 233 | | 237 | |
| | 238 | // Instrumentations |
| 234 | PassInstrumentationCallbacks instr_callbacks; | 239 | PassInstrumentationCallbacks instr_callbacks; |
| 235 | StandardInstrumentations std_instrumentations(false); | 240 | StandardInstrumentations std_instrumentations(false); |
| 236 | std_instrumentations.registerCallbacks(instr_callbacks); | 241 | std_instrumentations.registerCallbacks(instr_callbacks); |
| ... | @@ -253,6 +258,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM | ... | @@ -253,6 +258,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 253 | auto tlii = std::make_unique<TargetLibraryInfoImpl>(target_triple); | 258 | auto tlii = std::make_unique<TargetLibraryInfoImpl>(target_triple); |
| 254 | function_am.registerPass([&] { return TargetLibraryAnalysis(*tlii); }); | 259 | function_am.registerPass([&] { return TargetLibraryAnalysis(*tlii); }); |
| 255 | | 260 | |
| | 261 | // Initialize the AnalysisManagers |
| 256 | pass_builder.registerModuleAnalyses(module_am); | 262 | pass_builder.registerModuleAnalyses(module_am); |
| 257 | pass_builder.registerCGSCCAnalyses(cgscc_am); | 263 | pass_builder.registerCGSCCAnalyses(cgscc_am); |
| 258 | pass_builder.registerFunctionAnalyses(function_am); | 264 | pass_builder.registerFunctionAnalyses(function_am); |
| ... | @@ -260,7 +266,29 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM | ... | @@ -260,7 +266,29 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 260 | pass_builder.crossRegisterProxies(loop_am, function_am, | 266 | pass_builder.crossRegisterProxies(loop_am, function_am, |
| 261 | cgscc_am, module_am); | 267 | cgscc_am, module_am); |
| 262 | | 268 | |
| 263 | if (!is_debug) { | 269 | // IR verification |
| | 270 | if (assertions_on) { |
| | 271 | // Verify the input |
| | 272 | pass_builder.registerPipelineStartEPCallback( |
| | 273 | [](ModulePassManager &module_pm, OptimizationLevel OL) { |
| | 274 | module_pm.addPass(VerifierPass()); |
| | 275 | }); |
| | 276 | // Verify the output |
| | 277 | pass_builder.registerOptimizerLastEPCallback( |
| | 278 | [](ModulePassManager &module_pm, OptimizationLevel OL) { |
| | 279 | module_pm.addPass(VerifierPass()); |
| | 280 | }); |
| | 281 | } |
| | 282 | |
| | 283 | // Passes for either debug or release build |
| | 284 | if (is_debug) { |
| | 285 | // NOTE: Always inliner will go away (in debug build) |
| | 286 | // when the self-hosted compiler becomes mature. |
| | 287 | pass_builder.registerPipelineStartEPCallback( |
| | 288 | [](ModulePassManager &module_pm, OptimizationLevel OL) { |
| | 289 | module_pm.addPass(AlwaysInlinerPass()); |
| | 290 | }); |
| | 291 | } else { |
| 264 | pass_builder.registerPipelineStartEPCallback( | 292 | pass_builder.registerPipelineStartEPCallback( |
| 265 | [](ModulePassManager &module_pm, OptimizationLevel OL) { | 293 | [](ModulePassManager &module_pm, OptimizationLevel OL) { |
| 266 | module_pm.addPass( | 294 | module_pm.addPass( |
| ... | @@ -268,19 +296,17 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM | ... | @@ -268,19 +296,17 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 268 | }); | 296 | }); |
| 269 | } | 297 | } |
| 270 | | 298 | |
| | 299 | // Thread sanitizer |
| 271 | if (tsan) { | 300 | if (tsan) { |
| 272 | pass_builder.registerOptimizerLastEPCallback( | 301 | pass_builder.registerOptimizerLastEPCallback( |
| 273 | [](ModulePassManager &module_pm, OptimizationLevel level) { | 302 | [](ModulePassManager &module_pm, OptimizationLevel level) { |
| 274 | // Will be enabled regardless of optimization level | | |
| 275 | module_pm.addPass(ThreadSanitizerPass()); | 303 | module_pm.addPass(ThreadSanitizerPass()); |
| 276 | }); | 304 | }); |
| 277 | } | 305 | } |
| 278 | | 306 | |
| 279 | ModulePassManager module_pm; | 307 | ModulePassManager module_pm; |
| 280 | // FIXME: NewPM can not detach speed level from size level | | |
| 281 | // we can't create something like "maximum speed level and optimal size level" | | |
| 282 | // which is what the original code wanted to achieve | | |
| 283 | OptimizationLevel opt_level; | 308 | OptimizationLevel opt_level; |
| | 309 | // Setting up the optimization level |
| 284 | if (is_debug) | 310 | if (is_debug) |
| 285 | opt_level = OptimizationLevel::O0; | 311 | opt_level = OptimizationLevel::O0; |
| 286 | else if (is_small) | 312 | else if (is_small) |
| ... | @@ -288,6 +314,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM | ... | @@ -288,6 +314,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 288 | else | 314 | else |
| 289 | opt_level = OptimizationLevel::O3; | 315 | opt_level = OptimizationLevel::O3; |
| 290 | | 316 | |
| | 317 | // Initialize the PassManager |
| 291 | if (lto) { | 318 | if (lto) { |
| 292 | module_pm = pass_builder.buildLTOPreLinkDefaultPipeline(opt_level); | 319 | module_pm = pass_builder.buildLTOPreLinkDefaultPipeline(opt_level); |
| 293 | module_pm.addPass(CanonicalizeAliasesPass()); | 320 | module_pm.addPass(CanonicalizeAliasesPass()); |
| ... | @@ -314,10 +341,10 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM | ... | @@ -314,10 +341,10 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 314 | } | 341 | } |
| 315 | } | 342 | } |
| 316 | | 343 | |
| 317 | // optimization | 344 | // Optimization phase |
| 318 | module_pm.run(module, module_am); | 345 | module_pm.run(module, module_am); |
| 319 | | 346 | |
| 320 | // code generation | 347 | // Code generation phase |
| 321 | codegen_pm.run(module); | 348 | codegen_pm.run(module); |
| 322 | | 349 | |
| 323 | if (llvm_ir_filename) { | 350 | if (llvm_ir_filename) { |
| ... | @@ -325,6 +352,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM | ... | @@ -325,6 +352,7 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM |
| 325 | return true; | 352 | return true; |
| 326 | } | 353 | } |
| 327 | } | 354 | } |
| | 355 | |
| 328 | if (dest_bin && lto) { | 356 | if (dest_bin && lto) { |
| 329 | WriteBitcodeToFile(module, *dest_bin); | 357 | WriteBitcodeToFile(module, *dest_bin); |
| 330 | } | 358 | } |