@@ -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