diff --git a/cli/src/build.rs b/cli/src/build.rs index 3bde999b76..2cbb70d078 100644 --- a/cli/src/build.rs +++ b/cli/src/build.rs @@ -98,9 +98,12 @@ pub fn build_file( let compilation_end = compilation_start.elapsed().unwrap(); + let size = std::fs::metadata(&app_o_file).unwrap().len(); + println!( - "Finished compilation and code gen in {} ms\n", - compilation_end.as_millis() + "Finished compilation and code gen in {} ms\n\nProduced a app.o file of size {:?}\n", + compilation_end.as_millis(), + size, ); let cwd = app_o_file.parent().unwrap(); diff --git a/cli/src/repl/gen.rs b/cli/src/repl/gen.rs index f36672a455..775345182f 100644 --- a/cli/src/repl/gen.rs +++ b/cli/src/repl/gen.rs @@ -2,6 +2,7 @@ use crate::repl::eval; use bumpalo::Bump; use inkwell::context::Context; use roc_build::link::module_to_dylib; +use roc_build::program::FunctionIterator; use roc_collections::all::{MutMap, MutSet}; use roc_fmt::annotation::Formattable; use roc_fmt::annotation::{Newlines, Parens}; @@ -111,6 +112,15 @@ pub fn gen_and_eval(src: &[u8], target: Triple, opt_level: OptLevel) -> Result { + next: Option>, +} + +impl<'ctx> FunctionIterator<'ctx> { + pub fn from_module(module: &inkwell::module::Module<'ctx>) -> Self { + Self { + next: module.get_first_function(), + } + } +} + +impl<'ctx> Iterator for FunctionIterator<'ctx> { + type Item = FunctionValue<'ctx>; + + fn next(&mut self) -> Option { + match self.next { + Some(function) => { + self.next = function.get_next_function(); + + Some(function) + } + None => None, + } + } +} diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index 110745a880..dbd06bd64c 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -386,6 +386,9 @@ pub fn construct_optimization_passes<'a>( fpm.add_instruction_combining_pass(); fpm.add_tail_call_elimination_pass(); + // remove unused global values (e.g. those defined by zig, but unused in user code) + mpm.add_global_dce_pass(); + let pmb = PassManagerBuilder::create(); match opt_level { OptLevel::Normal => { diff --git a/compiler/gen/tests/helpers/eval.rs b/compiler/gen/tests/helpers/eval.rs index 95959224dd..bbe6888c78 100644 --- a/compiler/gen/tests/helpers/eval.rs +++ b/compiler/gen/tests/helpers/eval.rs @@ -1,5 +1,6 @@ use libloading::Library; use roc_build::link::module_to_dylib; +use roc_build::program::FunctionIterator; use roc_collections::all::{MutMap, MutSet}; fn promote_expr_to_module(src: &str) -> String { @@ -154,6 +155,15 @@ pub fn helper<'a>( let (dibuilder, compile_unit) = roc_gen::llvm::build::Env::new_debug_info(module); + // mark our zig-defined builtins as internal + use inkwell::module::Linkage; + for function in FunctionIterator::from_module(module) { + let name = function.get_name().to_str().unwrap(); + if name.starts_with("roc_builtins") { + function.set_linkage(Linkage::Internal); + } + } + // Compile and add all the Procs before adding main let env = roc_gen::llvm::build::Env { arena: &arena,