X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=docs%2FExceptionHandling.html;h=0b1c651704149634e01a00fc678c6ccb6fd39154;hp=8303a49fab5a6d4e3d6569b1da57b0d4a5246dfe;hb=1acd2eed98ce080d31e7995c5e2ddb1c4318a560;hpb=b0a1cbff0d9893631fb0a9ad5c6f4d0766645199 diff --git a/docs/ExceptionHandling.html b/docs/ExceptionHandling.html index 8303a49fab5..0b1c6517041 100644 --- a/docs/ExceptionHandling.html +++ b/docs/ExceptionHandling.html @@ -22,14 +22,14 @@
  1. Throw
  2. Try/Catch
  3. -
  4. Finallys
  5. +
  6. Cleanups
  7. Throw Filters
  8. +
  9. Restrictions
  • Exception Handling Intrinsics
    1. llvm.eh.exception
    2. llvm.eh.selector
    3. -
    4. llvm.eh.filter
    5. llvm.eh.typeid.for
  • Asm Table Formats @@ -72,21 +72,20 @@ C/C++.

    Exception handling for most programming languages is designed to recover from conditions that rarely occur during general use of an application. To that end, exception handling should not interfere with the main flow of an -application's algorithm by performing checkpointing tasks such as saving +application's algorithm by performing checkpointing tasks such as saving the current pc or register state.

    The Itanium ABI Exception Handling Specification defines a methodology for providing outlying data in the form of exception tables without inlining -speculative exception handling code in the flow of an application's main +speculative exception handling code in the flow of an application's main algorithm. Thus, the specification is said to add "zero-cost" to the normal execution of an application.

    A more complete description of the Itanium ABI exception handling runtime support of can be found at Itanium C++ ABI: -Exception Handling. A description of the exception frame format can be -found at Exception Frames, with details of the Dwarf specification at Dwarf 3 Standard. A description for the C++ exception table formats can be found at @@ -121,8 +120,8 @@ exceptions, the exception handling ABI provides a mechanism for supplying personalities. An exception handling personality is defined by way of a personality function (ex. for C++ __gxx_personality_v0) which receives the context of the exception, an exception structure containing -the exception object type and value, and a reference the exception table for the -current function. The personality function for the current compile unit is +the exception object type and value, and a reference to the exception table for +the current function. The personality function for the current compile unit is specified in a common exception frame.

    The organization of an exception table is language dependent. For C++, an @@ -195,7 +194,7 @@ unwinding of a throw.

    The term used to define a the place where an invoke continues after an exception is called a landing pad. LLVM landing pads are conceptually -alternative entry points into where a exception structure reference and a type +alternative function entry points where a exception structure reference and a type info index are passed in as arguments. The landing pad saves the exception structure reference and then proceeds to select the catch block that corresponds to the type info of the exception object.

    @@ -212,13 +211,20 @@ further use in the landing pad and catch code.

    llvm.eh.selector takes a minimum of three arguments. The first argument is the reference to the exception structure. The second argument is a reference to the personality function to be -used for this try catch sequence. The remaining arguments are references to the -type infos for each of the catch statements in the order they should be tested. -The catch all (...) is represented with a null i8*. The result -of the llvm.eh.selector is the index of -the type info in the corresponding exception table. The LLVM C++ front end -generates code to save this value in an alloca location for further use in the -landing pad and catch code.

    +used for this try catch sequence. Each of the remaining arguments is either a +reference to the type info for a catch statement, +a filter expression, +or the number zero representing a cleanup. +The exception is tested against the arguments sequentially from first to last. +The result of the llvm.eh.selector is a +positive number if the exception matched a type info, a negative number if it matched +a filter, and zero if it matched a cleanup. If nothing is matched, the behaviour of +the program is undefined. +The LLVM C++ front end generates code to save the selector value in an alloca +location for further use in the landing pad and catch code. +If a type info matched then the selector value is the index of the type info in +the exception table, which can be obtained using the +llvm.eh.typeid.for intrinsic.

    Once the landing pad has the type info selector, the code branches to the code for the first catch. The catch then checks the value of the type info @@ -236,7 +242,7 @@ selector.

    Finally, the entry and exit of catch code is bracketed with calls to __cxa_begin_catch and __cxa_end_catch. __cxa_begin_catch takes a exception structure reference as an argument -and returns the value of the exception object. __cxa_end_catch +and returns the value of the exception object. __cxa_end_catch takes a exception structure reference as an argument. This function clears the exception from the exception space. Note: a rethrow from within the catch may replace this call with a __cxa_rethrow.

    @@ -245,7 +251,7 @@ replace this call with a __cxa_rethrow.

    - Finallys + Cleanups
    @@ -254,7 +260,12 @@ replace this call with a __cxa_rethrow.

    from a landing pad to the first catch. Control may actually flow from the landing pad to clean up code and then to the first catch. Since the required clean up for each invoke in a try may be different (ex., intervening -constructor), there may be several landing pads for a given try.

    +constructor), there may be several landing pads for a given try. If cleanups +need to be run, the number zero should be passed as the last +llvm.eh.selector argument. +However for C++ a null i8* must be passed +instead. +

    @@ -268,17 +279,45 @@ constructor), there may be several landing pads for a given try.

    C++ allows the specification of which exception types that can be thrown from a function. To represent this a top level landing pad may exist to filter out invalid types. To express this in LLVM code the landing pad will call llvm.eh.filter instead of llvm.eh.selector. The arguments are the -same, but what gets created in the exception table is different. llvm.eh.filter will return a negative value -if it doesn't find a match. If no match is found then a call to -__cxa_call_unexpected should be made, otherwise +length of the filter expression (the number of type infos plus one), followed by +the type infos themselves. +llvm.eh.selector will return a negative +value if the exception does not match any of the type infos. If no match is +found then a call to __cxa_call_unexpected should be made, otherwise _Unwind_Resume. Each of these functions require a reference to the exception structure.

    + +
    + Restrictions +
    + +
    + +

    The semantics of the invoke instruction require that any exception that +unwinds through an invoke call should result in a branch to the invoke's unwind +label. However such a branch will only happen if the +llvm.eh.selector matches. +Thus in order to ensure correct operation, the front-end must only generate +llvm.eh.selector calls that are +guaranteed to always match whatever exception unwinds through the invoke. +For most languages it is enough to pass zero, indicating the presence of +a cleanup, as the last +llvm.eh.selector argument. +However for C++ this is not sufficient, because the C++ personality function +will terminate the program if it detects that unwinding the exception only +results in matches with cleanups. For C++ a null i8* should +be passed as the last +llvm.eh.selector argument instead. +This is interpreted as a catch-all by the C++ personality function, and will +always match. +

    + +
    +
    Exception Handling Intrinsics @@ -315,7 +354,8 @@ exception structure reference.

    -  i32 %llvm.eh.selector(i8*, i8*, i8*, ...)
    +  i32 %llvm.eh.selector.i32(i8*, i8*, i8*, ...)
    +  i64 %llvm.eh.selector.i64(i8*, i8*, i8*, ...)
     

    This intrinsic indicates that the exception selector is available at this @@ -326,32 +366,18 @@ exception selector.

    llvm.eh.selector takes a minimum of three arguments. The first argument is the reference to the exception structure. The second argument is a reference to the personality function to be -used for this try catch sequence. The remaining arguments are references to the -type infos for each of the catch statements in the order they should be tested. -The catch all (...) is represented with a null i8*.

    - -
    - - - - -
    -
    -  i32 %llvm.eh.filter(i8*, i8*, i8*, ...)
    -
    - -

    This intrinsic indicates that the exception selector is available at this -point in the code. The backend will replace this intrinsic with code to fetch -the second argument of a call. The effect is that the intrinsic result is the -exception selector.

    - -

    llvm.eh.filter takes a minimum of -three arguments. The first argument is the reference to the exception -structure. The second argument is a reference to the personality function to be -used for this function. The remaining arguments are references to the type infos -for each type that can be thrown by the current function.

    +used for this try catch sequence. Each of the remaining arguments is either a +reference to the type info for a catch statement, +a filter expression, +or the number zero representing a cleanup. +The exception is tested against the arguments sequentially from first to last. +The result of the llvm.eh.selector is a +positive number if the exception matched a type info, a negative number if it matched +a filter, and zero if it matched a cleanup. If nothing is matched, the behaviour of +the program is undefined. +If a type info matched then the selector value is the index of the type info in +the exception table, which can be obtained using the +llvm.eh.typeid.for intrinsic.

    @@ -362,7 +388,8 @@ for each type that can be thrown by the current function.

    -  i32 %llvm.eh.typeid.for(i8*)
    +  i32 %llvm.eh.typeid.for.i32(i8*)
    +  i64 %llvm.eh.typeid.for.i64(i8*)
     

    This intrinsic returns the type info index in the exception table of the @@ -410,7 +437,7 @@ all functions in the unit.

    An exception table contains information about what actions to take when an -exception is thrown in a particular part of a function's code. There is +exception is thrown in a particular part of a function's code. There is one exception table per function except leaf routines and functions that have only calls to non-throwing functions will not need an exception table.

    @@ -427,16 +454,7 @@ only calls to non-throwing functions will not need an exception table.

      -
    1. Need to create landing pads for code in between explicit landing pads. -The landing pads will have a zero action and a NULL landing pad address and are -used to inform the runtime that the exception should be rethrown.

    2. - -
    3. Actions for a given function should be folded to save space.

    4. - -
    5. Filters for inlined functions need to be handled more extensively. -Currently it's hardwired for one filter per function.

    6. - -
    7. Testing/Testing/Testing.

    8. +
    9. Testing/Testing/Testing.