Skip to content
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

MIR/two-phase borrowck takes a lot of time and memory for the ucd crate #53643

Closed
SimonSapin opened this issue Aug 23, 2018 · 24 comments
Closed
Assignees
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-performant Working towards the "performance is good" goal

Comments

@SimonSapin
Copy link
Contributor

Setup:

$ cargo new foo
$ cd foo
$ echo 'ucd = "=0.1.1"' >> Cargo.toml
$ echo '/usr/bin/time -f "Peak RSS: %M KB" "$@"' > wrapper  # requires GNU time
$ chmod +x wrapper
$ export RUSTC_WRAPPER=./wrapper

Baseline: 7.10s, peak RSS 542,664 KB

$ cargo clean && RUSTFLAGS="-Z time-passes" cargo +nightly-2018-08-19 check -p ucd
Output
    Checking ucd v0.1.1                                                                                                                                                                                                                        
  time: 0.599; rss: 185MB	parsing
  time: 0.000; rss: 185MB	attributes injection
  time: 0.000; rss: 185MB	recursion limit
  time: 0.000; rss: 185MB	crate injection
  time: 0.000; rss: 185MB	plugin loading
  time: 0.000; rss: 185MB	plugin registration
  time: 0.056; rss: 186MB	pre ast expansion lint checks
    time: 0.150; rss: 200MB	expand crate
    time: 0.000; rss: 200MB	check unused macros
  time: 0.150; rss: 200MB	expansion
  time: 0.000; rss: 200MB	maybe building test harness
  time: 0.008; rss: 200MB	maybe creating a macro crate
  time: 0.037; rss: 200MB	creating allocators
  time: 0.038; rss: 200MB	AST validation
  time: 0.064; rss: 206MB	name resolution
  time: 0.023; rss: 206MB	complete gated feature checking
  time: 0.103; rss: 278MB	lowering ast -> hir
  time: 0.085; rss: 278MB	early lint checks
  time: 0.170; rss: 330MB	indexing hir
  time: 0.000; rss: 195MB	load query result cache
  time: 0.000; rss: 195MB	looking for entry point
  time: 0.000; rss: 195MB	looking for plugin registrar
  time: 0.004; rss: 195MB	loop checking
  time: 0.004; rss: 195MB	attribute checking
  time: 0.011; rss: 197MB	stability checking
  time: 0.028; rss: 200MB	type collecting
  time: 0.000; rss: 200MB	outlives testing
  time: 0.000; rss: 200MB	impl wf inference
  time: 0.010; rss: 207MB	coherence checking
  time: 0.000; rss: 207MB	variance testing
  time: 0.095; rss: 237MB	wf checking
  time: 1.858; rss: 276MB	item-types checking
  time: 0.148; rss: 279MB	item-bodies checking
  time: 0.288; rss: 288MB	rvalue promotion
  time: 0.101; rss: 288MB	privacy checking
  time: 0.008; rss: 288MB	intrinsic checking
  time: 0.020; rss: 289MB	match checking
  time: 0.016; rss: 289MB	liveness checking
  time: 1.303; rss: 465MB	borrow checking
  time: 0.000; rss: 465MB	MIR borrow checking
  time: 0.000; rss: 465MB	dumping chalk-like clauses
  time: 0.000; rss: 465MB	MIR effect checking
  time: 0.010; rss: 465MB	death checking
  time: 0.004; rss: 465MB	unused lib feature checking
  time: 1.415; rss: 525MB	lint checking
  time: 0.000; rss: 525MB	resolving dependency formats
    time: 0.139; rss: 555MB	write metadata
    time: 0.000; rss: 555MB	assert dep graph
    time: 0.000; rss: 555MB	serialize dep graph
  time: 0.139; rss: 555MB	codegen
  time: 0.000; rss: 120MB	serialize work products
  time: 0.006; rss: 120MB	linking
    Finished dev [unoptimized + debuginfo] target(s) in 7.10s

With MIR-based two-phase borrowck: 67s, peak RSS 2,347,764 KB. A 9× increase in time and 4× increase in memory.

$ cargo clean && RUSTFLAGS="-Zborrowck=mir -Ztwo-phase-borrows -Z time-passes" cargo +nightly-2018-08-19 check -p ucd
Output
    Checking ucd v0.1.1                                                                                                                                                                                                                        
  time: 0.597; rss: 184MB	parsing
  time: 0.000; rss: 184MB	attributes injection
  time: 0.000; rss: 184MB	recursion limit
  time: 0.000; rss: 184MB	crate injection
  time: 0.000; rss: 184MB	plugin loading
  time: 0.000; rss: 184MB	plugin registration
  time: 0.065; rss: 185MB	pre ast expansion lint checks
    time: 0.151; rss: 200MB	expand crate
    time: 0.000; rss: 200MB	check unused macros
  time: 0.151; rss: 200MB	expansion
  time: 0.000; rss: 200MB	maybe building test harness
  time: 0.008; rss: 200MB	maybe creating a macro crate
  time: 0.036; rss: 200MB	creating allocators
  time: 0.042; rss: 201MB	AST validation
  time: 0.063; rss: 206MB	name resolution
  time: 0.013; rss: 206MB	complete gated feature checking
  time: 0.108; rss: 278MB	lowering ast -> hir
  time: 0.087; rss: 278MB	early lint checks
  time: 0.190; rss: 330MB	indexing hir
  time: 0.000; rss: 192MB	load query result cache
  time: 0.000; rss: 192MB	looking for entry point
  time: 0.000; rss: 192MB	looking for plugin registrar
  time: 0.005; rss: 192MB	loop checking
  time: 0.004; rss: 192MB	attribute checking
  time: 0.012; rss: 195MB	stability checking
  time: 0.030; rss: 198MB	type collecting
  time: 0.000; rss: 198MB	outlives testing
  time: 0.000; rss: 198MB	impl wf inference
  time: 0.020; rss: 205MB	coherence checking
  time: 0.000; rss: 205MB	variance testing
  time: 0.092; rss: 234MB	wf checking
  time: 1.881; rss: 274MB	item-types checking
  time: 0.149; rss: 275MB	item-bodies checking
  time: 0.269; rss: 285MB	rvalue promotion
  time: 0.098; rss: 285MB	privacy checking
  time: 0.009; rss: 285MB	intrinsic checking
  time: 0.021; rss: 286MB	match checking
  time: 0.005; rss: 286MB	liveness checking
  time: 0.000; rss: 286MB	borrow checking
    time: 0.000; rss: 322MB	solve_nll_region_constraints(DefId(0/0:572 ~ ucd[512d]::{{impl}}[9]::clone[0]))
    time: 0.000; rss: 322MB	solve_nll_region_constraints(DefId(0/0:569 ~ ucd[512d]::{{impl}}[7]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 322MB	solve_nll_region_constraints(DefId(0/0:566 ~ ucd[512d]::{{impl}}[6]::eq[0]))
    time: 0.000; rss: 322MB	solve_nll_region_constraints(DefId(0/0:567 ~ ucd[512d]::{{impl}}[6]::ne[0]))
    time: 0.000; rss: 322MB	solve_nll_region_constraints(DefId(0/0:564 ~ ucd[512d]::{{impl}}[5]::fmt[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/0:562 ~ ucd[512d]::{{impl}}[4]::cmp[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/0:556 ~ ucd[512d]::{{impl}}[3]::partial_cmp[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/1:773 ~ ucd[512d]::{{impl}}[3]::lt[0]::{{closure}}[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/0:557 ~ ucd[512d]::{{impl}}[3]::lt[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/1:774 ~ ucd[512d]::{{impl}}[3]::le[0]::{{closure}}[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/0:558 ~ ucd[512d]::{{impl}}[3]::le[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/1:775 ~ ucd[512d]::{{impl}}[3]::gt[0]::{{closure}}[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/0:559 ~ ucd[512d]::{{impl}}[3]::gt[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/1:776 ~ ucd[512d]::{{impl}}[3]::ge[0]::{{closure}}[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/0:560 ~ ucd[512d]::{{impl}}[3]::ge[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/0:149 ~ ucd[512d]::cp_decode[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/0:153 ~ ucd[512d]::{{impl}}[0]::new[0]))
    time: 0.000; rss: 328MB	solve_nll_region_constraints(DefId(0/0:154 ~ ucd[512d]::{{impl}}[0]::hangul[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/1:24 ~ ucd[512d]::{{impl}}[1]::next[0]::{{closure}}[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:157 ~ ucd[512d]::{{impl}}[1]::next[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:158 ~ ucd[512d]::{{impl}}[1]::size_hint[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:261 ~ ucd[512d]::Codepoint[0]::is_alpha[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:262 ~ ucd[512d]::Codepoint[0]::is_lower[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:263 ~ ucd[512d]::Codepoint[0]::is_upper[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:264 ~ ucd[512d]::Codepoint[0]::is_white[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:266 ~ ucd[512d]::{{impl}}[2]::age[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:267 ~ ucd[512d]::{{impl}}[2]::block[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:268 ~ ucd[512d]::{{impl}}[2]::category[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:269 ~ ucd[512d]::{{impl}}[2]::codepoint[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:270 ~ ucd[512d]::{{impl}}[2]::iso_comment[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:271 ~ ucd[512d]::{{impl}}[2]::is_alphabetic[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:272 ~ ucd[512d]::{{impl}}[2]::is_alphabetic_other[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:273 ~ ucd[512d]::{{impl}}[2]::is_dash[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:274 ~ ucd[512d]::{{impl}}[2]::is_default_ignorable[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:275 ~ ucd[512d]::{{impl}}[2]::is_default_ignorable_other[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:276 ~ ucd[512d]::{{impl}}[2]::is_deprecated[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:277 ~ ucd[512d]::{{impl}}[2]::is_diacritic[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:278 ~ ucd[512d]::{{impl}}[2]::is_extender[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:279 ~ ucd[512d]::{{impl}}[2]::is_hex_digit[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:280 ~ ucd[512d]::{{impl}}[2]::is_hex_digit_ascii[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:281 ~ ucd[512d]::{{impl}}[2]::is_hyphen[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:282 ~ ucd[512d]::{{impl}}[2]::is_logical_order_exception[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:283 ~ ucd[512d]::{{impl}}[2]::is_math[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:284 ~ ucd[512d]::{{impl}}[2]::is_math_other[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:285 ~ ucd[512d]::{{impl}}[2]::is_noncharacter[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:286 ~ ucd[512d]::{{impl}}[2]::is_preprended_concatenation_mark[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:287 ~ ucd[512d]::{{impl}}[2]::is_quotation_mark[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:288 ~ ucd[512d]::{{impl}}[2]::is_sentence_terminal[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:289 ~ ucd[512d]::{{impl}}[2]::is_soft_dotted[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:290 ~ ucd[512d]::{{impl}}[2]::is_terminal_punctuation[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:291 ~ ucd[512d]::{{impl}}[2]::is_variation_selector[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:292 ~ ucd[512d]::{{impl}}[2]::is_whitespace[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:293 ~ ucd[512d]::{{impl}}[2]::numeric_type[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/1:25 ~ ucd[512d]::{{impl}}[2]::numeric_value[0]::{{closure}}[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:294 ~ ucd[512d]::{{impl}}[2]::numeric_value[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:295 ~ ucd[512d]::{{impl}}[2]::is_id_continue[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:296 ~ ucd[512d]::{{impl}}[2]::is_id_continue_nfkc[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:297 ~ ucd[512d]::{{impl}}[2]::is_id_continue_other[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:298 ~ ucd[512d]::{{impl}}[2]::is_id_start[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:299 ~ ucd[512d]::{{impl}}[2]::is_id_start_nfkc[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:300 ~ ucd[512d]::{{impl}}[2]::is_id_start_other[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:301 ~ ucd[512d]::{{impl}}[2]::is_pattern_syntax[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:302 ~ ucd[512d]::{{impl}}[2]::is_pattern_whitespace[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:303 ~ ucd[512d]::{{impl}}[2]::east_asian_width[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:304 ~ ucd[512d]::{{impl}}[2]::hangul_syllable_type[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:305 ~ ucd[512d]::{{impl}}[2]::jamo_short_name[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:306 ~ ucd[512d]::{{impl}}[2]::indic_positional_category[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:307 ~ ucd[512d]::{{impl}}[2]::indic_syllabic_category[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:308 ~ ucd[512d]::{{impl}}[2]::is_ideograph[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:309 ~ ucd[512d]::{{impl}}[2]::is_ideograph_description_sequence_binary_operator[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:310 ~ ucd[512d]::{{impl}}[2]::is_ideograph_description_sequence_radical[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:311 ~ ucd[512d]::{{impl}}[2]::is_ideograph_description_sequence_trinary_operator[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:312 ~ ucd[512d]::{{impl}}[2]::is_ideograph_unified[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:313 ~ ucd[512d]::{{impl}}[2]::join_control[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:314 ~ ucd[512d]::{{impl}}[2]::joining_group[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:315 ~ ucd[512d]::{{impl}}[2]::joining_type[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:316 ~ ucd[512d]::{{impl}}[2]::script[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/1:26 ~ ucd[512d]::{{impl}}[2]::script_extensions[0]::{{closure}}[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:317 ~ ucd[512d]::{{impl}}[2]::script_extensions[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:318 ~ ucd[512d]::{{impl}}[2]::bidi_class[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:319 ~ ucd[512d]::{{impl}}[2]::bidi_is_control[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:320 ~ ucd[512d]::{{impl}}[2]::bidi_is_mirrored[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:321 ~ ucd[512d]::{{impl}}[2]::bidi_mirror[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:322 ~ ucd[512d]::{{impl}}[2]::bidi_paired_bracket[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:323 ~ ucd[512d]::{{impl}}[2]::bidi_paired_bracket_type[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:324 ~ ucd[512d]::{{impl}}[2]::casefold[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:325 ~ ucd[512d]::{{impl}}[2]::casefold_nfkc[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:326 ~ ucd[512d]::{{impl}}[2]::casefold_nfkc_closure[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:327 ~ ucd[512d]::{{impl}}[2]::casefold_simple[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:328 ~ ucd[512d]::{{impl}}[2]::changes_when_casefolded[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:329 ~ ucd[512d]::{{impl}}[2]::changes_when_casefolded_nfkc[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:330 ~ ucd[512d]::{{impl}}[2]::changes_when_casemapped[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:331 ~ ucd[512d]::{{impl}}[2]::changes_when_lowercased[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:332 ~ ucd[512d]::{{impl}}[2]::changes_when_titlecased[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:333 ~ ucd[512d]::{{impl}}[2]::changes_when_uppercased[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:334 ~ ucd[512d]::{{impl}}[2]::is_case_ignorable[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:335 ~ ucd[512d]::{{impl}}[2]::is_cased[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:336 ~ ucd[512d]::{{impl}}[2]::is_lowercase[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:337 ~ ucd[512d]::{{impl}}[2]::is_lowercase_other[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:338 ~ ucd[512d]::{{impl}}[2]::is_uppercase[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:339 ~ ucd[512d]::{{impl}}[2]::is_uppercase_other[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:340 ~ ucd[512d]::{{impl}}[2]::lowercase[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:341 ~ ucd[512d]::{{impl}}[2]::lowercase_simple[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:342 ~ ucd[512d]::{{impl}}[2]::titlecase[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:343 ~ ucd[512d]::{{impl}}[2]::titlecase_simple[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:344 ~ ucd[512d]::{{impl}}[2]::uppercase[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:345 ~ ucd[512d]::{{impl}}[2]::uppercase_simple[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:346 ~ ucd[512d]::{{impl}}[2]::canonical_combining_class[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:347 ~ ucd[512d]::{{impl}}[2]::decomposition_map[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:348 ~ ucd[512d]::{{impl}}[2]::decomposition_map[0]::SBASE[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:349 ~ ucd[512d]::{{impl}}[2]::decomposition_map[0]::LBASE[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:350 ~ ucd[512d]::{{impl}}[2]::decomposition_map[0]::VBASE[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:351 ~ ucd[512d]::{{impl}}[2]::decomposition_map[0]::TBASE[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:352 ~ ucd[512d]::{{impl}}[2]::decomposition_map[0]::VCOUNT[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:353 ~ ucd[512d]::{{impl}}[2]::decomposition_map[0]::TCOUNT[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:354 ~ ucd[512d]::{{impl}}[2]::decomposition_map[0]::NCOUNT[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:355 ~ ucd[512d]::{{impl}}[2]::decomposition_type[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:356 ~ ucd[512d]::{{impl}}[2]::excluded_from_composition[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:357 ~ ucd[512d]::{{impl}}[2]::excluded_from_composition_fully[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:358 ~ ucd[512d]::{{impl}}[2]::expands_on_nfc[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:359 ~ ucd[512d]::{{impl}}[2]::expands_on_nfd[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:360 ~ ucd[512d]::{{impl}}[2]::expands_on_nfkc[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:361 ~ ucd[512d]::{{impl}}[2]::expands_on_nfkd[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:362 ~ ucd[512d]::{{impl}}[2]::quick_check_nfc[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:363 ~ ucd[512d]::{{impl}}[2]::quick_check_nfd[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:364 ~ ucd[512d]::{{impl}}[2]::quick_check_nfkc[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:365 ~ ucd[512d]::{{impl}}[2]::quick_check_nfkd[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:366 ~ ucd[512d]::{{impl}}[2]::grapheme_cluster_break[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:367 ~ ucd[512d]::{{impl}}[2]::is_grapheme_base[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:368 ~ ucd[512d]::{{impl}}[2]::is_grapheme_extend[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:369 ~ ucd[512d]::{{impl}}[2]::is_grapheme_extend_other[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:370 ~ ucd[512d]::{{impl}}[2]::is_grapheme_link[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:371 ~ ucd[512d]::{{impl}}[2]::linebreak_class[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:372 ~ ucd[512d]::{{impl}}[2]::sentence_break[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:373 ~ ucd[512d]::{{impl}}[2]::word_break[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:119 ~ ucd[512d]::tables[0]::Search[0]::includes[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/1:10 ~ ucd[512d]::tables[0]::{{impl}}[0]::search[0]::{{closure}}[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:122 ~ ucd[512d]::tables[0]::{{impl}}[0]::search[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/1:12 ~ ucd[512d]::tables[0]::{{impl}}[1]::search[0]::{{closure}}[0]))
    time: 0.000; rss: 331MB	solve_nll_region_constraints(DefId(0/0:125 ~ ucd[512d]::tables[0]::{{impl}}[1]::search[0]))
    time: 0.000; rss: 332MB	solve_nll_region_constraints(DefId(0/1:13 ~ ucd[512d]::tables[0]::{{impl}}[2]::search[0]::{{closure}}[0]))
    time: 0.000; rss: 332MB	solve_nll_region_constraints(DefId(0/0:128 ~ ucd[512d]::tables[0]::{{impl}}[2]::search[0]))
    time: 0.000; rss: 332MB	solve_nll_region_constraints(DefId(0/0:383 ~ ucd[512d]::tables[0]::general[0]::{{impl}}[4]::clone[0]))
    time: 0.000; rss: 332MB	solve_nll_region_constraints(DefId(0/0:380 ~ ucd[512d]::tables[0]::general[0]::{{impl}}[2]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 332MB	solve_nll_region_constraints(DefId(0/0:378 ~ ucd[512d]::tables[0]::general[0]::{{impl}}[1]::eq[0]))
    time: 0.000; rss: 336MB	solve_nll_region_constraints(DefId(0/0:376 ~ ucd[512d]::tables[0]::general[0]::{{impl}}[0]::fmt[0]))
    time: 0.000; rss: 336MB	solve_nll_region_constraints(DefId(0/0:8 ~ ucd[512d]::tables[0]::general[0]::UCD_BLOCK[0]))
    time: 0.000; rss: 336MB	solve_nll_region_constraints(DefId(0/0:9 ~ ucd[512d]::tables[0]::general[0]::UCD_AGE[0]))
    time: 0.000; rss: 336MB	solve_nll_region_constraints(DefId(0/0:393 ~ ucd[512d]::tables[0]::general[0]::{{impl}}[9]::clone[0]))
    time: 0.000; rss: 336MB	solve_nll_region_constraints(DefId(0/0:390 ~ ucd[512d]::tables[0]::general[0]::{{impl}}[7]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 336MB	solve_nll_region_constraints(DefId(0/0:388 ~ ucd[512d]::tables[0]::general[0]::{{impl}}[6]::eq[0]))
    time: 0.000; rss: 336MB	solve_nll_region_constraints(DefId(0/0:386 ~ ucd[512d]::tables[0]::general[0]::{{impl}}[5]::fmt[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:10 ~ ucd[512d]::tables[0]::general[0]::UCD_CAT[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:11 ~ ucd[512d]::tables[0]::general[0]::UCD_COMBCLS[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:403 ~ ucd[512d]::tables[0]::bidi[0]::{{impl}}[4]::clone[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:400 ~ ucd[512d]::tables[0]::bidi[0]::{{impl}}[2]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:398 ~ ucd[512d]::tables[0]::bidi[0]::{{impl}}[1]::eq[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:396 ~ ucd[512d]::tables[0]::bidi[0]::{{impl}}[0]::fmt[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:14 ~ ucd[512d]::tables[0]::bidi[0]::UCD_BIDI_CLASS[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:15 ~ ucd[512d]::tables[0]::bidi[0]::UCD_BIDI_MIRRORED[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:413 ~ ucd[512d]::tables[0]::bidi[0]::{{impl}}[9]::clone[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:410 ~ ucd[512d]::tables[0]::bidi[0]::{{impl}}[7]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:408 ~ ucd[512d]::tables[0]::bidi[0]::{{impl}}[6]::eq[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:406 ~ ucd[512d]::tables[0]::bidi[0]::{{impl}}[5]::fmt[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:16 ~ ucd[512d]::tables[0]::bidi[0]::UCD_BIDI_BRATYPE[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:17 ~ ucd[512d]::tables[0]::bidi[0]::UCD_BIDI_MIRROR[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:18 ~ ucd[512d]::tables[0]::bidi[0]::UCD_BIDI_PAIRED[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:21 ~ ucd[512d]::tables[0]::misc[0]::UCD_NUMS[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:22 ~ ucd[512d]::tables[0]::misc[0]::UCD_NUMVAL[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:423 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[4]::clone[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:420 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[2]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:418 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[1]::eq[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:416 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[0]::fmt[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:23 ~ ucd[512d]::tables[0]::misc[0]::UCD_NUMTYPE[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:433 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[9]::clone[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:430 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[7]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:428 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[6]::eq[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:426 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[5]::fmt[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:24 ~ ucd[512d]::tables[0]::misc[0]::UCD_EAWIDTH[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:443 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[14]::clone[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:440 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[12]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:438 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[11]::eq[0]))
    time: 0.000; rss: 339MB	solve_nll_region_constraints(DefId(0/0:436 ~ ucd[512d]::tables[0]::misc[0]::{{impl}}[10]::fmt[0]))
    time: 0.000; rss: 351MB	solve_nll_region_constraints(DefId(0/0:25 ~ ucd[512d]::tables[0]::misc[0]::UCD_LB[0]))
    time: 0.000; rss: 351MB	solve_nll_region_constraints(DefId(0/0:453 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[4]::clone[0]))
    time: 0.000; rss: 351MB	solve_nll_region_constraints(DefId(0/0:450 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[2]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 351MB	solve_nll_region_constraints(DefId(0/0:448 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[1]::eq[0]))
    time: 0.000; rss: 351MB	solve_nll_region_constraints(DefId(0/0:446 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[0]::fmt[0]))
    time: 0.000; rss: 351MB	solve_nll_region_constraints(DefId(0/0:28 ~ ucd[512d]::tables[0]::scripts[0]::UCD_JOINGRP[0]))
    time: 0.000; rss: 351MB	solve_nll_region_constraints(DefId(0/0:463 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[9]::clone[0]))
    time: 0.000; rss: 351MB	solve_nll_region_constraints(DefId(0/0:460 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[7]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 351MB	solve_nll_region_constraints(DefId(0/0:458 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[6]::eq[0]))
    time: 0.000; rss: 351MB	solve_nll_region_constraints(DefId(0/0:456 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[5]::fmt[0]))
    time: 0.000; rss: 352MB	solve_nll_region_constraints(DefId(0/0:29 ~ ucd[512d]::tables[0]::scripts[0]::UCD_JOINTYPE[0]))
    time: 0.000; rss: 352MB	solve_nll_region_constraints(DefId(0/0:473 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[14]::clone[0]))
    time: 0.000; rss: 352MB	solve_nll_region_constraints(DefId(0/0:470 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[12]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 352MB	solve_nll_region_constraints(DefId(0/0:468 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[11]::eq[0]))
    time: 0.000; rss: 352MB	solve_nll_region_constraints(DefId(0/0:466 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[10]::fmt[0]))
    time: 0.000; rss: 354MB	solve_nll_region_constraints(DefId(0/0:30 ~ ucd[512d]::tables[0]::scripts[0]::UCD_SCRIPT[0]))
    time: 0.000; rss: 354MB	solve_nll_region_constraints(DefId(0/0:31 ~ ucd[512d]::tables[0]::scripts[0]::UCD_SCRIPT_MAP[0]))
    time: 0.001; rss: 364MB	solve_nll_region_constraints(DefId(0/0:32 ~ ucd[512d]::tables[0]::scripts[0]::UCD_SCRIPTEXT[0]))
    time: 0.000; rss: 365MB	solve_nll_region_constraints(DefId(0/0:483 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[19]::clone[0]))
    time: 0.000; rss: 365MB	solve_nll_region_constraints(DefId(0/0:480 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[17]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 365MB	solve_nll_region_constraints(DefId(0/0:478 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[16]::eq[0]))
    time: 0.000; rss: 365MB	solve_nll_region_constraints(DefId(0/0:476 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[15]::fmt[0]))
    time: 0.000; rss: 365MB	solve_nll_region_constraints(DefId(0/0:33 ~ ucd[512d]::tables[0]::scripts[0]::UCD_JSN[0]))
    time: 0.000; rss: 365MB	solve_nll_region_constraints(DefId(0/0:493 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[24]::clone[0]))
    time: 0.000; rss: 365MB	solve_nll_region_constraints(DefId(0/0:490 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[22]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 365MB	solve_nll_region_constraints(DefId(0/0:488 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[21]::eq[0]))
    time: 0.000; rss: 365MB	solve_nll_region_constraints(DefId(0/0:486 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[20]::fmt[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:34 ~ ucd[512d]::tables[0]::scripts[0]::UCD_INSC[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:503 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[29]::clone[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:500 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[27]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:498 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[26]::eq[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:496 ~ ucd[512d]::tables[0]::scripts[0]::{{impl}}[25]::fmt[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:35 ~ ucd[512d]::tables[0]::scripts[0]::UCD_INPC[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:38 ~ ucd[512d]::tables[0]::function[0]::UCD_HEX_DIGIT_ASCII[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:39 ~ ucd[512d]::tables[0]::function[0]::UCD_PREPENDED_CONCATENATION_MARK[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:40 ~ ucd[512d]::tables[0]::function[0]::UCD_HYPHEN[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:41 ~ ucd[512d]::tables[0]::function[0]::UCD_HEX_DIGIT[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:42 ~ ucd[512d]::tables[0]::function[0]::UCD_WHITE[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:43 ~ ucd[512d]::tables[0]::function[0]::UCD_LOGICAL_ORDER_EXCEPTION[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:44 ~ ucd[512d]::tables[0]::function[0]::UCD_TERM_SENTENCE[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:45 ~ ucd[512d]::tables[0]::function[0]::UCD_DASH[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:46 ~ ucd[512d]::tables[0]::function[0]::UCD_QUOT[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:47 ~ ucd[512d]::tables[0]::function[0]::UCD_TERM_PUNC[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:48 ~ ucd[512d]::tables[0]::function[0]::UCD_EXTENDER[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:49 ~ ucd[512d]::tables[0]::function[0]::UCD_SOFT_DOTTED[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:50 ~ ucd[512d]::tables[0]::function[0]::UCD_DEFAULT_IGNORABLE[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:51 ~ ucd[512d]::tables[0]::function[0]::UCD_ALPHA[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:52 ~ ucd[512d]::tables[0]::function[0]::UCD_DEFAULT_IGNORABLE_OTHER[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:53 ~ ucd[512d]::tables[0]::function[0]::UCD_MATH_OTHER[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:54 ~ ucd[512d]::tables[0]::function[0]::UCD_DIACRITIC[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:55 ~ ucd[512d]::tables[0]::function[0]::UCD_MATH[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:56 ~ ucd[512d]::tables[0]::function[0]::UCD_ALPHA_OTHER[0]))
    time: 0.000; rss: 366MB	solve_nll_region_constraints(DefId(0/0:59 ~ ucd[512d]::tables[0]::bool[0]::UCD_QUICK_NFD[0]))
    time: 0.000; rss: 367MB	solve_nll_region_constraints(DefId(0/0:60 ~ ucd[512d]::tables[0]::bool[0]::UCD_QUICK_NFKD[0]))
    time: 0.000; rss: 367MB	solve_nll_region_constraints(DefId(0/0:61 ~ ucd[512d]::tables[0]::bool[0]::UCD_GRAPH_LINK[0]))
    time: 0.000; rss: 367MB	solve_nll_region_constraints(DefId(0/0:62 ~ ucd[512d]::tables[0]::bool[0]::UCD_EXPANDING_NFC[0]))
    time: 0.000; rss: 372MB	solve_nll_region_constraints(DefId(0/0:63 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASE_CHANGES_CASEFOLD[0]))
    time: 0.000; rss: 374MB	solve_nll_region_constraints(DefId(0/0:64 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASE_CHANGES_LOWER[0]))
    time: 0.000; rss: 378MB	solve_nll_region_constraints(DefId(0/0:65 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASE_CHANGES_UPPER[0]))
    time: 0.000; rss: 378MB	solve_nll_region_constraints(DefId(0/0:66 ~ ucd[512d]::tables[0]::bool[0]::UCD_COMP_EXCL[0]))
    time: 0.000; rss: 380MB	solve_nll_region_constraints(DefId(0/0:67 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASE_CHANGES_TITLE[0]))
    time: 0.000; rss: 380MB	solve_nll_region_constraints(DefId(0/0:68 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASE_CHANGES_CASEMAP[0]))
    time: 0.000; rss: 380MB	solve_nll_region_constraints(DefId(0/0:69 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASE_IS_LOWER_OTHER[0]))
    time: 0.000; rss: 381MB	solve_nll_region_constraints(DefId(0/0:70 ~ ucd[512d]::tables[0]::bool[0]::UCD_EXPANDING_NFD[0]))
    time: 0.000; rss: 381MB	solve_nll_region_constraints(DefId(0/0:71 ~ ucd[512d]::tables[0]::bool[0]::UCD_GRAPH_EXT[0]))
    time: 0.000; rss: 381MB	solve_nll_region_constraints(DefId(0/0:72 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASED[0]))
    time: 0.000; rss: 384MB	solve_nll_region_constraints(DefId(0/0:73 ~ ucd[512d]::tables[0]::bool[0]::UCD_ID_START_NFKC[0]))
    time: 0.000; rss: 384MB	solve_nll_region_constraints(DefId(0/0:74 ~ ucd[512d]::tables[0]::bool[0]::UCD_EXPANDING_NFKC[0]))
    time: 0.000; rss: 384MB	solve_nll_region_constraints(DefId(0/0:75 ~ ucd[512d]::tables[0]::bool[0]::UCD_COMP_EXCL_FULL[0]))
    time: 0.000; rss: 386MB	solve_nll_region_constraints(DefId(0/0:76 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASE_IS_LOWER[0]))
    time: 0.000; rss: 388MB	solve_nll_region_constraints(DefId(0/0:77 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASE_IS_UPPER[0]))
    time: 0.000; rss: 388MB	solve_nll_region_constraints(DefId(0/0:78 ~ ucd[512d]::tables[0]::bool[0]::UCD_IDEO_UNIFIED[0]))
    time: 0.000; rss: 388MB	solve_nll_region_constraints(DefId(0/0:79 ~ ucd[512d]::tables[0]::bool[0]::UCD_PATT_SYNTAX[0]))
    time: 0.000; rss: 391MB	solve_nll_region_constraints(DefId(0/0:80 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASE_CHANGES_CASEFOLD_NFKC[0]))
    time: 0.000; rss: 393MB	solve_nll_region_constraints(DefId(0/0:81 ~ ucd[512d]::tables[0]::bool[0]::UCD_ID_CONT[0]))
    time: 0.000; rss: 393MB	solve_nll_region_constraints(DefId(0/0:82 ~ ucd[512d]::tables[0]::bool[0]::UCD_CASE_IGNORABLE[0]))
    time: 0.000; rss: 396MB	solve_nll_region_constraints(DefId(0/0:83 ~ ucd[512d]::tables[0]::bool[0]::UCD_GRAPH_BASE[0]))
    time: 0.000; rss: 396MB	solve_nll_region_constraints(DefId(0/0:84 ~ ucd[512d]::tables[0]::bool[0]::UCD_GRAPH_EXT_OTHER[0]))
    time: 0.000; rss: 398MB	solve_nll_region_constraints(DefId(0/0:85 ~ ucd[512d]::tables[0]::bool[0]::UCD_ID_CONT_NFKC[0]))
    time: 0.000; rss: 398MB	solve_nll_region_constraints(DefId(0/0:86 ~ ucd[512d]::tables[0]::bool[0]::UCD_EXPANDING_NFKD[0]))
    time: 0.000; rss: 398MB	solve_nll_region_constraints(DefId(0/0:87 ~ ucd[512d]::tables[0]::bool[0]::UCD_IDEO[0]))
    time: 0.000; rss: 400MB	solve_nll_region_constraints(DefId(0/0:88 ~ ucd[512d]::tables[0]::bool[0]::UCD_ID_START[0]))
    time: 0.000; rss: 400MB	solve_nll_region_constraints(DefId(0/0:513 ~ ucd[512d]::tables[0]::rem[0]::{{impl}}[4]::clone[0]))
    time: 0.000; rss: 400MB	solve_nll_region_constraints(DefId(0/0:510 ~ ucd[512d]::tables[0]::rem[0]::{{impl}}[2]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 400MB	solve_nll_region_constraints(DefId(0/0:508 ~ ucd[512d]::tables[0]::rem[0]::{{impl}}[1]::eq[0]))
    time: 0.000; rss: 400MB	solve_nll_region_constraints(DefId(0/0:506 ~ ucd[512d]::tables[0]::rem[0]::{{impl}}[0]::fmt[0]))
    time: 0.000; rss: 400MB	solve_nll_region_constraints(DefId(0/0:91 ~ ucd[512d]::tables[0]::rem[0]::UCD_QNFC[0]))
    time: 0.000; rss: 400MB	solve_nll_region_constraints(DefId(0/0:92 ~ ucd[512d]::tables[0]::rem[0]::UCD_QNFKC[0]))
    time: 0.000; rss: 405MB	solve_nll_region_constraints(DefId(0/0:93 ~ ucd[512d]::tables[0]::rem[0]::UCD_CASE_SIMP_UP[0]))
    time: 0.000; rss: 409MB	solve_nll_region_constraints(DefId(0/0:94 ~ ucd[512d]::tables[0]::rem[0]::UCD_CASE_SIMP_LW[0]))
    time: 0.000; rss: 411MB	solve_nll_region_constraints(DefId(0/0:95 ~ ucd[512d]::tables[0]::rem[0]::UCD_CASE_SIMP_TI[0]))
    time: 0.000; rss: 414MB	solve_nll_region_constraints(DefId(0/0:96 ~ ucd[512d]::tables[0]::rem[0]::UCD_CASE_SIMP_FD[0]))
    time: 0.006; rss: 473MB	solve_nll_region_constraints(DefId(0/0:97 ~ ucd[512d]::tables[0]::rem[0]::UCD_CASE_UP[0]))
    time: 0.003; rss: 468MB	solve_nll_region_constraints(DefId(0/0:98 ~ ucd[512d]::tables[0]::rem[0]::UCD_CASE_LW[0]))
    time: 0.003; rss: 487MB	solve_nll_region_constraints(DefId(0/0:99 ~ ucd[512d]::tables[0]::rem[0]::UCD_CASE_TI[0]))
    time: 0.003; rss: 497MB	solve_nll_region_constraints(DefId(0/0:100 ~ ucd[512d]::tables[0]::rem[0]::UCD_CASE_FD[0]))
    time: 0.572; rss: 2392MB	solve_nll_region_constraints(DefId(0/0:101 ~ ucd[512d]::tables[0]::rem[0]::UCD_CASE_FD_NFKC[0]))
    time: 0.001; rss: 525MB	solve_nll_region_constraints(DefId(0/0:102 ~ ucd[512d]::tables[0]::rem[0]::UCD_CASE_FD_CLOS[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:523 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[4]::clone[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:520 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[2]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:518 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[1]::eq[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:516 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[0]::fmt[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:105 ~ ucd[512d]::tables[0]::decomp[0]::UCD_DECOMP_TYPE[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:533 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[9]::clone[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:530 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[7]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:528 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[6]::eq[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:526 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[5]::fmt[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:106 ~ ucd[512d]::tables[0]::decomp[0]::UCD_GCB[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:543 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[14]::clone[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:540 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[12]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:538 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[11]::eq[0]))
    time: 0.000; rss: 525MB	solve_nll_region_constraints(DefId(0/0:536 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[10]::fmt[0]))
    time: 0.000; rss: 526MB	solve_nll_region_constraints(DefId(0/0:107 ~ ucd[512d]::tables[0]::decomp[0]::UCD_WBRK[0]))
    time: 0.000; rss: 526MB	solve_nll_region_constraints(DefId(0/0:553 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[19]::clone[0]))
    time: 0.000; rss: 526MB	solve_nll_region_constraints(DefId(0/0:550 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[17]::assert_receiver_is_total_eq[0]))
    time: 0.000; rss: 526MB	solve_nll_region_constraints(DefId(0/0:548 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[16]::eq[0]))
    time: 0.000; rss: 526MB	solve_nll_region_constraints(DefId(0/0:546 ~ ucd[512d]::tables[0]::decomp[0]::{{impl}}[15]::fmt[0]))
    time: 0.000; rss: 528MB	solve_nll_region_constraints(DefId(0/0:108 ~ ucd[512d]::tables[0]::decomp[0]::UCD_SBRK[0]))
    time: 0.052; rss: 1302MB	solve_nll_region_constraints(DefId(0/0:109 ~ ucd[512d]::tables[0]::decomp[0]::UCD_DECOMP_MAP[0]))
  time: 62.044; rss: 554MB	MIR borrow checking
  time: 0.000; rss: 554MB	dumping chalk-like clauses
  time: 0.000; rss: 554MB	MIR effect checking
  time: 0.010; rss: 554MB	death checking
  time: 0.004; rss: 554MB	unused lib feature checking
  time: 1.402; rss: 569MB	lint checking
  time: 0.000; rss: 569MB	resolving dependency formats
      time: 0.000; rss: 593MB	solve_nll_region_constraints(DefId(0/1:14 ~ ucd[512d]::CharIterInternal[0]::Iterator[0]))
      time: 0.000; rss: 593MB	solve_nll_region_constraints(DefId(0/1:16 ~ ucd[512d]::CharIterInternal[0]::Double[0]))
      time: 0.000; rss: 593MB	solve_nll_region_constraints(DefId(0/1:19 ~ ucd[512d]::CharIterInternal[0]::Single[0]))
      time: 0.000; rss: 593MB	solve_nll_region_constraints(DefId(0/1:768 ~ ucd[512d]::Number[0]::Integer[0]))
      time: 0.000; rss: 593MB	solve_nll_region_constraints(DefId(0/1:770 ~ ucd[512d]::Number[0]::Rational[0]))
    time: 0.137; rss: 593MB	write metadata
    time: 0.000; rss: 593MB	assert dep graph
    time: 0.000; rss: 593MB	serialize dep graph
  time: 0.138; rss: 593MB	codegen
  time: 0.000; rss: 121MB	serialize work products
  time: 0.006; rss: 121MB	linking
    Finished dev [unoptimized + debuginfo] target(s) in 1m 07s

Note however that the current Nightly (tested above) is already a lot better than nightly-2018-07-17 (currently used in Servo) where the baseline is about the same but MIR-based two-phase borrowck takes 25,660,988 KB (25 GB) and 457 seconds (7m37), a 47× and 64× increase from baseline.

In both cases, the outlier in -Z time-passes points to this item of the crate:

https://github.com/sourtin/libucd/blob/fc89190397d21e43ab9b2246ab5b4aad88524875/src/tables/rem.rs#L4126-L7836

pub static UCD_CASE_FD_NFKC: &'static [((u8,u8,u8),&'static [(u8,u8,u8)])] = &[
    // ~3.7k lines of generated data
];
@SimonSapin SimonSapin added A-NLL Area: Non-lexical lifetimes (NLL) NLL-performant Working towards the "performance is good" goal labels Aug 23, 2018
@lqd
Copy link
Member

lqd commented Aug 23, 2018

cc @rust-lang/wg-compiler-nll

@nikomatsakis
Copy link
Contributor

Should we add this to perf? Seems like maybe yes

@nikomatsakis nikomatsakis added this to the Rust 2018 RC milestone Aug 24, 2018
@nikomatsakis
Copy link
Contributor

I can confirm this is "really dang slow" in my local testing. Doing a profile.

@nikomatsakis
Copy link
Contributor

The TL;DR is that there are an "awful lot of borrows". We spend something like 61% of our time propagating borrows -- and the rest I think is spent just comparing against borrows. I would expect #53328 might help here, but maybe there is something simpler we can do too. Last time we solved this via #53176 -- I suspect a slightly expanded version ought to apply here.

@SimonSapin
Copy link
Contributor Author

Could there a be a fast(er) path for "trivial" 'static borrows of literals?

@lqd
Copy link
Member

lqd commented Aug 24, 2018

A note for memory usage, I've tested this crate with #53327 and similarly to html5ever it will bring it down by 50%: Peak RSS: 1072048 KB

@nikomatsakis
Copy link
Contributor

I believe we can safely skip a shared borrow of a local variable if the following conditions are met:

Unfortunately, that last condition -- "declared as immutable" -- does not hold in the case of ucd. This is because the locals in question are temporaries, and we always create temporaries as mutable.

We could check a more general condition: basically it doesn't matter how the local is declared, it only matters if it is assigned to after the borrow, but that would require us to duplicate the code that knows about assignments etc.

We could also convince the MIR builder to create immutable temporaries in some conditions. In this particular case, the temporary is created via a &[...] expression, and hence I think winds up being created as part of the as_place call here:

ExprKind::Borrow { region, borrow_kind, arg } => {
let arg_place = unpack!(block = this.as_place(block, arg));
block.and(Rvalue::Ref(region, borrow_kind, arg_place))
}

One could imagine threading down some information about what sort of temporary to create (e.g., "this is a shared borrow, so create an immutable temporary").

Putting that together it feels like the steps needed here are:

  • If locals_are_invalidated_at_exit is false,
    • Create a bit set containing all locals that have a StorageDead
      • Maybe MoveData has something like this? Doubt it.
  • Tweak MIR construction to make an immutable borrow
  • Modify the ignore_borrow code for locals to check whether the "magic three" conditions are met

The ignore_borrow function is here:

https://github.com/rust-lang/rust/blob/master/src/librustc_mir/borrow_check/place_ext.rs#L33

@mikhail-m1
Copy link
Contributor

working on it

@nnethercote
Copy link
Contributor

Here's some Callgrind output. The hottest function by far is precompute_borrows_out_of_scope().

--------------------------------------------------------------------------------
-- Auto-annotated source: /home/njn/moz/rust0/src/librustc_mir/dataflow/impls/borrows.rs
--------------------------------------------------------------------------------
           Ir 

-- line 57 ----------------------------------------
            .      mir: &Mir<'tcx>,
            .      regioncx: &Rc<RegionInferenceContext<'tcx>>,
            .      borrows_out_of_scope_at_location: &mut FxHashMap<Location, Vec<BorrowIndex>>,
            .      borrow_index: BorrowIndex,
            .      borrow_region: RegionVid,
            .      location: Location,
            .  ) {
            .      // Keep track of places we've locations to check and locations that we have checked.
       73,356      let mut stack = vec![ location ];
            .      let mut visited = FxHashSet();
       97,808      visited.insert(location);
    7,114,950  => /home/njn/moz/rust0/src/libstd/collections/hash/set.rs:<std::collections::hash::set::HashSet<T, S>>::insert (24450x)
            .  
            .      debug!(
            .          "borrow {:?} has region {:?} with value {:?}",
            .          borrow_index,
            .          borrow_region,
            .          regioncx.region_value_str(borrow_region),
            .      );
            .      debug!("borrow {:?} starts at {:?}", borrow_index, location);
2,237,113,404      while let Some(location) = stack.pop() {
            .          // If region does not contain a point at the location, then add to list and skip
            .          // successor locations.
5,592,783,510          if !regioncx.region_contains(borrow_region, location) {
52,572,164,242  => /home/njn/moz/rust0/src/librustc_mir/borrow_check/nll/region_infer/mod.rs:rustc_mir::borrow_check::nll::region_infer::RegionInferenceContext::region_contains (1,118,556,686x)
            .              debug!("borrow {:?} gets killed at {:?}", borrow_index, location);
       19,740              borrows_out_of_scope_at_location
      561,036  => /home/njn/moz/rust0/src/libstd/collections/hash/map.rs:<std::collections::hash::map::Entry<'a, K, V>>::or_default (3944x)
      967,818  => /home/njn/moz/rust0/src/libstd/collections/hash/map.rs:<std::collections::hash::map::HashMap<K, V, S>>::entry (3944x)
        7,896                  .entry(location)
            .                  .or_default()
            .                  .push(borrow_index);
            .              continue;
            .          }
            .  
1,118,552,754          let bb_data = &mir[location.block];
            .          // If this is the last statement in the block, then add the
            .          // terminator successors next.
3,355,658,262          if location.statement_index == bb_data.statements.len() {
            .              // Add successors to locations to visit, if not visited before.
       52,110              if let Some(ref terminator) = bb_data.terminator {
       78,165                  for block in terminator.successors() {
      646,293  => /home/njn/moz/rust0/src/librustc/mir/mod.rs:rustc::mir::Terminator::successors (26053x)
       21,546                      let loc = block.start_location();
       21,534  => /home/njn/moz/rust0/src/librustc/mir/mod.rs:rustc::mir::BasicBlock::start_location (7178x)
       35,910                      if visited.insert(loc) {
      985,265  => /home/njn/moz/rust0/src/libstd/collections/hash/set.rs:<std::collections::hash::set::HashSet<T, S>>::insert (7178x)
            .                          stack.push(loc);
            .                      }
            .                  }
            .              }
            .          } else {
            .              // Visit next statement in block.
3,355,580,097              let loc = location.successor_within_block();
4,474,106,756  => /home/njn/moz/rust0/src/librustc/mir/mod.rs:rustc::mir::Location::successor_within_block (1,118,526,689x)
5,592,633,495              if visited.insert(loc) {
156,161,136,069  => /home/njn/moz/rust0/src/libstd/collections/hash/set.rs:<std::collections::hash::set::HashSet<T, S>>::insert (1,118,526,689x)
            .                  stack.push(loc);
            .              }
            .          }
            .      }
            .  }
            .  

The hot path goes through the regioncx.region_contains() call at the top of the loop and the visited.insert() and stack.push() at the bottom of the loop more than 1.1 billion times.

@nnethercote
Copy link
Contributor

There's something quadratic about the way precompute_borrows_out_of_scope is called. I added some eprintln instrumentation to count how often different paths within that function are called. Some sample output from a ucd run:

n: 148919 0 148919 1 1 0 0 0 148918 148918 0
n: 148905 0 148905 1 1 0 0 0 148904 148904 0
n: 148891 0 148891 1 1 0 0 0 148890 148890 0
n: 148877 0 148877 1 1 0 0 0 148876 148876 0
n: 148863 0 148863 1 1 0 0 0 148862 148862 0
n: 148849 0 148849 1 1 0 0 0 148848 148848 0
... continues like this for a long time ...
n: 773 0 773 1 1 0 0 0 772 772 0
n: 757 0 757 1 1 0 0 0 756 756 0
n: 741 0 741 1 1 0 0 0 740 740 0
n: 725 0 725 1 1 0 0 0 724 724 0
n: 707 0 707 1 1 0 0 0 706 706 0
n: 691 0 691 1 1 0 0 0 690 690 0
n: 675 0 675 1 1 0 0 0 674 674 0
n: 659 0 659 1 1 0 0 0 658 658 0
n: 643 0 643 1 1 0 0 0 642 642 0
n: 638 0 638 1 1 0 0 0 637 637 0

@nnethercote
Copy link
Contributor

I'm also puzzled by this part of the code:

            // Visit next statement in block.
            let loc = location.successor_within_block();
            if visited.insert(loc) {
                stack.push(loc);
            }

It seems like tracking visited-ness at the statement level shouldn't be necessary -- we should instead be able to do it at the basic block level, right? I.e. we can check if a basic block has been visited, and if it hasn't, we can process all the statements within it without any further checking.

If I'm right about that, then the visited.insert() above should always return true. Instrumentation shows that is mostly true, but occasionally within a precompute_borrows_out_of_scope call there is a single visited.insert() call that returns false, i.e. the loc has been visited.

@bjorn3
Copy link
Member

bjorn3 commented Aug 28, 2018

@nnethercote you commented the same three times :)

@memoryruins
Copy link
Contributor

@bjorn3 github experienced a 500 internal error last night and caused a ton of comments posted at that exact moment to duplicate

@pnkfelix
Copy link
Member

@nikomatsakis the strategy you outlined above should take care of the execution time issue, but the memory usage issue, at least according to @SimonSapin 's analysis, is happening earlier in the pipeline, during solve_nll_region_constraitns. Do you have any thoughts about that?

@pnkfelix
Copy link
Member

Ah never mind; discussing with lqd led me to realize I had misread Simon’s comment and had thought the current memory regression was far more grave

@nikomatsakis
Copy link
Contributor

@nnethercote

It seems like tracking visited-ness at the statement level shouldn't be necessary -- we should instead be able to do it at the basic block level, right? I.e. we can check if a basic block has been visited, and if it hasn't, we can process all the statements within it without any further checking.

In principle yes, but it's hard to get it just right. In particular, the borrow can start in the middle of a basic block -- and you can loop back to the start. So I've considered doing the tracking at the basic block level, but not marking the initial block fixed, and then having an extra check for when you loop back to the start point.

In any case, I do think we can do better than this code, but I think the best fix for UCD is simply not to have the borrows in the first place. And I had hoped to rework the loop as part of #53328 -- but I guess no reason not to do it earlier too, it's an independnt task

@nikomatsakis
Copy link
Contributor

@pnkfelix just for the record, the max-rss results with #53327 applied are:

ucd-check avg: -16.8% min: -67.2% max: 0.0%
clean-check 566,472.00 566,724.00 0.0%
nll-check 2,352,152.00 772,052.00 -67.2%
baseline incremental-check 611,488.00 610,048.00 -0.2%
clean incremental-check 535,840.00 535,884.00 0.0%

Thus the memory use is 136%. Not so bad.

@nnethercote
Copy link
Contributor

think the best fix for UCD is simply not to have the borrows in the first place.

This function was hot for html5ever until you fixed that. And now it's hot for ucd but you will fix that. So there's a chance some other slightly different pattern will end up here again.

In short, I agree that fixing it both ways is a good idea :)

@nikomatsakis
Copy link
Contributor

@nnethercote

In short, I agree that fixing it both ways is a good idea :)

Yes, I agree. In particular, there will be cases where we can't just make the borrows go away. =)

(I do also mildly worry about messing up some optimization here and ignoring borrows when we ought not to.)

@nnethercote
Copy link
Contributor

Yesterday, I started looking at rewriting precompute_borrows_out_of_scope, and will continue on Monday. It's fiddly getting the algorithm into a nice state, but definitely doable.

@nnethercote
Copy link
Contributor

nnethercote commented Sep 4, 2018

Yesterday, I started looking at rewriting precompute_borrows_out_of_scope, and will continue on Monday.

#53942

@nnethercote
Copy link
Contributor

Just to expand on the quadratic-ness of precompute_borrows_out_of_scope() a bit more... the time is dominated by analysis of a single BB with 148,932 statements within it. Here's the sequence of calls, where each line shows the starting location, then the number of BBs analyzed (always 1), then the number of statements analyzed.

precompute bb0[13] 1 148919
precompute bb0[27] 1 148905
precompute bb0[41] 1 148891
precompute bb0[55] 1 148877
precompute bb0[69] 1 148863
precompute bb0[83] 1 148849
precompute bb0[97] 1 148835
precompute bb0[111] 1 148821
precompute bb0[125] 1 148807
precompute bb0[139] 1 148793
...
precompute bb0[100007] 1 48925
precompute bb0[100019] 1 48913
precompute bb0[100031] 1 48901
precompute bb0[100043] 1 48889
...
precompute bb0[138623] 1 10309
precompute bb0[138635] 1 10297
precompute bb0[138647] 1 10285
precompute bb0[138659] 1 10273
precompute bb0[138671] 1 10261
precompute bb0[138683] 1 10249
precompute bb0[138695] 1 10237
precompute bb0[138700] 1 10232

It's clearly iterating through every 12th or 14th of BB's statements, and for each one it iterates from that statement to the BB's end. Boom, quadratic.

@nikomatsakis
Copy link
Contributor

Bumping to RC 2 — important goal, but not an RC blocker.

mikhail-m1 added a commit to mikhail-m1/rust that referenced this issue Sep 6, 2018
bors added a commit that referenced this issue Sep 8, 2018
Skip a shared borrow of a immutable local variables

issue #53643

r? @nikomatsakis
@nikomatsakis
Copy link
Contributor

So it's not 110% CPU and 135% RAM. Seems fine. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non-lexical lifetimes (NLL) NLL-performant Working towards the "performance is good" goal
Projects
None yet
Development

No branches or pull requests

8 participants