mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Merge branch 'main' into simplify_examples
Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com>
This commit is contained in:
commit
735d4c13bb
16 changed files with 3568 additions and 3077 deletions
|
@ -1,3 +1,4 @@
|
|||
use inkwell::memory_buffer::MemoryBuffer;
|
||||
pub use roc_gen_llvm::llvm::build::FunctionIterator;
|
||||
use roc_gen_llvm::llvm::build::{module_from_builtins, LlvmBackendMode};
|
||||
use roc_gen_llvm::llvm::externs::add_default_roc_externs;
|
||||
|
@ -6,6 +7,7 @@ use roc_module::symbol::{Interns, ModuleId};
|
|||
use roc_mono::ir::OptLevel;
|
||||
use roc_region::all::LineInfo;
|
||||
use roc_solve_problem::TypeError;
|
||||
use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
|
@ -16,7 +18,6 @@ use roc_collections::all::MutSet;
|
|||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct CodeGenTiming {
|
||||
pub code_gen: Duration,
|
||||
pub emit_o_file: Duration,
|
||||
}
|
||||
|
||||
pub fn report_problems_monomorphized(loaded: &mut MonomorphizedModule) -> Problems {
|
||||
|
@ -156,25 +157,39 @@ fn report_problems_help(
|
|||
}
|
||||
}
|
||||
|
||||
pub enum CodeObject {
|
||||
MemoryBuffer(MemoryBuffer),
|
||||
Vector(Vec<u8>),
|
||||
}
|
||||
|
||||
impl Deref for CodeObject {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match self {
|
||||
CodeObject::MemoryBuffer(memory_buffer) => memory_buffer.as_slice(),
|
||||
CodeObject::Vector(vector) => vector.as_slice(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn gen_from_mono_module(
|
||||
arena: &bumpalo::Bump,
|
||||
loaded: MonomorphizedModule,
|
||||
roc_file_path: &Path,
|
||||
target: &target_lexicon::Triple,
|
||||
app_o_file: &Path,
|
||||
opt_level: OptLevel,
|
||||
emit_debug_info: bool,
|
||||
preprocessed_host_path: &Path,
|
||||
wasm_dev_stack_bytes: Option<u32>,
|
||||
) -> CodeGenTiming {
|
||||
) -> (CodeObject, CodeGenTiming) {
|
||||
match opt_level {
|
||||
OptLevel::Normal | OptLevel::Size | OptLevel::Optimize => gen_from_mono_module_llvm(
|
||||
arena,
|
||||
loaded,
|
||||
roc_file_path,
|
||||
target,
|
||||
app_o_file,
|
||||
opt_level,
|
||||
emit_debug_info,
|
||||
),
|
||||
|
@ -182,7 +197,6 @@ pub fn gen_from_mono_module(
|
|||
arena,
|
||||
loaded,
|
||||
target,
|
||||
app_o_file,
|
||||
preprocessed_host_path,
|
||||
wasm_dev_stack_bytes,
|
||||
),
|
||||
|
@ -192,15 +206,14 @@ pub fn gen_from_mono_module(
|
|||
// TODO how should imported modules factor into this? What if those use builtins too?
|
||||
// TODO this should probably use more helper functions
|
||||
// TODO make this polymorphic in the llvm functions so it can be reused for another backend.
|
||||
pub fn gen_from_mono_module_llvm(
|
||||
fn gen_from_mono_module_llvm(
|
||||
arena: &bumpalo::Bump,
|
||||
loaded: MonomorphizedModule,
|
||||
roc_file_path: &Path,
|
||||
target: &target_lexicon::Triple,
|
||||
app_o_file: &Path,
|
||||
opt_level: OptLevel,
|
||||
emit_debug_info: bool,
|
||||
) -> CodeGenTiming {
|
||||
) -> (CodeObject, CodeGenTiming) {
|
||||
use crate::target::{self, convert_opt_level};
|
||||
use inkwell::attributes::{Attribute, AttributeLoc};
|
||||
use inkwell::context::Context;
|
||||
|
@ -312,12 +325,9 @@ pub fn gen_from_mono_module_llvm(
|
|||
// Uncomment this to see the module's optimized LLVM instruction output:
|
||||
// env.module.print_to_stderr();
|
||||
|
||||
let code_gen = code_gen_start.elapsed();
|
||||
let emit_o_file_start = Instant::now();
|
||||
|
||||
// annotate the LLVM IR output with debug info
|
||||
// so errors are reported with the line number of the LLVM source
|
||||
if emit_debug_info {
|
||||
let memory_buffer = if emit_debug_info {
|
||||
module.strip_debug_info();
|
||||
|
||||
let mut app_ll_dbg_file = PathBuf::from(roc_file_path);
|
||||
|
@ -326,6 +336,9 @@ pub fn gen_from_mono_module_llvm(
|
|||
let mut app_bc_file = PathBuf::from(roc_file_path);
|
||||
app_bc_file.set_extension("bc");
|
||||
|
||||
let mut app_o_file = PathBuf::from(roc_file_path);
|
||||
app_o_file.set_extension("o");
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
// write the ll code to a file, so we can modify it
|
||||
|
@ -384,6 +397,8 @@ pub fn gen_from_mono_module_llvm(
|
|||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
||||
MemoryBuffer::create_from_file(&app_o_file).expect("memory buffer creation works")
|
||||
} else {
|
||||
// Emit the .o file
|
||||
use target_lexicon::Architecture;
|
||||
|
@ -394,49 +409,48 @@ pub fn gen_from_mono_module_llvm(
|
|||
target::target_machine(target, convert_opt_level(opt_level), reloc).unwrap();
|
||||
|
||||
target_machine
|
||||
.write_to_file(env.module, FileType::Object, app_o_file)
|
||||
.expect("Writing .o file failed");
|
||||
.write_to_memory_buffer(env.module, FileType::Object)
|
||||
.expect("Writing .o file failed")
|
||||
}
|
||||
Architecture::Wasm32 => {
|
||||
// Useful for debugging
|
||||
// module.print_to_file(app_ll_file);
|
||||
module.write_bitcode_to_path(app_o_file);
|
||||
module.write_bitcode_to_memory()
|
||||
}
|
||||
_ => panic!(
|
||||
"TODO gracefully handle unsupported architecture: {:?}",
|
||||
target.architecture
|
||||
),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let emit_o_file = emit_o_file_start.elapsed();
|
||||
let code_gen = code_gen_start.elapsed();
|
||||
|
||||
CodeGenTiming {
|
||||
code_gen,
|
||||
emit_o_file,
|
||||
}
|
||||
(
|
||||
CodeObject::MemoryBuffer(memory_buffer),
|
||||
CodeGenTiming { code_gen },
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "target-wasm32")]
|
||||
pub fn gen_from_mono_module_dev(
|
||||
fn gen_from_mono_module_dev(
|
||||
arena: &bumpalo::Bump,
|
||||
loaded: MonomorphizedModule,
|
||||
target: &target_lexicon::Triple,
|
||||
app_o_file: &Path,
|
||||
preprocessed_host_path: &Path,
|
||||
wasm_dev_stack_bytes: Option<u32>,
|
||||
) -> CodeGenTiming {
|
||||
) -> (CodeObject, CodeGenTiming) {
|
||||
use target_lexicon::Architecture;
|
||||
|
||||
match target.architecture {
|
||||
Architecture::Wasm32 => gen_from_mono_module_dev_wasm32(
|
||||
arena,
|
||||
loaded,
|
||||
app_o_file,
|
||||
preprocessed_host_path,
|
||||
wasm_dev_stack_bytes,
|
||||
),
|
||||
Architecture::X86_64 | Architecture::Aarch64(_) => {
|
||||
gen_from_mono_module_dev_assembly(arena, loaded, target, app_o_file)
|
||||
gen_from_mono_module_dev_assembly(arena, loaded, target)
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
|
@ -447,15 +461,14 @@ pub fn gen_from_mono_module_dev(
|
|||
arena: &bumpalo::Bump,
|
||||
loaded: MonomorphizedModule,
|
||||
target: &target_lexicon::Triple,
|
||||
app_o_file: &Path,
|
||||
_host_input_path: &Path,
|
||||
_wasm_dev_stack_bytes: Option<u32>,
|
||||
) -> CodeGenTiming {
|
||||
) -> (CodeObject, CodeGenTiming) {
|
||||
use target_lexicon::Architecture;
|
||||
|
||||
match target.architecture {
|
||||
Architecture::X86_64 | Architecture::Aarch64(_) => {
|
||||
gen_from_mono_module_dev_assembly(arena, loaded, target, app_o_file)
|
||||
gen_from_mono_module_dev_assembly(arena, loaded, target)
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
|
@ -465,10 +478,9 @@ pub fn gen_from_mono_module_dev(
|
|||
fn gen_from_mono_module_dev_wasm32(
|
||||
arena: &bumpalo::Bump,
|
||||
loaded: MonomorphizedModule,
|
||||
app_o_file: &Path,
|
||||
preprocessed_host_path: &Path,
|
||||
wasm_dev_stack_bytes: Option<u32>,
|
||||
) -> CodeGenTiming {
|
||||
) -> (CodeObject, CodeGenTiming) {
|
||||
let code_gen_start = Instant::now();
|
||||
let MonomorphizedModule {
|
||||
module_id,
|
||||
|
@ -513,31 +525,18 @@ fn gen_from_mono_module_dev_wasm32(
|
|||
roc_gen_wasm::build_app_binary(&env, &mut interns, host_module, procedures);
|
||||
|
||||
let code_gen = code_gen_start.elapsed();
|
||||
let emit_o_file_start = Instant::now();
|
||||
|
||||
// The app_o_file is actually the final binary
|
||||
std::fs::write(&app_o_file, &final_binary_bytes).unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"I wasn't able to write to the output file {}\n{}",
|
||||
app_o_file.display(),
|
||||
e
|
||||
)
|
||||
});
|
||||
|
||||
let emit_o_file = emit_o_file_start.elapsed();
|
||||
|
||||
CodeGenTiming {
|
||||
code_gen,
|
||||
emit_o_file,
|
||||
}
|
||||
(
|
||||
CodeObject::Vector(final_binary_bytes),
|
||||
CodeGenTiming { code_gen },
|
||||
)
|
||||
}
|
||||
|
||||
fn gen_from_mono_module_dev_assembly(
|
||||
arena: &bumpalo::Bump,
|
||||
loaded: MonomorphizedModule,
|
||||
target: &target_lexicon::Triple,
|
||||
app_o_file: &Path,
|
||||
) -> CodeGenTiming {
|
||||
) -> (CodeObject, CodeGenTiming) {
|
||||
let code_gen_start = Instant::now();
|
||||
|
||||
let lazy_literals = true;
|
||||
|
@ -564,17 +563,10 @@ fn gen_from_mono_module_dev_assembly(
|
|||
let module_object = roc_gen_dev::build_module(&env, &mut interns, target, procedures);
|
||||
|
||||
let code_gen = code_gen_start.elapsed();
|
||||
let emit_o_file_start = Instant::now();
|
||||
|
||||
let module_out = module_object
|
||||
.write()
|
||||
.expect("failed to build output object");
|
||||
std::fs::write(&app_o_file, module_out).expect("failed to write object to file");
|
||||
|
||||
let emit_o_file = emit_o_file_start.elapsed();
|
||||
|
||||
CodeGenTiming {
|
||||
code_gen,
|
||||
emit_o_file,
|
||||
}
|
||||
(CodeObject::Vector(module_out), CodeGenTiming { code_gen })
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue