merge llvm ir optimization locations

This commit is contained in:
Brendan Hansknecht 2024-12-11 17:25:47 -08:00
parent d5dfdfb36e
commit 87537b800e
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
5 changed files with 92 additions and 143 deletions

View file

@ -1,4 +1,7 @@
use roc_error_macros::internal_error;
use roc_mono::ir::OptLevel;
use roc_target::Target;
use std::path::Path;
// generated using "opt --passes="default<Oz>" --print-pipeline-passes example.ll"
//
@ -17,3 +20,64 @@ pub fn get_llvm_passes_str(opt_level: OptLevel) -> &'static str {
},
}
}
pub fn optimize_llvm_ir(
env: &roc_gen_llvm::llvm::build::Env,
target: Target,
opt_level: OptLevel,
emit_debug_info: bool,
ll_file_path: &Path,
) {
env.dibuilder.finalize();
if !emit_debug_info {
env.module.strip_debug_info();
}
// TODO: double check how much time is spent verifying here and below.
// For real compilation, we may not want to pay the cost.
// Verify the module before optimizing
if let Err(errors) = env.module.verify() {
// write the ll code to a file, so we can modify it
env.module.print_to_file(ll_file_path).unwrap();
internal_error!(
"😱 LLVM errors when defining module; I wrote the full LLVM IR to {:?}\n\n {}",
ll_file_path,
errors.to_string(),
);
}
// Uncomment this to see the module's optimized LLVM instruction output:
// env.module.print_to_stderr();
let inkwell_opt_level = crate::target::convert_opt_level(opt_level);
let inkwell_llvm_passes = get_llvm_passes_str(opt_level);
let inkwell_target_machine =
crate::target::target_machine(target, inkwell_opt_level, inkwell::targets::RelocMode::PIC)
.unwrap_or_else(|| internal_error!("invalid target machine"));
env.module
.run_passes(
inkwell_llvm_passes,
&inkwell_target_machine,
inkwell::passes::PassBuilderOptions::create(),
)
.unwrap_or_else(|e| internal_error!("invalid llvm optimization passes: {:?}", e));
// Verify the module after optimizing
if let Err(errors) = env.module.verify() {
// write the ll code to a file, so we can modify it
env.module.print_to_file(ll_file_path).unwrap();
internal_error!(
"😱 LLVM errors when optimizing module; I wrote the full LLVM IR to {:?}\n\n {}",
ll_file_path,
errors.to_string(),
);
}
// Uncomment this to see the module's optimized LLVM instruction output:
// env.module.print_to_stderr();
}

View file

@ -263,43 +263,7 @@ fn gen_from_mono_module_llvm<'a>(
let generate_final_ir = all_code_gen_start.elapsed();
let code_gen_object_start = Instant::now();
env.dibuilder.finalize();
if !emit_debug_info {
module.strip_debug_info();
}
// Uncomment this to see the module's optimized LLVM instruction output:
// env.module.print_to_stderr();
let inkwell_opt_level = crate::target::convert_opt_level(opt_level);
let inkwell_llvm_passes = crate::llvm_passes::get_llvm_passes_str(opt_level);
let inkwell_target_machine =
crate::target::target_machine(target, inkwell_opt_level, inkwell::targets::RelocMode::PIC)
.expect("should be a valid target machine");
module
.run_passes(
inkwell_llvm_passes,
&inkwell_target_machine,
inkwell::passes::PassBuilderOptions::create(),
)
.expect("valid llvm optimization passes");
// Verify the module
if let Err(errors) = env.module.verify() {
// write the ll code to a file, so we can modify it
env.module.print_to_file(&app_ll_file).unwrap();
internal_error!(
"😱 LLVM errors when defining module; I wrote the full LLVM IR to {:?}\n\n {}",
app_ll_file,
errors.to_string(),
);
}
// Uncomment this to see the module's optimized LLVM instruction output:
// env.module.print_to_stderr();
crate::llvm_passes::optimize_llvm_ir(&env, target, opt_level, emit_debug_info, &app_ll_file);
let gen_sanitizers = cfg!(feature = "sanitizers") && std::env::var("ROC_SANITIZERS").is_ok();
let memory_buffer = if fuzz || gen_sanitizers {