diff options
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/MachineFunction.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp | 61 | ||||
-rw-r--r-- | llvm/lib/CodeGen/WasmEHPrepare.cpp | 43 |
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); + } +} |