[llvm-branch-commits] [llvm] 4e4df1e - [WebAssembly] Remove unreachable EH pads
Heejin Ahn via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Jan 9 03:47:37 PST 2021
Author: Heejin Ahn
Date: 2021-01-09T03:42:38-08:00
New Revision: 4e4df1e38d6b66083b3badb78e56b8b0f6045fd1
URL: https://github.com/llvm/llvm-project/commit/4e4df1e38d6b66083b3badb78e56b8b0f6045fd1
DIFF: https://github.com/llvm/llvm-project/commit/4e4df1e38d6b66083b3badb78e56b8b0f6045fd1.diff
LOG: [WebAssembly] Remove unreachable EH pads
This removes unreachable EH pads in LateEHPrepare. This is not for
optimization but for preparation for CFGStackify. In CFGStackify, we
determine where to place `try` marker by computing the nearest common
dominator of all predecessors of an EH pad, but when an EH pad does not
have a predecessor, it becomes tricky. We can insert an empty dummy BB
before the EH pad and place the `try` there, but removing unreachable EH
pads is simpler.
This moves an existing exception label test from eh-label.mir to
exception.mir and adds a new test there.
This also adds some comments to existing methods.
Reviewed By: dschuff, tlively
Differential Revision: https://reviews.llvm.org/D94044
Added:
llvm/test/CodeGen/WebAssembly/exception.mir
Modified:
llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
Removed:
llvm/test/CodeGen/WebAssembly/eh-labels.mir
################################################################################
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
index 5501af0b2bbd..a0201b199612 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
@@ -15,7 +15,7 @@
#include "WebAssembly.h"
#include "WebAssemblySubtarget.h"
#include "WebAssemblyUtilities.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/WasmEHFuncInfo.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -32,6 +32,7 @@ class WebAssemblyLateEHPrepare final : public MachineFunctionPass {
}
bool runOnMachineFunction(MachineFunction &MF) override;
+ bool removeUnreachableEHPads(MachineFunction &MF);
void recordCatchRetBBs(MachineFunction &MF);
bool hoistCatches(MachineFunction &MF);
bool addCatchAlls(MachineFunction &MF);
@@ -40,7 +41,7 @@ class WebAssemblyLateEHPrepare final : public MachineFunctionPass {
bool restoreStackPointer(MachineFunction &MF);
MachineBasicBlock *getMatchingEHPad(MachineInstr *MI);
- SmallSet<MachineBasicBlock *, 8> CatchRetBBs;
+ SmallPtrSet<MachineBasicBlock *, 8> CatchRetBBs;
public:
static char ID; // Pass identification, replacement for typeid
@@ -94,14 +95,18 @@ WebAssemblyLateEHPrepare::getMatchingEHPad(MachineInstr *MI) {
template <typename Container>
static void eraseDeadBBsAndChildren(const Container &MBBs) {
SmallVector<MachineBasicBlock *, 8> WL(MBBs.begin(), MBBs.end());
+ SmallPtrSet<MachineBasicBlock *, 8> Deleted;
while (!WL.empty()) {
MachineBasicBlock *MBB = WL.pop_back_val();
- if (!MBB->pred_empty())
+ if (Deleted.count(MBB) || !MBB->pred_empty())
continue;
SmallVector<MachineBasicBlock *, 4> Succs(MBB->successors());
WL.append(MBB->succ_begin(), MBB->succ_end());
for (auto *Succ : Succs)
MBB->removeSuccessor(Succ);
+ // To prevent deleting the same BB multiple times, which can happen when
+ // 'MBBs' contain both a parent and a child
+ Deleted.insert(MBB);
MBB->eraseFromParent();
}
}
@@ -117,6 +122,7 @@ bool WebAssemblyLateEHPrepare::runOnMachineFunction(MachineFunction &MF) {
bool Changed = false;
if (MF.getFunction().hasPersonalityFn()) {
+ Changed |= removeUnreachableEHPads(MF);
recordCatchRetBBs(MF);
Changed |= hoistCatches(MF);
Changed |= addCatchAlls(MF);
@@ -128,9 +134,20 @@ bool WebAssemblyLateEHPrepare::runOnMachineFunction(MachineFunction &MF) {
return Changed;
}
-// Record which BB ends with 'CATCHRET' instruction, because this will be
-// replaced with BRs later. This set of 'CATCHRET' BBs is necessary in
-// 'getMatchingEHPad' function.
+// Remove unreachable EH pads and its children. If they remain, CFG
+// stackification can be tricky.
+bool WebAssemblyLateEHPrepare::removeUnreachableEHPads(MachineFunction &MF) {
+ SmallVector<MachineBasicBlock *, 4> ToDelete;
+ for (auto &MBB : MF)
+ if (MBB.isEHPad() && MBB.pred_empty())
+ ToDelete.push_back(&MBB);
+ eraseDeadBBsAndChildren(ToDelete);
+ return !ToDelete.empty();
+}
+
+// Record which BB ends with catchret instruction, because this will be replaced
+// with 'br's later. This set of catchret BBs is necessary in 'getMatchingEHPad'
+// function.
void WebAssemblyLateEHPrepare::recordCatchRetBBs(MachineFunction &MF) {
CatchRetBBs.clear();
for (auto &MBB : MF) {
@@ -204,6 +221,8 @@ bool WebAssemblyLateEHPrepare::addCatchAlls(MachineFunction &MF) {
return Changed;
}
+// Replace pseudo-instructions catchret and cleanupret with br and rethrow
+// respectively.
bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) {
bool Changed = false;
const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
@@ -239,6 +258,7 @@ bool WebAssemblyLateEHPrepare::replaceFuncletReturns(MachineFunction &MF) {
return Changed;
}
+// Remove unnecessary unreachables after a throw or rethrow.
bool WebAssemblyLateEHPrepare::removeUnnecessaryUnreachables(
MachineFunction &MF) {
bool Changed = false;
diff --git a/llvm/test/CodeGen/WebAssembly/eh-labels.mir b/llvm/test/CodeGen/WebAssembly/exception.mir
similarity index 64%
rename from llvm/test/CodeGen/WebAssembly/eh-labels.mir
rename to llvm/test/CodeGen/WebAssembly/exception.mir
index 105b21acc4f7..0548123f315b 100644
--- a/llvm/test/CodeGen/WebAssembly/eh-labels.mir
+++ b/llvm/test/CodeGen/WebAssembly/exception.mir
@@ -1,7 +1,5 @@
# RUN: llc -mtriple=wasm32-unknown-unknown -exception-model=wasm -mattr=+exception-handling -run-pass wasm-late-eh-prepare -run-pass wasm-cfg-stackify %s -o - | FileCheck %s
-# This tests 'try' and 'catch' instructions are correctly placed with respect to
-# EH_LABEL instructions.
--- |
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
@@ -11,10 +9,15 @@
define void @eh_label_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
ret void
}
+ define void @unreachable_ehpad_test() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
+ ret void
+ }
...
---
-# CHECK-LABEL: eh_label_test
+# This tests 'try' and 'catch' instructions are correctly placed with respect to
+# EH_LABEL instructions.
+# CHECK-LABEL: name: eh_label_test
name: eh_label_test
liveins:
- { reg: '$arguments' }
@@ -44,3 +47,27 @@ body: |
; predecessors: %bb.0, %bb.1
RETURN implicit-def dead $arguments
...
+---
+# Unreachable EH pads should be removed by LateEHPrepare.
+# CHECK-LABEL: name: unreachable_ehpad_test
+name: unreachable_ehpad_test
+liveins:
+ - { reg: '$arguments' }
+body: |
+ ; CHECK: bb.0
+ bb.0:
+ successors: %bb.2
+ BR %bb.2, implicit-def dead $arguments
+
+ ; This EH pad is unreachable, so it should be removed by LateEHPrepare
+ ; CHECK-NOT: bb.1 (landing-pad)
+ bb.1 (landing-pad):
+ successors: %bb.2
+ EH_LABEL <mcsymbol .Ltmp2>
+ CATCHRET %bb.2, %bb.0, implicit-def dead $arguments
+
+ ; CHECK: bb.2
+ bb.2:
+ ; predecessors: %bb.0, %bb.1
+ RETURN implicit-def dead $arguments
+...
More information about the llvm-branch-commits
mailing list