@@ -93,9 +93,14 @@ fn run_qbdi(mut args: impl Iterator<Item = String>) {
9393 command. env ( "LD_PRELOAD" , & library. display ( ) . to_string ( ) ) ;
9494 }
9595
96+ let mut filter = true ;
9697 // TODO could extract things here
9798 for arg in args {
98- let _ = command. arg ( arg) ;
99+ if let "--qbdi-all" = arg. as_str ( ) {
100+ filter = false ;
101+ } else {
102+ let _ = command. arg ( arg) ;
103+ }
99104 }
100105
101106 command. stdout ( Stdio :: piped ( ) ) ;
@@ -104,7 +109,16 @@ fn run_qbdi(mut args: impl Iterator<Item = String>) {
104109
105110 let mut content = BufReader :: new ( child. stdout . unwrap ( ) ) ;
106111
107- let mut items: HashMap < String , Vec < ( String , usize ) > > = HashMap :: new ( ) ;
112+ #[ derive( Default ) ]
113+ struct Item {
114+ total : usize ,
115+ instruction_kind : Vec < ( String , usize ) > ,
116+ }
117+
118+ // TODO this seems highly inefficient
119+ let mut items: HashMap < String , Item > = HashMap :: new ( ) ;
120+
121+ let mut total_count = 0 ;
108122 for line in content. lines ( ) {
109123 let line = line. unwrap ( ) ;
110124 if let Some ( rest) = line. strip_prefix ( "bm::" ) {
@@ -118,33 +132,45 @@ fn run_qbdi(mut args: impl Iterator<Item = String>) {
118132 // TODO ...?
119133 continue ;
120134 } ;
121- items
122- . entry ( func. to_owned ( ) )
123- . or_default ( )
124- . push ( ( kind. to_owned ( ) , count) ) ;
135+
136+ total_count += count;
137+
138+ let func = format ! ( "{func:#}" , func = rustc_demangle:: demangle( & func) ) ;
139+ // let func: Sting = if let Some(rest) = func.strip_prefix('<') {
140+ // let (_, rhs) = rest.split_once(" as ").unwrap();
141+ // let (lhs, _) = rhs.split_once('>').unwrap();
142+ // formatlhs.to_owned()
143+ // } else {
144+ // func
145+ // };
146+
147+ if filter {
148+ let bad_prefixes = & [ "std::" , "core::" , "alloc::" , "_" , "*" , "OUTLINED_FUNCTION_" ] ;
149+ let skip = bad_prefixes. iter ( ) . any ( |prefix| func. starts_with ( prefix) ) ;
150+ if skip {
151+ continue ;
152+ }
153+ }
154+
155+ let item = items
156+ . entry ( func)
157+ . or_default ( ) ;
158+
159+ item. total += count;
160+ item. instruction_kind . push ( ( kind. to_owned ( ) , count) ) ;
125161 } else {
126162 println ! ( "{line}" ) ;
127163 }
128164 }
129165
130- for ( func, mut items) in items {
131- let func = format ! ( "{func:#}" , func = rustc_demangle:: demangle( & func) ) ;
132- let func: & str = if let Some ( rest) = func. strip_prefix ( '<' ) {
133- let ( _, rhs) = rest. split_once ( " as " ) . unwrap ( ) ;
134- let ( lhs, _) = rhs. split_once ( '>' ) . unwrap ( ) ;
135- lhs
136- } else {
137- & func
138- } ;
139- let bad_prefixes = & [ "std::" , "core::" , "alloc::" , "_" , "*" , "OUTLINED_FUNCTION_" ] ;
140- let skip = bad_prefixes. iter ( ) . any ( |prefix| func. starts_with ( prefix) ) ;
141- if skip {
142- continue ;
143- }
144- print ! ( " {func}" ) ;
145- items. sort_unstable_by_key ( |( _, value) | usize:: MAX - value) ;
146- for ( kind, count) in items {
147- print ! ( " [{kind}: {count}]" ) ;
166+ let mut items: Vec < ( String , Item ) > = Vec :: from_iter ( items) ;
167+ items. sort_unstable_by_key ( |( _, value) | usize:: MAX - value. total ) ;
168+
169+ for ( func, mut item) in items {
170+ print ! ( "{func} - {total} instructions" , total=item. total) ;
171+ item. instruction_kind . sort_unstable_by_key ( |( _, value) | usize:: MAX - value) ;
172+ for ( kind, count) in & item. instruction_kind {
173+ print ! ( " ({kind}={count})" ) ;
148174 }
149175 println ! ( ) ;
150176 }
0 commit comments