@@ -25,6 +25,7 @@ use rustc_target::abi::{FieldIdx, Size, VariantIdx};
25
25
26
26
use polonius_engine:: Atom ;
27
27
pub use rustc_ast:: Mutability ;
28
+ use rustc_data_structures:: fx:: FxHashMap ;
28
29
use rustc_data_structures:: fx:: FxHashSet ;
29
30
use rustc_data_structures:: graph:: dominators:: Dominators ;
30
31
use rustc_index:: { Idx , IndexSlice , IndexVec } ;
@@ -35,6 +36,8 @@ use rustc_span::{Span, DUMMY_SP};
35
36
use either:: Either ;
36
37
37
38
use std:: borrow:: Cow ;
39
+ use std:: cell:: RefCell ;
40
+ use std:: collections:: hash_map:: Entry ;
38
41
use std:: fmt:: { self , Debug , Display , Formatter , Write } ;
39
42
use std:: ops:: { Index , IndexMut } ;
40
43
use std:: { iter, mem} ;
@@ -97,6 +100,36 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
97
100
}
98
101
}
99
102
103
+ thread_local ! {
104
+ static PASS_NAMES : RefCell <FxHashMap <& ' static str , & ' static str >> = {
105
+ RefCell :: new( FxHashMap :: default ( ) )
106
+ } ;
107
+ }
108
+
109
+ /// Converts a MIR pass name into a snake case form to match the profiling naming style.
110
+ fn to_profiler_name ( type_name : & ' static str ) -> & ' static str {
111
+ PASS_NAMES . with ( |names| match names. borrow_mut ( ) . entry ( type_name) {
112
+ Entry :: Occupied ( e) => * e. get ( ) ,
113
+ Entry :: Vacant ( e) => {
114
+ let snake_case: String = type_name
115
+ . chars ( )
116
+ . flat_map ( |c| {
117
+ if c. is_ascii_uppercase ( ) {
118
+ vec ! [ '_' , c. to_ascii_lowercase( ) ]
119
+ } else if c == '-' {
120
+ vec ! [ '_' ]
121
+ } else {
122
+ vec ! [ c]
123
+ }
124
+ } )
125
+ . collect ( ) ;
126
+ let result = & * String :: leak ( format ! ( "mir_pass{}" , snake_case) ) ;
127
+ e. insert ( result) ;
128
+ result
129
+ }
130
+ } )
131
+ }
132
+
100
133
/// A streamlined trait that you can implement to create a pass; the
101
134
/// pass will be named after the type, and it will consist of a main
102
135
/// loop that goes over each available MIR and applies `run_pass`.
@@ -106,6 +139,10 @@ pub trait MirPass<'tcx> {
106
139
if let Some ( ( _, tail) ) = name. rsplit_once ( ':' ) { tail } else { name }
107
140
}
108
141
142
+ fn profiler_name ( & self ) -> & ' static str {
143
+ to_profiler_name ( self . name ( ) )
144
+ }
145
+
109
146
/// Returns `true` if this pass is enabled with the current combination of compiler flags.
110
147
fn is_enabled ( & self , _sess : & Session ) -> bool {
111
148
true
0 commit comments