mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-29 10:25:12 +00:00
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239567 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -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);
|
||||
|
Reference in New Issue
Block a user