20
20
use std:: collections:: HashMap ;
21
21
use std:: iter:: Sum ;
22
22
use std:: mem;
23
+ use std:: ops:: AddAssign ;
23
24
24
25
use gazebo:: prelude:: * ;
25
26
@@ -45,24 +46,55 @@ impl<'a> Sum<&'a BcInstrStat> for BcInstrStat {
45
46
}
46
47
}
47
48
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
+
48
56
#[ derive( Default , Clone , Copy , Dupe , Debug ) ]
49
57
struct BcInstrPairsStat {
50
58
count : u64 ,
51
59
// We are not measuring time here, because even time for single opcode
52
60
// is not very accurate or helpful, and time for pairs is even less helpful.
53
61
}
54
62
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
+
55
70
#[ derive( Clone , Debug ) ]
56
71
pub ( crate ) struct BcProfileData {
57
72
by_instr : [ BcInstrStat ; BcOpcode :: COUNT ] ,
58
73
}
59
74
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
+
60
83
#[ derive( Default , Clone , Debug ) ]
61
84
pub ( crate ) struct BcPairsProfileData {
62
85
last : Option < BcOpcode > ,
63
86
by_instr : HashMap < [ BcOpcode ; 2 ] , BcInstrPairsStat > ,
64
87
}
65
88
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
+
66
98
// Derive doesn't work here.
67
99
impl Default for BcProfileData {
68
100
fn default ( ) -> Self {
@@ -104,6 +136,14 @@ impl BcProfileData {
104
136
}
105
137
csv. finish ( )
106
138
}
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
+ }
107
147
}
108
148
109
149
impl BcPairsProfileData {
@@ -138,6 +178,16 @@ impl BcPairsProfileData {
138
178
}
139
179
csv. finish ( )
140
180
}
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
+ }
141
191
}
142
192
143
193
enum BcProfileDataMode {
@@ -210,6 +260,8 @@ mod tests {
210
260
use crate :: environment:: Globals ;
211
261
use crate :: environment:: Module ;
212
262
use crate :: eval:: bc:: opcode:: BcOpcode ;
263
+ use crate :: eval:: runtime:: profile:: bc:: BcPairsProfileData ;
264
+ use crate :: eval:: runtime:: profile:: bc:: BcProfileData ;
213
265
use crate :: eval:: Evaluator ;
214
266
use crate :: eval:: ProfileMode ;
215
267
use crate :: syntax:: AstModule ;
@@ -261,4 +313,18 @@ mod tests {
261
313
csv
262
314
) ;
263
315
}
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
+ }
264
330
}
0 commit comments