[llvm] r335005 - [WebAssembly] Add WasmEHFuncInfo for unwind destination information

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 18 17:26:39 PDT 2018


Author: aheejin
Date: Mon Jun 18 17:26:39 2018
New Revision: 335005

URL: http://llvm.org/viewvc/llvm-project?rev=335005&view=rev
Log:
[WebAssembly] Add WasmEHFuncInfo for unwind destination information

Summary:
Add WasmEHFuncInfo and routines to calculate and fill in this struct to
keep track of unwind destination information. This will be used in
other EH related passes.

Reviewers: dschuff

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

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

Added:
    llvm/trunk/include/llvm/CodeGen/WasmEHFuncInfo.h
Modified:
    llvm/trunk/include/llvm/CodeGen/MachineFunction.h
    llvm/trunk/lib/CodeGen/MachineFunction.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
    llvm/trunk/lib/CodeGen/WasmEHPrepare.cpp

Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunction.h?rev=335005&r1=335004&r2=335005&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineFunction.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h Mon Jun 18 17:26:39 2018
@@ -73,6 +73,7 @@ class SlotIndexes;
 class TargetMachine;
 class TargetRegisterClass;
 class TargetSubtargetInfo;
+struct WasmEHFuncInfo;
 struct WinEHFuncInfo;
 
 template <> struct ilist_alloc_traits<MachineBasicBlock> {
@@ -245,6 +246,10 @@ class MachineFunction {
   // Keep track of jump tables for switch instructions
   MachineJumpTableInfo *JumpTableInfo;
 
+  // Keeps track of Wasm exception handling related data. This will be null for
+  // functions that aren't using a wasm EH personality.
+  WasmEHFuncInfo *WasmEHInfo = nullptr;
+
   // Keeps track of Windows exception handling related data. This will be null
   // for functions that aren't using a funclet-based EH personality.
   WinEHFuncInfo *WinEHInfo = nullptr;
@@ -432,6 +437,12 @@ public:
   MachineConstantPool *getConstantPool() { return ConstantPool; }
   const MachineConstantPool *getConstantPool() const { return ConstantPool; }
 
+  /// getWasmEHFuncInfo - Return information about how the current function uses
+  /// Wasm exception handling. Returns null for functions that don't use wasm
+  /// exception handling.
+  const WasmEHFuncInfo *getWasmEHFuncInfo() const { return WasmEHInfo; }
+  WasmEHFuncInfo *getWasmEHFuncInfo() { return WasmEHInfo; }
+
   /// getWinEHFuncInfo - Return information about how the current function uses
   /// Windows exception handling. Returns null for functions that don't use
   /// funclets for exception handling.

Added: llvm/trunk/include/llvm/CodeGen/WasmEHFuncInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/WasmEHFuncInfo.h?rev=335005&view=auto
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/WasmEHFuncInfo.h (added)
+++ llvm/trunk/include/llvm/CodeGen/WasmEHFuncInfo.h Mon Jun 18 17:26:39 2018
@@ -0,0 +1,75 @@
+//===--- llvm/CodeGen/WasmEHFuncInfo.h --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Data structures for Wasm exception handling schemes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_WASMEHFUNCINFO_H
+#define LLVM_CODEGEN_WASMEHFUNCINFO_H
+
+namespace llvm {
+
+using BBOrMBB = PointerUnion<const BasicBlock *, MachineBasicBlock *>;
+
+struct WasmEHFuncInfo {
+  // When there is an entry <A, B>, if an exception is not caught by A, it
+  // should next unwind to the EH pad B.
+  DenseMap<BBOrMBB, BBOrMBB> EHPadUnwindMap;
+  // For entry <A, B>, A is a BB with an instruction that may throw
+  // (invoke/cleanupret in LLVM IR, call/rethrow in the backend) and B is an EH
+  // pad that A unwinds to.
+  DenseMap<BBOrMBB, BBOrMBB> ThrowUnwindMap;
+
+  // Helper functions
+  const BasicBlock *getEHPadUnwindDest(const BasicBlock *BB) const {
+    return EHPadUnwindMap.lookup(BB).get<const BasicBlock *>();
+  }
+  void setEHPadUnwindDest(const BasicBlock *BB, const BasicBlock *Dest) {
+    EHPadUnwindMap[BB] = Dest;
+  }
+  const BasicBlock *getThrowUnwindDest(BasicBlock *BB) const {
+    return ThrowUnwindMap.lookup(BB).get<const BasicBlock *>();
+  }
+  void setThrowUnwindDest(const BasicBlock *BB, const BasicBlock *Dest) {
+    ThrowUnwindMap[BB] = Dest;
+  }
+  bool hasEHPadUnwindDest(const BasicBlock *BB) const {
+    return EHPadUnwindMap.count(BB);
+  }
+  bool hasThrowUnwindDest(const BasicBlock *BB) const {
+    return ThrowUnwindMap.count(BB);
+  }
+
+  MachineBasicBlock *getEHPadUnwindDest(MachineBasicBlock *MBB) const {
+    return EHPadUnwindMap.lookup(MBB).get<MachineBasicBlock *>();
+  }
+  void setEHPadUnwindDest(MachineBasicBlock *MBB, MachineBasicBlock *Dest) {
+    EHPadUnwindMap[MBB] = Dest;
+  }
+  MachineBasicBlock *getThrowUnwindDest(MachineBasicBlock *MBB) const {
+    return ThrowUnwindMap.lookup(MBB).get<MachineBasicBlock *>();
+  }
+  void setThrowUnwindDest(MachineBasicBlock *MBB, MachineBasicBlock *Dest) {
+    ThrowUnwindMap[MBB] = Dest;
+  }
+  bool hasEHPadUnwindDest(MachineBasicBlock *MBB) const {
+    return EHPadUnwindMap.count(MBB);
+  }
+  bool hasThrowUnwindDest(MachineBasicBlock *MBB) const {
+    return ThrowUnwindMap.count(MBB);
+  }
+};
+
+// Analyze the IR in the given function to build WasmEHFuncInfo.
+void calculateWasmEHInfo(const Function *F, WasmEHFuncInfo &FuncInfo);
+
+}; // namespace llvm
+
+#endif // LLVM_CODEGEN_WASMEHFUNCINFO_H

Modified: llvm/trunk/lib/CodeGen/MachineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunction.cpp?rev=335005&r1=335004&r2=335005&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineFunction.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineFunction.cpp Mon Jun 18 17:26:39 2018
@@ -37,6 +37,7 @@
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CodeGen/WasmEHFuncInfo.h"
 #include "llvm/CodeGen/WinEHFuncInfo.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/IR/Attributes.h"
@@ -175,6 +176,11 @@ void MachineFunction::init() {
     WinEHInfo = new (Allocator) WinEHFuncInfo();
   }
 
+  if (isScopedEHPersonality(classifyEHPersonality(
+          F.hasPersonalityFn() ? F.getPersonalityFn() : nullptr))) {
+    WasmEHInfo = new (Allocator) WasmEHFuncInfo();
+  }
+
   assert(Target.isCompatibleDataLayout(getDataLayout()) &&
          "Can't create a MachineFunction using a Module with a "
          "Target-incompatible DataLayout attached\n");

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp?rev=335005&r1=335004&r2=335005&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp Mon Jun 18 17:26:39 2018
@@ -23,6 +23,7 @@
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetRegisterInfo.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CodeGen/WasmEHFuncInfo.h"
 #include "llvm/CodeGen/WinEHFuncInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -118,6 +119,10 @@ void FunctionLoweringInfo::set(const Fun
       }
     }
   }
+  if (Personality == EHPersonality::Wasm_CXX) {
+    WasmEHFuncInfo &EHInfo = *MF->getWasmEHFuncInfo();
+    calculateWasmEHInfo(&fn, EHInfo);
+  }
 
   // Initialize the mapping of values to registers.  This is only set up for
   // instruction values that are used outside of the block that defines
@@ -282,28 +287,46 @@ void FunctionLoweringInfo::set(const Fun
     }
   }
 
-  if (!isFuncletEHPersonality(Personality))
-    return;
-
-  WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo();
+  if (isFuncletEHPersonality(Personality)) {
+    WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo();
 
-  // Map all BB references in the WinEH data to MBBs.
-  for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) {
-    for (WinEHHandlerType &H : TBME.HandlerArray) {
-      if (H.Handler)
-        H.Handler = MBBMap[H.Handler.get<const BasicBlock *>()];
+    // Map all BB references in the WinEH data to MBBs.
+    for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) {
+      for (WinEHHandlerType &H : TBME.HandlerArray) {
+        if (H.Handler)
+          H.Handler = MBBMap[H.Handler.get<const BasicBlock *>()];
+      }
+    }
+    for (CxxUnwindMapEntry &UME : EHInfo.CxxUnwindMap)
+      if (UME.Cleanup)
+        UME.Cleanup = MBBMap[UME.Cleanup.get<const BasicBlock *>()];
+    for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) {
+      const auto *BB = UME.Handler.get<const BasicBlock *>();
+      UME.Handler = MBBMap[BB];
+    }
+    for (ClrEHUnwindMapEntry &CME : EHInfo.ClrEHUnwindMap) {
+      const auto *BB = CME.Handler.get<const BasicBlock *>();
+      CME.Handler = MBBMap[BB];
     }
   }
-  for (CxxUnwindMapEntry &UME : EHInfo.CxxUnwindMap)
-    if (UME.Cleanup)
-      UME.Cleanup = MBBMap[UME.Cleanup.get<const BasicBlock *>()];
-  for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) {
-    const BasicBlock *BB = UME.Handler.get<const BasicBlock *>();
-    UME.Handler = MBBMap[BB];
-  }
-  for (ClrEHUnwindMapEntry &CME : EHInfo.ClrEHUnwindMap) {
-    const BasicBlock *BB = CME.Handler.get<const BasicBlock *>();
-    CME.Handler = MBBMap[BB];
+
+  else if (Personality == EHPersonality::Wasm_CXX) {
+    WasmEHFuncInfo &EHInfo = *MF->getWasmEHFuncInfo();
+    // Map all BB references in the WinEH data to MBBs.
+    DenseMap<BBOrMBB, BBOrMBB> NewMap;
+    for (auto &KV : EHInfo.EHPadUnwindMap) {
+      const auto *Src = KV.first.get<const BasicBlock *>();
+      const auto *Dst = KV.second.get<const BasicBlock *>();
+      NewMap[MBBMap[Src]] = MBBMap[Dst];
+    }
+    EHInfo.EHPadUnwindMap = std::move(NewMap);
+    NewMap.clear();
+    for (auto &KV : EHInfo.ThrowUnwindMap) {
+      const auto *Src = KV.first.get<const BasicBlock *>();
+      const auto *Dst = KV.second.get<const BasicBlock *>();
+      NewMap[MBBMap[Src]] = MBBMap[Dst];
+    }
+    EHInfo.ThrowUnwindMap = std::move(NewMap);
   }
 }
 

Modified: llvm/trunk/lib/CodeGen/WasmEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WasmEHPrepare.cpp?rev=335005&r1=335004&r2=335005&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WasmEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WasmEHPrepare.cpp Mon Jun 18 17:26:39 2018
@@ -116,6 +116,7 @@
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/TargetLowering.h"
 #include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/CodeGen/WasmEHFuncInfo.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Intrinsics.h"
@@ -329,3 +330,45 @@ void WasmEHPrepare::prepareEHPad(BasicBl
   GetSelectorCI->replaceAllUsesWith(Selector);
   GetSelectorCI->eraseFromParent();
 }
+
+void llvm::calculateWasmEHInfo(const Function *F, WasmEHFuncInfo &EHInfo) {
+  for (const auto &BB : *F) {
+    if (!BB.isEHPad())
+      continue;
+    const Instruction *Pad = BB.getFirstNonPHI();
+
+    // If an exception is not caught by a catchpad (i.e., it is a foreign
+    // exception), it will unwind to its parent catchswitch's unwind
+    // destination. We don't record an unwind destination for cleanuppads
+    // because every exception should be caught by it.
+    if (const auto *CatchPad = dyn_cast<CatchPadInst>(Pad)) {
+      const auto *UnwindBB = CatchPad->getCatchSwitch()->getUnwindDest();
+      if (!UnwindBB)
+        continue;
+      const Instruction *UnwindPad = UnwindBB->getFirstNonPHI();
+      if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(UnwindPad))
+        // Currently there should be only one handler per a catchswitch.
+        EHInfo.setEHPadUnwindDest(&BB, *CatchSwitch->handlers().begin());
+      else // cleanuppad
+        EHInfo.setEHPadUnwindDest(&BB, UnwindBB);
+    }
+  }
+
+  // Record the unwind destination for invoke and cleanupret instructions.
+  for (const auto &BB : *F) {
+    const Instruction *TI = BB.getTerminator();
+    BasicBlock *UnwindBB = nullptr;
+    if (const auto *Invoke = dyn_cast<InvokeInst>(TI))
+      UnwindBB = Invoke->getUnwindDest();
+    else if (const auto *CleanupRet = dyn_cast<CleanupReturnInst>(TI))
+      UnwindBB = CleanupRet->getUnwindDest();
+    if (!UnwindBB)
+      continue;
+    const Instruction *UnwindPad = UnwindBB->getFirstNonPHI();
+    if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(UnwindPad))
+      // Currently there should be only one handler per a catchswitch.
+      EHInfo.setThrowUnwindDest(&BB, *CatchSwitch->handlers().begin());
+    else // cleanuppad
+      EHInfo.setThrowUnwindDest(&BB, UnwindBB);
+  }
+}




More information about the llvm-commits mailing list