@@ -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 {
@@ -1866,18 +1909,16 @@ pub fn trans_fn(ccx: @mut CrateContext,
1866
1909
param_substs: Option <@param_substs>,
1867
1910
id: ast:: node_id,
1868
1911
attrs: & [ ast:: attribute] ) {
1869
- let do_time = ccx . sess . trans_stats ( ) ;
1870
- let start = if do_time { time :: get_time ( ) }
1871
- else { time :: Timespec :: new( 0 , 0 ) } ;
1912
+
1913
+ let the_path_str = path_str ( ccx . sess , path ) ;
1914
+ let _s = StatRecorder :: new( ccx , the_path_str ) ;
1872
1915
debug!( "trans_fn(self_arg=%?, param_substs=%s)" ,
1873
1916
self_arg,
1874
1917
param_substs. repr( ccx. tcx) ) ;
1875
1918
let _icx = push_ctxt( "trans_fn" ) ;
1876
- ccx. stats. n_fns += 1 ;
1877
- let the_path_str = path_str( ccx. sess, path) ;
1878
1919
let output_type = ty:: ty_fn_ret( ty:: node_id_to_type( ccx. tcx, id) ) ;
1879
1920
trans_closure( ccx,
1880
- path,
1921
+ copy path,
1881
1922
decl,
1882
1923
body,
1883
1924
llfndecl,
@@ -1893,10 +1934,6 @@ pub fn trans_fn(ccx: @mut CrateContext,
1893
1934
}
1894
1935
} ,
1895
1936
|_bcx| { } ) ;
1896
- if do_time {
1897
- let end = time:: get_time( ) ;
1898
- ccx. log_fn_time( the_path_str, start, end) ;
1899
- }
1900
1937
}
1901
1938
1902
1939
pub fn trans_enum_variant( ccx: @mut CrateContext ,
@@ -2961,8 +2998,14 @@ pub fn trans_crate(sess: session::Session,
2961
2998
io::println(fmt!(" n_monos: %u", ccx.stats.n_monos));
2962
2999
io::println(fmt!(" n_inlines: %u", ccx.stats.n_inlines));
2963
3000
io::println(fmt!(" n_closures: %u", ccx.stats.n_closures));
3001
+ io::println(" fn stats: ");
3002
+ do sort::quick_sort(ccx.stats.fn_stats) |&(_, _, insns_a), &(_, _, insns_b)| {
3003
+ insns_a > insns_b
3004
+ }
3005
+ for ccx.stats.fn_stats.iter().advance |&(name, ms, insns)| {
3006
+ io::println(fmt!(" %u insns, %u ms, %s", insns, ms, name));
3007
+ }
2964
3008
}
2965
-
2966
3009
if ccx.sess.count_llvm_insns() {
2967
3010
for ccx.stats.llvm_insns.iter().advance |(&k, &v)| {
2968
3011
io::println(fmt!(" %-7 u %s" , v, k) ) ;
0 commit comments