@@ -25,6 +25,7 @@ use rustc_target::abi::{FieldIdx, Size, VariantIdx};
2525
2626use polonius_engine:: Atom ;
2727pub use rustc_ast:: Mutability ;
28+ use rustc_data_structures:: fx:: FxHashMap ;
2829use rustc_data_structures:: fx:: FxHashSet ;
2930use rustc_data_structures:: graph:: dominators:: Dominators ;
3031use rustc_index:: { Idx , IndexSlice , IndexVec } ;
@@ -35,6 +36,8 @@ use rustc_span::{Span, DUMMY_SP};
3536use either:: Either ;
3637
3738use std:: borrow:: Cow ;
39+ use std:: cell:: RefCell ;
40+ use std:: collections:: hash_map:: Entry ;
3841use std:: fmt:: { self , Debug , Display , Formatter , Write } ;
3942use std:: ops:: { Index , IndexMut } ;
4043use std:: { iter, mem} ;
@@ -97,6 +100,36 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
97100 }
98101}
99102
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+
100133/// A streamlined trait that you can implement to create a pass; the
101134/// pass will be named after the type, and it will consist of a main
102135/// loop that goes over each available MIR and applies `run_pass`.
@@ -106,6 +139,10 @@ pub trait MirPass<'tcx> {
106139 if let Some ( ( _, tail) ) = name. rsplit_once ( ':' ) { tail } else { name }
107140 }
108141
142+ fn profiler_name ( & self ) -> & ' static str {
143+ to_profiler_name ( self . name ( ) )
144+ }
145+
109146 /// Returns `true` if this pass is enabled with the current combination of compiler flags.
110147 fn is_enabled ( & self , _sess : & Session ) -> bool {
111148 true
0 commit comments