Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.d/step5-p7-region-f64.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Performance

- Loop regions can use shape-proven F64 field reads in Number arithmetic, including values carried through local variables. Learned regions refuse receivers whose requested field is not an identity F64 lane and use the generic path for them.
16 changes: 12 additions & 4 deletions crates/perry-codegen/src/codegen/static_shape_ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,13 +504,14 @@ pub(crate) fn static_shape_id_for_keys_global(keys_global: &str) -> Option<u32>
/// inline key of the birth shape, or when a key in `boxed_mask` (a bare
/// store of a value not proven a canonical double) sits on a non-`Any` lane
/// of the birth rep: the runtime's pack refuses that word too (charter step
/// 5). A returned id is a guard immediate: it joins the module's seed set
/// like any other.
/// 5). The third result is R in region-key order: only identity F64 lanes
/// of this exact birth ShapeId set a bit. A returned id is a guard immediate:
/// it joins the module's seed set like any other.
pub(crate) fn static_region_slots(
keys_global: &str,
keys: &[String],
boxed_mask: u32,
) -> Option<(u32, Vec<u32>)> {
) -> Option<(u32, Vec<u32>, u32)> {
MODULE_STATIC_IDS.with(|m| {
let m = m.borrow();
let (id, shape) = m.get(keys_global)?;
Expand Down Expand Up @@ -538,8 +539,15 @@ pub(crate) fn static_region_slots(
{
return None;
}
let r_mask = slots.iter().enumerate().fold(0u32, |mask, (i, &slot)| {
if (shape.rep >> (2 * slot)) & 0b11 == 0b01 {
mask | (1 << i)
} else {
mask
}
});
note_guard_id(*id, Some(shape));
Some((*id, slots))
Some((*id, slots, r_mask))
})
}

Expand Down
25 changes: 25 additions & 0 deletions crates/perry-codegen/src/codegen/static_shape_ids_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,3 +368,28 @@ fn class_birth_names_anon_shapes_as_literals_and_skips_class_zero() {
assert_eq!(o.class_id, 0);
assert!(o.shape.is_none());
}

#[test]
fn region_static_r_is_the_exact_birth_shapes_f64_key_mask() {
let shape = BirthShape {
rep: 0b01 | (0b01 << 4),
..class("ra\0rb\0rc\0", 3, 0x517)
};
let global = "p7_region_keys".to_string();
MODULE_STATIC_IDS.with(|m| {
m.borrow_mut()
.insert(global.clone(), (SHAPE_ID_BASE + 917, shape));
});
let keys = vec!["rc".to_string(), "rb".to_string(), "ra".to_string()];
let (_, slots, r) = static_region_slots(&global, &keys, 0).expect("birth keys are inline");
assert_eq!(slots, vec![2, 1, 0]);
assert_eq!(r, 0b101, "R follows key order, not birth slot order");
assert!(
static_region_slots(&global, &keys, 0b001).is_none(),
"a boxed store to an F64 birth lane is refused"
);
MODULE_STATIC_IDS.with(|m| {
m.borrow_mut().remove(&global);
});
take_module_static_seeds();
}
4 changes: 4 additions & 0 deletions crates/perry-codegen/src/collectors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ pub(crate) use proven_this::{
tower_route_profitable as pshape_tower_route_profitable,
};
pub(crate) use ptr_numarray::{NumArrayDensity, NumArrayLocal};
pub(crate) use ptr_shape::{
collect_numeric_by_construction_locals_in_region, region_number_flow_reads,
RegionNumberAssumptions,
};
pub(crate) use ptr_shape::{ptr_shape_locals_enabled, PtrShapeLocal};
pub(crate) use ptr_shape_callbacks::collect_array_callback_shapes;
pub(crate) use ptr_shape_returns::collect_exported_return_shapes;
Expand Down
4 changes: 4 additions & 0 deletions crates/perry-codegen/src/collectors/ptr_shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1968,6 +1968,10 @@ mod numeric;
use numeric::{
collect_numeric_by_construction_locals, prove_group_numeric_fields, prove_numeric_fields,
};
pub(crate) use numeric::{
collect_numeric_by_construction_locals_in_region, region_number_flow_reads,
RegionNumberAssumptions,
};
// #8105: the same locals fixpoint, consumed outside the `Ptr<Shape>` pass by
// `collectors/number_by_construction.rs`.
pub(in crate::collectors) use numeric::collect_numeric_by_construction_locals as collect_numeric_by_construction_locals_for_type_analysis;
Expand Down
Loading
Loading