@@ -72,6 +72,7 @@ use std::uint;
72
72
use std:: vec;
73
73
use std:: local_data;
74
74
use extra:: time;
75
+ use extra:: sort;
75
76
use syntax:: ast:: ident;
76
77
use syntax:: ast_map:: { path, path_elt_to_str, path_name} ;
77
78
use syntax:: ast_util:: { local_def, path_to_ident} ;
@@ -141,6 +142,48 @@ fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool {
141
142
}
142
143
}
143
144
145
+ struct StatRecorder < ' self > {
146
+ ccx : @mut CrateContext ,
147
+ name : & ' self str ,
148
+ start : u64 ,
149
+ istart : uint ,
150
+ }
151
+
152
+ impl < ' self > StatRecorder < ' self > {
153
+ pub fn new ( ccx : @mut CrateContext ,
154
+ name : & ' self str ) -> StatRecorder < ' self > {
155
+ let start = if ccx. sess . trans_stats ( ) {
156
+ time:: precise_time_ns ( )
157
+ } else {
158
+ 0
159
+ } ;
160
+ let istart = ccx. stats . n_llvm_insns ;
161
+ StatRecorder {
162
+ ccx : ccx,
163
+ name : name,
164
+ start : start,
165
+ istart : istart,
166
+ }
167
+ }
168
+ }
169
+
170
+ #[ unsafe_destructor]
171
+ impl < ' self > Drop for StatRecorder < ' self > {
172
+ pub fn drop ( & self ) {
173
+ if self . ccx . sess . trans_stats ( ) {
174
+ let end = time:: precise_time_ns ( ) ;
175
+ let elapsed = ( ( end - self . start ) / 1_000_000 ) as uint ;
176
+ let iend = self . ccx . stats . n_llvm_insns ;
177
+ self . ccx . stats . fn_stats . push ( ( self . name . to_owned ( ) ,
178
+ elapsed,
179
+ iend - self . istart ) ) ;
180
+ self . ccx . stats . n_fns += 1 ;
181
+ // Reset LLVM insn count to avoid compound costs.
182
+ self . ccx . stats . n_llvm_insns = self . istart ;
183
+ }
184
+ }
185
+ }
186
+
144
187
pub fn decl_fn ( llmod : ModuleRef , name : & str , cc : lib:: llvm:: CallConv , ty : Type ) -> ValueRef {
145
188
let llfn: ValueRef = do name. as_c_str |buf| {
146
189
unsafe {
@@ -1888,18 +1931,16 @@ pub fn trans_fn(ccx: @mut CrateContext,
1888
1931
param_substs: Option <@param_substs>,
1889
1932
id: ast:: node_id,
1890
1933
attrs: & [ ast:: attribute] ) {
1891
- let do_time = ccx . sess . trans_stats ( ) ;
1892
- let start = if do_time { time :: get_time ( ) }
1893
- else { time :: Timespec :: new( 0 , 0 ) } ;
1934
+
1935
+ let the_path_str = path_str ( ccx . sess , path ) ;
1936
+ let _s = StatRecorder :: new( ccx , the_path_str ) ;
1894
1937
debug!( "trans_fn(self_arg=%?, param_substs=%s)" ,
1895
1938
self_arg,
1896
1939
param_substs. repr( ccx. tcx) ) ;
1897
1940
let _icx = push_ctxt( "trans_fn" ) ;
1898
- ccx. stats. n_fns += 1 ;
1899
- let the_path_str = path_str( ccx. sess, path) ;
1900
1941
let output_type = ty:: ty_fn_ret( ty:: node_id_to_type( ccx. tcx, id) ) ;
1901
1942
trans_closure( ccx,
1902
- path,
1943
+ copy path,
1903
1944
decl,
1904
1945
body,
1905
1946
llfndecl,
@@ -1915,10 +1956,6 @@ pub fn trans_fn(ccx: @mut CrateContext,
1915
1956
}
1916
1957
} ,
1917
1958
|_bcx| { } ) ;
1918
- if do_time {
1919
- let end = time:: get_time( ) ;
1920
- ccx. log_fn_time( the_path_str, start, end) ;
1921
- }
1922
1959
}
1923
1960
1924
1961
pub fn trans_enum_variant( ccx: @mut CrateContext ,
@@ -2983,8 +3020,14 @@ pub fn trans_crate(sess: session::Session,
2983
3020
io::println(fmt!(" n_monos: %u", ccx.stats.n_monos));
2984
3021
io::println(fmt!(" n_inlines: %u", ccx.stats.n_inlines));
2985
3022
io::println(fmt!(" n_closures: %u", ccx.stats.n_closures));
3023
+ io::println(" fn stats: ");
3024
+ do sort::quick_sort(ccx.stats.fn_stats) |&(_, _, insns_a), &(_, _, insns_b)| {
3025
+ insns_a > insns_b
3026
+ }
3027
+ for ccx.stats.fn_stats.iter().advance |&(name, ms, insns)| {
3028
+ io::println(fmt!(" %u insns, %u ms, %s", insns, ms, name));
3029
+ }
2986
3030
}
2987
-
2988
3031
if ccx.sess.count_llvm_insns() {
2989
3032
for ccx.stats.llvm_insns.iter().advance |(&k, &v)| {
2990
3033
io::println(fmt!(" %-7 u %s" , v, k) ) ;
0 commit comments