Merge pull request #5548 from JTeeuwissen/fix-oc-test-panics-after-roc-check-said-zero-errors,-zero-warnings

Index array symbols unknown symbols
This commit is contained in:
Ayaz 2023-06-13 13:44:12 -05:00 committed by GitHub
commit c907b12cf0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 47 deletions

View file

@ -3131,7 +3131,6 @@ fn update<'a>(
&layout_interner, &layout_interner,
module_id, module_id,
ident_ids, ident_ids,
state.target_info,
&mut update_mode_ids, &mut update_mode_ids,
&mut state.procedures, &mut state.procedures,
); );

View file

@ -1121,7 +1121,7 @@ fn specialize_list<'a, 'i>(
environment: &mut DropSpecializationEnvironment<'a>, environment: &mut DropSpecializationEnvironment<'a>,
incremented_children: &mut CountingMap<Child>, incremented_children: &mut CountingMap<Child>,
symbol: &Symbol, symbol: &Symbol,
item_layout: InLayout, item_layout: InLayout<'a>,
continuation: &'a Stmt<'a>, continuation: &'a Stmt<'a>,
) -> &'a Stmt<'a> { ) -> &'a Stmt<'a> {
let current_length = environment.list_length.get(symbol).copied(); let current_length = environment.list_length.get(symbol).copied();
@ -1138,11 +1138,11 @@ fn specialize_list<'a, 'i>(
layout_interner.contains_refcounted(item_layout), layout_interner.contains_refcounted(item_layout),
current_length, current_length,
) { ) {
// Only specialize lists if the amount of children is known.
// Otherwise we might have to insert an unbouned number of decrements.
(true, Some(length)) => { (true, Some(length)) => {
match environment.list_children.get(symbol) { match environment.list_children.get(symbol) {
// Only specialize lists if all children are known. Some(children) => {
// Otherwise we might have to insert an unbouned number of decrements.
Some(children) if children.len() as u64 == length => {
// TODO perhaps this allocation can be avoided. // TODO perhaps this allocation can be avoided.
let children_clone = children.clone(); let children_clone = children.clone();
@ -1182,16 +1182,55 @@ fn specialize_list<'a, 'i>(
// Reversed to ensure that the generated code decrements the items in the correct order. // Reversed to ensure that the generated code decrements the items in the correct order.
for i in (0..length).rev() { for i in (0..length).rev() {
let (s, popped) = index_symbols.get(&i).unwrap(); match index_symbols.get(&i) {
// If the symbol is known, we can decrement it (if incremented before).
Some((s, popped)) => {
if !*popped { if !*popped {
// Decrement the children that were not incremented before. And thus don't cancel out. // Decrement the children that were not incremented before. And thus don't cancel out.
newer_continuation = arena newer_continuation = arena.alloc(Stmt::Refcounting(
.alloc(Stmt::Refcounting(ModifyRc::Dec(*s), newer_continuation)); ModifyRc::Dec(*s),
newer_continuation,
));
} }
// Do nothing for the children that were incremented before, as the decrement will cancel out. // Do nothing for the children that were incremented before, as the decrement will cancel out.
} }
// If the symbol is unknown, we have to get the value from the list.
// Should only happen when list elements are discarded.
None => {
let field_symbol = environment
.create_symbol(ident_ids, &format!("field_val_{}", i));
let index_symbol = environment
.create_symbol(ident_ids, &format!("index_val_{}", i));
let dec = arena.alloc(Stmt::Refcounting(
ModifyRc::Dec(field_symbol),
newer_continuation,
));
let index = arena.alloc(Stmt::Let(
field_symbol,
Expr::Call(Call {
call_type: CallType::LowLevel {
op: LowLevel::ListGetUnsafe,
update_mode: UpdateModeId::BACKEND_DUMMY,
},
arguments: arena.alloc([*symbol, index_symbol]),
}),
item_layout,
dec,
));
newer_continuation = arena.alloc(Stmt::Let(
index_symbol,
Expr::Literal(Literal::Int(i128::to_ne_bytes(i as i128))),
Layout::isize(layout_interner.target_info()),
index,
));
}
};
}
newer_continuation newer_continuation
} }

View file

@ -20,7 +20,6 @@ use bumpalo::collections::vec::Vec;
use bumpalo::collections::CollectIn; use bumpalo::collections::CollectIn;
use roc_collections::{MutMap, MutSet}; use roc_collections::{MutMap, MutSet};
use roc_module::symbol::{IdentIds, ModuleId, Symbol}; use roc_module::symbol::{IdentIds, ModuleId, Symbol};
use roc_target::TargetInfo;
/** /**
Insert reset and reuse operations into the IR. Insert reset and reuse operations into the IR.
@ -31,7 +30,6 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
layout_interner: &'i STLayoutInterner<'a>, layout_interner: &'i STLayoutInterner<'a>,
home: ModuleId, home: ModuleId,
ident_ids: &'i mut IdentIds, ident_ids: &'i mut IdentIds,
target_info: TargetInfo,
update_mode_ids: &'i mut UpdateModeIds, update_mode_ids: &'i mut UpdateModeIds,
procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>, procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
) { ) {
@ -46,7 +44,6 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
global_layouts.clone(), global_layouts.clone(),
proc.clone(), proc.clone(),
@ -60,7 +57,6 @@ fn insert_reset_reuse_operations_proc<'a, 'i>(
layout_interner: &'i STLayoutInterner<'a>, layout_interner: &'i STLayoutInterner<'a>,
home: ModuleId, home: ModuleId,
ident_ids: &'i mut IdentIds, ident_ids: &'i mut IdentIds,
target_info: TargetInfo,
update_mode_ids: &'i mut UpdateModeIds, update_mode_ids: &'i mut UpdateModeIds,
mut symbol_layout: SymbolLayout<'a>, mut symbol_layout: SymbolLayout<'a>,
mut proc: Proc<'a>, mut proc: Proc<'a>,
@ -82,7 +78,6 @@ fn insert_reset_reuse_operations_proc<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
&mut env, &mut env,
arena.alloc(proc.body), arena.alloc(proc.body),
@ -100,7 +95,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner: &'i STLayoutInterner<'a>, layout_interner: &'i STLayoutInterner<'a>,
home: ModuleId, home: ModuleId,
ident_ids: &'i mut IdentIds, ident_ids: &'i mut IdentIds,
target_info: TargetInfo,
update_mode_ids: &'i mut UpdateModeIds, update_mode_ids: &'i mut UpdateModeIds,
environment: &mut ReuseEnvironment<'a>, environment: &mut ReuseEnvironment<'a>,
stmt: &'a Stmt<'a>, stmt: &'a Stmt<'a>,
@ -145,7 +139,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
// See if we have a token. // See if we have a token.
match environment.pop_reuse_token(&get_reuse_layout_info( match environment.pop_reuse_token(&get_reuse_layout_info(
layout_interner, layout_interner,
target_info,
union_layout, union_layout,
)) { )) {
// We have a reuse token for this layout, use it. // We have a reuse token for this layout, use it.
@ -214,7 +207,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
environment, environment,
current_stmt, current_stmt,
@ -258,7 +250,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
&mut branch_env, &mut branch_env,
branch, branch,
@ -286,7 +277,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
&mut branch_env, &mut branch_env,
branch, branch,
@ -428,11 +418,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
environment.push_reuse_token( environment.push_reuse_token(
arena, arena,
get_reuse_layout_info( get_reuse_layout_info(layout_interner, union_layout),
layout_interner,
target_info,
union_layout,
),
reuse_token, reuse_token,
layout, layout,
); );
@ -451,7 +437,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
environment, environment,
continuation, continuation,
@ -459,21 +444,15 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
// If we inserted a reuse token, we need to insert a reset reuse operation if the reuse token is consumed. // If we inserted a reuse token, we need to insert a reset reuse operation if the reuse token is consumed.
if let Some((layout, union_layout, symbol, reuse_token, dec_ref)) = reuse_pair { if let Some((layout, union_layout, symbol, reuse_token, dec_ref)) = reuse_pair {
let stack_reuse_token = environment.peek_reuse_token(&get_reuse_layout_info( let stack_reuse_token = environment
layout_interner, .peek_reuse_token(&get_reuse_layout_info(layout_interner, union_layout));
target_info,
union_layout,
));
match stack_reuse_token { match stack_reuse_token {
Some(token_with_layout) if token_with_layout.token == reuse_token => { Some(token_with_layout) if token_with_layout.token == reuse_token => {
// The token we inserted is still on the stack, so we don't need to insert a reset operation. // The token we inserted is still on the stack, so we don't need to insert a reset operation.
// We do need to remove the token from the environment. To prevent errors higher in the tree. // We do need to remove the token from the environment. To prevent errors higher in the tree.
let _ = environment.pop_reuse_token(&get_reuse_layout_info( let _ = environment
layout_interner, .pop_reuse_token(&get_reuse_layout_info(layout_interner, union_layout));
target_info,
union_layout,
));
} }
_ => { _ => {
// The token we inserted is no longer on the stack, it must have been consumed. // The token we inserted is no longer on the stack, it must have been consumed.
@ -525,7 +504,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
environment, environment,
remainder, remainder,
@ -551,7 +529,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
environment, environment,
remainder, remainder,
@ -575,7 +552,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
environment, environment,
remainder, remainder,
@ -611,7 +587,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
&mut first_pass_environment, &mut first_pass_environment,
remainder, remainder,
@ -693,7 +668,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
&mut first_pass_body_environment, &mut first_pass_body_environment,
body, body,
@ -784,7 +758,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
environment, environment,
remainder, remainder,
@ -871,7 +844,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner, layout_interner,
home, home,
ident_ids, ident_ids,
target_info,
update_mode_ids, update_mode_ids,
&mut body_environment, &mut body_environment,
body, body,
@ -1340,10 +1312,10 @@ fn drop_unused_reuse_tokens<'a>(
fn get_reuse_layout_info<'a, 'i>( fn get_reuse_layout_info<'a, 'i>(
layout_interner: &'i STLayoutInterner<'a>, layout_interner: &'i STLayoutInterner<'a>,
target_info: TargetInfo,
union_layout: UnionLayout<'a>, union_layout: UnionLayout<'a>,
) -> TokenLayout { ) -> TokenLayout {
let (size, alignment) = union_layout.data_size_and_alignment(layout_interner, target_info); let (size, alignment) =
union_layout.data_size_and_alignment(layout_interner, layout_interner.target_info());
let has_tag = match union_layout { let has_tag = match union_layout {
UnionLayout::NonRecursive(_) => unreachable!("Non recursive unions should not be reused."), UnionLayout::NonRecursive(_) => unreachable!("Non recursive unions should not be reused."),
// The memory for union layouts that has a tag_id can be reused for new allocations with tag_id. // The memory for union layouts that has a tag_id can be reused for new allocations with tag_id.