summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
diff options
context:
space:
mode:
authorHeejin Ahn <aheejin@gmail.com>2018-11-16 00:47:18 +0000
committerHeejin Ahn <aheejin@gmail.com>2018-11-16 00:47:18 +0000
commit095796a391e5e8343ce462ce97fdc493d20478cd (patch)
tree53daa4333ce0a05d5da5f3b9b8998d4ed88ef4c9 /llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
parent2f5683e6b0d3c7348929e05a2a781690e598c533 (diff)
downloadbcm5719-llvm-095796a391e5e8343ce462ce97fdc493d20478cd.tar.gz
bcm5719-llvm-095796a391e5e8343ce462ce97fdc493d20478cd.zip
[WebAssembly] Split BBs after throw instructions
Summary: `throw` instruction is a terminator in wasm, but BBs were not splitted after `throw` instructions, causing machine instruction verifier to fail. This patch - Splits BBs after `throw` instructions in WasmEHPrepare and adding an unreachable instruction after `throw`, which will be deleted in LateEHPrepare pass - Refactors WasmEHPrepare into two member functions - Changes the semantics of `eraseBBsAndChildren` in LateEHPrepare pass to match that of WasmEHPrepare pass, which is newly added. Now `eraseBBsAndChildren` does not delete BBs with remaining predecessors. - Fixes style nits, making static function names conform to clang-tidy - Re-enables the test temporarily disabled by rL346840 && rL346845 Reviewers: dschuff Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D54571 llvm-svn: 347003
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp58
1 files changed, 44 insertions, 14 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
index 98953f09482..871e92082a4 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
@@ -31,6 +31,7 @@ class WebAssemblyLateEHPrepare final : public MachineFunctionPass {
bool runOnMachineFunction(MachineFunction &MF) override;
+ bool removeUnnecessaryUnreachables(MachineFunction &MF);
bool replaceFuncletReturns(MachineFunction &MF);
bool hoistCatches(MachineFunction &MF);
bool addCatchAlls(MachineFunction &MF);
@@ -59,7 +60,7 @@ FunctionPass *llvm::createWebAssemblyLateEHPrepare() {
// possible search paths should be the same.
// Returns nullptr in case it does not find any EH pad in the search, or finds
// multiple different EH pads.
-static MachineBasicBlock *GetMatchingEHPad(MachineInstr *MI) {
+static MachineBasicBlock *getMatchingEHPad(MachineInstr *MI) {
MachineFunction *MF = MI->getParent()->getParent();
SmallVector<MachineBasicBlock *, 2> WL;
SmallPtrSet<MachineBasicBlock *, 2> Visited;
@@ -83,18 +84,15 @@ static MachineBasicBlock *GetMatchingEHPad(MachineInstr *MI) {
return EHPad;
}
-// Erases the given BBs and all their children from the function. If other BBs
-// have the BB as a successor, the successor relationships will be deleted as
-// well.
+// Erase the specified BBs if the BB does not have any remaining predecessors,
+// and also all its dead children.
template <typename Container>
-static void EraseBBsAndChildren(const Container &MBBs) {
+static void eraseDeadBBsAndChildren(const Container &MBBs) {
SmallVector<MachineBasicBlock *, 8> WL(MBBs.begin(), MBBs.end());
while (!WL.empty()) {
MachineBasicBlock *MBB = WL.pop_back_val();
- SmallVector<MachineBasicBlock *, 4> Preds(MBB->pred_begin(),
- MBB->pred_end());
- for (auto *Pred : Preds)
- Pred->removeSuccessor(MBB);
+ if (!MBB->pred_empty())
+ continue;
SmallVector<MachineBasicBlock *, 4> Succs(MBB->succ_begin(),
MBB->succ_end());
WL.append(MBB->succ_begin(), MBB->succ_end());
@@ -110,6 +108,7 @@ bool WebAssemblyLateEHPrepare::runOnMachineFunction(MachineFunction &MF) {
return false;
bool Changed = false;
+ Changed |= removeUnnecessaryUnreachables(MF);
Changed |= addRethrows(MF);
if (!MF.getFunction().hasPersonalityFn())
return Changed;
@@ -122,6 +121,31 @@ bool WebAssemblyLateEHPrepare::runOnMachineFunction(MachineFunction &MF) {
return Changed;
}
+bool WebAssemblyLateEHPrepare::removeUnnecessaryUnreachables(
+ MachineFunction &MF) {
+ bool Changed = false;
+ for (auto &MBB : MF) {
+ for (auto &MI : MBB) {
+ if (!WebAssembly::isThrow(MI))
+ continue;
+ Changed = true;
+
+ // The instruction after the throw should be an unreachable or a branch to
+ // another BB that should eventually lead to an unreachable. Delete it
+ // because throw itself is a terminator, and also delete successors if
+ // any.
+ MBB.erase(std::next(MachineBasicBlock::iterator(MI)), MBB.end());
+ SmallVector<MachineBasicBlock *, 8> Succs(MBB.succ_begin(),
+ MBB.succ_end());
+ for (auto *Succ : Succs)
+ MBB.removeSuccessor(Succ);
+ eraseDeadBBsAndChildren(Succs);
+ }
+ }
+
+ return Changed;
+}
+
bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) {
bool Changed = false;
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
@@ -183,7 +207,7 @@ bool WebAssemblyLateEHPrepare::hoistCatches(MachineFunction &MF) {
Catches.push_back(&MI);
for (auto *Catch : Catches) {
- MachineBasicBlock *EHPad = GetMatchingEHPad(Catch);
+ MachineBasicBlock *EHPad = getMatchingEHPad(Catch);
assert(EHPad && "No matching EH pad for catch");
if (EHPad->begin() == Catch)
continue;
@@ -242,7 +266,7 @@ bool WebAssemblyLateEHPrepare::addRethrows(MachineFunction &MF) {
Rethrow = BuildMI(MBB, InsertPt, MI.getDebugLoc(),
TII.get(WebAssembly::RETHROW_TO_CALLER));
- // Becasue __cxa_rethrow does not return, the instruction after the
+ // Because __cxa_rethrow does not return, the instruction after the
// rethrow should be an unreachable or a branch to another BB that should
// eventually lead to an unreachable. Delete it because rethrow itself is
// a terminator, and also delete non-EH pad successors if any.
@@ -251,7 +275,9 @@ bool WebAssemblyLateEHPrepare::addRethrows(MachineFunction &MF) {
for (auto *Succ : MBB.successors())
if (!Succ->isEHPad())
NonPadSuccessors.push_back(Succ);
- EraseBBsAndChildren(NonPadSuccessors);
+ for (auto *Succ : NonPadSuccessors)
+ MBB.removeSuccessor(Succ);
+ eraseDeadBBsAndChildren(NonPadSuccessors);
}
return Changed;
}
@@ -283,7 +309,7 @@ bool WebAssemblyLateEHPrepare::ensureSingleBBTermPads(MachineFunction &MF) {
bool Changed = false;
for (auto *Call : ClangCallTerminateCalls) {
- MachineBasicBlock *EHPad = GetMatchingEHPad(Call);
+ MachineBasicBlock *EHPad = getMatchingEHPad(Call);
assert(EHPad && "No matching EH pad for catch");
// If it is already the form we want, skip it
@@ -308,7 +334,11 @@ bool WebAssemblyLateEHPrepare::ensureSingleBBTermPads(MachineFunction &MF) {
BuildMI(*EHPad, InsertPos, Call->getDebugLoc(),
TII.get(WebAssembly::UNREACHABLE));
EHPad->erase(InsertPos, EHPad->end());
- EraseBBsAndChildren(EHPad->successors());
+ SmallVector<MachineBasicBlock *, 8> Succs(EHPad->succ_begin(),
+ EHPad->succ_end());
+ for (auto *Succ : Succs)
+ EHPad->removeSuccessor(Succ);
+ eraseDeadBBsAndChildren(Succs);
}
return Changed;
}
OpenPOWER on IntegriCloud