[llvm] 5afdd64 - [WebAssembly] Update InstPrinter and AsmParser for new EH instructions
Heejin Ahn via llvm-commits
llvm-commits at lists.llvm.org
Sat Feb 6 08:55:13 PST 2021
Author: Heejin Ahn
Date: 2021-02-06T08:54:56-08:00
New Revision: 5afdd64a535cf0a7ff31950f76ccae194d9fbe3f
URL: https://github.com/llvm/llvm-project/commit/5afdd64a535cf0a7ff31950f76ccae194d9fbe3f
DIFF: https://github.com/llvm/llvm-project/commit/5afdd64a535cf0a7ff31950f76ccae194d9fbe3f.diff
LOG: [WebAssembly] Update InstPrinter and AsmParser for new EH instructions
This updates InstPrinter and AsmParser for `delegate` and `catch_all`
instructions. Both will reject programs with multiple `catch_all`s per a
single `try`. And InstPrinter uses `EHInstStack` to figure out whether
to print catch label comments: It does not print catch label comments
for second `catch` or `catch_all` in a `try`.
Reviewed By: aardappel
Differential Revision: https://reviews.llvm.org/D94051
Added:
Modified:
llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
llvm/test/MC/WebAssembly/annotations.s
llvm/test/MC/WebAssembly/basic-assembly-errors.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index 0328381f9e8a..9a2ae0100b50 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -216,6 +216,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
Block,
Loop,
Try,
+ CatchAll,
If,
Else,
Undefined,
@@ -273,7 +274,9 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
case Loop:
return {"loop", "end_loop"};
case Try:
- return {"try", "end_try"};
+ return {"try", "end_try/delegate"};
+ case CatchAll:
+ return {"catch_all", "end_try"};
case If:
return {"if", "end_if"};
case Else:
@@ -533,10 +536,17 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
if (pop(Name, Try))
return true;
push(Try);
+ } else if (Name == "catch_all") {
+ if (pop(Name, Try))
+ return true;
+ push(CatchAll);
} else if (Name == "end_if") {
if (pop(Name, If, Else))
return true;
} else if (Name == "end_try") {
+ if (pop(Name, Try, CatchAll))
+ return true;
+ } else if (Name == "delegate") {
if (pop(Name, Try))
return true;
} else if (Name == "end_loop") {
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
index 1df3574e703a..c4d0f2a27948 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -108,6 +108,7 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
ControlFlowStack.push_back(std::make_pair(ControlFlowCounter, false));
EHPadStack.push_back(ControlFlowCounter);
DelegateStack.push_back(ControlFlowCounter++);
+ EHInstStack.push_back(TRY);
return;
case WebAssembly::END_LOOP:
@@ -133,11 +134,12 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
case WebAssembly::END_TRY:
case WebAssembly::END_TRY_S:
- if (ControlFlowStack.empty()) {
+ if (ControlFlowStack.empty() || EHInstStack.empty()) {
printAnnotation(OS, "End marker mismatch!");
} else {
printAnnotation(
OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');
+ EHInstStack.pop_back();
}
return;
@@ -145,11 +147,26 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
case WebAssembly::CATCH_S:
case WebAssembly::CATCH_ALL:
case WebAssembly::CATCH_ALL_S:
- if (EHPadStack.empty() || DelegateStack.empty()) {
+ // There can be multiple catch instructions for one try instruction, so
+ // we print a label only for the first 'catch' label.
+ if (EHInstStack.empty()) {
printAnnotation(OS, "try-catch mismatch!");
- } else {
- printAnnotation(OS, "catch" + utostr(EHPadStack.pop_back_val()) + ':');
- DelegateStack.pop_back();
+ } else if (EHInstStack.back() == CATCH_ALL) {
+ printAnnotation(OS, "catch/catch_all cannot occur after catch_all");
+ } else if (EHInstStack.back() == TRY) {
+ if (EHPadStack.empty() || DelegateStack.empty()) {
+ printAnnotation(OS, "try-catch mismatch!");
+ } else {
+ printAnnotation(OS,
+ "catch" + utostr(EHPadStack.pop_back_val()) + ':');
+ DelegateStack.pop_back();
+ }
+ EHInstStack.pop_back();
+ if (Opc == WebAssembly::CATCH || Opc == WebAssembly::CATCH_S) {
+ EHInstStack.push_back(CATCH);
+ } else {
+ EHInstStack.push_back(CATCH_ALL);
+ }
}
return;
@@ -167,7 +184,7 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
case WebAssembly::DELEGATE:
case WebAssembly::DELEGATE_S:
if (ControlFlowStack.empty() || EHPadStack.empty() ||
- DelegateStack.empty()) {
+ DelegateStack.empty() || EHInstStack.empty()) {
printAnnotation(OS, "try-delegate mismatch!");
} else {
// 'delegate' is
@@ -181,6 +198,7 @@ void WebAssemblyInstPrinter::printInst(const MCInst *MI, uint64_t Address,
": ";
EHPadStack.pop_back();
DelegateStack.pop_back();
+ EHInstStack.pop_back();
uint64_t Depth = MI->getOperand(0).getImm();
if (Depth >= DelegateStack.size()) {
Label += "to caller";
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
index e0306bb49e91..5c6f9775ac49 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
@@ -33,6 +33,9 @@ class WebAssemblyInstPrinter final : public MCInstPrinter {
// separate stack for 'delegate'.
SmallVector<uint64_t, 4> DelegateStack;
+ enum EHInstKind { TRY, CATCH, CATCH_ALL };
+ SmallVector<EHInstKind, 4> EHInstStack;
+
public:
WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
const MCRegisterInfo &MRI);
diff --git a/llvm/test/MC/WebAssembly/annotations.s b/llvm/test/MC/WebAssembly/annotations.s
index 04c3eefa4e4a..9a797a17ad9f 100644
--- a/llvm/test/MC/WebAssembly/annotations.s
+++ b/llvm/test/MC/WebAssembly/annotations.s
@@ -21,9 +21,12 @@ test_annotation:
try
rethrow 0
catch __cpp_exception
+ catch_all
block
try
br 0
+ try
+ delegate 1
catch_all
end_try
end_block
@@ -46,9 +49,12 @@ test_annotation:
# CHECK-NEXT: try
# CHECK-NEXT: rethrow 0 # down to catch3
# CHECK-NEXT: catch __cpp_exception # catch3:
+# CHECK-NEXT: catch_all{{$}}
# CHECK-NEXT: block
# CHECK-NEXT: try
# CHECK-NEXT: br 0 # 0: down to label5
+# CHECK-NEXT: try
+# CHECK-NEXT: delegate 1 # label/catch6: down to catch4
# CHECK-NEXT: catch_all # catch5:
# CHECK-NEXT: end_try # label5:
# CHECK-NEXT: end_block # label4:
diff --git a/llvm/test/MC/WebAssembly/basic-assembly-errors.s b/llvm/test/MC/WebAssembly/basic-assembly-errors.s
index 45a09654d01d..24002ef995bb 100644
--- a/llvm/test/MC/WebAssembly/basic-assembly-errors.s
+++ b/llvm/test/MC/WebAssembly/basic-assembly-errors.s
@@ -18,8 +18,16 @@ test0:
# CHECK: Block construct type mismatch, expected: end_block, instead got: end_if
end_if
try
+# CHECK: Block construct type mismatch, expected: end_try/delegate, instead got: end_block
+ end_block
loop
-# CHECK: Block construct type mismatch, expected: end_loop, instead got: end_function
+ try
+ catch_all
+ catch_all
+# CHECK: error: Block construct type mismatch, expected: end_try, instead got: catch_all
+ end
+# CHECK: Block construct type mismatch, expected: end_try, instead got: end_function
+# CHECK: error: Unmatched block construct(s) at function end: catch_all
# CHECK: error: Unmatched block construct(s) at function end: loop
# CHECK: error: Unmatched block construct(s) at function end: try
# CHECK: error: Unmatched block construct(s) at function end: block
More information about the llvm-commits
mailing list