// 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 {
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.
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);
- }
}
; CHECK: i32.call $drop=, __cxa_begin_catch
; CHECK: try
; CHECK: call foo
-; CHECK: br 2 # 2: down to label10
+; CHECK: br 2 # 2: down to label9
; CHECK: catch
; CHECK: call __cxa_end_catch
; CHECK: rethrow # down to catch3
; CHECK: catch {{.*}} # catch3:
; CHECK: call __cxa_end_catch
; CHECK: rethrow # to caller
-; CHECK: end_try # label10:
+; CHECK: end_try # label9:
; CHECK: call __cxa_end_catch
; CHECK: br 2 # 2: down to label6
; CHECK: end_try