Skip to content

[nll] hash borrows in scope for better performance #53159

Closed
@nikomatsakis

Description

@nikomatsakis

So I have an idea for how to improve performance in cases like html5ever where there are tons of borrows in scope at certain points. Right now, we have a pretty naive algorithm that implements over all borrows in scope:

/// Encapsulates the idea of iterating over every borrow that involves a particular path
pub(super) fn each_borrow_involving_path<'a, 'tcx, 'gcx: 'tcx, F, I, S> (
s: &mut S,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
_context: Context,
access_place: (ShallowOrDeep, &Place<'tcx>),
borrow_set: &BorrowSet<'tcx>,
candidates: I,
mut op: F,
) where
F: FnMut(&mut S, BorrowIndex, &BorrowData<'tcx>) -> Control,
I: Iterator<Item=BorrowIndex>

I think we would do better if we stored the "borrows in scope" organized by the "root local" of the borrow:

/// If this is a place like `x.f.g`, returns the local
/// `x`. Returns `None` if this is based in a static.
fn root_local(&self) -> Option<Local>;

In fact, I think we could do a "quick hack" to make this work. The BorrowSet already has an index of borrow indices based on their "root locals":

/// Map from local to all the borrows on that local
crate local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,

So what we can do is to modify each_borrow_involving_path. Instead of taking an iterator over borrows in scope, it would take some sort of is_borrow_in_scope: impl Fn(BorrowIndex) -> bool function. It would then find the root local (if any) of the access path, find all borrows that apply to that root local, and iterate over those, testing if each of them is in scope.

We could make this more efficient in many ways -- e.g., using bitsets and things -- but this basic change should already eliminate some of the horrible O(n^2) behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)NLL-performantWorking towards the "performance is good" goalT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.WG-compiler-performanceWorking group: Compiler Performance

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions