mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 00:32:55 +00:00
Make llvm.eh.actions an intrinsic and add docs for it
These docs *don't* match the way WinEHPrepare uses them yet, and verifier support isn't implemented either. The implementation will come after the documentation text is reviewed and agreed upon. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232003 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e4a40f7a1c
commit
b2d414391a
@ -498,6 +498,47 @@ When used in the native Windows C++ exception handling implementation, this
|
||||
intrinsic serves as a placeholder to delimit code before a catch handler is
|
||||
outlined. After the handler is outlined, this intrinsic is simply removed.
|
||||
|
||||
.. _llvm.eh.actions:
|
||||
|
||||
``llvm.eh.actions``
|
||||
----------------------
|
||||
|
||||
.. code-block:: llvm
|
||||
|
||||
void @llvm.eh.actions()
|
||||
|
||||
This intrinsic represents the list of actions to take when an exception is
|
||||
thrown. It is typically used by Windows exception handling schemes where cleanup
|
||||
outlining is required by the runtime. The arguments are a sequence of ``i32``
|
||||
sentinels indicating the action type followed by some pre-determined number of
|
||||
arguments required to implement that action.
|
||||
|
||||
A code of ``i32 0`` indicates a cleanup action, which expects one additional
|
||||
argument. The argument is a pointer to a function that implements the cleanup
|
||||
action.
|
||||
|
||||
A code of ``i32 1`` indicates a catch action, which expects three additional
|
||||
arguments. Different EH schemes give different meanings to the three arguments,
|
||||
but the first argument indicates whether the catch should fire, the second is a
|
||||
pointer to stack object where the exception object should be stored, and the
|
||||
third is the code to run to catch the exception.
|
||||
|
||||
For Windows C++ exception handling, the first argument for a catch handler is a
|
||||
pointer to the RTTI type descriptor for the object to catch. The third argument
|
||||
is a pointer to a function implementing the catch. This function returns the
|
||||
address of the basic block where execution should resume after handling the
|
||||
exception.
|
||||
|
||||
For Windows SEH, the first argument is a pointer to the filter function, which
|
||||
indicates if the exception should be caught or not. The second argument is
|
||||
typically null. The third argument is the address of a basic block where the
|
||||
exception will be handled. In other words, catch handlers are not outlined in
|
||||
SEH. After running cleanups, execution immediately resumes at this PC.
|
||||
|
||||
In order to preserve the structure of the CFG, a call to '``llvm.eh.actions``'
|
||||
must be followed by an ':ref:`indirectbr <i_indirectbr>`' instruction that jumps
|
||||
to the result of the intrinsic call.
|
||||
|
||||
|
||||
SJLJ Intrinsics
|
||||
---------------
|
||||
|
@ -418,6 +418,9 @@ def int_eh_begincatch : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
|
||||
[NoCapture<0>, NoCapture<1>]>;
|
||||
def int_eh_endcatch : Intrinsic<[], []>;
|
||||
|
||||
// Represents the list of actions to take when an exception is thrown.
|
||||
def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>;
|
||||
|
||||
// __builtin_unwind_init is an undocumented GCC intrinsic that causes all
|
||||
// callee-saved registers to be saved and restored (regardless of whether they
|
||||
// are used) in the calling function. It is used by libgcc_eh.
|
||||
|
@ -383,12 +383,10 @@ bool WinEHPrepare::prepareCPPEHHandlers(
|
||||
Module *M = F.getParent();
|
||||
LLVMContext &Context = M->getContext();
|
||||
|
||||
// FIXME: Make this an intrinsic.
|
||||
// Create a new function to receive the handler contents.
|
||||
PointerType *Int8PtrType = Type::getInt8PtrTy(Context);
|
||||
Type *Int32Type = Type::getInt32Ty(Context);
|
||||
FunctionType *ActionTy = FunctionType::get(Int8PtrType, true);
|
||||
Value *ActionIntrin = M->getOrInsertFunction("llvm.eh.actions", ActionTy);
|
||||
Function *ActionIntrin = Intrinsic::getDeclaration(M, Intrinsic::eh_actions);
|
||||
|
||||
for (LandingPadInst *LPad : LPads) {
|
||||
// Look for evidence that this landingpad has already been processed.
|
||||
@ -396,8 +394,8 @@ bool WinEHPrepare::prepareCPPEHHandlers(
|
||||
BasicBlock *LPadBB = LPad->getParent();
|
||||
for (Instruction &Inst : LPadBB->getInstList()) {
|
||||
// FIXME: Make this an intrinsic.
|
||||
if (auto *Call = dyn_cast<CallInst>(&Inst)) {
|
||||
if (Call->getCalledFunction()->getName() == "llvm.eh.actions") {
|
||||
if (auto *IntrinCall = dyn_cast<IntrinsicInst>(&Inst)) {
|
||||
if (IntrinCall->getIntrinsicID() == Intrinsic::eh_actions) {
|
||||
LPadHasActionList = true;
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user