Skip to content

Commit 6605ff8

Browse files
committedJul 29, 2015
IR: Implement Value::mergeUseLists() iteratively
This avoids stack overflows when the the compiler does not perform tail call elimination. Apparently this happens for MSVC with the /Ob2 switch which may be used by external code including this header. Reported by and based on a patch from Jean-Francois Riendeau. Related to rdar://21900756 llvm-svn: 243590
1 parent 3393cfd commit 6605ff8

File tree

1 file changed

+22
-20
lines changed

1 file changed

+22
-20
lines changed
 

‎llvm/include/llvm/IR/Value.h

+22-20
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,28 @@ class Value {
493493
template <class Compare>
494494
static Use *mergeUseLists(Use *L, Use *R, Compare Cmp) {
495495
Use *Merged;
496-
mergeUseListsImpl(L, R, &Merged, Cmp);
496+
Use **Next = &Merged;
497+
498+
for (;;) {
499+
if (!L) {
500+
*Next = R;
501+
break;
502+
}
503+
if (!R) {
504+
*Next = L;
505+
break;
506+
}
507+
if (Cmp(*R, *L)) {
508+
*Next = R;
509+
Next = &R->Next;
510+
R = R->Next;
511+
} else {
512+
*Next = L;
513+
Next = &L->Next;
514+
L = L->Next;
515+
}
516+
}
517+
497518
return Merged;
498519
}
499520

@@ -586,25 +607,6 @@ template <class Compare> void Value::sortUseList(Compare Cmp) {
586607
}
587608
}
588609

589-
template <class Compare>
590-
void Value::mergeUseListsImpl(Use *L, Use *R, Use **Next, Compare Cmp) {
591-
if (!L) {
592-
*Next = R;
593-
return;
594-
}
595-
if (!R) {
596-
*Next = L;
597-
return;
598-
}
599-
if (Cmp(*R, *L)) {
600-
*Next = R;
601-
mergeUseListsImpl(L, R->Next, &R->Next, Cmp);
602-
return;
603-
}
604-
*Next = L;
605-
mergeUseListsImpl(L->Next, R, &L->Next, Cmp);
606-
}
607-
608610
// isa - Provide some specializations of isa so that we don't have to include
609611
// the subtype header files to test to see if the value is a subclass...
610612
//

0 commit comments

Comments
 (0)
Please sign in to comment.