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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243590 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matthias Braun 2015-07-29 23:22:48 +00:00
parent 7fe1972500
commit 6821f63c91

View File

@ -493,7 +493,28 @@ private:
template <class Compare>
static Use *mergeUseLists(Use *L, Use *R, Compare Cmp) {
Use *Merged;
mergeUseListsImpl(L, R, &Merged, Cmp);
Use **Next = &Merged;
for (;;) {
if (!L) {
*Next = R;
break;
}
if (!R) {
*Next = L;
break;
}
if (Cmp(*R, *L)) {
*Next = R;
Next = &R->Next;
R = R->Next;
} else {
*Next = L;
Next = &L->Next;
L = L->Next;
}
}
return Merged;
}
@ -586,25 +607,6 @@ template <class Compare> void Value::sortUseList(Compare Cmp) {
}
}
template <class Compare>
void Value::mergeUseListsImpl(Use *L, Use *R, Use **Next, Compare Cmp) {
if (!L) {
*Next = R;
return;
}
if (!R) {
*Next = L;
return;
}
if (Cmp(*R, *L)) {
*Next = R;
mergeUseListsImpl(L, R->Next, &R->Next, Cmp);
return;
}
*Next = L;
mergeUseListsImpl(L->Next, R, &L->Next, Cmp);
}
// isa - Provide some specializations of isa so that we don't have to include
// the subtype header files to test to see if the value is a subclass...
//