-void WinEHStatePass::addCXXStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
- // Set up RegNodeEscapeIndex
- int RegNodeEscapeIndex = escapeRegNode(F);
- FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex;
-
- calculateWinCXXEHStateNumbers(&F, FuncInfo);
- addStateStoresToFunclet(RegNode, FuncInfo, F, -1);
-}
-
-/// Assign every distinct landingpad a unique state number for SEH. Unlike C++
-/// EH, we can use this very simple algorithm while C++ EH cannot because catch
-/// handlers aren't outlined and the runtime doesn't have to figure out which
-/// catch handler frame to unwind to.
-void WinEHStatePass::addSEHStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
- // Remember and return the index that we used. We save it in WinEHFuncInfo so
- // that we can lower llvm.x86.seh.recoverfp later in filter functions without
- // too much trouble.
- int RegNodeEscapeIndex = escapeRegNode(F);
- FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex;
-
- calculateSEHStateNumbers(&F, FuncInfo);
- addStateStoresToFunclet(RegNode, FuncInfo, F, -1);
-}
-
-/// Escape RegNode so that we can access it from child handlers. Find the call
-/// to localescape, if any, in the entry block and append RegNode to the list
-/// of arguments.
-int WinEHStatePass::escapeRegNode(Function &F) {
- // Find the call to localescape and extract its arguments.
- IntrinsicInst *EscapeCall = nullptr;
- for (Instruction &I : F.getEntryBlock()) {
- IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
- if (II && II->getIntrinsicID() == Intrinsic::localescape) {
- EscapeCall = II;
- break;
- }
- }
- SmallVector<Value *, 8> Args;
- if (EscapeCall) {
- auto Ops = EscapeCall->arg_operands();
- Args.append(Ops.begin(), Ops.end());
- }
- Args.push_back(RegNode);
-
- // Replace the call (if it exists) with new one. Otherwise, insert at the end
- // of the entry block.
- Instruction *InsertPt = EscapeCall;
- if (!EscapeCall)
- InsertPt = F.getEntryBlock().getTerminator();
- IRBuilder<> Builder(InsertPt);
- Builder.CreateCall(FrameEscape, Args);
- if (EscapeCall)
- EscapeCall->eraseFromParent();
- return Args.size() - 1;
-}
+void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
+ // Mark the registration node. The backend needs to know which alloca it is so
+ // that it can recover the original frame pointer.
+ IRBuilder<> Builder(RegNode->getParent(), std::next(RegNode->getIterator()));
+ Value *RegNodeI8 = Builder.CreateBitCast(RegNode, Builder.getInt8PtrTy());
+ Builder.CreateCall(
+ Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehregnode),
+ {RegNodeI8});
+
+ // Calculate state numbers.
+ if (isAsynchronousEHPersonality(Personality))
+ calculateSEHStateNumbers(&F, FuncInfo);
+ else
+ calculateWinCXXEHStateNumbers(&F, FuncInfo);