Skip to content

Commit 3f417a7

Browse files
shen3qing1Qing Shen
andauthored
[NFC] [Coverage] Do not use recursion for getMaxCounterID (llvm#67870)
This causes stack overflows for real-world coverage reports. Tested with build/bin/llvm-lit -a llvm/test/tools/llvm-cov Co-authored-by: Qing Shen <[email protected]>
1 parent d0d6083 commit 3f417a7

File tree

1 file changed

+52
-12
lines changed

1 file changed

+52
-12
lines changed

llvm/lib/ProfileData/Coverage/CoverageMapping.cpp

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -223,19 +223,59 @@ Expected<int64_t> CounterMappingContext::evaluate(const Counter &C) const {
223223
}
224224

225225
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+
}
237276
}
238-
llvm_unreachable("Unhandled CounterKind");
277+
278+
return LastPoppedValue;
239279
}
240280

241281
void FunctionRecordIterator::skipOtherFiles() {

0 commit comments

Comments
 (0)