@@ -62,6 +62,7 @@ pub(super) struct CoverageCounters {
6262 /// corresponding operator (+ or -) and its LHS/RHS operands.
6363 expressions : IndexVec < ExpressionId , Expression > ,
6464
65+ expression_reference : FxHashMap < Expression , BcbCounter > ,
6566 /// Some terms referencing to composite expressions count sum execution times
6667 /// of several basic coverage blocks. Mostly such coverage terms are used by patterns including or pattern.
6768 /// Expressions for these terms should generate statements to some blocks in case
@@ -84,6 +85,7 @@ impl CoverageCounters {
8485 bcb_counters : IndexVec :: from_elem_n ( None , num_bcbs) ,
8586 bcb_edge_counters : FxHashMap :: default ( ) ,
8687 expressions : IndexVec :: new ( ) ,
88+ expression_reference : FxHashMap :: default ( ) ,
8789 combined_bcb_expressions : BTreeMap :: new ( ) ,
8890 } ;
8991
@@ -105,8 +107,37 @@ impl CoverageCounters {
105107 rhs : BcbCounter ,
106108 ) -> BcbCounter {
107109 let expression = Expression { lhs : lhs. as_term ( ) , op, rhs : rhs. as_term ( ) } ;
108- let id = self . expressions . push ( expression) ;
109- BcbCounter :: Expression { id }
110+ if let Some ( counter) = self . expression_reference . get ( & expression) {
111+ * counter
112+ } else {
113+ let counter = BcbCounter :: Expression { id : self . expressions . push ( expression. clone ( ) ) } ;
114+ self . expression_reference . insert ( expression, counter) ;
115+ // Later branches of pattern matching might try to make expression with C2 - (C2 - C1), (C2 - C1) + C1
116+ match ( lhs, op, rhs) {
117+ ( BcbCounter :: Counter { .. } , Op :: Add , BcbCounter :: Counter { .. } ) => {
118+ self . expression_reference . insert (
119+ Expression { lhs : counter. as_term ( ) , op : Op :: Subtract , rhs : lhs. as_term ( ) } ,
120+ rhs,
121+ ) ;
122+ self . expression_reference . insert (
123+ Expression { lhs : counter. as_term ( ) , op : Op :: Subtract , rhs : rhs. as_term ( ) } ,
124+ lhs,
125+ ) ;
126+ }
127+ ( BcbCounter :: Counter { .. } , Op :: Subtract , BcbCounter :: Counter { .. } ) => {
128+ self . expression_reference . insert (
129+ Expression { lhs : counter. as_term ( ) , op : Op :: Add , rhs : rhs. as_term ( ) } ,
130+ lhs,
131+ ) ;
132+ self . expression_reference . insert (
133+ Expression { lhs : lhs. as_term ( ) , op : Op :: Subtract , rhs : counter. as_term ( ) } ,
134+ rhs,
135+ ) ;
136+ }
137+ _ => { }
138+ }
139+ counter
140+ }
110141 }
111142
112143 /// Variant of `make_expression` that makes `lhs` optional and assumes [`Op::Add`].
0 commit comments