diff options
| author | Heejin Ahn <aheejin@gmail.com> | 2018-11-16 00:47:18 +0000 |
|---|---|---|
| committer | Heejin Ahn <aheejin@gmail.com> | 2018-11-16 00:47:18 +0000 |
| commit | 095796a391e5e8343ce462ce97fdc493d20478cd (patch) | |
| tree | 53daa4333ce0a05d5da5f3b9b8998d4ed88ef4c9 /llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp | |
| parent | 2f5683e6b0d3c7348929e05a2a781690e598c533 (diff) | |
| download | bcm5719-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.cpp | 58 |
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; } |

