1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

[WinEH] Moved funclet pads should be in relative order

We shifted the MachineBasicBlocks to the end of the MachineFunction in
DFS order.  This will not ensure that MachineBasicBlocks which fell
through to one another will remain contiguous.  Instead, implement
a stable sort algorithm for iplist.

This partially reverts commit r214150.

llvm-svn: 247978
This commit is contained in:
David Majnemer 2015-09-18 08:18:07 +00:00
parent 4c0fa3700e
commit 0f63c81aa5
3 changed files with 57 additions and 9 deletions

View File

@ -579,6 +579,53 @@ public:
void splice(iterator where, iplist &L2, iterator first, iterator last) { void splice(iterator where, iplist &L2, iterator first, iterator last) {
if (first != last) transfer(where, L2, first, last); if (first != last) transfer(where, L2, first, last);
} }
template <class Compare>
void merge(iplist &Right, Compare comp) {
if (this == &Right)
return;
iterator First1 = begin(), Last1 = end();
iterator First2 = Right.begin(), Last2 = Right.end();
while (First1 != Last1 && First2 != Last2) {
if (comp(*First2, *First1)) {
iterator Next = First2;
transfer(First1, Right, First2, ++Next);
First2 = Next;
} else {
++First1;
}
}
if (First2 != Last2)
transfer(Last1, Right, First2, Last2);
}
void merge(iplist &Right) { return merge(Right, op_less); }
template <class Compare>
void sort(Compare comp) {
// The list is empty, vacuously sorted.
if (empty())
return;
// The list has a single element, vacuously sorted.
if (std::next(begin()) == end())
return;
// Find the split point for the list.
iterator Center = begin(), End = begin();
while (End != end() && std::next(End) != end()) {
Center = std::next(Center);
End = std::next(std::next(End));
}
// Split the list into two.
iplist RightHalf;
RightHalf.splice(RightHalf.begin(), *this, Center, end());
// Sort the two sublists.
sort(comp);
RightHalf.sort(comp);
// Merge the two sublists back together.
merge(RightHalf, comp);
}
void sort() { sort(op_less); }
}; };

View File

@ -375,6 +375,11 @@ public:
BasicBlocks.erase(MBBI); BasicBlocks.erase(MBBI);
} }
template <typename Comp>
void sort(Comp comp) {
BasicBlocks.sort(comp);
}
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Internal functions used to automatically number MachineBasicBlocks // Internal functions used to automatically number MachineBasicBlocks
// //

View File

@ -12,7 +12,6 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/Passes.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
@ -34,7 +33,7 @@ public:
} }
static void static void
collectFuncletMembers(MapVector<MachineBasicBlock *, int> &FuncletMembership, collectFuncletMembers(DenseMap<MachineBasicBlock *, int> &FuncletMembership,
int Funclet, MachineBasicBlock *MBB) { int Funclet, MachineBasicBlock *MBB) {
// Don't revisit blocks. // Don't revisit blocks.
if (FuncletMembership.count(MBB) > 0) if (FuncletMembership.count(MBB) > 0)
@ -81,16 +80,13 @@ bool FuncletLayout::runOnMachineFunction(MachineFunction &F) {
if (FuncletBlocks.empty()) if (FuncletBlocks.empty())
return false; return false;
MapVector<MachineBasicBlock *, int> FuncletMembership; DenseMap<MachineBasicBlock *, int> FuncletMembership;
for (MachineBasicBlock *MBB : FuncletBlocks) for (MachineBasicBlock *MBB : FuncletBlocks)
collectFuncletMembers(FuncletMembership, MBB->getNumber(), MBB); collectFuncletMembers(FuncletMembership, MBB->getNumber(), MBB);
for (std::pair<llvm::MachineBasicBlock *, int> &FuncletMember : F.sort([&](MachineBasicBlock &x, MachineBasicBlock &y) {
FuncletMembership) { return FuncletMembership[&x] < FuncletMembership[&y];
// Move this block to the end of the function. });
MachineBasicBlock *MBB = FuncletMember.first;
MBB->moveAfter(--F.end());
}
// Conservatively assume we changed something. // Conservatively assume we changed something.
return true; return true;