@@ -167,27 +167,61 @@ void CounterMappingContext::dump(const Counter &C, raw_ostream &OS) const {
167
167
}
168
168
169
169
Expected<int64_t > CounterMappingContext::evaluate (const Counter &C) const {
170
- switch (C.getKind ()) {
171
- case Counter::Zero:
172
- return 0 ;
173
- case Counter::CounterValueReference:
174
- if (C.getCounterID () >= CounterValues.size ())
175
- return errorCodeToError (errc::argument_out_of_domain);
176
- return CounterValues[C.getCounterID ()];
177
- case Counter::Expression: {
178
- if (C.getExpressionID () >= Expressions.size ())
179
- return errorCodeToError (errc::argument_out_of_domain);
180
- const auto &E = Expressions[C.getExpressionID ()];
181
- Expected<int64_t > LHS = evaluate (E.LHS );
182
- if (!LHS)
183
- return LHS;
184
- Expected<int64_t > RHS = evaluate (E.RHS );
185
- if (!RHS)
186
- return RHS;
187
- return E.Kind == CounterExpression::Subtract ? *LHS - *RHS : *LHS + *RHS;
188
- }
170
+ struct StackElem {
171
+ Counter ICounter;
172
+ int64_t LHS = 0 ;
173
+ enum {
174
+ KNeverVisited = 0 ,
175
+ KVisitedOnce = 1 ,
176
+ KVisitedTwice = 2 ,
177
+ } VisitCount = KNeverVisited;
178
+ };
179
+
180
+ std::stack<StackElem> CounterStack;
181
+ CounterStack.push ({C});
182
+
183
+ int64_t LastPoppedValue;
184
+
185
+ while (!CounterStack.empty ()) {
186
+ StackElem &Current = CounterStack.top ();
187
+
188
+ switch (Current.ICounter .getKind ()) {
189
+ case Counter::Zero:
190
+ LastPoppedValue = 0 ;
191
+ CounterStack.pop ();
192
+ break ;
193
+ case Counter::CounterValueReference:
194
+ if (Current.ICounter .getCounterID () >= CounterValues.size ())
195
+ return errorCodeToError (errc::argument_out_of_domain);
196
+ LastPoppedValue = CounterValues[Current.ICounter .getCounterID ()];
197
+ CounterStack.pop ();
198
+ break ;
199
+ case Counter::Expression: {
200
+ if (Current.ICounter .getExpressionID () >= Expressions.size ())
201
+ return errorCodeToError (errc::argument_out_of_domain);
202
+ const auto &E = Expressions[Current.ICounter .getExpressionID ()];
203
+ if (Current.VisitCount == StackElem::KNeverVisited) {
204
+ CounterStack.push (StackElem{E.LHS });
205
+ Current.VisitCount = StackElem::KVisitedOnce;
206
+ } else if (Current.VisitCount == StackElem::KVisitedOnce) {
207
+ Current.LHS = LastPoppedValue;
208
+ CounterStack.push (StackElem{E.RHS });
209
+ Current.VisitCount = StackElem::KVisitedTwice;
210
+ } else {
211
+ int64_t LHS = Current.LHS ;
212
+ int64_t RHS = LastPoppedValue;
213
+ LastPoppedValue =
214
+ E.Kind == CounterExpression::Subtract ? LHS - RHS : LHS + RHS;
215
+ CounterStack.pop ();
216
+ }
217
+ break ;
218
+ }
219
+ default :
220
+ llvm_unreachable (" Unhandled CounterKind" );
221
+ }
189
222
}
190
- llvm_unreachable (" Unhandled CounterKind" );
223
+
224
+ return LastPoppedValue;
191
225
}
192
226
193
227
unsigned CounterMappingContext::getMaxCounterID (const Counter &C) const {
0 commit comments