mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 07:49:17 +03:00
Merge pull request #6560 from roc-lang/llvm-gen-from-mono-improvement
emit-ir and style improvement
This commit is contained in:
commit
074fcd0683
@ -166,12 +166,11 @@ fn gen_from_mono_module_llvm<'a>(
|
|||||||
let context = Context::create();
|
let context = Context::create();
|
||||||
let module = arena.alloc(module_from_builtins(target, &context, "app"));
|
let module = arena.alloc(module_from_builtins(target, &context, "app"));
|
||||||
|
|
||||||
// mark our zig-defined builtins as internal
|
|
||||||
let app_ll_file = {
|
let app_ll_file = {
|
||||||
let mut temp = PathBuf::from(roc_file_path);
|
let mut roc_file_path_buf = PathBuf::from(roc_file_path);
|
||||||
temp.set_extension("ll");
|
roc_file_path_buf.set_extension("ll");
|
||||||
|
|
||||||
temp
|
roc_file_path_buf
|
||||||
};
|
};
|
||||||
|
|
||||||
let kind_id = Attribute::get_named_enum_kind_id("alwaysinline");
|
let kind_id = Attribute::get_named_enum_kind_id("alwaysinline");
|
||||||
@ -278,27 +277,21 @@ fn gen_from_mono_module_llvm<'a>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if emit_llvm_ir {
|
|
||||||
eprintln!("Emitting LLVM IR to {}", &app_ll_file.display());
|
|
||||||
module.print_to_file(&app_ll_file).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uncomment this to see the module's optimized LLVM instruction output:
|
// Uncomment this to see the module's optimized LLVM instruction output:
|
||||||
// env.module.print_to_stderr();
|
// env.module.print_to_stderr();
|
||||||
|
|
||||||
// annotate the LLVM IR output with debug info
|
|
||||||
// so errors are reported with the line number of the LLVM source
|
|
||||||
let gen_sanitizers = cfg!(feature = "sanitizers") && std::env::var("ROC_SANITIZERS").is_ok();
|
let gen_sanitizers = cfg!(feature = "sanitizers") && std::env::var("ROC_SANITIZERS").is_ok();
|
||||||
let memory_buffer = if fuzz || gen_sanitizers {
|
let memory_buffer = if fuzz || gen_sanitizers {
|
||||||
let dir = tempfile::tempdir().unwrap();
|
let dir = tempfile::tempdir().unwrap();
|
||||||
let dir = dir.into_path();
|
let dir = dir.into_path();
|
||||||
|
|
||||||
let app_ll_file = dir.join("app.ll");
|
let temp_app_ll_file = dir.join("app.ll");
|
||||||
let app_bc_file = dir.join("app.bc");
|
let temp_app_processed_file = dir.join("app_processed.ll"); // app.ll with llvm passes applied
|
||||||
let app_o_file = dir.join("app.o");
|
let temp_app_processed_file_str = temp_app_processed_file.to_str().unwrap().to_owned();
|
||||||
|
let temp_app_o_file = dir.join("app.o");
|
||||||
|
|
||||||
// write the ll code to a file, so we can modify it
|
// write the ll code to a file, so we can modify it
|
||||||
module.print_to_file(&app_ll_file).unwrap();
|
module.print_to_file(&temp_app_ll_file).unwrap();
|
||||||
|
|
||||||
// Apply coverage passes.
|
// Apply coverage passes.
|
||||||
// Note, this is specifically tailored for `cargo afl` and afl++.
|
// Note, this is specifically tailored for `cargo afl` and afl++.
|
||||||
@ -340,40 +333,59 @@ fn gen_from_mono_module_llvm<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
let mut opt = Command::new("opt");
|
|
||||||
opt.args([
|
|
||||||
app_ll_file.to_str().unwrap(),
|
|
||||||
"-o",
|
|
||||||
app_bc_file.to_str().unwrap(),
|
|
||||||
])
|
|
||||||
.args(extra_args);
|
|
||||||
if !passes.is_empty() {
|
|
||||||
opt.arg(format!("-passes={}", passes.join(",")));
|
|
||||||
}
|
|
||||||
let opt = opt.output().unwrap();
|
|
||||||
|
|
||||||
assert!(opt.stderr.is_empty(), "{opt:#?}");
|
// apply passes to app.ll
|
||||||
|
let mut opt_command = Command::new("opt");
|
||||||
|
|
||||||
|
opt_command
|
||||||
|
.args([
|
||||||
|
temp_app_ll_file.to_str().unwrap(),
|
||||||
|
"-o",
|
||||||
|
&temp_app_processed_file_str,
|
||||||
|
])
|
||||||
|
.args(extra_args);
|
||||||
|
if !passes.is_empty() {
|
||||||
|
opt_command.arg(format!("-passes={}", passes.join(",")));
|
||||||
|
}
|
||||||
|
|
||||||
|
let opt_output = opt_command.output().unwrap();
|
||||||
|
|
||||||
|
assert!(opt_output.stderr.is_empty(), "{opt_output:#?}");
|
||||||
|
|
||||||
|
if emit_llvm_ir {
|
||||||
|
eprintln!("Emitting LLVM IR to {}", &app_ll_file.display());
|
||||||
|
|
||||||
|
std::fs::copy(temp_app_processed_file, app_ll_file).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
// write the .o file. Note that this builds the .o for the local machine,
|
// write the .o file. Note that this builds the .o for the local machine,
|
||||||
// and ignores the `target_machine` entirely.
|
// and ignores the `target_machine` entirely.
|
||||||
//
|
//
|
||||||
// different systems name this executable differently, so we shotgun for
|
// different systems name this executable differently, so we shotgun for
|
||||||
// the most common ones and then give up.
|
// the most common ones and then give up.
|
||||||
let bc_to_object = Command::new("llc")
|
let bc_to_object_output = Command::new("llc")
|
||||||
.args([
|
.args([
|
||||||
"-relocation-model=pic",
|
"-relocation-model=pic",
|
||||||
"-filetype=obj",
|
"-filetype=obj",
|
||||||
app_bc_file.to_str().unwrap(),
|
&temp_app_processed_file_str,
|
||||||
"-o",
|
"-o",
|
||||||
app_o_file.to_str().unwrap(),
|
temp_app_o_file.to_str().unwrap(),
|
||||||
])
|
])
|
||||||
.output()
|
.output()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert!(bc_to_object.status.success(), "{bc_to_object:#?}");
|
assert!(
|
||||||
|
bc_to_object_output.status.success(),
|
||||||
|
"{bc_to_object_output:#?}"
|
||||||
|
);
|
||||||
|
|
||||||
MemoryBuffer::create_from_file(&app_o_file).expect("memory buffer creation works")
|
MemoryBuffer::create_from_file(&temp_app_o_file).expect("memory buffer creation works")
|
||||||
} else {
|
} else {
|
||||||
|
if emit_llvm_ir {
|
||||||
|
eprintln!("Emitting LLVM IR to {}", &app_ll_file.display());
|
||||||
|
module.print_to_file(&app_ll_file).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
// Emit the .o file
|
// Emit the .o file
|
||||||
use target_lexicon::Architecture;
|
use target_lexicon::Architecture;
|
||||||
match target.architecture {
|
match target.architecture {
|
||||||
|
Loading…
Reference in New Issue
Block a user