First pass update erasure IR

This commit is contained in:
Ayaz Hafiz 2023-07-02 12:38:09 -05:00
parent 7ea85e44d2
commit dc56a0ffef
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
4 changed files with 128 additions and 151 deletions

View file

@ -2119,9 +2119,9 @@ impl<'a> Expr<'a> {
};
let callee = symbol_to_doc(alloc, *callee, pretty);
alloc
.text("ErasedMake { value:")
.text("ErasedMake { value: ")
.append(value)
.append(", callee:")
.append(", callee: ")
.append(callee)
.append(" }")
}
@ -4091,7 +4091,7 @@ impl<'a> ProcLayout<'a> {
arguments
} else {
let mut extended_args = Vec::with_capacity_in(arguments.len(), arena);
extended_args.extend(arguments.iter().chain(&[Layout::OPAQUE_PTR]).copied());
extended_args.extend(arguments.iter().chain(&[Layout::ERASED]).copied());
extended_args.into_bump_slice()
};

View file

@ -4,30 +4,26 @@ use roc_types::subs::Variable;
use crate::{
borrow::Ownership,
layout::{ErasedIndex, FunctionPointer, InLayout, LambdaName, Layout, LayoutCache, LayoutRepr},
layout::{FunctionPointer, InLayout, LambdaName, Layout, LayoutCache, LayoutRepr},
};
use super::{
with_hole, BranchInfo, Call, CallType, CapturedSymbols, Env, Expr, JoinPointId, Param, Procs,
Stmt, UpdateModeId,
with_hole, BranchInfo, Call, CallType, CapturedSymbols, Env, ErasedField, Expr, JoinPointId,
Param, Procs, Stmt, UpdateModeId,
};
const ERASED_FUNCTION_FIELD_LAYOUTS: &[InLayout] =
&[Layout::OPAQUE_PTR, Layout::OPAQUE_PTR, Layout::OPAQUE_PTR];
fn index_erased_function<'a>(
arena: &'a Bump,
assign_to: Symbol,
erased_function: Symbol,
index: ErasedIndex,
field: ErasedField,
) -> impl FnOnce(Stmt<'a>) -> Stmt<'a> {
move |rest| {
Stmt::Let(
assign_to,
Expr::StructAtIndex {
index: index as _,
structure: erased_function,
field_layouts: ERASED_FUNCTION_FIELD_LAYOUTS,
Expr::ErasedLoad {
symbol: erased_function,
field,
},
Layout::OPAQUE_PTR,
arena.alloc(rest),
@ -153,30 +149,30 @@ pub fn call_erased_function<'a>(
let join_point_id = JoinPointId(env.unique_symbol());
// f_value = f.value
// f_value = ErasedLoad(f, .value)
let f_value = env.unique_symbol();
let let_f_value = index_erased_function(arena, f_value, f, ErasedIndex::Value);
let let_f_value = index_erased_function(arena, f_value, f, ErasedField::Value);
// f_callee = f.callee
// f_callee = ErasedLoad(f, .callee)
let f_callee = env.unique_symbol();
let let_f_callee = index_erased_function(arena, f_callee, f, ErasedIndex::Callee);
let let_f_callee = index_erased_function(arena, f_callee, f, ErasedField::Callee);
let mut build_closure_data_branch = |env: &mut Env, pass_closure| {
// f_callee = cast(f_callee, (..params) -> ret);
// f_callee = Cast(f_callee, (..params) -> ret);
// result = f_callee ..args
// jump join result
let (f_args, function_argument_symbols) = if pass_closure {
// f_args = ...args, f.value
// f_args = ...args, f
// function_argument_symbols = ...args, f.value
let f_args = {
let mut args = AVec::with_capacity_in(f_args.len() + 1, arena);
args.extend(f_args.iter().chain(&[Layout::OPAQUE_PTR]).copied());
args.extend(f_args.iter().chain(&[Layout::ERASED]).copied());
args.into_bump_slice()
};
let function_argument_symbols = {
let mut args = AVec::with_capacity_in(function_argument_symbols.len() + 1, arena);
args.extend(function_argument_symbols.iter().chain(&[f_value]));
args.extend(function_argument_symbols.iter().chain(&[f]));
args.into_bump_slice()
};
(f_args, function_argument_symbols)
@ -239,9 +235,9 @@ pub fn call_erased_function<'a>(
};
let remainder =
// f_value = f.value
// f_value = ErasedLoad(f, .value)
let_f_value(
// f_callee = f.callee
// f_callee = ErasedLoad(f, .callee)
let_f_callee(
//
call_and_jump_on_value,
@ -302,33 +298,27 @@ pub fn build_erased_function<'a>(
assigned: Symbol,
hole: &'a Stmt<'a>,
) -> Stmt<'a> {
let value = env.unique_symbol();
let callee = env.unique_symbol();
let refcounter = env.unique_symbol();
// assigned = Expr::Struct({ value, callee, refcounter })
// hole <assigned>
let result = Stmt::Let(
assigned,
Expr::Struct(env.arena.alloc([value, callee, refcounter])),
Layout::ERASED,
hole,
);
// refcounter = TODO
// <hole>
let result = Stmt::Let(
refcounter,
Expr::NullPointer,
Layout::OPAQUE_PTR,
env.arena.alloc(result),
);
let ResolvedErasedLambda {
captures,
lambda_name,
} = resolved_lambda;
let value = match captures {
None => None,
Some(_) => Some(env.unique_symbol()),
};
let callee = env.unique_symbol();
// assigned = Expr::ErasedMake({ value, callee })
// hole <assigned>
let result = Stmt::Let(
assigned,
Expr::ErasedMake { value, callee },
Layout::ERASED,
hole,
);
// callee = Expr::FunctionPointer(f)
let result = Stmt::Let(
callee,
@ -339,16 +329,7 @@ pub fn build_erased_function<'a>(
// value = Expr::Box({s})
match captures {
None => {
// value = nullptr
// <hole>
Stmt::Let(
value,
Expr::NullPointer,
Layout::OPAQUE_PTR,
env.arena.alloc(result),
)
}
None => result,
Some(ResolvedErasedCaptures { layouts, symbols }) => {
// captures = {...captures}
// captures = Box(captures)
@ -364,7 +345,7 @@ pub fn build_erased_function<'a>(
layout_cache.put_in_direct_no_semantic(LayoutRepr::Boxed(stack_captures_layout));
let result = Stmt::Let(
value,
value.unwrap(),
Expr::Call(Call {
call_type: CallType::LowLevel {
op: LowLevel::PtrCast,
@ -473,6 +454,7 @@ pub fn unpack_closure_data<'a>(
captures: &[(Symbol, Variable)],
mut hole: Stmt<'a>,
) -> Stmt<'a> {
let loaded_captures = env.unique_symbol();
let heap_captures = env.unique_symbol();
let stack_captures = env.unique_symbol();
@ -525,5 +507,12 @@ pub fn unpack_closure_data<'a>(
env.arena.alloc(hole),
);
hole
let let_loaded_captures = index_erased_function(
env.arena,
loaded_captures,
captures_symbol,
ErasedField::Value,
);
let_loaded_captures(hole)
}

View file

@ -1413,7 +1413,7 @@ impl<'a> ClosureDataKind<'a> {
pub fn data_layout(&self) -> InLayout<'a> {
match self {
Self::LambdaSet(lambda_set) => lambda_set.full_layout,
Self::Erased => Layout::OPAQUE_PTR,
Self::Erased => Layout::ERASED,
}
}
}
@ -2603,14 +2603,6 @@ impl<'a> Layout<'a> {
}
}
/// Index into an [Erased layout][Layout::ERASED].
#[repr(u8)]
pub(crate) enum ErasedIndex {
Value = 0,
Callee = 1,
RefCounter = 2,
}
impl<'a> LayoutRepr<'a> {
pub const UNIT: Self = LayoutRepr::struct_(&[]);
pub const BOOL: Self = LayoutRepr::Builtin(Builtin::Bool);