summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/MachineFunction.cpp6
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp61
-rw-r--r--llvm/lib/CodeGen/WasmEHPrepare.cpp43
3 files changed, 91 insertions, 19 deletions
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index e47aeb64910..a376614ade9 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -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");
diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index a3a6d43881b..42c7181dac4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -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 Function &fn, MachineFunction &mf,
}
}
}
+ 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 Function &fn, MachineFunction &mf,
}
}
- 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);
}
}
diff --git a/llvm/lib/CodeGen/WasmEHPrepare.cpp b/llvm/lib/CodeGen/WasmEHPrepare.cpp
index cd11230236c..83d04da5dd0 100644
--- a/llvm/lib/CodeGen/WasmEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WasmEHPrepare.cpp
@@ -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(BasicBlock *BB, unsigned Index) {
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);
+ }
+}
OpenPOWER on IntegriCloud