[llvm] r232003 - Make llvm.eh.actions an intrinsic and add docs for it

Reid Kleckner reid at kleckner.net
Wed Mar 11 18:45:38 PDT 2015


Author: rnk
Date: Wed Mar 11 20:45:37 2015
New Revision: 232003

URL: http://llvm.org/viewvc/llvm-project?rev=232003&view=rev
Log:
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.

Modified:
    llvm/trunk/docs/ExceptionHandling.rst
    llvm/trunk/include/llvm/IR/Intrinsics.td
    llvm/trunk/lib/CodeGen/WinEHPrepare.cpp

Modified: llvm/trunk/docs/ExceptionHandling.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ExceptionHandling.rst?rev=232003&r1=232002&r2=232003&view=diff
==============================================================================
--- llvm/trunk/docs/ExceptionHandling.rst (original)
+++ llvm/trunk/docs/ExceptionHandling.rst Wed Mar 11 20:45:37 2015
@@ -498,6 +498,47 @@ When used in the native Windows C++ exce
 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
 ---------------

Modified: llvm/trunk/include/llvm/IR/Intrinsics.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Intrinsics.td?rev=232003&r1=232002&r2=232003&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Intrinsics.td (original)
+++ llvm/trunk/include/llvm/IR/Intrinsics.td Wed Mar 11 20:45:37 2015
@@ -418,6 +418,9 @@ def int_eh_begincatch : Intrinsic<[], [l
                                   [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.

Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=232003&r1=232002&r2=232003&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Wed Mar 11 20:45:37 2015
@@ -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;
         }





More information about the llvm-commits mailing list