separate emitting debug info from emitting llvm-ir

This commit is contained in:
Brendan Hansknecht 2023-12-04 13:12:58 -08:00
parent 496cd6710a
commit da301df37b
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
3 changed files with 48 additions and 15 deletions

View file

@ -50,7 +50,8 @@ pub const CMD_GLUE: &str = "glue";
pub const CMD_GEN_STUB_LIB: &str = "gen-stub-lib";
pub const CMD_PREPROCESS_HOST: &str = "preprocess-host";
pub const FLAG_DEBUG: &str = "debug";
pub const FLAG_EMIT_LLVM_IR: &str = "emit-llvm-ir";
pub const FLAG_PROFILING: &str = "profiling";
pub const FLAG_BUNDLE: &str = "bundle";
pub const FLAG_DEV: &str = "dev";
pub const FLAG_OPTIMIZE: &str = "optimize";
@ -102,9 +103,15 @@ pub fn build_app() -> Command {
.action(ArgAction::SetTrue)
.required(false);
let flag_debug = Arg::new(FLAG_DEBUG)
.long(FLAG_DEBUG)
.help("Store LLVM debug information in the generated program")
let flag_emit_llvm_ir = Arg::new(FLAG_EMIT_LLVM_IR)
.long(FLAG_EMIT_LLVM_IR)
.help("Emit a `.ll` file containing the LLVM IR of the program")
.action(ArgAction::SetTrue)
.required(false);
let flag_profiling = Arg::new(FLAG_PROFILING)
.long(FLAG_PROFILING)
.help("Keep debug info in the final generated program even in optmized builds")
.action(ArgAction::SetTrue)
.required(false);
@ -163,7 +170,8 @@ pub fn build_app() -> Command {
.arg(flag_max_threads.clone())
.arg(flag_opt_size.clone())
.arg(flag_dev.clone())
.arg(flag_debug.clone())
.arg(flag_emit_llvm_ir.clone())
.arg(flag_profiling.clone())
.arg(flag_time.clone())
.arg(flag_linker.clone())
.arg(flag_prebuilt.clone())
@ -212,7 +220,8 @@ pub fn build_app() -> Command {
.arg(flag_max_threads.clone())
.arg(flag_opt_size.clone())
.arg(flag_dev.clone())
.arg(flag_debug.clone())
.arg(flag_emit_llvm_ir.clone())
.arg(flag_profiling.clone())
.arg(flag_time.clone())
.arg(flag_linker.clone())
.arg(flag_prebuilt.clone())
@ -234,7 +243,8 @@ pub fn build_app() -> Command {
.arg(flag_max_threads.clone())
.arg(flag_opt_size.clone())
.arg(flag_dev.clone())
.arg(flag_debug.clone())
.arg(flag_emit_llvm_ir.clone())
.arg(flag_profiling.clone())
.arg(flag_time.clone())
.arg(flag_linker.clone())
.arg(flag_prebuilt.clone())
@ -247,7 +257,8 @@ pub fn build_app() -> Command {
.arg(flag_max_threads.clone())
.arg(flag_opt_size.clone())
.arg(flag_dev.clone())
.arg(flag_debug.clone())
.arg(flag_emit_llvm_ir.clone())
.arg(flag_profiling.clone())
.arg(flag_time.clone())
.arg(flag_linker.clone())
.arg(flag_prebuilt.clone())
@ -376,7 +387,8 @@ pub fn build_app() -> Command {
.arg(flag_max_threads)
.arg(flag_opt_size)
.arg(flag_dev)
.arg(flag_debug)
.arg(flag_emit_llvm_ir)
.arg(flag_profiling)
.arg(flag_time)
.arg(flag_linker)
.arg(flag_prebuilt)
@ -696,7 +708,13 @@ pub fn build(
CodeGenBackend::Llvm(backend_mode)
};
let emit_debug_info = matches.get_flag(FLAG_DEBUG);
let emit_llvm_ir = matches.get_flag(FLAG_EMIT_LLVM_IR);
if emit_llvm_ir && !matches!(code_gen_backend, CodeGenBackend::Llvm(_)) {
user_error!("Cannot emit llvm ir while using a dev backend.");
}
let emit_debug_info = matches.get_flag(FLAG_PROFILING)
|| matches!(opt_level, OptLevel::Development | OptLevel::Normal);
let emit_timings = matches.get_flag(FLAG_TIME);
let threading = match matches.get_one::<usize>(FLAG_MAX_THREADS) {
@ -745,6 +763,7 @@ pub fn build(
backend: code_gen_backend,
opt_level,
emit_debug_info,
emit_llvm_ir,
};
let load_config = standard_load_config(&triple, build_ordering, threading);

View file

@ -85,6 +85,7 @@ pub struct CodeGenOptions {
pub backend: CodeGenBackend,
pub opt_level: OptLevel,
pub emit_debug_info: bool,
pub emit_llvm_ir: bool,
}
type GenFromMono<'a> = (CodeObject, CodeGenTiming, ExpectMetadata<'a>);
@ -101,6 +102,7 @@ pub fn gen_from_mono_module<'a>(
) -> GenFromMono<'a> {
let path = roc_file_path;
let debug = code_gen_options.emit_debug_info;
let emit_llvm_ir = code_gen_options.emit_llvm_ir;
let opt = code_gen_options.opt_level;
match code_gen_options.backend {
@ -120,9 +122,16 @@ pub fn gen_from_mono_module<'a>(
wasm_dev_stack_bytes,
backend_mode,
),
CodeGenBackend::Llvm(backend_mode) => {
gen_from_mono_module_llvm(arena, loaded, path, target, opt, backend_mode, debug)
}
CodeGenBackend::Llvm(backend_mode) => gen_from_mono_module_llvm(
arena,
loaded,
path,
target,
opt,
backend_mode,
debug,
emit_llvm_ir,
),
}
}
@ -137,6 +146,7 @@ fn gen_from_mono_module_llvm<'a>(
opt_level: OptLevel,
backend_mode: LlvmBackendMode,
emit_debug_info: bool,
emit_llvm_ir: bool,
) -> GenFromMono<'a> {
use crate::target::{self, convert_opt_level};
use inkwell::attributes::{Attribute, AttributeLoc};
@ -242,7 +252,9 @@ fn gen_from_mono_module_llvm<'a>(
env.dibuilder.finalize();
// TODO: pipeline flag here to conditionally strip debug info.
if !emit_debug_info {
module.strip_debug_info();
}
// Uncomment this to see the module's optimized LLVM instruction output:
// env.module.print_to_stderr();
@ -356,7 +368,7 @@ fn gen_from_mono_module_llvm<'a>(
assert!(bc_to_object.status.success(), "{bc_to_object:#?}");
MemoryBuffer::create_from_file(&app_o_file).expect("memory buffer creation works")
} else if emit_debug_info {
} else if emit_llvm_ir {
let mut app_ll_dbg_file = PathBuf::from(roc_file_path);
app_ll_dbg_file.set_extension("dbg.ll");
@ -1320,6 +1332,7 @@ pub fn build_str_test<'a>(
backend: CodeGenBackend::Llvm(LlvmBackendMode::Binary),
opt_level: OptLevel::Normal,
emit_debug_info: false,
emit_llvm_ir: false,
};
let emit_timings = false;

View file

@ -55,6 +55,7 @@ pub fn generate(
backend,
opt_level: OptLevel::Development,
emit_debug_info: false,
emit_llvm_ir: false,
};
let load_config = standard_load_config(