Call add_intrinsics after add_default_roc_externs

This is necessary to prevent defining things twice
This commit is contained in:
Richard Feldman 2021-05-23 17:33:12 -04:00
parent e6ece40f76
commit ebad3597c9
4 changed files with 67 additions and 50 deletions

View file

@ -8,7 +8,7 @@ use roc_can::builtins::builtin_defs_map;
use roc_collections::all::{MutMap, MutSet}; use roc_collections::all::{MutMap, MutSet};
use roc_fmt::annotation::Formattable; use roc_fmt::annotation::Formattable;
use roc_fmt::annotation::{Newlines, Parens}; use roc_fmt::annotation::{Newlines, Parens};
use roc_gen::llvm::build::{build_proc, build_proc_header, OptLevel}; use roc_gen::llvm::build::{add_intrinsics, build_proc, build_proc_header, OptLevel};
use roc_gen::llvm::externs::add_default_roc_externs; use roc_gen::llvm::externs::add_default_roc_externs;
use roc_load::file::LoadingProblem; use roc_load::file::LoadingProblem;
use roc_parse::parser::SyntaxError; use roc_parse::parser::SyntaxError;
@ -128,11 +128,17 @@ pub fn gen_and_eval<'a>(
Ok(ReplOutput::Problems(lines)) Ok(ReplOutput::Problems(lines))
} else { } else {
let context = Context::create(); let context = Context::create();
let builder = context.create_builder();
let ptr_bytes = target.pointer_width().unwrap().bytes() as u32; let ptr_bytes = target.pointer_width().unwrap().bytes() as u32;
let module = arena.alloc(roc_gen::llvm::build::module_from_builtins(&context, "")); let module = arena.alloc(roc_gen::llvm::build::module_from_builtins(&context, ""));
// Add roc_alloc, roc_realloc, and roc_dealloc, since the repl has no
// platform to provide them. These must be added *before* adding intrinsics!
add_default_roc_externs(&context, module, &builder, ptr_bytes);
// Add LLVM intrinsics.
add_intrinsics(&context, &module);
// mark our zig-defined builtins as internal // mark our zig-defined builtins as internal
for function in FunctionIterator::from_module(module) { for function in FunctionIterator::from_module(module) {
let name = function.get_name().to_str().unwrap(); let name = function.get_name().to_str().unwrap();
@ -141,12 +147,6 @@ pub fn gen_and_eval<'a>(
} }
} }
// Add roc_alloc, roc_realloc, and roc_dealloc, since the repl has no
// platform to provide them.
let builder = context.create_builder();
add_default_roc_externs(&context, module, &builder, ptr_bytes);
debug_assert_eq!(exposed_to_host.len(), 1); debug_assert_eq!(exposed_to_host.len(), 1);
let (main_fn_symbol, main_fn_var) = exposed_to_host.iter().next().unwrap(); let (main_fn_symbol, main_fn_var) = exposed_to_host.iter().next().unwrap();
let main_fn_symbol = *main_fn_symbol; let main_fn_symbol = *main_fn_symbol;
@ -262,14 +262,17 @@ pub fn gen_and_eval<'a>(
module_pass.run_on(env.module); module_pass.run_on(env.module);
// Verify the module
if let Err(errors) = env.module.verify() {
panic!("Errors defining module: {:?}", errors);
}
// 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();
// Verify the module
if let Err(errors) = env.module.verify() {
panic!(
"Errors defining module: {}\n\nUncomment things nearby to see more details.",
errors
);
}
let lib = module_to_dylib(&env.module, &target, opt_level) let lib = module_to_dylib(&env.module, &target, opt_level)
.expect("Error loading compiled dylib for test"); .expect("Error loading compiled dylib for test");
let res_answer = unsafe { let res_answer = unsafe {

View file

@ -3,7 +3,9 @@ use bumpalo::Bump;
use inkwell::context::Context; use inkwell::context::Context;
use inkwell::targets::{CodeModel, FileType, RelocMode}; use inkwell::targets::{CodeModel, FileType, RelocMode};
use inkwell::values::FunctionValue; use inkwell::values::FunctionValue;
use roc_gen::llvm::build::{build_proc, build_proc_header, module_from_builtins, OptLevel, Scope}; use roc_gen::llvm::build::{
add_intrinsics, build_proc, build_proc_header, module_from_builtins, OptLevel, Scope,
};
use roc_load::file::MonomorphizedModule; use roc_load::file::MonomorphizedModule;
use roc_mono::layout::LayoutIds; use roc_mono::layout::LayoutIds;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
@ -84,6 +86,9 @@ pub fn gen_from_mono_module(
let context = Context::create(); let context = Context::create();
let module = arena.alloc(module_from_builtins(&context, "app")); let module = arena.alloc(module_from_builtins(&context, "app"));
// Add LLVM intrinsics.
add_intrinsics(&context, &module);
// strip Zig debug stuff // strip Zig debug stuff
// module.strip_debug_info(); // module.strip_debug_info();

View file

@ -338,13 +338,10 @@ pub fn module_from_builtins<'ctx>(ctx: &'ctx Context, module_name: &str) -> Modu
let module = Module::parse_bitcode_from_buffer(&memory_buffer, ctx) let module = Module::parse_bitcode_from_buffer(&memory_buffer, ctx)
.unwrap_or_else(|err| panic!("Unable to import builtins bitcode. LLVM error: {:?}", err)); .unwrap_or_else(|err| panic!("Unable to import builtins bitcode. LLVM error: {:?}", err));
// Add LLVM intrinsics.
add_intrinsics(ctx, &module);
module module
} }
fn add_intrinsics<'ctx>(ctx: &'ctx Context, module: &Module<'ctx>) { pub fn add_intrinsics<'ctx>(ctx: &'ctx Context, module: &Module<'ctx>) {
// List of all supported LLVM intrinsics: // List of all supported LLVM intrinsics:
// //
// https://releases.llvm.org/10.0.0/docs/LangRef.html#standard-c-library-intrinsics // https://releases.llvm.org/10.0.0/docs/LangRef.html#standard-c-library-intrinsics
@ -358,33 +355,41 @@ fn add_intrinsics<'ctx>(ctx: &'ctx Context, module: &Module<'ctx>) {
let i8_type = ctx.i8_type(); let i8_type = ctx.i8_type();
let i8_ptr_type = ctx.i8_type().ptr_type(AddressSpace::Generic); let i8_ptr_type = ctx.i8_type().ptr_type(AddressSpace::Generic);
add_intrinsic( // In the repl, this may already be defined (because there's no platform
module, // in the repl). Redefining it causes linker errors!
ROC_ALLOC_64, if module.get_function(ROC_ALLOC_64).is_none() {
i8_ptr_type.fn_type( add_intrinsic(
&[ module,
// alignment: u32 ROC_ALLOC_64,
i32_type.into(), i8_ptr_type.fn_type(
// size: usize &[
i64_type.into(), // alignment: u32
], i32_type.into(),
false, // size: usize
), i64_type.into(),
); ],
false,
),
);
}
add_intrinsic( // In the repl, this may already be defined (because there's no platform
module, // in the repl). Redefining it causes linker errors!
ROC_ALLOC_32, if module.get_function(ROC_ALLOC_32).is_none() {
i8_ptr_type.fn_type( add_intrinsic(
&[ module,
// alignment: u32 ROC_ALLOC_32,
i32_type.into(), i8_ptr_type.fn_type(
// size: usize &[
i32_type.into(), // alignment: u32
], i32_type.into(),
false, // size: usize
), i32_type.into(),
); ],
false,
),
);
}
add_intrinsic( add_intrinsic(
module, module,

View file

@ -4,6 +4,7 @@ use roc_build::program::FunctionIterator;
use roc_can::builtins::builtin_defs_map; use roc_can::builtins::builtin_defs_map;
use roc_can::def::Def; use roc_can::def::Def;
use roc_collections::all::{MutMap, MutSet}; use roc_collections::all::{MutMap, MutSet};
use roc_gen::llvm::build::add_intrinsics;
use roc_gen::llvm::externs::add_default_roc_externs; use roc_gen::llvm::externs::add_default_roc_externs;
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use roc_types::subs::VarStore; use roc_types::subs::VarStore;
@ -180,8 +181,16 @@ pub fn helper<'a>(
), ),
}; };
let builder = context.create_builder();
let module = roc_gen::llvm::build::module_from_builtins(context, "app"); let module = roc_gen::llvm::build::module_from_builtins(context, "app");
// Add roc_alloc, roc_realloc, and roc_dealloc, since the repl has no
// platform to provide them. These must be added *before* adding intrinsics!
add_default_roc_externs(context, &module, &builder, ptr_bytes);
// Add LLVM intrinsics.
add_intrinsics(context, &module);
// strip Zig debug stuff // strip Zig debug stuff
module.strip_debug_info(); module.strip_debug_info();
@ -216,11 +225,6 @@ pub fn helper<'a>(
} }
} }
// Add roc_alloc, roc_realloc, and roc_dealloc, since the repl has no
// platform to provide them.
let builder = context.create_builder();
add_default_roc_externs(&context, module, &builder, ptr_bytes);
// Compile and add all the Procs before adding main // Compile and add all the Procs before adding main
let env = roc_gen::llvm::build::Env { let env = roc_gen::llvm::build::Env {
arena: &arena, arena: &arena,