2020use std:: collections:: HashMap ;
2121use std:: iter:: Sum ;
2222use std:: mem;
23+ use std:: ops:: AddAssign ;
2324
2425use gazebo:: prelude:: * ;
2526
@@ -45,24 +46,55 @@ impl<'a> Sum<&'a BcInstrStat> for BcInstrStat {
4546 }
4647}
4748
49+ impl < ' a > AddAssign < & ' a BcInstrStat > for BcInstrStat {
50+ fn add_assign ( & mut self , other : & ' a BcInstrStat ) {
51+ let BcInstrStat { count } = other;
52+ self . count += count;
53+ }
54+ }
55+
4856#[ derive( Default , Clone , Copy , Dupe , Debug ) ]
4957struct BcInstrPairsStat {
5058 count : u64 ,
5159 // We are not measuring time here, because even time for single opcode
5260 // is not very accurate or helpful, and time for pairs is even less helpful.
5361}
5462
63+ impl < ' a > AddAssign < & ' a BcInstrPairsStat > for BcInstrPairsStat {
64+ fn add_assign ( & mut self , other : & ' a BcInstrPairsStat ) {
65+ let BcInstrPairsStat { count } = other;
66+ self . count += count;
67+ }
68+ }
69+
5570#[ derive( Clone , Debug ) ]
5671pub ( crate ) struct BcProfileData {
5772 by_instr : [ BcInstrStat ; BcOpcode :: COUNT ] ,
5873}
5974
75+ impl < ' a > AddAssign < & ' a BcProfileData > for BcProfileData {
76+ fn add_assign ( & mut self , rhs : & ' a BcProfileData ) {
77+ for ( lhs, rhs) in self . by_instr . iter_mut ( ) . zip ( rhs. by_instr . iter ( ) ) {
78+ * lhs += rhs;
79+ }
80+ }
81+ }
82+
6083#[ derive( Default , Clone , Debug ) ]
6184pub ( crate ) struct BcPairsProfileData {
6285 last : Option < BcOpcode > ,
6386 by_instr : HashMap < [ BcOpcode ; 2 ] , BcInstrPairsStat > ,
6487}
6588
89+ impl < ' a > AddAssign < & ' a BcPairsProfileData > for BcPairsProfileData {
90+ fn add_assign ( & mut self , rhs : & ' a BcPairsProfileData ) {
91+ self . last = None ;
92+ for ( pair, stat) in & rhs. by_instr {
93+ * self . by_instr . entry ( * pair) . or_default ( ) += stat;
94+ }
95+ }
96+ }
97+
6698// Derive doesn't work here.
6799impl Default for BcProfileData {
68100 fn default ( ) -> Self {
@@ -104,6 +136,14 @@ impl BcProfileData {
104136 }
105137 csv. finish ( )
106138 }
139+
140+ pub ( crate ) fn merge < ' a > ( iter : impl IntoIterator < Item = & ' a BcProfileData > ) -> BcProfileData {
141+ let mut sum = BcProfileData :: default ( ) ;
142+ for profile in iter {
143+ sum += profile;
144+ }
145+ sum
146+ }
107147}
108148
109149impl BcPairsProfileData {
@@ -138,6 +178,16 @@ impl BcPairsProfileData {
138178 }
139179 csv. finish ( )
140180 }
181+
182+ pub ( crate ) fn merge < ' a > (
183+ iter : impl IntoIterator < Item = & ' a BcPairsProfileData > ,
184+ ) -> BcPairsProfileData {
185+ let mut sum = BcPairsProfileData :: default ( ) ;
186+ for profile in iter {
187+ sum += profile;
188+ }
189+ sum
190+ }
141191}
142192
143193enum BcProfileDataMode {
@@ -210,6 +260,8 @@ mod tests {
210260 use crate :: environment:: Globals ;
211261 use crate :: environment:: Module ;
212262 use crate :: eval:: bc:: opcode:: BcOpcode ;
263+ use crate :: eval:: runtime:: profile:: bc:: BcPairsProfileData ;
264+ use crate :: eval:: runtime:: profile:: bc:: BcProfileData ;
213265 use crate :: eval:: Evaluator ;
214266 use crate :: eval:: ProfileMode ;
215267 use crate :: syntax:: AstModule ;
@@ -261,4 +313,18 @@ mod tests {
261313 csv
262314 ) ;
263315 }
316+
317+ #[ test]
318+ fn test_bc_profile_data_merge ( ) {
319+ let bc = BcProfileData :: default ( ) ;
320+ // Smoke test.
321+ BcProfileData :: merge ( [ & bc, & bc, & bc] ) ;
322+ }
323+
324+ #[ test]
325+ fn test_bc_pairs_profile_data_merge ( ) {
326+ let bc = BcPairsProfileData :: default ( ) ;
327+ // Smoke test.
328+ BcPairsProfileData :: merge ( [ & bc, & bc, & bc] ) ;
329+ }
264330}
0 commit comments