Store specialized variable for use in dbg as fake symbol in lowlevel call

This commit is contained in:
Ayaz Hafiz 2022-12-14 16:23:08 -06:00
parent fe90355265
commit a96225e92e
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
6 changed files with 48 additions and 8 deletions

View file

@ -1287,6 +1287,14 @@ fn lowlevel_spec<'a>(
builder.add_make_tuple(block, &[byte_index, string, is_ok, problem_code])
}
Dbg => {
let arguments = [env.symbols[&arguments[0]]];
let result_type =
layout_spec(env, builder, interner, layout, &WhenRecursive::Unreachable)?;
builder.add_unknown_with(block, &arguments, result_type)
}
_other => {
// println!("missing {:?}", _other);
// TODO overly pessimstic

View file

@ -11,7 +11,7 @@ use roc_builtins::bitcode::{self, FloatWidth, IntWidth};
use roc_error_macros::internal_error;
use roc_module::{low_level::LowLevel, symbol::Symbol};
use roc_mono::{
ir::HigherOrderLowLevel,
ir::{HigherOrderLowLevel, LookupType},
layout::{Builtin, LambdaSet, Layout, LayoutIds},
};
use roc_target::PtrWidth;
@ -1120,14 +1120,19 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
}
},
Dbg => {
// now what
arguments!(condition);
assert_eq!(args.len(), 2);
let condition = load_symbol(scope, &args[0]);
let dbg_spec_var_symbol = args[1];
if env.mode.runs_expects() {
let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(args[0]) };
let shared_memory = crate::llvm::expect::SharedMemoryPointer::get(env);
// HACK(dbg-spec-var): the specialized type variable is passed along as a fake symbol
let specialized_var =
unsafe { LookupType::from_index(dbg_spec_var_symbol.ident_id().index() as _) };
crate::llvm::expect::clone_to_shared_memory(
env,
scope,
@ -1136,7 +1141,7 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
args[0],
region,
&[args[0]],
&[roc_mono::ir::LookupType::NULL], // TODO
&[specialized_var],
);
crate::llvm::expect::notify_parent_dbg(env, &shared_memory);

View file

@ -594,6 +594,13 @@ impl IdentId {
pub const fn index(self) -> usize {
self.0 as usize
}
/// # Safety
///
/// The index is not guaranteed to know to exist.
pub unsafe fn from_index(index: u32) -> Self {
Self(index)
}
}
/// Stores a mapping between Ident and IdentId.

View file

@ -948,7 +948,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
ListIsUnique => arena.alloc_slice_copy(&[borrowed]),
Dbg => arena.alloc_slice_copy(&[borrowed]),
Dbg => arena.alloc_slice_copy(&[borrowed, /* dbg-spec-var */ irrelevant]),
BoxExpr | UnboxExpr => {
unreachable!("These lowlevel operations are turned into mono Expr's")

View file

@ -555,7 +555,13 @@ impl<'a, 'i> Context<'a, 'i> {
match &call_type {
LowLevel { op, .. } => {
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars);
let b = match op {
roc_module::low_level::LowLevel::Dbg => {
// NB(dbg-spec-var) second var is the Variable
self.add_dec_after_lowlevel(&arguments[..1], ps, b, b_live_vars)
}
_ => self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars),
};
let v = Expr::Call(crate::ir::Call {
call_type,

View file

@ -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::{IdentIds, ModuleId, Symbol};
use roc_module::symbol::{IdentId, IdentIds, ModuleId, Symbol};
use roc_problem::can::{RuntimeError, ShadowKind};
use roc_region::all::{Loc, Region};
use roc_std::RocDec;
@ -6711,13 +6711,23 @@ pub fn from_can<'a>(
} => {
let rest = from_can(env, variable, loc_continuation.value, procs, layout_cache);
let spec_var = env
.expectation_subs
.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]),
arguments: env.arena.alloc([dbg_symbol, dbg_spec_var_symbol]),
};
let dbg_layout = layout_cache
@ -6745,6 +6755,10 @@ pub fn from_can<'a>(
);
}
// 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
}