mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +00:00
use Cell, remove threading of identids
This commit is contained in:
parent
47840a4e65
commit
3291cc680e
5 changed files with 48 additions and 58 deletions
|
@ -2,7 +2,7 @@ use crate::{Backend, Env, Relocation};
|
|||
use bumpalo::collections::Vec;
|
||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
||||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_module::symbol::{IdentIds, Symbol};
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_mono::gen_refcount::RefcountProcGenerator;
|
||||
use roc_mono::ir::{BranchInfo, JoinPointId, Literal, Param, ProcLayout, SelfRecursive, Stmt};
|
||||
use roc_mono::layout::{Builtin, Layout};
|
||||
|
@ -543,7 +543,6 @@ impl<
|
|||
|
||||
fn build_switch(
|
||||
&mut self,
|
||||
ident_ids: &mut IdentIds,
|
||||
cond_symbol: &Symbol,
|
||||
_cond_layout: &Layout<'a>, // cond_layout must be a integer due to potential jump table optimizations.
|
||||
branches: &'a [(u64, BranchInfo<'a>, Stmt<'a>)],
|
||||
|
@ -566,7 +565,7 @@ impl<
|
|||
let start_offset = ASM::jne_reg64_imm64_imm32(&mut self.buf, cond_reg, *val, 0);
|
||||
|
||||
// Build all statements in this branch.
|
||||
self.build_stmt(ident_ids, stmt, ret_layout);
|
||||
self.build_stmt(stmt, ret_layout);
|
||||
|
||||
// Build unconditional jump to the end of this switch.
|
||||
// Since we don't know the offset yet, set it to 0 and overwrite later.
|
||||
|
@ -590,7 +589,7 @@ impl<
|
|||
}
|
||||
let (branch_info, stmt) = default_branch;
|
||||
if let BranchInfo::None = branch_info {
|
||||
self.build_stmt(ident_ids, stmt, ret_layout);
|
||||
self.build_stmt(stmt, ret_layout);
|
||||
|
||||
// Update all return jumps to jump past the default case.
|
||||
let ret_offset = self.buf.len();
|
||||
|
@ -612,7 +611,6 @@ impl<
|
|||
|
||||
fn build_join(
|
||||
&mut self,
|
||||
ident_ids: &mut IdentIds,
|
||||
id: &JoinPointId,
|
||||
parameters: &'a [Param<'a>],
|
||||
body: &'a Stmt<'a>,
|
||||
|
@ -651,7 +649,7 @@ impl<
|
|||
sub_backend.load_args(args.into_bump_slice(), ret_layout);
|
||||
|
||||
// Build all statements in body.
|
||||
sub_backend.build_stmt(ident_ids, body, ret_layout);
|
||||
sub_backend.build_stmt(body, ret_layout);
|
||||
|
||||
// Merge the "sub function" into the main function.
|
||||
let sub_func_offset = self.buf.len() as u64;
|
||||
|
@ -695,7 +693,7 @@ impl<
|
|||
);
|
||||
|
||||
// Build remainder of function.
|
||||
self.build_stmt(ident_ids, remainder, ret_layout)
|
||||
self.build_stmt(remainder, ret_layout)
|
||||
}
|
||||
|
||||
fn build_jump(
|
||||
|
|
|
@ -7,7 +7,7 @@ use roc_builtins::bitcode::{self, FloatWidth, IntWidth};
|
|||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_module::ident::{ModuleName, TagName};
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{IdentIds, Interns, ModuleId, Symbol};
|
||||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||
use roc_mono::gen_refcount::RefcountProcGenerator;
|
||||
use roc_mono::ir::{
|
||||
BranchInfo, CallType, Expr, JoinPointId, ListLiteralElement, Literal, Param, Proc, ProcLayout,
|
||||
|
@ -111,11 +111,7 @@ where
|
|||
fn build_wrapped_jmp(&mut self) -> (&'a [u8], u64);
|
||||
|
||||
/// build_proc creates a procedure and outputs it to the wrapped object writer.
|
||||
fn build_proc(
|
||||
&mut self,
|
||||
ident_ids: &mut IdentIds,
|
||||
proc: Proc<'a>,
|
||||
) -> (&'a [u8], &[Relocation]) {
|
||||
fn build_proc(&mut self, proc: Proc<'a>) -> (&'a [u8], &[Relocation]) {
|
||||
let layout_id = LayoutIds::default().get(proc.name, &proc.ret_layout);
|
||||
let proc_name = self.env().symbol_to_string(proc.name, layout_id);
|
||||
self.reset(proc_name, proc.is_self_recursive);
|
||||
|
@ -125,18 +121,18 @@ where
|
|||
}
|
||||
self.scan_ast(&proc.body);
|
||||
self.create_free_map();
|
||||
self.build_stmt(ident_ids, &proc.body, &proc.ret_layout);
|
||||
self.build_stmt(&proc.body, &proc.ret_layout);
|
||||
self.finalize()
|
||||
}
|
||||
|
||||
/// build_stmt builds a statement and outputs at the end of the buffer.
|
||||
fn build_stmt(&mut self, ident_ids: &mut IdentIds, stmt: &Stmt<'a>, ret_layout: &Layout<'a>) {
|
||||
fn build_stmt(&mut self, stmt: &Stmt<'a>, ret_layout: &Layout<'a>) {
|
||||
match stmt {
|
||||
Stmt::Let(sym, expr, layout, following) => {
|
||||
self.build_expr(sym, expr, layout);
|
||||
self.set_layout_map(*sym, layout);
|
||||
self.free_symbols(stmt);
|
||||
self.build_stmt(ident_ids, following, ret_layout);
|
||||
self.build_stmt(following, ret_layout);
|
||||
}
|
||||
Stmt::Ret(sym) => {
|
||||
self.load_literal_symbols(&[*sym]);
|
||||
|
@ -145,21 +141,31 @@ where
|
|||
}
|
||||
Stmt::Refcounting(modify, following) => {
|
||||
let sym = modify.get_symbol();
|
||||
let layout = self.layout_map().get(&sym).unwrap().clone();
|
||||
let layout = *self.layout_map().get(&sym).unwrap();
|
||||
|
||||
// Expand the Refcounting statement into more detailed IR with a function call
|
||||
// If this layout requires a new RC proc, we get enough info to create a linker symbol
|
||||
// for it. Here we don't create linker symbols at this time, but in Wasm backend, we do.
|
||||
let (rc_stmt, new_proc_info) = self
|
||||
.refcount_proc_gen_mut()
|
||||
.expand_refcount_stmt(ident_ids, layout, modify, *following);
|
||||
let (rc_stmt, new_proc_info) = {
|
||||
let module_id = self.env().module_id;
|
||||
let mut interns = self.env().interns.take();
|
||||
let ident_ids = interns.all_ident_ids.get_mut(&module_id).unwrap();
|
||||
|
||||
let expanded = self
|
||||
.refcount_proc_gen_mut()
|
||||
.expand_refcount_stmt(ident_ids, layout, modify, *following);
|
||||
|
||||
self.env().interns.set(interns);
|
||||
|
||||
expanded
|
||||
};
|
||||
|
||||
if let Some((rc_proc_symbol, rc_proc_layout)) = new_proc_info {
|
||||
self.refcount_proc_symbols_mut()
|
||||
.push((rc_proc_symbol, rc_proc_layout));
|
||||
}
|
||||
|
||||
self.build_stmt(ident_ids, &rc_stmt, ret_layout)
|
||||
self.build_stmt(&rc_stmt, ret_layout)
|
||||
}
|
||||
Stmt::Switch {
|
||||
cond_symbol,
|
||||
|
@ -170,7 +176,6 @@ where
|
|||
} => {
|
||||
self.load_literal_symbols(&[*cond_symbol]);
|
||||
self.build_switch(
|
||||
ident_ids,
|
||||
cond_symbol,
|
||||
cond_layout,
|
||||
branches,
|
||||
|
@ -188,7 +193,7 @@ where
|
|||
for param in parameters.iter() {
|
||||
self.set_layout_map(param.symbol, ¶m.layout);
|
||||
}
|
||||
self.build_join(ident_ids, id, parameters, body, remainder, ret_layout);
|
||||
self.build_join(id, parameters, body, remainder, ret_layout);
|
||||
self.free_symbols(stmt);
|
||||
}
|
||||
Stmt::Jump(id, args) => {
|
||||
|
@ -212,7 +217,6 @@ where
|
|||
// build_switch generates a instructions for a switch statement.
|
||||
fn build_switch(
|
||||
&mut self,
|
||||
ident_ids: &mut IdentIds,
|
||||
cond_symbol: &Symbol,
|
||||
cond_layout: &Layout<'a>,
|
||||
branches: &'a [(u64, BranchInfo<'a>, Stmt<'a>)],
|
||||
|
@ -223,7 +227,6 @@ where
|
|||
// build_join generates a instructions for a join statement.
|
||||
fn build_join(
|
||||
&mut self,
|
||||
ident_ids: &mut IdentIds,
|
||||
id: &JoinPointId,
|
||||
parameters: &'a [Param<'a>],
|
||||
body: &'a Stmt<'a>,
|
||||
|
|
|
@ -8,7 +8,7 @@ use object::{
|
|||
SymbolFlags, SymbolKind, SymbolScope,
|
||||
};
|
||||
use roc_collections::all::MutMap;
|
||||
use roc_module::symbol::{self, IdentIds};
|
||||
use roc_module::symbol;
|
||||
use roc_mono::ir::{Proc, ProcLayout};
|
||||
use roc_mono::layout::LayoutIds;
|
||||
use roc_reporting::internal_error;
|
||||
|
@ -22,7 +22,6 @@ use target_lexicon::{Architecture as TargetArch, BinaryFormat as TargetBF, Tripl
|
|||
/// It takes the request to build a module and output the object file for the module.
|
||||
pub fn build_module<'a>(
|
||||
env: &'a Env,
|
||||
ident_ids: &'a mut IdentIds,
|
||||
target: &Triple,
|
||||
procedures: MutMap<(symbol::Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
) -> Object {
|
||||
|
@ -39,8 +38,6 @@ pub fn build_module<'a>(
|
|||
x86_64::X86_64SystemV,
|
||||
> = Backend::new(env);
|
||||
build_object(
|
||||
env,
|
||||
ident_ids,
|
||||
procedures,
|
||||
backend,
|
||||
Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little),
|
||||
|
@ -58,8 +55,6 @@ pub fn build_module<'a>(
|
|||
x86_64::X86_64SystemV,
|
||||
> = Backend::new(env);
|
||||
build_object(
|
||||
env,
|
||||
ident_ids,
|
||||
procedures,
|
||||
backend,
|
||||
Object::new(
|
||||
|
@ -81,8 +76,6 @@ pub fn build_module<'a>(
|
|||
aarch64::AArch64Call,
|
||||
> = Backend::new(env);
|
||||
build_object(
|
||||
env,
|
||||
ident_ids,
|
||||
procedures,
|
||||
backend,
|
||||
Object::new(BinaryFormat::Elf, Architecture::Aarch64, Endianness::Little),
|
||||
|
@ -100,8 +93,6 @@ pub fn build_module<'a>(
|
|||
aarch64::AArch64Call,
|
||||
> = Backend::new(env);
|
||||
build_object(
|
||||
env,
|
||||
ident_ids,
|
||||
procedures,
|
||||
backend,
|
||||
Object::new(
|
||||
|
@ -169,8 +160,6 @@ fn generate_wrapper<'a, B: Backend<'a>>(
|
|||
}
|
||||
|
||||
fn build_object<'a, B: Backend<'a>>(
|
||||
_env: &'a Env,
|
||||
ident_ids: &'a mut IdentIds,
|
||||
procedures: MutMap<(symbol::Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
mut backend: B,
|
||||
mut output: Object,
|
||||
|
@ -240,7 +229,6 @@ fn build_object<'a, B: Backend<'a>>(
|
|||
&mut output,
|
||||
&mut backend,
|
||||
&mut relocations,
|
||||
ident_ids,
|
||||
data_section,
|
||||
fn_name,
|
||||
section_id,
|
||||
|
@ -249,10 +237,22 @@ fn build_object<'a, B: Backend<'a>>(
|
|||
)
|
||||
}
|
||||
|
||||
// Generate IR for refcounting procedures
|
||||
let rc_proc_gen = backend.refcount_proc_gen_mut();
|
||||
let rc_procs = rc_proc_gen.generate_refcount_procs(arena, ident_ids);
|
||||
backend.env().module_id.register_debug_idents(ident_ids);
|
||||
let rc_procs = {
|
||||
let module_id = backend.env().module_id;
|
||||
|
||||
let mut interns = backend.env().interns.take();
|
||||
|
||||
// Generate IR for refcounting procedures
|
||||
let rc_proc_gen = backend.refcount_proc_gen_mut();
|
||||
|
||||
let ident_ids = interns.all_ident_ids.get_mut(&module_id).unwrap();
|
||||
let rc_procs = rc_proc_gen.generate_refcount_procs(arena, ident_ids);
|
||||
backend.env().module_id.register_debug_idents(ident_ids);
|
||||
|
||||
backend.env().interns.set(interns);
|
||||
|
||||
rc_procs
|
||||
};
|
||||
|
||||
let empty = bumpalo::collections::Vec::new_in(arena);
|
||||
let rc_symbols_and_layouts = std::mem::replace(backend.refcount_proc_symbols_mut(), empty);
|
||||
|
@ -277,7 +277,6 @@ fn build_object<'a, B: Backend<'a>>(
|
|||
&mut output,
|
||||
&mut backend,
|
||||
&mut relocations,
|
||||
ident_ids,
|
||||
data_section,
|
||||
fn_name,
|
||||
section_id,
|
||||
|
@ -344,7 +343,6 @@ fn build_proc<'a, B: Backend<'a>>(
|
|||
output: &mut Object,
|
||||
backend: &mut B,
|
||||
relocations: &mut Vec<'a, (SectionId, object::write::Relocation)>,
|
||||
ident_ids: &mut IdentIds,
|
||||
data_section: SectionId,
|
||||
fn_name: String,
|
||||
section_id: SectionId,
|
||||
|
@ -352,7 +350,7 @@ fn build_proc<'a, B: Backend<'a>>(
|
|||
proc: Proc<'a>,
|
||||
) {
|
||||
let mut local_data_index = 0;
|
||||
let (proc_data, relocs) = backend.build_proc(ident_ids, proc);
|
||||
let (proc_data, relocs) = backend.build_proc(proc);
|
||||
let proc_offset = output.add_symbol_data(proc_id, section_id, proc_data, 16);
|
||||
for reloc in relocs {
|
||||
let elfreloc = match reloc {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue