@@ -223,19 +223,59 @@ Expected<int64_t> CounterMappingContext::evaluate(const Counter &C) const {
223
223
}
224
224
225
225
unsigned CounterMappingContext::getMaxCounterID (const Counter &C) const {
226
- switch (C.getKind ()) {
227
- case Counter::Zero:
228
- return 0 ;
229
- case Counter::CounterValueReference:
230
- return C.getCounterID ();
231
- case Counter::Expression: {
232
- if (C.getExpressionID () >= Expressions.size ())
233
- return 0 ;
234
- const auto &E = Expressions[C.getExpressionID ()];
235
- return std::max (getMaxCounterID (E.LHS ), getMaxCounterID (E.RHS ));
236
- }
226
+ struct StackElem {
227
+ Counter ICounter;
228
+ int64_t LHS = 0 ;
229
+ enum {
230
+ KNeverVisited = 0 ,
231
+ KVisitedOnce = 1 ,
232
+ KVisitedTwice = 2 ,
233
+ } VisitCount = KNeverVisited;
234
+ };
235
+
236
+ std::stack<StackElem> CounterStack;
237
+ CounterStack.push ({C});
238
+
239
+ int64_t LastPoppedValue;
240
+
241
+ while (!CounterStack.empty ()) {
242
+ StackElem &Current = CounterStack.top ();
243
+
244
+ switch (Current.ICounter .getKind ()) {
245
+ case Counter::Zero:
246
+ LastPoppedValue = 0 ;
247
+ CounterStack.pop ();
248
+ break ;
249
+ case Counter::CounterValueReference:
250
+ LastPoppedValue = Current.ICounter .getCounterID ();
251
+ CounterStack.pop ();
252
+ break ;
253
+ case Counter::Expression: {
254
+ if (Current.ICounter .getExpressionID () >= Expressions.size ()) {
255
+ LastPoppedValue = 0 ;
256
+ CounterStack.pop ();
257
+ } else {
258
+ const auto &E = Expressions[Current.ICounter .getExpressionID ()];
259
+ if (Current.VisitCount == StackElem::KNeverVisited) {
260
+ CounterStack.push (StackElem{E.LHS });
261
+ Current.VisitCount = StackElem::KVisitedOnce;
262
+ } else if (Current.VisitCount == StackElem::KVisitedOnce) {
263
+ Current.LHS = LastPoppedValue;
264
+ CounterStack.push (StackElem{E.RHS });
265
+ Current.VisitCount = StackElem::KVisitedTwice;
266
+ } else {
267
+ int64_t LHS = Current.LHS ;
268
+ int64_t RHS = LastPoppedValue;
269
+ LastPoppedValue = std::max (LHS, RHS);
270
+ CounterStack.pop ();
271
+ }
272
+ }
273
+ break ;
274
+ }
275
+ }
237
276
}
238
- llvm_unreachable (" Unhandled CounterKind" );
277
+
278
+ return LastPoppedValue;
239
279
}
240
280
241
281
void FunctionRecordIterator::skipOtherFiles () {
0 commit comments