Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison docs/ExceptionHandling.rst @ 83:60c9769439b8
LLVM 3.7
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 18 Feb 2015 14:55:36 +0900 |
parents | 54457678186b |
children | afa8332a0e37 |
comparison
equal
deleted
inserted
replaced
78:af83660cff7b | 83:60c9769439b8 |
---|---|
61 frame information in out-of-line tables, SJLJ exception handling builds and | 61 frame information in out-of-line tables, SJLJ exception handling builds and |
62 removes the unwind frame context at runtime. This results in faster exception | 62 removes the unwind frame context at runtime. This results in faster exception |
63 handling at the expense of slower execution when no exceptions are thrown. As | 63 handling at the expense of slower execution when no exceptions are thrown. As |
64 exceptions are, by their nature, intended for uncommon code paths, DWARF | 64 exceptions are, by their nature, intended for uncommon code paths, DWARF |
65 exception handling is generally preferred to SJLJ. | 65 exception handling is generally preferred to SJLJ. |
66 | |
67 Windows Runtime Exception Handling | |
68 ----------------------------------- | |
69 | |
70 Windows runtime based exception handling uses the same basic IR structure as | |
71 Itanium ABI based exception handling, but it relies on the personality | |
72 functions provided by the native Windows runtime library, ``__CxxFrameHandler3`` | |
73 for C++ exceptions: ``__C_specific_handler`` for 64-bit SEH or | |
74 ``_frame_handler3/4`` for 32-bit SEH. This results in a very different | |
75 execution model and requires some minor modifications to the initial IR | |
76 representation and a significant restructuring just before code generation. | |
77 | |
78 General information about the Windows x64 exception handling mechanism can be | |
79 found at `MSDN Exception Handling (x64) | |
80 <https://msdn.microsoft.com/en-us/library/1eyas8tf(v=vs.80).aspx>_`. | |
66 | 81 |
67 Overview | 82 Overview |
68 -------- | 83 -------- |
69 | 84 |
70 When an exception is thrown in LLVM code, the runtime does its best to find a | 85 When an exception is thrown in LLVM code, the runtime does its best to find a |
304 ``A``, it's in for a rude awakening. Consequently, landing pads must test for | 319 ``A``, it's in for a rude awakening. Consequently, landing pads must test for |
305 the selector results they understand and then resume exception propagation with | 320 the selector results they understand and then resume exception propagation with |
306 the `resume instruction <LangRef.html#i_resume>`_ if none of the conditions | 321 the `resume instruction <LangRef.html#i_resume>`_ if none of the conditions |
307 match. | 322 match. |
308 | 323 |
324 C++ Exception Handling using the Windows Runtime | |
325 ================================================= | |
326 | |
327 (Note: Windows C++ exception handling support is a work in progress and is | |
328 not yet fully implemented. The text below describes how it will work | |
329 when completed.) | |
330 | |
331 The Windows runtime function for C++ exception handling uses a multi-phase | |
332 approach. When an exception occurs it searches the current callstack for a | |
333 frame that has a handler for the exception. If a handler is found, it then | |
334 calls the cleanup handler for each frame above the handler which has a | |
335 cleanup handler before calling the catch handler. These calls are all made | |
336 from a stack context different from the original frame in which the handler | |
337 is defined. Therefore, it is necessary to outline these handlers from their | |
338 original context before code generation. | |
339 | |
340 Catch handlers are called with a pointer to the handler itself as the first | |
341 argument and a pointer to the parent function's stack frame as the second | |
342 argument. The catch handler uses the `llvm.recoverframe | |
343 <LangRef.html#llvm-frameallocate-and-llvm-framerecover-intrinsics>`_ to get a | |
344 pointer to a frame allocation block that is created in the parent frame using | |
345 the `llvm.allocateframe | |
346 <LangRef.html#llvm-frameallocate-and-llvm-framerecover-intrinsics>`_ intrinsic. | |
347 The ``WinEHPrepare`` pass will have created a structure definition for the | |
348 contents of this block. The first two members of the structure will always be | |
349 (1) a 32-bit integer that the runtime uses to track the exception state of the | |
350 parent frame for the purposes of handling chained exceptions and (2) a pointer | |
351 to the object associated with the exception (roughly, the parameter of the | |
352 catch clause). These two members will be followed by any frame variables from | |
353 the parent function which must be accessed in any of the functions unwind or | |
354 catch handlers. The catch handler returns the address at which execution | |
355 should continue. | |
356 | |
357 Cleanup handlers perform any cleanup necessary as the frame goes out of scope, | |
358 such as calling object destructors. The runtime handles the actual unwinding | |
359 of the stack. If an exception occurs in a cleanup handler the runtime manages | |
360 termination of the process. Cleanup handlers are called with the same arguments | |
361 as catch handlers (a pointer to the handler and a pointer to the parent stack | |
362 frame) and use the same mechanism described above to access frame variables | |
363 in the parent function. Cleanup handlers do not return a value. | |
364 | |
365 The IR generated for Windows runtime based C++ exception handling is initially | |
366 very similar to the ``landingpad`` mechanism described above. Calls to | |
367 libc++abi functions (such as ``__cxa_begin_catch``/``__cxa_end_catch`` and | |
368 ``__cxa_throw_exception`` are replaced with calls to intrinsics or Windows | |
369 runtime functions (such as ``llvm.eh.begincatch``/``llvm.eh.endcatch`` and | |
370 ``__CxxThrowException``). | |
371 | |
372 During the WinEHPrepare pass, the handler functions are outlined into handler | |
373 functions and the original landing pad code is replaced with a call to the | |
374 ``llvm.eh.actions`` intrinsic that describes the order in which handlers will | |
375 be processed from the logical location of the landing pad and an indirect | |
376 branch to the return value of the ``llvm.eh.actions`` intrinsic. The | |
377 ``llvm.eh.actions`` intrinsic is defined as returning the address at which | |
378 execution will continue. This is a temporary construct which will be removed | |
379 before code generation, but it allows for the accurate tracking of control | |
380 flow until then. | |
381 | |
382 A typical landing pad will look like this after outlining: | |
383 | |
384 .. code-block:: llvm | |
385 | |
386 lpad: | |
387 %vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) | |
388 cleanup | |
389 catch i8* bitcast (i8** @_ZTIi to i8*) | |
390 catch i8* bitcast (i8** @_ZTIf to i8*) | |
391 %recover = call i8* (...)* @llvm.eh.actions( | |
392 i32 3, i8* bitcast (i8** @_ZTIi to i8*), i8* (i8*, i8*)* @_Z4testb.catch.1) | |
393 i32 2, i8* null, void (i8*, i8*)* @_Z4testb.cleanup.1) | |
394 i32 1, i8* bitcast (i8** @_ZTIf to i8*), i8* (i8*, i8*)* @_Z4testb.catch.0) | |
395 i32 0, i8* null, void (i8*, i8*)* @_Z4testb.cleanup.0) | |
396 indirectbr i8* %recover, [label %try.cont1, label %try.cont2] | |
397 | |
398 In this example, the landing pad represents an exception handling context with | |
399 two catch handlers and a cleanup handler that have been outlined. If an | |
400 exception is thrown with a type that matches ``_ZTIi``, the ``_Z4testb.catch.1`` | |
401 handler will be called an no clean-up is needed. If an exception is thrown | |
402 with a type that matches ``_ZTIf``, first the ``_Z4testb.cleanup.1`` handler | |
403 will be called to perform unwind-related cleanup, then the ``_Z4testb.catch.1`` | |
404 handler will be called. If an exception is throw which does not match either | |
405 of these types and the exception is handled by another frame further up the | |
406 call stack, first the ``_Z4testb.cleanup.1`` handler will be called, then the | |
407 ``_Z4testb.cleanup.0`` handler (which corresponds to a different scope) will be | |
408 called, and exception handling will continue at the next frame in the call | |
409 stack will be called. One of the catch handlers will return the address of | |
410 ``%try.cont1`` in the parent function and the other will return the address of | |
411 ``%try.cont2``, meaning that execution continues at one of those blocks after | |
412 an exception is caught. | |
413 | |
414 | |
309 Exception Handling Intrinsics | 415 Exception Handling Intrinsics |
310 ============================= | 416 ============================= |
311 | 417 |
312 In addition to the ``landingpad`` and ``resume`` instructions, LLVM uses several | 418 In addition to the ``landingpad`` and ``resume`` instructions, LLVM uses several |
313 intrinsic functions (name prefixed with ``llvm.eh``) to provide exception | 419 intrinsic functions (name prefixed with ``llvm.eh``) to provide exception |
326 This intrinsic returns the type info index in the exception table of the current | 432 This intrinsic returns the type info index in the exception table of the current |
327 function. This value can be used to compare against the result of | 433 function. This value can be used to compare against the result of |
328 ``landingpad`` instruction. The single argument is a reference to a type info. | 434 ``landingpad`` instruction. The single argument is a reference to a type info. |
329 | 435 |
330 Uses of this intrinsic are generated by the C++ front-end. | 436 Uses of this intrinsic are generated by the C++ front-end. |
437 | |
438 .. _llvm.eh.begincatch: | |
439 | |
440 ``llvm.eh.begincatch`` | |
441 ---------------------- | |
442 | |
443 .. code-block:: llvm | |
444 | |
445 i8* @llvm.eh.begincatch(i8* %exn) | |
446 | |
447 | |
448 This intrinsic marks the beginning of catch handling code within the blocks | |
449 following a ``landingpad`` instruction. The exact behavior of this function | |
450 depends on the compilation target and the personality function associated | |
451 with the ``landingpad`` instruction. | |
452 | |
453 The argument to this intrinsic is a pointer that was previously extracted from | |
454 the aggregate return value of the ``landingpad`` instruction. The return | |
455 value of the intrinsic is a pointer to the exception object to be used by the | |
456 catch code. This pointer is returned as an ``i8*`` value, but the actual type | |
457 of the object will depend on the exception that was thrown. | |
458 | |
459 Uses of this intrinsic are generated by the C++ front-end. Many targets will | |
460 use implementation-specific functions (such as ``__cxa_begin_catch``) instead | |
461 of this intrinsic. The intrinsic is provided for targets that require a more | |
462 abstract interface. | |
463 | |
464 When used in the native Windows C++ exception handling implementation, this | |
465 intrinsic serves as a placeholder to delimit code before a catch handler is | |
466 outlined. When the handler is is outlined, this intrinsic will be replaced | |
467 by instructions that retrieve the exception object pointer from the frame | |
468 allocation block. | |
469 | |
470 | |
471 .. _llvm.eh.endcatch: | |
472 | |
473 ``llvm.eh.endcatch`` | |
474 ---------------------- | |
475 | |
476 .. code-block:: llvm | |
477 | |
478 void @llvm.eh.endcatch() | |
479 | |
480 | |
481 This intrinsic marks the end of catch handling code within the current block, | |
482 which will be a successor of a block which called ``llvm.eh.begincatch''. | |
483 The exact behavior of this function depends on the compilation target and the | |
484 personality function associated with the corresponding ``landingpad`` | |
485 instruction. | |
486 | |
487 There may be more than one call to ``llvm.eh.endcatch`` for any given call to | |
488 ``llvm.eh.begincatch`` with each ``llvm.eh.endcatch`` call corresponding to the | |
489 end of a different control path. All control paths following a call to | |
490 ``llvm.eh.begincatch`` must reach a call to ``llvm.eh.endcatch``. | |
491 | |
492 Uses of this intrinsic are generated by the C++ front-end. Many targets will | |
493 use implementation-specific functions (such as ``__cxa_begin_catch``) instead | |
494 of this intrinsic. The intrinsic is provided for targets that require a more | |
495 abstract interface. | |
496 | |
497 When used in the native Windows C++ exception handling implementation, this | |
498 intrinsic serves as a placeholder to delimit code before a catch handler is | |
499 outlined. After the handler is outlined, this intrinsic is simply removed. | |
500 | |
331 | 501 |
332 SJLJ Intrinsics | 502 SJLJ Intrinsics |
333 --------------- | 503 --------------- |
334 | 504 |
335 The ``llvm.eh.sjlj`` intrinsics are used internally within LLVM's | 505 The ``llvm.eh.sjlj`` intrinsics are used internally within LLVM's |