Skip to content

Commit

Permalink
Merge pull request #974 from hash-org/fix-956
Browse files Browse the repository at this point in the history
  • Loading branch information
feds01 authored Sep 15, 2023
2 parents 9c56d6a + f842756 commit ac1a72a
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 132 deletions.
2 changes: 1 addition & 1 deletion compiler/hash-ir/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ impl RValue {
RValue::BinaryOp(op, box (lhs, rhs)) => op.ty(lhs.ty(locals), rhs.ty(locals)),
RValue::CheckedBinaryOp(op, box (lhs, rhs)) => {
let ty = op.ty(lhs.ty(locals), rhs.ty(locals));
IrTy::tuple(&[ty, COMMON_IR_TYS.bool])
IrTy::make_tuple(&[ty, COMMON_IR_TYS.bool])
}
RValue::Cast(_, _, ty) => *ty,
RValue::Len(_) => COMMON_IR_TYS.usize,
Expand Down
89 changes: 25 additions & 64 deletions compiler/hash-ir/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use hash_storage::{
static_sequence_store_indirect, static_single_store,
store::{
statics::{SingleStoreValue, StoreId},
SequenceStore, StoreKey,
SequenceStore,
},
};
use hash_target::{
Expand Down Expand Up @@ -270,7 +270,7 @@ pub enum IrTy {

impl IrTy {
/// Make a tuple type, i.e. `(T1, T2, T3, ...)`
pub fn tuple(tys: &[IrTyId]) -> IrTyId {
pub fn tuple(tys: &[IrTyId]) -> IrTy {
let variants = index_vec![AdtVariant {
name: 0usize.into(),
fields: tys
Expand All @@ -281,8 +281,11 @@ impl IrTy {
.collect(),
}];
let adt = Adt::new_with_flags("tuple".into(), variants, AdtFlags::TUPLE);
let ty = Self::Adt(Adt::create(adt));
IrTy::create(ty)
Self::Adt(Adt::create(adt))
}

pub fn make_tuple(tys: &[IrTyId]) -> IrTyId {
IrTy::create(IrTy::tuple(tys))
}

/// Create a reference type to the provided [IrTy].
Expand Down Expand Up @@ -525,67 +528,17 @@ macro_rules! create_common_ty_table {
/// using the associated [IrTyId]s of this map.
pub struct CommonIrTys {
$(pub $name: IrTyId, )*

/// A slice of bytes, i.e. `[u8]`.
pub byte_slice: IrTyId,

/// A string, i.e. `&str`.
pub str: IrTyId,

/// A general pointer to bytes, i.e. `&u8`.
pub ptr: IrTyId,

/// A general pointer to bytes, i.e. `&raw u8`.
pub raw_ptr: IrTyId,

/// A void pointer, i.e. `&()`.
pub void_ptr: IrTyId,

/// The big unsigned integer type.
pub ubig: IrTyId,

/// The big signed integer type.
pub ibig: IrTyId,
}

impl CommonIrTys {
pub fn new() -> CommonIrTys {
let table = CommonIrTys {
$($name: IrTy::create($value), )*
byte_slice: IrTyId::from_index_unchecked(0),
ptr: IrTyId::from_index_unchecked(0),
raw_ptr: IrTyId::from_index_unchecked(0),
void_ptr: IrTyId::from_index_unchecked(0),
str: IrTyId::from_index_unchecked(0),
ubig: IrTyId::from_index_unchecked(0),
ibig: IrTyId::from_index_unchecked(0),
};

// Create a `unit` type in order to reserve the first index of
// the ADT for a `()` type.
let _ = IrTy::tuple(&[]);

// @@Hack: find a way to nicely create this within the `create_common_ty_table!`,
// however this would require somehow referencing entries within the table before
// they are defined...
let byte_slice = IrTy::create(IrTy::Slice(table.u8));
let ptr = IrTy::create(IrTy::Ref(table.u8, Mutability::Immutable, RefKind::Normal));
let raw_ptr = IrTy::create(IrTy::Ref(table.u8, Mutability::Immutable, RefKind::Raw));
let void_ptr = IrTy::create(IrTy::Ref(table.unit, Mutability::Immutable, RefKind::Raw));
let str = IrTy::create(IrTy::Ref(table.unsized_str, Mutability::Immutable, RefKind::Normal));

let ubig = IrTy::create(IrTy::Slice(table.u64));
let ibig = IrTy::tuple(&[table.bool, table.ubig]);
$(let $name = IrTy::create($value); )*

CommonIrTys {
byte_slice,
ptr,
raw_ptr,
void_ptr,
str,
ubig,
ibig,
..table
$($name,)*
}
}
}
Expand All @@ -606,14 +559,6 @@ create_common_ty_table!(
char: IrTy::Char,
never: IrTy::Never,

// ------------------------------------------
// Unsized string refers to the inner type of a `str`.
//
// @@Temporary This is only temporary until str/[T] type semantics and rules are decided and
// implemented.
// ------------------------------------------
unsized_str: IrTy::Str,

// ------------------------------------------
// Floating point types
// ------------------------------------------
Expand Down Expand Up @@ -644,6 +589,22 @@ create_common_ty_table!(
// ------------------------------------------
usize: IrTy::UInt(UIntTy::USize),
unit: IrTy::Adt(AdtId::UNIT),

// ------------------------------------------
// BigInts
// ------------------------------------------
ubig: IrTy::Slice(u64),
ibig: IrTy::tuple(&[bool, ubig]),

// ------------------------------------------
// Pointer types
// ------------------------------------------
byte_slice: IrTy::Slice(u8),
ptr: IrTy::Ref(u8, Mutability::Immutable, RefKind::Normal),
raw_ptr: IrTy::Ref(u8, Mutability::Immutable, RefKind::Raw),
void_ptr: IrTy::Ref(unit, Mutability::Immutable, RefKind::Raw),
unsized_str: IrTy::Str,
str: IrTy::Ref(unsized_str, Mutability::Immutable, RefKind::Normal),
);

lazy_static::lazy_static!(
Expand Down
2 changes: 1 addition & 1 deletion compiler/hash-lower/src/build/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ impl<'tcx> BodyBuilder<'tcx> {

if op.is_checkable() && is_integral {
// Create a new tuple that contains the result of the operation
let ty = IrTy::tuple(&[ty, COMMON_IR_TYS.bool]);
let ty = IrTy::make_tuple(&[ty, COMMON_IR_TYS.bool]);

let temp = self.temp_place(ty);
let rvalue = RValue::CheckedBinaryOp(op, operands);
Expand Down
14 changes: 7 additions & 7 deletions compiler/hash-lower/src/discover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use std::ops::ControlFlow;

use hash_attrs::{attr::attr_store, builtin::attrs};
use hash_pipeline::workspace::StageInfo;
use hash_storage::store::{statics::StoreId, TrivialSequenceStoreKey};
use hash_storage::store::{statics::StoreId, Store, TrivialSequenceStoreKey};
use hash_tir::{
atom_info::ItemInAtomInfo,
stores::tir_stores,
tir::{FnDefId, HasAstNodeId, ModDef, ModKind, ModMemberValue, TermId},
tir::{FnDefId, HasAstNodeId, ModKind, ModMemberValue, TermId},
visitor::{Atom, Visitor},
};
use hash_utils::{derive_more::Constructor, indexmap::IndexSet};
Expand Down Expand Up @@ -91,18 +91,18 @@ impl FnDiscoverer<'_> {
pub fn discover_fns(&self) -> DiscoveredFns {
let mut fns = DiscoveredFns::new();

for mod_def_id in ModDef::iter_all_mods() {
tir_stores().mod_def().for_each_entry(|def| {
// Check if we can skip this module as it may of already been queued before
// during some other pipeline run.
//
// @@Incomplete: mod-blocks that are already lowered won't be caught by
// the queue-deduplication.
match mod_def_id.borrow().kind {
match def.borrow().kind {
ModKind::Source(id) if !self.stage_info.get(id).is_lowered() => {}
_ => continue,
_ => return,
};

for member in mod_def_id.borrow().members.iter() {
for member in def.borrow().members.iter() {
match member.borrow().value {
ModMemberValue::Mod(_) => {
// Will be handled later in the loop
Expand All @@ -128,7 +128,7 @@ impl FnDiscoverer<'_> {
}
}
}
}
});

fns
}
Expand Down
39 changes: 24 additions & 15 deletions compiler/hash-storage/src/store/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ use parking_lot::{
pub trait StoreKey: Copy + Eq {
/// Turn the key into an index.
fn to_index(self) -> usize;

/// Create a key from an index.
///
/// This should generally not be used in client code.
fn from_index_unchecked(index: usize) -> Self;
/// # Safety
/// - This will create a [StoreKey] without checking the boundaries in the
/// [Store].
/// - This should generally not be used in client code.
unsafe fn from_index_unchecked(index: usize) -> Self;
}

/// Create a new [`StoreKey`] with the given name.
Expand All @@ -26,11 +30,12 @@ macro_rules! new_store_key {

impl $crate::store::StoreKey for $name {

#[inline(always)]
fn to_index(self) -> usize {
self.index.try_into().unwrap()
}

fn from_index_unchecked(index: usize) -> Self {
unsafe fn from_index_unchecked(index: usize) -> Self {
Self { index: index.try_into().unwrap() }
}
}
Expand Down Expand Up @@ -73,18 +78,20 @@ pub trait Store<Key: StoreKey, Value> {
fn internal_data(&self) -> &StoreInternalData<Value>;

/// Iterate over all keys in the store.
fn for_each_entry(&self, f: impl Fn(Key)) {
fn for_each_entry(&self, mut f: impl FnMut(Key)) {
let len = self.internal_data().read().len();
for index in 0..len {
f(Key::from_index_unchecked(index));
unsafe {
for index in 0..len {
f(Key::from_index_unchecked(index));
}
}
}

/// Create a value inside the store, given its key, returning its key.
fn create_with(&self, value_fn: impl FnOnce(Key) -> Value) -> Key {
let mut data = self.internal_data().write();
let next_index = data.len();
let key = Key::from_index_unchecked(next_index);
let key = unsafe { Key::from_index_unchecked(next_index) };
let value = value_fn(key);
data.push(value);
key
Expand All @@ -95,7 +102,7 @@ pub trait Store<Key: StoreKey, Value> {
let mut data = self.internal_data().write();
let next_index = data.len();
data.push(value);
Key::from_index_unchecked(next_index)
unsafe { Key::from_index_unchecked(next_index) }
}

/// Get a value by a key, and map it to another value given its reference.
Expand All @@ -120,23 +127,25 @@ pub trait Store<Key: StoreKey, Value> {
f: impl FnOnce(&[&Value]) -> T,
) -> T {
let data = self.internal_data().read();
let values =
keys.into_iter().map(|key| data.get(key.to_index()).unwrap()).collect::<Vec<_>>();
let values = keys
.into_iter()
.map(|key| unsafe { data.get_unchecked(key.to_index()) })
.collect::<Vec<_>>();
f(&values)
}

/// Borrow a value mutably, given a key. Returns an appropriate handle which
/// implements `DerefMut` to the value.
fn borrow_mut(&self, key: Key) -> StoreBorrowMutHandle<'_, Value> {
let data = self.internal_data().write();
RwLockWriteGuard::map(data, |d| d.get_mut(key.to_index()).unwrap())
RwLockWriteGuard::map(data, |d| unsafe { d.get_unchecked_mut(key.to_index()) })
}

/// Borrow a value, given a key. Returns an appropriate handle which
/// implements `Deref` to the value.
fn borrow(&self, key: Key) -> StoreBorrowHandle<'_, Value> {
let data = self.internal_data().read();
RwLockReadGuard::map(data, |d| d.get(key.to_index()).unwrap())
RwLockReadGuard::map(data, |d| unsafe { d.get_unchecked(key.to_index()) })
}

/// Modify a value by a key, possibly returning another value.
Expand All @@ -146,7 +155,7 @@ pub trait Store<Key: StoreKey, Value> {
/// [`CloneStore::modify()`] instead.
fn modify_fast<T>(&self, key: Key, f: impl FnOnce(&mut Value) -> T) -> T {
let mut data = self.internal_data().write();
let value = data.get_mut(key.to_index()).unwrap();
let value = unsafe { data.get_unchecked_mut(key.to_index()) };
f(value)
}
}
Expand All @@ -155,7 +164,7 @@ pub trait Store<Key: StoreKey, Value> {
pub trait CloneStore<Key: StoreKey, Value: Clone>: Store<Key, Value> {
/// Get a value by its key.
fn get(&self, key: Key) -> Value {
self.internal_data().read().get(key.to_index()).unwrap().clone()
unsafe { self.internal_data().read().get_unchecked(key.to_index()).clone() }
}

/// Get a value by a key, and map it to another value given its reference.
Expand Down Expand Up @@ -183,7 +192,7 @@ pub trait CloneStore<Key: StoreKey, Value: Clone>: Store<Key, Value> {
/// Set a key's value to a new value, returning the old value.
fn set(&self, key: Key, new_value: Value) -> Value {
let mut data = self.internal_data().write();
let value_ref = data.get_mut(key.to_index()).unwrap();
let value_ref = unsafe { data.get_unchecked_mut(key.to_index()) };
let old_value = value_ref.clone();
*value_ref = new_value;
old_value
Expand Down
Loading

0 comments on commit ac1a72a

Please sign in to comment.