mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +00:00
add symbol storage into generic64 backend
This commit is contained in:
parent
6e10e00534
commit
0d70a4f9f8
2 changed files with 54 additions and 5 deletions
|
@ -14,6 +14,8 @@ pub mod aarch64;
|
||||||
mod storage;
|
mod storage;
|
||||||
pub mod x86_64;
|
pub mod x86_64;
|
||||||
|
|
||||||
|
use storage::StorageManager;
|
||||||
|
|
||||||
const TARGET_INFO: TargetInfo = TargetInfo::default_x86_64();
|
const TARGET_INFO: TargetInfo = TargetInfo::default_x86_64();
|
||||||
|
|
||||||
pub trait CallConv<GeneralReg: RegTrait, FloatReg: RegTrait> {
|
pub trait CallConv<GeneralReg: RegTrait, FloatReg: RegTrait> {
|
||||||
|
@ -269,10 +271,12 @@ pub struct Backend64Bit<
|
||||||
layout_map: MutMap<Symbol, Layout<'a>>,
|
layout_map: MutMap<Symbol, Layout<'a>>,
|
||||||
free_map: MutMap<*const Stmt<'a>, Vec<'a, Symbol>>,
|
free_map: MutMap<*const Stmt<'a>, Vec<'a, Symbol>>,
|
||||||
|
|
||||||
symbol_storage_map: MutMap<Symbol, SymbolStorage<GeneralReg, FloatReg>>,
|
|
||||||
literal_map: MutMap<Symbol, (*const Literal<'a>, *const Layout<'a>)>,
|
literal_map: MutMap<Symbol, (*const Literal<'a>, *const Layout<'a>)>,
|
||||||
join_map: MutMap<JoinPointId, u64>,
|
join_map: MutMap<JoinPointId, u64>,
|
||||||
|
|
||||||
|
storage_manager: StorageManager<'a, GeneralReg, FloatReg, ASM, CC>,
|
||||||
|
symbol_storage_map: MutMap<Symbol, SymbolStorage<GeneralReg, FloatReg>>,
|
||||||
|
|
||||||
// This should probably be smarter than a vec.
|
// This should probably be smarter than a vec.
|
||||||
// There are certain registers we should always use first. With pushing and popping, this could get mixed.
|
// There are certain registers we should always use first. With pushing and popping, this could get mixed.
|
||||||
general_free_regs: Vec<'a, GeneralReg>,
|
general_free_regs: Vec<'a, GeneralReg>,
|
||||||
|
@ -331,6 +335,7 @@ pub fn new_backend_64bit<
|
||||||
free_stack_chunks: bumpalo::vec![in env.arena],
|
free_stack_chunks: bumpalo::vec![in env.arena],
|
||||||
stack_size: 0,
|
stack_size: 0,
|
||||||
fn_call_stack_size: 0,
|
fn_call_stack_size: 0,
|
||||||
|
storage_manager: storage::new_storage_manager(env),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,6 +389,7 @@ impl<
|
||||||
self.float_free_regs
|
self.float_free_regs
|
||||||
.extend_from_slice(CC::FLOAT_DEFAULT_FREE_REGS);
|
.extend_from_slice(CC::FLOAT_DEFAULT_FREE_REGS);
|
||||||
self.helper_proc_symbols.clear();
|
self.helper_proc_symbols.clear();
|
||||||
|
self.storage_manager.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn literal_map(&mut self) -> &mut MutMap<Symbol, (*const Literal<'a>, *const Layout<'a>)> {
|
fn literal_map(&mut self) -> &mut MutMap<Symbol, (*const Literal<'a>, *const Layout<'a>)> {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::generic64::{Assembler, CallConv, RegTrait};
|
use crate::generic64::{Assembler, CallConv, RegTrait};
|
||||||
|
use crate::Env;
|
||||||
use bumpalo::collections::Vec;
|
use bumpalo::collections::Vec;
|
||||||
use roc_collections::all::{MutMap, MutSet};
|
use roc_collections::all::{MutMap, MutSet};
|
||||||
use roc_error_macros::internal_error;
|
use roc_error_macros::internal_error;
|
||||||
|
@ -46,7 +47,7 @@ enum Storage<'a, GeneralReg: RegTrait, FloatReg: RegTrait> {
|
||||||
Stack(StackStorage<'a, GeneralReg, FloatReg>),
|
Stack(StackStorage<'a, GeneralReg, FloatReg>),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct StorageManager<
|
pub struct StorageManager<
|
||||||
'a,
|
'a,
|
||||||
GeneralReg: RegTrait,
|
GeneralReg: RegTrait,
|
||||||
FloatReg: RegTrait,
|
FloatReg: RegTrait,
|
||||||
|
@ -84,6 +85,31 @@ struct StorageManager<
|
||||||
stack_size: u32,
|
stack_size: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_storage_manager<
|
||||||
|
'a,
|
||||||
|
GeneralReg: RegTrait,
|
||||||
|
FloatReg: RegTrait,
|
||||||
|
ASM: Assembler<GeneralReg, FloatReg>,
|
||||||
|
CC: CallConv<GeneralReg, FloatReg>,
|
||||||
|
>(
|
||||||
|
env: &'a Env,
|
||||||
|
) -> StorageManager<'a, GeneralReg, FloatReg, ASM, CC> {
|
||||||
|
StorageManager {
|
||||||
|
phantom_asm: PhantomData,
|
||||||
|
phantom_cc: PhantomData,
|
||||||
|
symbol_storage_map: MutMap::default(),
|
||||||
|
reference_map: MutMap::default(),
|
||||||
|
general_free_regs: bumpalo::vec![in env.arena],
|
||||||
|
general_used_regs: bumpalo::vec![in env.arena],
|
||||||
|
general_used_callee_saved_regs: MutSet::default(),
|
||||||
|
float_free_regs: bumpalo::vec![in env.arena],
|
||||||
|
float_used_regs: bumpalo::vec![in env.arena],
|
||||||
|
float_used_callee_saved_regs: MutSet::default(),
|
||||||
|
free_stack_chunks: bumpalo::vec![in env.arena],
|
||||||
|
stack_size: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
'a,
|
'a,
|
||||||
FloatReg: RegTrait,
|
FloatReg: RegTrait,
|
||||||
|
@ -92,6 +118,23 @@ impl<
|
||||||
CC: CallConv<GeneralReg, FloatReg>,
|
CC: CallConv<GeneralReg, FloatReg>,
|
||||||
> StorageManager<'a, GeneralReg, FloatReg, ASM, CC>
|
> StorageManager<'a, GeneralReg, FloatReg, ASM, CC>
|
||||||
{
|
{
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.symbol_storage_map.clear();
|
||||||
|
self.reference_map.clear();
|
||||||
|
self.general_used_callee_saved_regs.clear();
|
||||||
|
self.general_free_regs.clear();
|
||||||
|
self.general_used_regs.clear();
|
||||||
|
self.general_free_regs
|
||||||
|
.extend_from_slice(CC::GENERAL_DEFAULT_FREE_REGS);
|
||||||
|
self.float_used_callee_saved_regs.clear();
|
||||||
|
self.float_free_regs.clear();
|
||||||
|
self.float_used_regs.clear();
|
||||||
|
self.float_free_regs
|
||||||
|
.extend_from_slice(CC::FLOAT_DEFAULT_FREE_REGS);
|
||||||
|
self.free_stack_chunks.clear();
|
||||||
|
self.stack_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Get a general register from the free list.
|
// Get a general register from the free list.
|
||||||
// Will free data to the stack if necessary to get the register.
|
// Will free data to the stack if necessary to get the register.
|
||||||
fn get_general_reg(&mut self, _buf: &mut Vec<'a, u8>) -> GeneralReg {
|
fn get_general_reg(&mut self, _buf: &mut Vec<'a, u8>) -> GeneralReg {
|
||||||
|
@ -111,7 +154,7 @@ impl<
|
||||||
|
|
||||||
// Claims a general reg for a specific symbol.
|
// Claims a general reg for a specific symbol.
|
||||||
// They symbol should not already have storage.
|
// They symbol should not already have storage.
|
||||||
fn claim_general_reg(&mut self, buf: &mut Vec<'a, u8>, sym: &Symbol) -> GeneralReg {
|
pub fn claim_general_reg(&mut self, buf: &mut Vec<'a, u8>, sym: &Symbol) -> GeneralReg {
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
self.symbol_storage_map.get(sym),
|
self.symbol_storage_map.get(sym),
|
||||||
None,
|
None,
|
||||||
|
@ -126,7 +169,7 @@ impl<
|
||||||
|
|
||||||
// This claims a temporary register and enables is used in the passed in function.
|
// This claims a temporary register and enables is used in the passed in function.
|
||||||
// Temporary registers are not safe across call instructions.
|
// Temporary registers are not safe across call instructions.
|
||||||
fn with_tmp_general_reg<F: FnOnce(&mut Self, &mut Vec<'a, u8>, GeneralReg)>(
|
pub fn with_tmp_general_reg<F: FnOnce(&mut Self, &mut Vec<'a, u8>, GeneralReg)>(
|
||||||
&mut self,
|
&mut self,
|
||||||
buf: &mut Vec<'a, u8>,
|
buf: &mut Vec<'a, u8>,
|
||||||
callback: F,
|
callback: F,
|
||||||
|
@ -140,7 +183,7 @@ impl<
|
||||||
// The symbol must already be stored somewhere.
|
// The symbol must already be stored somewhere.
|
||||||
// Will fail on values stored in float regs.
|
// Will fail on values stored in float regs.
|
||||||
// Will fail for values that don't fit in a single register.
|
// Will fail for values that don't fit in a single register.
|
||||||
fn to_general_reg(&mut self, buf: &mut Vec<'a, u8>, sym: &Symbol) -> GeneralReg {
|
pub fn to_general_reg(&mut self, buf: &mut Vec<'a, u8>, sym: &Symbol) -> GeneralReg {
|
||||||
let storage = if let Some(storage) = self.symbol_storage_map.remove(sym) {
|
let storage = if let Some(storage) = self.symbol_storage_map.remove(sym) {
|
||||||
storage
|
storage
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue