mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
inline subs operations more aggressively
This commit is contained in:
parent
3f07afe3b5
commit
f4cb2ec254
3 changed files with 87 additions and 23 deletions
|
@ -1406,8 +1406,8 @@ impl Subs {
|
||||||
|
|
||||||
/// Unions two keys without the possibility of failure.
|
/// Unions two keys without the possibility of failure.
|
||||||
pub fn union(&mut self, left: Variable, right: Variable, desc: Descriptor) {
|
pub fn union(&mut self, left: Variable, right: Variable, desc: Descriptor) {
|
||||||
let l_root = self.utable.get_root_key(left);
|
let l_root = self.utable.inlined_get_root_key(left);
|
||||||
let r_root = self.utable.get_root_key(right);
|
let r_root = self.utable.inlined_get_root_key(right);
|
||||||
|
|
||||||
// NOTE this swapping is intentional! most of our unifying commands are based on the elm
|
// NOTE this swapping is intentional! most of our unifying commands are based on the elm
|
||||||
// source, but unify_roots is from `ena`, not the elm source. Turns out that they have
|
// source, but unify_roots is from `ena`, not the elm source. Turns out that they have
|
||||||
|
@ -1451,23 +1451,25 @@ impl Subs {
|
||||||
&self.utable.probe_value_ref(key).value.content
|
&self.utable.probe_value_ref(key).value.content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_root_key(&mut self, key: Variable) -> Variable {
|
pub fn get_root_key(&mut self, key: Variable) -> Variable {
|
||||||
self.utable.get_root_key(key)
|
self.utable.inlined_get_root_key(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_root_key_without_compacting(&self, key: Variable) -> Variable {
|
pub fn get_root_key_without_compacting(&self, key: Variable) -> Variable {
|
||||||
self.utable.get_root_key_without_compacting(key)
|
self.utable.get_root_key_without_compacting(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set(&mut self, key: Variable, r_value: Descriptor) {
|
pub fn set(&mut self, key: Variable, r_value: Descriptor) {
|
||||||
let l_key = self.utable.get_root_key(key);
|
let l_key = self.utable.inlined_get_root_key(key);
|
||||||
|
|
||||||
self.utable.update_value(l_key, |node| node.value = r_value);
|
self.utable.update_value(l_key, |node| node.value = r_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_rank(&mut self, key: Variable, rank: Rank) {
|
pub fn set_rank(&mut self, key: Variable, rank: Rank) {
|
||||||
let l_key = self.utable.get_root_key(key);
|
let l_key = self.utable.inlined_get_root_key(key);
|
||||||
|
|
||||||
self.utable.update_value(l_key, |node| {
|
self.utable.update_value(l_key, |node| {
|
||||||
node.value.rank = rank;
|
node.value.rank = rank;
|
||||||
|
@ -1475,7 +1477,7 @@ impl Subs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mark(&mut self, key: Variable, mark: Mark) {
|
pub fn set_mark(&mut self, key: Variable, mark: Mark) {
|
||||||
let l_key = self.utable.get_root_key(key);
|
let l_key = self.utable.inlined_get_root_key(key);
|
||||||
|
|
||||||
self.utable.update_value(l_key, |node| {
|
self.utable.update_value(l_key, |node| {
|
||||||
node.value.mark = mark;
|
node.value.mark = mark;
|
||||||
|
@ -1483,7 +1485,7 @@ impl Subs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_rank_mark(&mut self, key: Variable, rank: Rank, mark: Mark) {
|
pub fn set_rank_mark(&mut self, key: Variable, rank: Rank, mark: Mark) {
|
||||||
let l_key = self.utable.get_root_key(key);
|
let l_key = self.utable.inlined_get_root_key(key);
|
||||||
|
|
||||||
self.utable.update_value(l_key, |node| {
|
self.utable.update_value(l_key, |node| {
|
||||||
node.value.rank = rank;
|
node.value.rank = rank;
|
||||||
|
@ -1492,7 +1494,7 @@ impl Subs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_content(&mut self, key: Variable, content: Content) {
|
pub fn set_content(&mut self, key: Variable, content: Content) {
|
||||||
let l_key = self.utable.get_root_key(key);
|
let l_key = self.utable.inlined_get_root_key(key);
|
||||||
|
|
||||||
self.utable.update_value(l_key, |node| {
|
self.utable.update_value(l_key, |node| {
|
||||||
node.value.content = content;
|
node.value.content = content;
|
||||||
|
@ -1508,7 +1510,7 @@ impl Subs {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get_rank_set_mark(&mut self, key: Variable, mark: Mark) -> Rank {
|
pub fn get_rank_set_mark(&mut self, key: Variable, mark: Mark) -> Rank {
|
||||||
let l_key = self.utable.get_root_key(key);
|
let l_key = self.utable.inlined_get_root_key(key);
|
||||||
|
|
||||||
let mut rank = Rank::NONE;
|
let mut rank = Rank::NONE;
|
||||||
|
|
||||||
|
|
|
@ -4,3 +4,51 @@ app "helloZig"
|
||||||
provides [ main ] to pf
|
provides [ main ] to pf
|
||||||
|
|
||||||
main = "Hello, World!\n"
|
main = "Hello, World!\n"
|
||||||
|
|
||||||
|
Utf8ByteProblem :
|
||||||
|
[
|
||||||
|
InvalidStartByte,
|
||||||
|
UnexpectedEndOfSequence,
|
||||||
|
ExpectedContinuation,
|
||||||
|
OverlongEncoding,
|
||||||
|
CodepointTooLarge,
|
||||||
|
EncodesSurrogateHalf,
|
||||||
|
]
|
||||||
|
|
||||||
|
Utf8Problem : { byteIndex : Nat, problem : Utf8ByteProblem }
|
||||||
|
|
||||||
|
isEmpty : Str -> Bool
|
||||||
|
concat : Str, Str -> Str
|
||||||
|
|
||||||
|
joinWith : List Str, Str -> Str
|
||||||
|
split : Str, Str -> List Str
|
||||||
|
repeat : Str, Nat -> Str
|
||||||
|
countGraphemes : Str -> Nat
|
||||||
|
startsWithCodePt : Str, U32 -> Bool
|
||||||
|
|
||||||
|
toUtf8 : Str -> List U8
|
||||||
|
|
||||||
|
fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8ByteProblem Nat ]*
|
||||||
|
fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [ BadUtf8 Utf8ByteProblem Nat, OutOfBounds ]*
|
||||||
|
|
||||||
|
startsWith : Str, Str -> Bool
|
||||||
|
endsWith : Str, Str -> Bool
|
||||||
|
|
||||||
|
trim : Str -> Str
|
||||||
|
trimLeft : Str -> Str
|
||||||
|
trimRight : Str -> Str
|
||||||
|
|
||||||
|
toDec : Str -> Result Dec [ InvalidNumStr ]*
|
||||||
|
toF64 : Str -> Result F64 [ InvalidNumStr ]*
|
||||||
|
toF32 : Str -> Result F32 [ InvalidNumStr ]*
|
||||||
|
toNat : Str -> Result Nat [ InvalidNumStr ]*
|
||||||
|
toU128 : Str -> Result U128 [ InvalidNumStr ]*
|
||||||
|
toI128 : Str -> Result I128 [ InvalidNumStr ]*
|
||||||
|
toU64 : Str -> Result U64 [ InvalidNumStr ]*
|
||||||
|
toI64 : Str -> Result I64 [ InvalidNumStr ]*
|
||||||
|
toU32 : Str -> Result U32 [ InvalidNumStr ]*
|
||||||
|
toI32 : Str -> Result I32 [ InvalidNumStr ]*
|
||||||
|
toU16 : Str -> Result U16 [ InvalidNumStr ]*
|
||||||
|
toI16 : Str -> Result I16 [ InvalidNumStr ]*
|
||||||
|
toU8 : Str -> Result U8 [ InvalidNumStr ]*
|
||||||
|
toI8 : Str -> Result I8 [ InvalidNumStr ]*
|
||||||
|
|
30
vendor/ena/src/unify/mod.rs
vendored
30
vendor/ena/src/unify/mod.rs
vendored
|
@ -298,11 +298,19 @@ impl<S: UnificationStore> UnificationTable<S> {
|
||||||
///
|
///
|
||||||
/// NB. This is a building-block operation and you would probably
|
/// NB. This is a building-block operation and you would probably
|
||||||
/// prefer to call `probe` below.
|
/// prefer to call `probe` below.
|
||||||
pub fn get_root_key(&mut self, vid: S::Key) -> S::Key {
|
///
|
||||||
|
/// This is an always-inlined version of this function for the hot
|
||||||
|
/// callsites. `uninlined_get_root_key` is the never-inlined version.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn inlined_get_root_key(&mut self, vid: S::Key) -> S::Key {
|
||||||
|
let redirect = {
|
||||||
match self.value(vid).parent(vid) {
|
match self.value(vid).parent(vid) {
|
||||||
None => vid,
|
None => return vid,
|
||||||
Some(redirect) => {
|
Some(redirect) => redirect,
|
||||||
let root_key: S::Key = self.get_root_key(redirect);
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let root_key: S::Key = self.uninlined_get_root_key(redirect);
|
||||||
if root_key != redirect {
|
if root_key != redirect {
|
||||||
// Path compression
|
// Path compression
|
||||||
self.update_value(vid, |value| value.parent = root_key);
|
self.update_value(vid, |value| value.parent = root_key);
|
||||||
|
@ -310,9 +318,15 @@ impl<S: UnificationStore> UnificationTable<S> {
|
||||||
|
|
||||||
root_key
|
root_key
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// This is a never-inlined version of this function for cold callsites.
|
||||||
|
// 'inlined_get_root_key` is the always-inlined version.
|
||||||
|
#[inline(never)]
|
||||||
|
fn uninlined_get_root_key(&mut self, vid: S::Key) -> S::Key {
|
||||||
|
self.inlined_get_root_key(vid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
pub fn get_root_key_without_compacting(&self, mut vid: S::Key) -> S::Key {
|
pub fn get_root_key_without_compacting(&self, mut vid: S::Key) -> S::Key {
|
||||||
while let Some(redirect) = self.value(vid).parent(vid) {
|
while let Some(redirect) = self.value(vid).parent(vid) {
|
||||||
vid = redirect;
|
vid = redirect;
|
||||||
|
@ -435,7 +449,7 @@ where
|
||||||
K1: Into<K>,
|
K1: Into<K>,
|
||||||
{
|
{
|
||||||
let id = id.into();
|
let id = id.into();
|
||||||
self.get_root_key(id)
|
self.inlined_get_root_key(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the current value for the given key. If the key has
|
/// Returns the current value for the given key. If the key has
|
||||||
|
@ -446,7 +460,7 @@ where
|
||||||
K1: Into<K>,
|
K1: Into<K>,
|
||||||
{
|
{
|
||||||
let id = id.into();
|
let id = id.into();
|
||||||
let id = self.get_root_key(id);
|
let id = self.inlined_get_root_key(id);
|
||||||
self.value(id).value.clone()
|
self.value(id).value.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +484,7 @@ where
|
||||||
K1: Into<K>,
|
K1: Into<K>,
|
||||||
{
|
{
|
||||||
let id = id.into();
|
let id = id.into();
|
||||||
let id = self.get_root_key(id);
|
let id = self.inlined_get_root_key(id);
|
||||||
self.value_mut(id)
|
self.value_mut(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue