diff options
author | Reid Kleckner <reid@kleckner.net> | 2015-06-11 22:32:23 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2015-06-11 22:32:23 +0000 |
commit | a9d62535727e23588c86dd6ad1d339cb331799ac (patch) | |
tree | 080dba998fbb1a75d1939d30c6428d450d08a5f2 /llvm/lib/Target/X86/X86WinEHState.cpp | |
parent | 6bb26dafa4cda63c14da97e65eff1e982375fd16 (diff) | |
download | bcm5719-llvm-a9d62535727e23588c86dd6ad1d339cb331799ac.tar.gz bcm5719-llvm-a9d62535727e23588c86dd6ad1d339cb331799ac.zip |
[WinEH] Create an llvm.x86.seh.exceptioninfo intrinsic
This intrinsic is like framerecover plus a load. It recovers the EH
registration stack allocation from the parent frame and loads the
exception information field out of it, giving back a pointer to an
EXCEPTION_POINTERS struct. It's designed for clang to use in SEH filter
expressions instead of accessing the EXCEPTION_POINTERS parameter that
is available on x64.
This required a minor change to MC to allow defining a label variable to
another absolute framerecover label variable.
llvm-svn: 239567
Diffstat (limited to 'llvm/lib/Target/X86/X86WinEHState.cpp')
-rw-r--r-- | llvm/lib/Target/X86/X86WinEHState.cpp | 35 |
1 files changed, 6 insertions, 29 deletions
diff --git a/llvm/lib/Target/X86/X86WinEHState.cpp b/llvm/lib/Target/X86/X86WinEHState.cpp index afad3f930da..e037f08790c 100644 --- a/llvm/lib/Target/X86/X86WinEHState.cpp +++ b/llvm/lib/Target/X86/X86WinEHState.cpp @@ -67,8 +67,6 @@ private: void addCXXStateStoresToFunclet(Value *ParentRegNode, WinEHFuncInfo &FuncInfo, Function &F, int BaseState); void insertStateNumberStore(Value *ParentRegNode, Instruction *IP, int State); - iplist<Instruction>::iterator - rewriteExceptionInfoIntrinsics(IntrinsicInst *Intrin); Value *emitEHLSDA(IRBuilder<> &Builder, Function *F); @@ -487,6 +485,12 @@ void WinEHStatePass::addCXXStateStoresToFunclet(Value *ParentRegNode, void WinEHStatePass::addSEHStateStores(Function &F, MachineModuleInfo &MMI) { WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(&F); + // Remember and return the index that we used. We save it in WinEHFuncInfo so + // that we can lower llvm.x86.seh.exceptioninfo later in filter functions + // without too much trouble. + int RegNodeEscapeIndex = escapeRegNode(F); + FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex; + // Iterate all the instructions and emit state number stores. int CurState = 0; SmallPtrSet<BasicBlock *, 4> ExceptBlocks; @@ -495,7 +499,6 @@ void WinEHStatePass::addSEHStateStores(Function &F, MachineModuleInfo &MMI) { if (auto *CI = dyn_cast<CallInst>(I)) { auto *Intrin = dyn_cast<IntrinsicInst>(CI); if (Intrin) { - I = rewriteExceptionInfoIntrinsics(Intrin); // Calls that "don't throw" are considered to be able to throw asynch // exceptions, but intrinsics cannot. continue; @@ -542,32 +545,6 @@ void WinEHStatePass::addSEHStateStores(Function &F, MachineModuleInfo &MMI) { } } -/// Rewrite llvm.eh.exceptioncode and llvm.eh.exceptioninfo to memory loads in -/// IR. -iplist<Instruction>::iterator -WinEHStatePass::rewriteExceptionInfoIntrinsics(IntrinsicInst *Intrin) { - Intrinsic::ID ID = Intrin->getIntrinsicID(); - if (ID != Intrinsic::eh_exceptioncode && ID != Intrinsic::eh_exceptioninfo) - return Intrin; - - // RegNode->ExceptionPointers - IRBuilder<> Builder(Intrin); - Value *Ptrs = - Builder.CreateLoad(Builder.CreateStructGEP(RegNodeTy, RegNode, 1)); - Value *Res; - if (ID == Intrinsic::eh_exceptioncode) { - // Ptrs->ExceptionRecord->Code - Ptrs = Builder.CreateBitCast( - Ptrs, Builder.getInt32Ty()->getPointerTo()->getPointerTo()); - Value *Rec = Builder.CreateLoad(Ptrs); - Res = Builder.CreateLoad(Rec); - } else { - Res = Ptrs; - } - Intrin->replaceAllUsesWith(Res); - return Intrin->eraseFromParent(); -} - void WinEHStatePass::insertStateNumberStore(Value *ParentRegNode, Instruction *IP, int State) { IRBuilder<> Builder(IP); |