mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
make dbg transparent to refcounting
This commit is contained in:
parent
1286878d39
commit
f76df8a356
10 changed files with 215 additions and 28 deletions
|
@ -611,6 +611,7 @@ fn stmt_spec<'a>(
|
|||
|
||||
builder.add_choice(block, &cases)
|
||||
}
|
||||
Dbg { remainder, .. } => stmt_spec(builder, interner, env, block, layout, remainder),
|
||||
Expect { remainder, .. } => stmt_spec(builder, interner, env, block, layout, remainder),
|
||||
ExpectFx { remainder, .. } => stmt_spec(builder, interner, env, block, layout, remainder),
|
||||
Ret(symbol) => Ok(env.symbols[symbol]),
|
||||
|
|
|
@ -1107,6 +1107,7 @@ trait Backend<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
Stmt::Dbg { .. } => todo!("dbg not implemented in the dev backend"),
|
||||
Stmt::Expect { .. } => todo!("expect is not implemented in the dev backend"),
|
||||
Stmt::ExpectFx { .. } => todo!("expect-fx is not implemented in the dev backend"),
|
||||
|
||||
|
|
|
@ -2661,6 +2661,39 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
|||
}
|
||||
}
|
||||
|
||||
Dbg {
|
||||
symbol,
|
||||
variable: specialized_var,
|
||||
remainder,
|
||||
} => {
|
||||
if env.mode.runs_expects() {
|
||||
let shared_memory = crate::llvm::expect::SharedMemoryPointer::get(env);
|
||||
let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(*symbol) };
|
||||
|
||||
crate::llvm::expect::clone_to_shared_memory(
|
||||
env,
|
||||
scope,
|
||||
layout_ids,
|
||||
&shared_memory,
|
||||
*symbol,
|
||||
region,
|
||||
&[*symbol],
|
||||
&[*specialized_var],
|
||||
);
|
||||
|
||||
crate::llvm::expect::notify_parent_dbg(env, &shared_memory);
|
||||
}
|
||||
|
||||
build_exp_stmt(
|
||||
env,
|
||||
layout_ids,
|
||||
func_spec_solutions,
|
||||
scope,
|
||||
parent,
|
||||
remainder,
|
||||
)
|
||||
}
|
||||
|
||||
Expect {
|
||||
condition: cond_symbol,
|
||||
region,
|
||||
|
|
|
@ -714,6 +714,7 @@ impl<'a> WasmBackend<'a> {
|
|||
|
||||
Stmt::Refcounting(modify, following) => self.stmt_refcounting(modify, following),
|
||||
|
||||
Stmt::Dbg { .. } => todo!("dbg is not implemented in the wasm backend"),
|
||||
Stmt::Expect { .. } => todo!("expect is not implemented in the wasm backend"),
|
||||
Stmt::ExpectFx { .. } => todo!("expect-fx is not implemented in the wasm backend"),
|
||||
|
||||
|
|
|
@ -314,6 +314,7 @@ impl<'a> ParamMap<'a> {
|
|||
stack.push(cont);
|
||||
}
|
||||
|
||||
Dbg { remainder, .. } => stack.push(remainder),
|
||||
Expect { remainder, .. } => stack.push(remainder),
|
||||
ExpectFx { remainder, .. } => stack.push(remainder),
|
||||
|
||||
|
@ -823,6 +824,10 @@ impl<'a> BorrowInfState<'a> {
|
|||
self.collect_stmt(param_map, default_branch.1);
|
||||
}
|
||||
|
||||
Dbg { remainder, .. } => {
|
||||
self.collect_stmt(param_map, remainder);
|
||||
}
|
||||
|
||||
Expect { remainder, .. } => {
|
||||
self.collect_stmt(param_map, remainder);
|
||||
}
|
||||
|
@ -1007,6 +1012,7 @@ fn call_info_stmt<'a>(arena: &'a Bump, stmt: &Stmt<'a>, info: &mut CallInfo<'a>)
|
|||
stack.push(default_branch.1);
|
||||
}
|
||||
|
||||
Dbg { remainder, .. } => stack.push(remainder),
|
||||
Expect { remainder, .. } => stack.push(remainder),
|
||||
ExpectFx { remainder, .. } => stack.push(remainder),
|
||||
|
||||
|
|
|
@ -305,6 +305,9 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
self.check_modify_rc(rc);
|
||||
self.check_stmt(rest);
|
||||
}
|
||||
&Stmt::Dbg { remainder, .. } => {
|
||||
self.check_stmt(remainder);
|
||||
}
|
||||
&Stmt::Expect {
|
||||
condition,
|
||||
region: _,
|
||||
|
|
|
@ -108,6 +108,13 @@ pub fn occurring_variables(stmt: &Stmt<'_>) -> (MutSet<Symbol>, MutSet<Symbol>)
|
|||
stack.push(cont);
|
||||
}
|
||||
|
||||
Dbg {
|
||||
symbol, remainder, ..
|
||||
} => {
|
||||
result.insert(*symbol);
|
||||
stack.push(remainder);
|
||||
}
|
||||
|
||||
Expect {
|
||||
condition,
|
||||
remainder,
|
||||
|
@ -1200,6 +1207,26 @@ impl<'a, 'i> Context<'a, 'i> {
|
|||
(switch, case_live_vars)
|
||||
}
|
||||
|
||||
Dbg {
|
||||
symbol,
|
||||
variable,
|
||||
remainder,
|
||||
} => {
|
||||
let (b, mut b_live_vars) = self.visit_stmt(codegen, remainder);
|
||||
|
||||
let expect = self.arena.alloc(Stmt::Dbg {
|
||||
symbol: *symbol,
|
||||
variable: *variable,
|
||||
remainder: b,
|
||||
});
|
||||
|
||||
let expect = self.add_inc_before_consume_all(&[*symbol], expect, &b_live_vars);
|
||||
|
||||
b_live_vars.extend([symbol]);
|
||||
|
||||
(expect, b_live_vars)
|
||||
}
|
||||
|
||||
Expect {
|
||||
remainder,
|
||||
condition,
|
||||
|
@ -1364,6 +1391,13 @@ pub fn collect_stmt(
|
|||
collect_stmt(cont, jp_live_vars, vars)
|
||||
}
|
||||
|
||||
Dbg {
|
||||
symbol, remainder, ..
|
||||
} => {
|
||||
vars.insert(*symbol);
|
||||
collect_stmt(remainder, jp_live_vars, vars)
|
||||
}
|
||||
|
||||
Expect {
|
||||
condition,
|
||||
remainder,
|
||||
|
|
|
@ -27,7 +27,7 @@ use roc_late_solve::storage::{ExternalModuleStorage, ExternalModuleStorageSnapsh
|
|||
use roc_late_solve::{resolve_ability_specialization, AbilitiesView, Resolved, UnificationFailed};
|
||||
use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{IdentId, IdentIds, ModuleId, Symbol};
|
||||
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||
use roc_problem::can::{RuntimeError, ShadowKind};
|
||||
use roc_region::all::{Loc, Region};
|
||||
use roc_std::RocDec;
|
||||
|
@ -1640,6 +1640,14 @@ pub enum Stmt<'a> {
|
|||
/// what happens after the expect
|
||||
remainder: &'a Stmt<'a>,
|
||||
},
|
||||
Dbg {
|
||||
/// The expression we're displaying
|
||||
symbol: Symbol,
|
||||
/// The specialized variable of the expression
|
||||
variable: Variable,
|
||||
/// What happens after the dbg
|
||||
remainder: &'a Stmt<'a>,
|
||||
},
|
||||
/// a join point `join f <params> = <continuation> in remainder`
|
||||
Join {
|
||||
id: JoinPointId,
|
||||
|
@ -2230,6 +2238,15 @@ impl<'a> Stmt<'a> {
|
|||
.append(alloc.hardline())
|
||||
.append(cont.to_doc(alloc, interner, pretty)),
|
||||
|
||||
Dbg {
|
||||
symbol, remainder, ..
|
||||
} => alloc
|
||||
.text("dbg ")
|
||||
.append(symbol_to_doc(alloc, *symbol, pretty))
|
||||
.append(";")
|
||||
.append(alloc.hardline())
|
||||
.append(remainder.to_doc(alloc, interner, pretty)),
|
||||
|
||||
Expect {
|
||||
condition,
|
||||
remainder,
|
||||
|
@ -6716,26 +6733,16 @@ pub fn from_can<'a>(
|
|||
.as_mut()
|
||||
.unwrap()
|
||||
.fresh_unnamed_flex_var();
|
||||
// HACK(dbg-spec-var): pass the specialized type variable along injected into a fake symbol
|
||||
let dbg_spec_var_symbol = Symbol::new(ModuleId::ATTR, unsafe {
|
||||
IdentId::from_index(spec_var.index())
|
||||
});
|
||||
|
||||
// TODO: need to store the specialized variable of this dbg in the expectation_subs
|
||||
let call = crate::ir::Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::Dbg,
|
||||
update_mode: env.next_update_mode_id(),
|
||||
},
|
||||
arguments: env.arena.alloc([dbg_symbol, dbg_spec_var_symbol]),
|
||||
let dbg_stmt = Stmt::Dbg {
|
||||
symbol: dbg_symbol,
|
||||
variable: spec_var,
|
||||
remainder: env.arena.alloc(rest),
|
||||
};
|
||||
|
||||
let dbg_layout = layout_cache
|
||||
.from_var(env.arena, variable, env.subs)
|
||||
.expect("invalid dbg_layout");
|
||||
|
||||
let expr = Expr::Call(call);
|
||||
let mut stmt = Stmt::Let(dbg_symbol, expr, dbg_layout, env.arena.alloc(rest));
|
||||
// Now that the dbg value has been specialized, export its specialized type into the
|
||||
// expectations subs.
|
||||
store_specialized_expectation_lookups(env, [variable], &[spec_var]);
|
||||
|
||||
let symbol_is_reused = matches!(
|
||||
can_reuse_symbol(env, procs, &loc_condition.value, variable),
|
||||
|
@ -6743,23 +6750,19 @@ pub fn from_can<'a>(
|
|||
);
|
||||
|
||||
// skip evaluating the condition if it's just a symbol
|
||||
if !symbol_is_reused {
|
||||
stmt = with_hole(
|
||||
if symbol_is_reused {
|
||||
dbg_stmt
|
||||
} else {
|
||||
with_hole(
|
||||
env,
|
||||
loc_condition.value,
|
||||
variable,
|
||||
procs,
|
||||
layout_cache,
|
||||
dbg_symbol,
|
||||
env.arena.alloc(stmt),
|
||||
);
|
||||
env.arena.alloc(dbg_stmt),
|
||||
)
|
||||
}
|
||||
|
||||
// Now that the dbg value has been specialized, export its specialized type into the
|
||||
// expectations subs.
|
||||
store_specialized_expectation_lookups(env, [variable], &[spec_var]);
|
||||
|
||||
stmt
|
||||
}
|
||||
|
||||
LetRec(defs, cont, _cycle_mark) => {
|
||||
|
@ -7138,6 +7141,23 @@ fn substitute_in_stmt_help<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
Dbg {
|
||||
symbol,
|
||||
variable,
|
||||
remainder,
|
||||
} => {
|
||||
let new_remainder =
|
||||
substitute_in_stmt_help(arena, remainder, subs).unwrap_or(remainder);
|
||||
|
||||
let expect = Dbg {
|
||||
symbol: substitute(subs, *symbol).unwrap_or(*symbol),
|
||||
variable: *variable,
|
||||
remainder: new_remainder,
|
||||
};
|
||||
|
||||
Some(arena.alloc(expect))
|
||||
}
|
||||
|
||||
Expect {
|
||||
condition,
|
||||
region,
|
||||
|
|
|
@ -191,6 +191,27 @@ fn function_s<'a, 'i>(
|
|||
}
|
||||
}
|
||||
|
||||
Dbg {
|
||||
symbol,
|
||||
variable,
|
||||
remainder,
|
||||
} => {
|
||||
let continuation: &Stmt = remainder;
|
||||
let new_continuation = function_s(env, w, c, continuation);
|
||||
|
||||
if std::ptr::eq(continuation, new_continuation) || continuation == new_continuation {
|
||||
stmt
|
||||
} else {
|
||||
let new_refcounting = Dbg {
|
||||
symbol: *symbol,
|
||||
variable: *variable,
|
||||
remainder: new_continuation,
|
||||
};
|
||||
|
||||
arena.alloc(new_refcounting)
|
||||
}
|
||||
}
|
||||
|
||||
Expect {
|
||||
condition,
|
||||
region,
|
||||
|
@ -438,6 +459,34 @@ fn function_d_main<'a, 'i>(
|
|||
}
|
||||
}
|
||||
|
||||
Dbg {
|
||||
symbol,
|
||||
variable,
|
||||
remainder,
|
||||
} => {
|
||||
let (b, found) = function_d_main(env, x, c, remainder);
|
||||
|
||||
if found || *symbol != x {
|
||||
let refcounting = Dbg {
|
||||
symbol: *symbol,
|
||||
variable: *variable,
|
||||
remainder: b,
|
||||
};
|
||||
|
||||
(arena.alloc(refcounting), found)
|
||||
} else {
|
||||
let b = try_function_s(env, x, c, b);
|
||||
|
||||
let refcounting = Dbg {
|
||||
symbol: *symbol,
|
||||
variable: *variable,
|
||||
remainder: b,
|
||||
};
|
||||
|
||||
(arena.alloc(refcounting), found)
|
||||
}
|
||||
}
|
||||
|
||||
Expect {
|
||||
condition,
|
||||
region,
|
||||
|
@ -656,6 +705,22 @@ fn function_r<'a, 'i>(env: &mut Env<'a, 'i>, stmt: &'a Stmt<'a>) -> &'a Stmt<'a>
|
|||
arena.alloc(Refcounting(*modify_rc, b))
|
||||
}
|
||||
|
||||
Dbg {
|
||||
symbol,
|
||||
variable,
|
||||
remainder,
|
||||
} => {
|
||||
let b = function_r(env, remainder);
|
||||
|
||||
let expect = Dbg {
|
||||
symbol: *symbol,
|
||||
variable: *variable,
|
||||
remainder: b,
|
||||
};
|
||||
|
||||
arena.alloc(expect)
|
||||
}
|
||||
|
||||
Expect {
|
||||
condition,
|
||||
region,
|
||||
|
@ -726,6 +791,9 @@ fn has_live_var<'a>(jp_live_vars: &JPLiveVarMap, stmt: &'a Stmt<'a>, needle: Sym
|
|||
Refcounting(modify_rc, cont) => {
|
||||
modify_rc.get_symbol() == needle || has_live_var(jp_live_vars, cont, needle)
|
||||
}
|
||||
Dbg {
|
||||
symbol, remainder, ..
|
||||
} => *symbol == needle || has_live_var(jp_live_vars, remainder, needle),
|
||||
Expect {
|
||||
condition,
|
||||
remainder,
|
||||
|
|
|
@ -249,6 +249,26 @@ fn insert_jumps<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
Dbg {
|
||||
symbol,
|
||||
variable,
|
||||
remainder,
|
||||
} => match insert_jumps(
|
||||
arena,
|
||||
remainder,
|
||||
goal_id,
|
||||
needle,
|
||||
needle_arguments,
|
||||
needle_result,
|
||||
) {
|
||||
Some(cont) => Some(arena.alloc(Dbg {
|
||||
symbol: *symbol,
|
||||
variable: *variable,
|
||||
remainder: cont,
|
||||
})),
|
||||
None => None,
|
||||
},
|
||||
|
||||
Expect {
|
||||
condition,
|
||||
region,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue