mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
Add Num.abs as inlined function
This commit is contained in:
parent
9e6eb85166
commit
13781a6f8f
5 changed files with 248 additions and 65 deletions
|
@ -15,9 +15,10 @@ use bumpalo::Bump;
|
|||
use object::write::Object;
|
||||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_module::ident::TagName;
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{Interns, Symbol};
|
||||
use roc_mono::ir::{CallType, Expr, JoinPointId, Literal, Proc, Stmt};
|
||||
use roc_mono::layout::Layout;
|
||||
use roc_mono::layout::{Builtin, Layout};
|
||||
use target_lexicon::{BinaryFormat, Triple};
|
||||
|
||||
pub mod elf;
|
||||
|
@ -68,9 +69,13 @@ where
|
|||
/// last_seen_map gets the map from symbol to when it is last seen in the function.
|
||||
fn last_seen_map(&mut self) -> &mut MutMap<Symbol, *const Stmt<'a>>;
|
||||
|
||||
/// set_symbol_to_lit sets a symbol to be equal to a literal.
|
||||
/// When the symbol is used, the literal should be loaded.
|
||||
fn set_symbol_to_lit(&mut self, sym: &Symbol, lit: &Literal<'a>);
|
||||
/// load_literal sets a symbol to be equal to a literal.
|
||||
fn load_literal(
|
||||
&mut self,
|
||||
sym: &Symbol,
|
||||
lit: &Literal<'a>,
|
||||
layout: &Layout<'a>,
|
||||
) -> Result<(), String>;
|
||||
|
||||
/// free_symbol frees any registers or stack space used to hold a symbol.
|
||||
fn free_symbol(&mut self, sym: &Symbol);
|
||||
|
@ -85,8 +90,6 @@ where
|
|||
fn finalize(&mut self) -> Result<(&'a [u8], &[Relocation]), String>;
|
||||
|
||||
/// build_proc creates a procedure and outputs it to the wrapped object writer.
|
||||
/// This will need to return the list of relocations because they have to be added differently based on file format.
|
||||
/// Also, assembly will of course be generated by individual calls on backend like may setup_stack.
|
||||
fn build_proc(&mut self, proc: Proc<'a>) -> Result<(&'a [u8], &[Relocation]), String> {
|
||||
self.reset();
|
||||
// TODO: let the backend know of all the arguments.
|
||||
|
@ -119,22 +122,70 @@ where
|
|||
|
||||
/// build_expr builds the expressions for the specified symbol.
|
||||
/// The builder must keep track of the symbol because it may be refered to later.
|
||||
/// In many cases values can be lazy loaded, like literals.
|
||||
fn build_expr(
|
||||
&mut self,
|
||||
sym: &Symbol,
|
||||
expr: &Expr<'a>,
|
||||
_layout: &Layout<'a>,
|
||||
layout: &Layout<'a>,
|
||||
) -> Result<(), String> {
|
||||
match expr {
|
||||
Expr::Literal(lit) => {
|
||||
self.set_symbol_to_lit(sym, lit);
|
||||
self.load_literal(sym, lit, layout);
|
||||
Ok(())
|
||||
}
|
||||
Expr::FunctionCall {
|
||||
call_type: CallType::ByName(func_sym),
|
||||
args,
|
||||
..
|
||||
} => {
|
||||
match *func_sym {
|
||||
Symbol::NUM_ABS => {
|
||||
// Instead of calling the function, just inline it.
|
||||
self.build_expr(sym, &Expr::RunLowLevel(LowLevel::NumAbs, args), layout)
|
||||
}
|
||||
x => Err(format!("the function, {:?}, is not yet implemented", x)),
|
||||
}
|
||||
}
|
||||
Expr::RunLowLevel(lowlevel, args) => {
|
||||
self.build_run_low_level(sym, lowlevel, args, layout)
|
||||
}
|
||||
x => Err(format!("the expression, {:?}, is not yet implemented", x)),
|
||||
}
|
||||
}
|
||||
|
||||
/// build_run_low_level builds the low level opertation and outputs to the specified symbol.
|
||||
/// The builder must keep track of the symbol because it may be refered to later.
|
||||
fn build_run_low_level(
|
||||
&mut self,
|
||||
sym: &Symbol,
|
||||
lowlevel: &LowLevel,
|
||||
args: &'a [Symbol],
|
||||
layout: &Layout<'a>,
|
||||
) -> Result<(), String> {
|
||||
match lowlevel {
|
||||
LowLevel::NumAbs => self.build_num_abs(sym, &args[0], layout),
|
||||
x => Err(format!("low level, {:?}. is not yet implemented", x)),
|
||||
}
|
||||
}
|
||||
|
||||
/// build_num_abs stores the absolute value of src into dst.
|
||||
fn build_num_abs(
|
||||
&mut self,
|
||||
dst: &Symbol,
|
||||
src: &Symbol,
|
||||
layout: &Layout<'a>,
|
||||
) -> Result<(), String> {
|
||||
// TODO: when this is expanded to flaots. deal with typecasting here, and then call correct low level method.
|
||||
match layout {
|
||||
Layout::Builtin(Builtin::Int64) => self.build_num_abs_i64(dst, src),
|
||||
x => Err(format!("layout, {:?}, not implemented yet", x)),
|
||||
}
|
||||
}
|
||||
|
||||
/// build_num_abs stores the absolute value of src into dst.
|
||||
/// It only deals with inputs and outputs of i64 type.
|
||||
fn build_num_abs_i64(&mut self, dst: &Symbol, src: &Symbol) -> Result<(), String>;
|
||||
|
||||
/// maybe_free will check if the symbol is last seen in the current state. If so, it will free the symbol resources, like registers.
|
||||
fn maybe_free_symbol(&mut self, sym: &Symbol, stmt: &Stmt<'a>) {
|
||||
match self.last_seen_map().get(sym) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue