[llvm] r345343 - [WebAssembly] Support EH instructions in InstPrinter

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 25 16:45:48 PDT 2018


Author: aheejin
Date: Thu Oct 25 16:45:48 2018
New Revision: 345343

URL: http://llvm.org/viewvc/llvm-project?rev=345343&view=rev
Log:
[WebAssembly] Support EH instructions in InstPrinter

Summary: This adds support for exception handling instructions to InstPrinter.

Reviewers: dschuff, aardappel

Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits

Differential Revision: https://reviews.llvm.org/D53634

Added:
    llvm/trunk/test/CodeGen/WebAssembly/annotations.mir
Modified:
    llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
    llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h

Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp?rev=345343&r1=345342&r2=345343&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp Thu Oct 25 16:45:48 2018
@@ -35,7 +35,7 @@ using namespace llvm;
 WebAssemblyInstPrinter::WebAssemblyInstPrinter(const MCAsmInfo &MAI,
                                                const MCInstrInfo &MII,
                                                const MCRegisterInfo &MRI)
-    : MCInstPrinter(MAI, MII, MRI), ControlFlowCounter(0) {}
+    : MCInstPrinter(MAI, MII, MRI) {}
 
 void WebAssemblyInstPrinter::printRegName(raw_ostream &OS,
                                           unsigned RegNo) const {
@@ -70,30 +70,65 @@ void WebAssemblyInstPrinter::printInst(c
   if (CommentStream) {
     // Observe any effects on the control flow stack, for use in annotating
     // control flow label references.
-    switch (MI->getOpcode()) {
+    unsigned Opc = MI->getOpcode();
+    switch (Opc) {
     default:
       break;
+
     case WebAssembly::LOOP:
-    case WebAssembly::LOOP_S: {
+    case WebAssembly::LOOP_S:
       printAnnotation(OS, "label" + utostr(ControlFlowCounter) + ':');
       ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, true));
       break;
-    }
+
     case WebAssembly::BLOCK:
     case WebAssembly::BLOCK_S:
       ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false));
       break;
+
+    case WebAssembly::TRY:
+    case WebAssembly::TRY_S:
+      ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false));
+      EHPadStack.push_back(EHPadStackCounter++);
+      LastSeenEHInst = TRY;
+      break;
+
     case WebAssembly::END_LOOP:
     case WebAssembly::END_LOOP_S:
       assert(!ControlFlowStack.empty() && "End marker mismatch!");
       ControlFlowStack.pop_back();
       break;
+
     case WebAssembly::END_BLOCK:
     case WebAssembly::END_BLOCK_S:
       assert(!ControlFlowStack.empty() && "End marker mismatch!");
       printAnnotation(
           OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');
       break;
+
+    case WebAssembly::END_TRY:
+    case WebAssembly::END_TRY_S:
+      assert(!ControlFlowStack.empty() && "End marker mismatch!");
+      printAnnotation(
+          OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');
+      LastSeenEHInst = END_TRY;
+      break;
+
+    case WebAssembly::CATCH_I32:
+    case WebAssembly::CATCH_I32_S:
+    case WebAssembly::CATCH_I64:
+    case WebAssembly::CATCH_I64_S:
+    case WebAssembly::CATCH_ALL:
+    case WebAssembly::CATCH_ALL_S:
+      assert(LastSeenEHInst != END_TRY);
+      // There can be multiple catch instructions for one try instruction, so we
+      // only print 'catch' label when the last seen EH instruction was 'try'.
+      if (LastSeenEHInst == TRY) {
+        assert(!EHPadStack.empty() && "try-catch mismatch!");
+        printAnnotation(OS, "catch" + utostr(EHPadStack.pop_back_val()) + ':');
+      }
+      LastSeenEHInst = CATCH;
+      break;
     }
 
     // Annotate any control flow label references.
@@ -108,9 +143,26 @@ void WebAssemblyInstPrinter::printInst(c
       uint64_t Depth = MI->getOperand(i).getImm();
       if (!Printed.insert(Depth).second)
         continue;
-      const auto &Pair = ControlFlowStack.rbegin()[Depth];
-      printAnnotation(OS, utostr(Depth) + ": " + (Pair.second ? "up" : "down") +
-                              " to label" + utostr(Pair.first));
+
+      if (Opc == WebAssembly::RETHROW || Opc == WebAssembly::RETHROW_S) {
+        assert(Depth <= EHPadStack.size() && "Invalid depth argument!");
+        if (Depth == EHPadStack.size()) {
+          // This can happen when rethrow instruction breaks out of all nests
+          // and throws up to the current function's caller.
+          printAnnotation(OS, utostr(Depth) + ": " + "to caller");
+        } else {
+          uint64_t CatchNo = EHPadStack.rbegin()[Depth];
+          printAnnotation(OS, utostr(Depth) + ": " + "down to catch" +
+                                  utostr(CatchNo));
+        }
+
+      } else {
+        assert(Depth < ControlFlowStack.size() && "Invalid depth argument!");
+        const auto &Pair = ControlFlowStack.rbegin()[Depth];
+        printAnnotation(OS, utostr(Depth) + ": " +
+                                (Pair.second ? "up" : "down") + " to label" +
+                                utostr(Pair.first));
+      }
     }
   }
 }

Modified: llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h?rev=345343&r1=345342&r2=345343&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h Thu Oct 25 16:45:48 2018
@@ -25,8 +25,13 @@ namespace llvm {
 class MCSubtargetInfo;
 
 class WebAssemblyInstPrinter final : public MCInstPrinter {
-  uint64_t ControlFlowCounter;
-  SmallVector<std::pair<uint64_t, bool>, 0> ControlFlowStack;
+  uint64_t ControlFlowCounter = 0;
+  uint64_t EHPadStackCounter = 0;
+  SmallVector<std::pair<uint64_t, bool>, 4> ControlFlowStack;
+  SmallVector<uint64_t, 4> EHPadStack;
+
+  enum EHInstKind { TRY, CATCH, END_TRY };
+  EHInstKind LastSeenEHInst = END_TRY;
 
 public:
   WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,

Added: llvm/trunk/test/CodeGen/WebAssembly/annotations.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/annotations.mir?rev=345343&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/annotations.mir (added)
+++ llvm/trunk/test/CodeGen/WebAssembly/annotations.mir Thu Oct 25 16:45:48 2018
@@ -0,0 +1,94 @@
+# RUN: llc -mtriple=wasm32-unknown-unknown -start-after xray-instrumentation -wasm-keep-registers %s -o - | FileCheck %s
+
+---
+# Tests if block/loop/try/catch/end instructions are correctly printed with
+# their annotations.
+
+# CHECK: test0:
+# CHECK:   block
+# CHECK:   try
+# CHECK:   br        0               # 0: down to label1
+# CHECK:   catch_all                 # catch0:
+# CHECK:   block
+# CHECK:   br_if     0, 1            # 0: down to label2
+# CHECK:   loop                      # label3:
+# CHECK:   br_if     0, 1            # 0: up to label3
+# CHECK:   end_loop
+# CHECK:   end_block                 # label2:
+# CHECK:   try
+# CHECK:   rethrow   0               # 0: down to catch1
+# CHECK:   catch_all                 # catch1:
+# CHECK:   block
+# CHECK:   try
+# CHECK:   br        0               # 0: down to label6
+# CHECK:   catch_all                 # catch2:
+# CHECK:   unreachable
+# CHECK:   end_try                   # label6:
+# CHECK:   end_block                 # label5:
+# CHECK:   rethrow   0               # 0: to caller
+# CHECK:   end_try                   # label4:
+# CHECK:   end_try                   # label1:
+# CHECK:   end_block                 # label0:
+
+name: test0
+liveins:
+  - { reg: '$arguments', reg: '$value_stack' }
+body: |
+  bb.0:
+    successors: %bb.7, %bb.1
+    BLOCK 64, implicit-def $value_stack, implicit $value_stack
+    TRY 64, implicit-def $value_stack, implicit $value_stack
+    BR 0, implicit-def $arguments
+
+  bb.1 (landing-pad):
+  ; predecessors: %bb.0
+    successors: %bb.2, %bb.3
+
+    CATCH_ALL implicit-def $arguments
+    BLOCK 64, implicit-def $value_stack, implicit $value_stack
+    BR_IF 0, 1, implicit-def $arguments, implicit-def $value_stack, implicit $value_stack
+
+  bb.2:
+  ; predecessors: %bb.1, %bb.2
+    successors: %bb.2, %bb.3
+
+    LOOP 64, implicit-def $value_stack, implicit $value_stack
+    BR_IF 0, 1, implicit-def $arguments
+
+  bb.3:
+  ; predecessors: %bb.1, %bb.2
+    successors: %bb.4
+
+    END_LOOP implicit-def $value_stack, implicit $value_stack
+    END_BLOCK implicit-def $value_stack, implicit $value_stack
+    TRY 64, implicit-def $value_stack, implicit $value_stack
+    RETHROW 0, implicit-def $arguments
+
+  bb.4 (landing-pad):
+  ; predecessors: %bb.3
+    successors: %bb.6, %bb.5
+
+    CATCH_ALL implicit-def $arguments
+    BLOCK 64, implicit-def $value_stack, implicit $value_stack
+    TRY 64, implicit-def $value_stack, implicit $value_stack
+    BR 0, implicit-def $arguments
+
+  bb.5 (landing-pad):
+  ; predecessors: %bb.4
+    CATCH_ALL implicit-def $arguments
+    UNREACHABLE implicit-def dead $arguments
+
+  bb.6:
+  ; predecessors: %bb.4
+    END_TRY implicit-def $value_stack, implicit $value_stack
+    END_BLOCK implicit-def $value_stack, implicit $value_stack
+    RETHROW 0, implicit-def $arguments
+
+  bb.7:
+  ; predecessors: %bb.0
+    END_TRY implicit-def $value_stack, implicit $value_stack
+    END_TRY implicit-def $value_stack, implicit $value_stack
+    END_BLOCK implicit-def $value_stack, implicit $value_stack
+    FALLTHROUGH_RETURN_VOID implicit-def dead $arguments
+    END_FUNCTION implicit-def $value_stack, implicit $value_stack
+...




More information about the llvm-commits mailing list