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,
module_id,
ident_ids,
state.target_info,
&mut update_mode_ids,
&mut state.procedures,
);

View file

@ -1121,7 +1121,7 @@ fn specialize_list<'a, 'i>(
environment: &mut DropSpecializationEnvironment<'a>,
incremented_children: &mut CountingMap<Child>,
symbol: &Symbol,
item_layout: InLayout,
item_layout: InLayout<'a>,
continuation: &'a Stmt<'a>,
) -> &'a Stmt<'a> {
let current_length = environment.list_length.get(symbol).copied();
@ -1138,11 +1138,11 @@ fn specialize_list<'a, 'i>(
layout_interner.contains_refcounted(item_layout),
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)) => {
match environment.list_children.get(symbol) {
// Only specialize lists if all children are known.
// Otherwise we might have to insert an unbouned number of decrements.
Some(children) if children.len() as u64 == length => {
Some(children) => {
// TODO perhaps this allocation can be avoided.
let children_clone = children.clone();
@ -1182,15 +1182,54 @@ fn specialize_list<'a, 'i>(
// Reversed to ensure that the generated code decrements the items in the correct order.
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 {
// Decrement the children that were not incremented before. And thus don't cancel out.
newer_continuation = arena.alloc(Stmt::Refcounting(
ModifyRc::Dec(*s),
newer_continuation,
));
}
if !*popped {
// Decrement the children that were not incremented before. And thus don't cancel out.
newer_continuation = arena
.alloc(Stmt::Refcounting(ModifyRc::Dec(*s), newer_continuation));
}
// 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));
// Do nothing for the children that were incremented before, as the decrement will cancel out.
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

View file

@ -20,7 +20,6 @@ use bumpalo::collections::vec::Vec;
use bumpalo::collections::CollectIn;
use roc_collections::{MutMap, MutSet};
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
use roc_target::TargetInfo;
/**
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>,
home: ModuleId,
ident_ids: &'i mut IdentIds,
target_info: TargetInfo,
update_mode_ids: &'i mut UpdateModeIds,
procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
) {
@ -46,7 +44,6 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
global_layouts.clone(),
proc.clone(),
@ -60,7 +57,6 @@ fn insert_reset_reuse_operations_proc<'a, 'i>(
layout_interner: &'i STLayoutInterner<'a>,
home: ModuleId,
ident_ids: &'i mut IdentIds,
target_info: TargetInfo,
update_mode_ids: &'i mut UpdateModeIds,
mut symbol_layout: SymbolLayout<'a>,
mut proc: Proc<'a>,
@ -82,7 +78,6 @@ fn insert_reset_reuse_operations_proc<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
&mut env,
arena.alloc(proc.body),
@ -100,7 +95,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner: &'i STLayoutInterner<'a>,
home: ModuleId,
ident_ids: &'i mut IdentIds,
target_info: TargetInfo,
update_mode_ids: &'i mut UpdateModeIds,
environment: &mut ReuseEnvironment<'a>,
stmt: &'a Stmt<'a>,
@ -145,7 +139,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
// See if we have a token.
match environment.pop_reuse_token(&get_reuse_layout_info(
layout_interner,
target_info,
union_layout,
)) {
// We have a reuse token for this layout, use it.
@ -214,7 +207,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
environment,
current_stmt,
@ -258,7 +250,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
&mut branch_env,
branch,
@ -286,7 +277,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
&mut branch_env,
branch,
@ -428,11 +418,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
environment.push_reuse_token(
arena,
get_reuse_layout_info(
layout_interner,
target_info,
union_layout,
),
get_reuse_layout_info(layout_interner, union_layout),
reuse_token,
layout,
);
@ -451,7 +437,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
environment,
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 let Some((layout, union_layout, symbol, reuse_token, dec_ref)) = reuse_pair {
let stack_reuse_token = environment.peek_reuse_token(&get_reuse_layout_info(
layout_interner,
target_info,
union_layout,
));
let stack_reuse_token = environment
.peek_reuse_token(&get_reuse_layout_info(layout_interner, union_layout));
match stack_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.
// 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(
layout_interner,
target_info,
union_layout,
));
let _ = environment
.pop_reuse_token(&get_reuse_layout_info(layout_interner, union_layout));
}
_ => {
// 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,
home,
ident_ids,
target_info,
update_mode_ids,
environment,
remainder,
@ -551,7 +529,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
environment,
remainder,
@ -575,7 +552,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
environment,
remainder,
@ -611,7 +587,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
&mut first_pass_environment,
remainder,
@ -693,7 +668,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
&mut first_pass_body_environment,
body,
@ -784,7 +758,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
environment,
remainder,
@ -871,7 +844,6 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
layout_interner,
home,
ident_ids,
target_info,
update_mode_ids,
&mut body_environment,
body,
@ -1340,10 +1312,10 @@ fn drop_unused_reuse_tokens<'a>(
fn get_reuse_layout_info<'a, 'i>(
layout_interner: &'i STLayoutInterner<'a>,
target_info: TargetInfo,
union_layout: UnionLayout<'a>,
) -> 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 {
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.