Skip to content

Inline get_root_key #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 19, 2019
Merged
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
2 changes: 1 addition & 1 deletion src/snapshot_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl<D> fmt::Debug for SnapshotVec<D>
D::Undo: fmt::Debug,
D::Value: fmt::Debug
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("SnapshotVec")
.field("values", &self.values)
.field("undo_log", &self.undo_log)
Expand Down
36 changes: 28 additions & 8 deletions src/unify/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,15 +321,19 @@ impl<S: UnificationStore> UnificationTable<S> {
///
/// NB. This is a building-block operation and you would probably
/// prefer to call `probe` below.
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)]
fn inlined_get_root_key(&mut self, vid: S::Key) -> S::Key {
let redirect = {
match self.value(vid).parent(vid) {
None => return vid,
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 {
// Path compression
self.update_value(vid, |value| value.parent = root_key);
Expand All @@ -338,6 +342,13 @@ impl<S: UnificationStore> UnificationTable<S> {
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)
}

fn update_value<OP>(&mut self, key: S::Key, op: OP)
where
OP: FnOnce(&mut VarValue<S::Key>),
Expand Down Expand Up @@ -422,7 +433,7 @@ impl<S: UnificationStore> UnificationTable<S> {
/// ////////////////////////////////////////////////////////////////////////
/// Public API

impl<'tcx, S, K, V> UnificationTable<S>
impl<S, K, V> UnificationTable<S>
where
S: UnificationStore<Key = K, Value = V>,
K: UnifyKey<Value = V>,
Expand Down Expand Up @@ -466,7 +477,7 @@ where
K1: Into<K>,
{
let id = id.into();
self.get_root_key(id)
self.uninlined_get_root_key(id)
}

/// Unions together two variables, merging their values. If
Expand All @@ -480,8 +491,8 @@ where
let a_id = a_id.into();
let b_id = b_id.into();

let root_a = self.get_root_key(a_id);
let root_b = self.get_root_key(b_id);
let root_a = self.uninlined_get_root_key(a_id);
let root_b = self.uninlined_get_root_key(b_id);

if root_a == root_b {
return Ok(());
Expand All @@ -499,7 +510,7 @@ where
K1: Into<K>,
{
let a_id = a_id.into();
let root_a = self.get_root_key(a_id);
let root_a = self.uninlined_get_root_key(a_id);
let value = V::unify_values(&self.value(root_a).value, &b)?;
self.update_value(root_a, |node| node.value = value);
Ok(())
Expand All @@ -508,11 +519,20 @@ where
/// Returns the current value for the given key. If the key has
/// been union'd, this will give the value from the current root.
pub fn probe_value<K1>(&mut self, id: K1) -> V
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn probe_value<K1>(&mut self, id: K1) -> V
pub fn probe_value(&mut self, id: impl Into<K>) -> V

where
K1: Into<K>,
{
self.inlined_probe_value(id)
}

// An always-inlined version of `probe_value`, for hot callsites.
#[inline(always)]
pub fn inlined_probe_value<K1>(&mut self, id: K1) -> V
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub fn inlined_probe_value<K1>(&mut self, id: K1) -> V
pub fn inlined_probe_value(&mut self, id: impl Into<K>) -> V

where
K1: Into<K>,
{
let id = id.into();
let id = self.get_root_key(id);
let id = self.inlined_get_root_key(id);
self.value(id).value.clone()
}
}
Expand Down