mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
don't store function arguments in alloca
This commit is contained in:
parent
a49a959362
commit
53e56e275d
3 changed files with 21 additions and 80 deletions
|
@ -70,16 +70,16 @@ impl Into<OptimizationLevel> for OptLevel {
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, PartialEq)]
|
#[derive(Default, Debug, Clone, PartialEq)]
|
||||||
pub struct Scope<'a, 'ctx> {
|
pub struct Scope<'a, 'ctx> {
|
||||||
symbols: ImMap<Symbol, (Layout<'a>, PointerValue<'ctx>)>,
|
symbols: ImMap<Symbol, (Layout<'a>, BasicValueEnum<'ctx>)>,
|
||||||
pub top_level_thunks: ImMap<Symbol, (Layout<'a>, FunctionValue<'ctx>)>,
|
pub top_level_thunks: ImMap<Symbol, (Layout<'a>, FunctionValue<'ctx>)>,
|
||||||
join_points: ImMap<JoinPointId, (BasicBlock<'ctx>, &'a [PointerValue<'ctx>])>,
|
join_points: ImMap<JoinPointId, (BasicBlock<'ctx>, &'a [PointerValue<'ctx>])>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'ctx> Scope<'a, 'ctx> {
|
impl<'a, 'ctx> Scope<'a, 'ctx> {
|
||||||
fn get(&self, symbol: &Symbol) -> Option<&(Layout<'a>, PointerValue<'ctx>)> {
|
fn get(&self, symbol: &Symbol) -> Option<&(Layout<'a>, BasicValueEnum<'ctx>)> {
|
||||||
self.symbols.get(symbol)
|
self.symbols.get(symbol)
|
||||||
}
|
}
|
||||||
pub fn insert(&mut self, symbol: Symbol, value: (Layout<'a>, PointerValue<'ctx>)) {
|
pub fn insert(&mut self, symbol: Symbol, value: (Layout<'a>, BasicValueEnum<'ctx>)) {
|
||||||
self.symbols.insert(symbol, value);
|
self.symbols.insert(symbol, value);
|
||||||
}
|
}
|
||||||
pub fn insert_top_level_thunk(
|
pub fn insert_top_level_thunk(
|
||||||
|
@ -1814,9 +1814,6 @@ fn invoke_roc_function<'a, 'ctx, 'env>(
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
let context = env.context;
|
let context = env.context;
|
||||||
|
|
||||||
let call_bt = basic_type_from_layout(env.arena, context, &layout, env.ptr_bytes);
|
|
||||||
let alloca = create_entry_block_alloca(env, parent, call_bt, symbol.ident_string(&env.interns));
|
|
||||||
|
|
||||||
let mut arg_vals: Vec<BasicValueEnum> = Vec::with_capacity_in(arguments.len(), env.arena);
|
let mut arg_vals: Vec<BasicValueEnum> = Vec::with_capacity_in(arguments.len(), env.arena);
|
||||||
|
|
||||||
for arg in arguments.iter() {
|
for arg in arguments.iter() {
|
||||||
|
@ -1852,8 +1849,9 @@ fn invoke_roc_function<'a, 'ctx, 'env>(
|
||||||
{
|
{
|
||||||
env.builder.position_at_end(pass_block);
|
env.builder.position_at_end(pass_block);
|
||||||
|
|
||||||
env.builder.build_store(alloca, call_result);
|
// env.builder.build_store(alloca, call_result);
|
||||||
scope.insert(symbol, (layout, alloca));
|
// scope.insert(symbol, (layout, alloca));
|
||||||
|
scope.insert(symbol, (layout, call_result));
|
||||||
|
|
||||||
build_exp_stmt(env, layout_ids, scope, parent, pass);
|
build_exp_stmt(env, layout_ids, scope, parent, pass);
|
||||||
|
|
||||||
|
@ -1911,32 +1909,8 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
for (symbol, expr, layout) in queue {
|
for (symbol, expr, layout) in queue {
|
||||||
debug_assert!(layout != &Layout::RecursivePointer);
|
debug_assert!(layout != &Layout::RecursivePointer);
|
||||||
let context = &env.context;
|
|
||||||
|
|
||||||
let val = build_exp_expr(env, layout_ids, &scope, parent, layout, &expr);
|
let val = build_exp_expr(env, layout_ids, &scope, parent, layout, &expr);
|
||||||
let expr_bt = if let Layout::RecursivePointer = layout {
|
|
||||||
match expr {
|
|
||||||
Expr::AccessAtIndex { field_layouts, .. } => {
|
|
||||||
let layout = Layout::Struct(field_layouts);
|
|
||||||
|
|
||||||
block_of_memory(env.context, &layout, env.ptr_bytes)
|
|
||||||
}
|
|
||||||
_ => unreachable!(
|
|
||||||
"a recursive pointer can only be loaded from a recursive tag union"
|
|
||||||
),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
basic_type_from_layout(env.arena, context, &layout, env.ptr_bytes)
|
|
||||||
};
|
|
||||||
|
|
||||||
let alloca = create_entry_block_alloca(
|
|
||||||
env,
|
|
||||||
parent,
|
|
||||||
expr_bt,
|
|
||||||
symbol.ident_string(&env.interns),
|
|
||||||
);
|
|
||||||
|
|
||||||
env.builder.build_store(alloca, val);
|
|
||||||
|
|
||||||
// Make a new scope which includes the binding we just encountered.
|
// Make a new scope which includes the binding we just encountered.
|
||||||
// This should be done *after* compiling the bound expr, since any
|
// This should be done *after* compiling the bound expr, since any
|
||||||
|
@ -1945,7 +1919,7 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
// access itself!
|
// access itself!
|
||||||
// scope = scope.clone();
|
// scope = scope.clone();
|
||||||
|
|
||||||
scope.insert(*symbol, (layout.clone(), alloca));
|
scope.insert(*symbol, (layout.clone(), val));
|
||||||
stack.push(*symbol);
|
stack.push(*symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2107,15 +2081,16 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
||||||
// construct the blocks that may jump to this join point
|
// construct the blocks that may jump to this join point
|
||||||
build_exp_stmt(env, layout_ids, scope, parent, remainder);
|
build_exp_stmt(env, layout_ids, scope, parent, remainder);
|
||||||
|
|
||||||
for (ptr, param) in joinpoint_args.iter().zip(parameters.iter()) {
|
|
||||||
scope.insert(param.symbol, (param.layout.clone(), *ptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
let phi_block = builder.get_insert_block().unwrap();
|
let phi_block = builder.get_insert_block().unwrap();
|
||||||
|
|
||||||
// put the cont block at the back
|
// put the cont block at the back
|
||||||
builder.position_at_end(cont_block);
|
builder.position_at_end(cont_block);
|
||||||
|
|
||||||
|
for (ptr, param) in joinpoint_args.iter().zip(parameters.iter()) {
|
||||||
|
let value = env.builder.build_load(*ptr, "load_jp_argument");
|
||||||
|
scope.insert(param.symbol, (param.layout.clone(), value));
|
||||||
|
}
|
||||||
|
|
||||||
// put the continuation in
|
// put the continuation in
|
||||||
let result = build_exp_stmt(env, layout_ids, scope, parent, continuation);
|
let result = build_exp_stmt(env, layout_ids, scope, parent, continuation);
|
||||||
|
|
||||||
|
@ -2177,9 +2152,8 @@ pub fn load_symbol<'a, 'ctx, 'env>(
|
||||||
symbol: &Symbol,
|
symbol: &Symbol,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
match scope.get(symbol) {
|
match scope.get(symbol) {
|
||||||
Some((_, ptr)) => env
|
Some((_, ptr)) => *ptr,
|
||||||
.builder
|
|
||||||
.build_load(*ptr, symbol.ident_string(&env.interns)),
|
|
||||||
None => panic!(
|
None => panic!(
|
||||||
"There was no entry for {:?} {} in scope {:?}",
|
"There was no entry for {:?} {} in scope {:?}",
|
||||||
symbol, symbol, scope
|
symbol, symbol, scope
|
||||||
|
@ -2187,27 +2161,13 @@ pub fn load_symbol<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ptr_from_symbol<'a, 'ctx, 'scope>(
|
|
||||||
scope: &'scope Scope<'a, 'ctx>,
|
|
||||||
symbol: Symbol,
|
|
||||||
) -> &'scope PointerValue<'ctx> {
|
|
||||||
match scope.get(&symbol) {
|
|
||||||
Some((_, ptr)) => ptr,
|
|
||||||
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_symbol_and_layout<'a, 'ctx, 'env, 'b>(
|
pub fn load_symbol_and_layout<'a, 'ctx, 'env, 'b>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
scope: &'b Scope<'a, 'ctx>,
|
scope: &'b Scope<'a, 'ctx>,
|
||||||
symbol: &Symbol,
|
symbol: &Symbol,
|
||||||
) -> (BasicValueEnum<'ctx>, &'b Layout<'a>) {
|
) -> (BasicValueEnum<'ctx>, &'b Layout<'a>) {
|
||||||
match scope.get(symbol) {
|
match scope.get(symbol) {
|
||||||
Some((layout, ptr)) => (
|
Some((layout, ptr)) => (*ptr, layout),
|
||||||
env.builder
|
|
||||||
.build_load(*ptr, symbol.ident_string(&env.interns)),
|
|
||||||
layout,
|
|
||||||
),
|
|
||||||
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
|
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3342,17 +3302,7 @@ pub fn build_proc<'a, 'ctx, 'env>(
|
||||||
// Add args to scope
|
// Add args to scope
|
||||||
for (arg_val, (layout, arg_symbol)) in fn_val.get_param_iter().zip(args) {
|
for (arg_val, (layout, arg_symbol)) in fn_val.get_param_iter().zip(args) {
|
||||||
set_name(arg_val, arg_symbol.ident_string(&env.interns));
|
set_name(arg_val, arg_symbol.ident_string(&env.interns));
|
||||||
|
scope.insert(*arg_symbol, (layout.clone(), arg_val));
|
||||||
let alloca = create_entry_block_alloca(
|
|
||||||
env,
|
|
||||||
fn_val,
|
|
||||||
arg_val.get_type(),
|
|
||||||
arg_symbol.ident_string(&env.interns),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.build_store(alloca, arg_val);
|
|
||||||
|
|
||||||
scope.insert(*arg_symbol, (layout.clone(), alloca));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = build_exp_stmt(env, layout_ids, &mut scope, fn_val, &proc.body);
|
let body = build_exp_stmt(env, layout_ids, &mut scope, fn_val, &proc.body);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::llvm::build::{
|
use crate::llvm::build::{
|
||||||
call_bitcode_fn, call_void_bitcode_fn, ptr_from_symbol, Env, InPlace, Scope,
|
call_bitcode_fn, call_void_bitcode_fn, complex_bitcast, Env, InPlace, Scope,
|
||||||
};
|
};
|
||||||
use crate::llvm::build_list::{allocate_list, store_list};
|
use crate::llvm::build_list::{allocate_list, store_list};
|
||||||
use crate::llvm::convert::collection;
|
use crate::llvm::convert::collection;
|
||||||
|
@ -61,20 +61,11 @@ fn str_symbol_to_i128<'a, 'ctx, 'env>(
|
||||||
scope: &Scope<'a, 'ctx>,
|
scope: &Scope<'a, 'ctx>,
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
) -> IntValue<'ctx> {
|
) -> IntValue<'ctx> {
|
||||||
let str_ptr = ptr_from_symbol(scope, symbol);
|
let string = load_symbol(env, scope, &symbol);
|
||||||
|
|
||||||
let i128_ptr = env
|
let i128_type = env.context.i128_type().into();
|
||||||
.builder
|
|
||||||
.build_bitcast(
|
|
||||||
*str_ptr,
|
|
||||||
env.context.i128_type().ptr_type(AddressSpace::Generic),
|
|
||||||
"cast",
|
|
||||||
)
|
|
||||||
.into_pointer_value();
|
|
||||||
|
|
||||||
env.builder
|
complex_bitcast(&env.builder, string, i128_type, "str_to_i128").into_int_value()
|
||||||
.build_load(i128_ptr, "load_as_i128")
|
|
||||||
.into_int_value()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn str_to_i128<'a, 'ctx, 'env>(
|
fn str_to_i128<'a, 'ctx, 'env>(
|
||||||
|
|
|
@ -5,7 +5,7 @@ app "nqueens"
|
||||||
|
|
||||||
main : Task.Task {} []
|
main : Task.Task {} []
|
||||||
main =
|
main =
|
||||||
queens 6
|
queens 10
|
||||||
|> Str.fromInt
|
|> Str.fromInt
|
||||||
|> Task.putLine
|
|> Task.putLine
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue