@@ -29,7 +29,6 @@ use profile::{Bytes, StopWatch};
29
29
use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace, RustLibSource};
30
30
use rayon::prelude::*;
31
31
use rustc_hash::FxHashSet;
32
- use stdx::format_to;
33
32
use syntax::{AstNode, SyntaxNode};
34
33
use vfs::{AbsPathBuf, Vfs, VfsPath};
35
34
@@ -176,8 +175,11 @@ impl flags::AnalysisStats {
176
175
shuffle(&mut rng, &mut bodies);
177
176
}
178
177
178
+ if !self.skip_lowering {
179
+ self.run_body_lowering(db, &vfs, &bodies, verbosity);
180
+ }
181
+
179
182
if !self.skip_inference {
180
- // FIXME: Consider running inference on all body kinds?
181
183
self.run_inference(db, &vfs, &bodies, verbosity);
182
184
}
183
185
@@ -238,8 +240,10 @@ impl flags::AnalysisStats {
238
240
continue;
239
241
}
240
242
all += 1;
241
- let Err(e) = db.layout_of_adt(hir_def::AdtId::from(a).into(), Substitution::empty(Interner), a.krate(db).into()) else {
242
- continue;
243
+ let Err(e)
244
+ = db.layout_of_adt(hir_def::AdtId::from(a).into(), Substitution::empty(Interner), a.krate(db).into())
245
+ else {
246
+ continue
243
247
};
244
248
if verbosity.is_spammy() {
245
249
let full_name = a
@@ -255,9 +259,11 @@ impl flags::AnalysisStats {
255
259
}
256
260
fail += 1;
257
261
}
258
- eprintln!("{:<20} {}", "Data layouts:", sw.elapsed());
262
+ let data_layout_time = sw.elapsed();
263
+ eprintln!("{:<20} {}", "Data layouts:", data_layout_time);
259
264
eprintln!("Failed data layouts: {fail} ({}%)", percentage(fail, all));
260
265
report_metric("failed data layouts", fail, "#");
266
+ report_metric("data layout time", data_layout_time.time.as_millis() as u64, "ms");
261
267
}
262
268
263
269
fn run_const_eval(&self, db: &RootDatabase, consts: &[hir::Const], verbosity: Verbosity) {
@@ -283,9 +289,11 @@ impl flags::AnalysisStats {
283
289
}
284
290
fail += 1;
285
291
}
286
- eprintln!("{:<20} {}", "Const evaluation:", sw.elapsed());
292
+ let const_eval_time = sw.elapsed();
293
+ eprintln!("{:<20} {}", "Const evaluation:", const_eval_time);
287
294
eprintln!("Failed const evals: {fail} ({}%)", percentage(fail, all));
288
295
report_metric("failed const evals", fail, "#");
296
+ report_metric("const eval time", const_eval_time.time.as_millis() as u64, "ms");
289
297
}
290
298
291
299
fn run_mir_lowering(&self, db: &RootDatabase, bodies: &[DefWithBody], verbosity: Verbosity) {
@@ -310,9 +318,11 @@ impl flags::AnalysisStats {
310
318
}
311
319
fail += 1;
312
320
}
313
- eprintln!("{:<20} {}", "MIR lowering:", sw.elapsed());
321
+ let mir_lowering_time = sw.elapsed();
322
+ eprintln!("{:<20} {}", "MIR lowering:", mir_lowering_time);
314
323
eprintln!("Mir failed bodies: {fail} ({}%)", percentage(fail, all));
315
324
report_metric("mir failed bodies", fail, "#");
325
+ report_metric("mir lowering time", mir_lowering_time.time.as_millis() as u64, "ms");
316
326
}
317
327
318
328
fn run_inference(
@@ -354,7 +364,7 @@ impl flags::AnalysisStats {
354
364
for &body_id in bodies {
355
365
let name = body_id.name(db).unwrap_or_else(Name::missing);
356
366
let module = body_id.module(db);
357
- let full_name = || {
367
+ let full_name = move || {
358
368
module
359
369
.krate()
360
370
.display_name(db)
@@ -366,7 +376,7 @@ impl flags::AnalysisStats {
366
376
.into_iter()
367
377
.filter_map(|it| it.name(db))
368
378
.rev()
369
- .chain(Some(name.clone( )))
379
+ .chain(Some(body_id. name(db).unwrap_or_else(Name::missing )))
370
380
.map(|it| it.display(db).to_string()),
371
381
)
372
382
.join("::")
@@ -376,26 +386,31 @@ impl flags::AnalysisStats {
376
386
continue;
377
387
}
378
388
}
379
- let mut msg = format!("processing: {}", full_name());
380
- if verbosity.is_verbose() {
381
- let source = match body_id {
382
- DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()),
383
- DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()),
384
- DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()),
385
- DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()),
386
- DefWithBody::InTypeConst(_) => unimplemented!(),
387
- };
388
- if let Some(src) = source {
389
- let original_file = src.file_id.original_file(db);
390
- let path = vfs.file_path(original_file);
391
- let syntax_range = src.value.text_range();
392
- format_to!(msg, " ({} {:?})", path, syntax_range);
389
+ let msg = move || {
390
+ if verbosity.is_verbose() {
391
+ let source = match body_id {
392
+ DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()),
393
+ DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()),
394
+ DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()),
395
+ DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()),
396
+ DefWithBody::InTypeConst(_) => unimplemented!(),
397
+ };
398
+ if let Some(src) = source {
399
+ let original_file = src.file_id.original_file(db);
400
+ let path = vfs.file_path(original_file);
401
+ let syntax_range = src.value.text_range();
402
+ format!("processing: {} ({} {:?})", full_name(), path, syntax_range)
403
+ } else {
404
+ format!("processing: {}", full_name())
405
+ }
406
+ } else {
407
+ format!("processing: {}", full_name())
393
408
}
394
- }
409
+ };
395
410
if verbosity.is_spammy() {
396
- bar.println(msg.to_string ());
411
+ bar.println(msg());
397
412
}
398
- bar.set_message(& msg);
413
+ bar.set_message(msg);
399
414
let (body, sm) = db.body_with_source_map(body_id.into());
400
415
let inference_result = db.infer(body_id.into());
401
416
@@ -596,6 +611,7 @@ impl flags::AnalysisStats {
596
611
}
597
612
598
613
bar.finish_and_clear();
614
+ let inference_time = inference_sw.elapsed();
599
615
eprintln!(
600
616
" exprs: {}, ??ty: {} ({}%), ?ty: {} ({}%), !ty: {}",
601
617
num_exprs,
@@ -614,12 +630,89 @@ impl flags::AnalysisStats {
614
630
percentage(num_pats_partially_unknown, num_pats),
615
631
num_pat_type_mismatches
616
632
);
633
+ eprintln!("{:<20} {}", "Inference:", inference_time);
617
634
report_metric("unknown type", num_exprs_unknown, "#");
618
635
report_metric("type mismatches", num_expr_type_mismatches, "#");
619
636
report_metric("pattern unknown type", num_pats_unknown, "#");
620
637
report_metric("pattern type mismatches", num_pat_type_mismatches, "#");
638
+ report_metric("inference time", inference_time.time.as_millis() as u64, "ms");
639
+ }
621
640
622
- eprintln!("{:<20} {}", "Inference:", inference_sw.elapsed());
641
+ fn run_body_lowering(
642
+ &self,
643
+ db: &RootDatabase,
644
+ vfs: &Vfs,
645
+ bodies: &[DefWithBody],
646
+ verbosity: Verbosity,
647
+ ) {
648
+ let mut bar = match verbosity {
649
+ Verbosity::Quiet | Verbosity::Spammy => ProgressReport::hidden(),
650
+ _ if self.output.is_some() => ProgressReport::hidden(),
651
+ _ => ProgressReport::new(bodies.len() as u64),
652
+ };
653
+
654
+ let mut sw = self.stop_watch();
655
+ bar.tick();
656
+ for &body_id in bodies {
657
+ let module = body_id.module(db);
658
+ let full_name = move || {
659
+ module
660
+ .krate()
661
+ .display_name(db)
662
+ .map(|it| it.canonical_name().to_string())
663
+ .into_iter()
664
+ .chain(
665
+ module
666
+ .path_to_root(db)
667
+ .into_iter()
668
+ .filter_map(|it| it.name(db))
669
+ .rev()
670
+ .chain(Some(body_id.name(db).unwrap_or_else(Name::missing)))
671
+ .map(|it| it.display(db).to_string()),
672
+ )
673
+ .join("::")
674
+ };
675
+ if let Some(only_name) = self.only.as_deref() {
676
+ if body_id.name(db).unwrap_or_else(Name::missing).display(db).to_string()
677
+ != only_name
678
+ && full_name() != only_name
679
+ {
680
+ continue;
681
+ }
682
+ }
683
+ let msg = move || {
684
+ if verbosity.is_verbose() {
685
+ let source = match body_id {
686
+ DefWithBody::Function(it) => it.source(db).map(|it| it.syntax().cloned()),
687
+ DefWithBody::Static(it) => it.source(db).map(|it| it.syntax().cloned()),
688
+ DefWithBody::Const(it) => it.source(db).map(|it| it.syntax().cloned()),
689
+ DefWithBody::Variant(it) => it.source(db).map(|it| it.syntax().cloned()),
690
+ DefWithBody::InTypeConst(_) => unimplemented!(),
691
+ };
692
+ if let Some(src) = source {
693
+ let original_file = src.file_id.original_file(db);
694
+ let path = vfs.file_path(original_file);
695
+ let syntax_range = src.value.text_range();
696
+ format!("processing: {} ({} {:?})", full_name(), path, syntax_range)
697
+ } else {
698
+ format!("processing: {}", full_name())
699
+ }
700
+ } else {
701
+ format!("processing: {}", full_name())
702
+ }
703
+ };
704
+ if verbosity.is_spammy() {
705
+ bar.println(msg());
706
+ }
707
+ bar.set_message(msg);
708
+ db.body_with_source_map(body_id.into());
709
+ bar.inc(1);
710
+ }
711
+
712
+ bar.finish_and_clear();
713
+ let body_lowering_time = sw.elapsed();
714
+ eprintln!("{:<20} {}", "Body lowering:", body_lowering_time);
715
+ report_metric("body lowering time", body_lowering_time.time.as_millis() as u64, "ms");
623
716
}
624
717
625
718
fn stop_watch(&self) -> StopWatch {
0 commit comments