OSDN Git Service

4d8d1bc9a29afdd9ea4afdfde86b8c3c6fcf3c88
[pf3gnuchains/gcc-fork.git] / gcc / except.c
1 /* Implements exception handling.
2    Copyright (C) 1989, 92-95, 1996 Free Software Foundation, Inc.
3    Contributed by Mike Stump <mrs@cygnus.com>.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22
23 /* An exception is an event that can be signaled from within a
24    function. This event can then be "caught" or "trapped" by the
25    callers of this function. This potentially allows program flow to
26    be transferred to any arbitrary code assocated with a function call
27    several levels up the stack.
28
29    The intended use for this mechanism is for signaling "exceptional
30    events" in an out-of-band fashion, hence its name. The C++ language
31    (and many other OO-styled or functional languages) practically
32    requires such a mechanism, as otherwise it becomes very difficult
33    or even impossible to signal failure conditions in complex
34    situations.  The traditional C++ example is when an error occurs in
35    the process of constructing an object; without such a mechanism, it
36    is impossible to signal that the error occurs without adding global
37    state variables and error checks around every object construction.
38
39    The act of causing this event to occur is referred to as "throwing
40    an exception". (Alternate terms include "raising an exception" or
41    "signaling an exception".) The term "throw" is used because control
42    is returned to the callers of the function that is signaling the
43    exception, and thus there is the concept of "throwing" the
44    exception up the call stack.
45
46    It is appropriate to speak of the "context of a throw". This
47    context refers to the address where the exception is thrown from,
48    and is used to determine which exception region will handle the
49    exception.
50
51    Regions of code within a function can be marked such that if it
52    contains the context of a throw, control will be passed to a
53    designated "exception handler". These areas are known as "exception
54    regions".  Exception regions cannot overlap, but they can be nested
55    to any arbitrary depth. Also, exception regions cannot cross
56    function boundaries.
57
58    Exception handlers can either be specified by the user (which we
59    will call a "user-defined handler") or generated by the compiler
60    (which we will designate as a "cleanup"). Cleanups are used to
61    perform tasks such as destruction of objects allocated on the
62    stack.
63
64    In the current implementaion, cleanups are handled by allocating an
65    exception region for the area that the cleanup is designated for,
66    and the handler for the region performs the cleanup and then
67    rethrows the exception to the outer exception region. From the
68    standpoint of the current implementation, there is little
69    distinction made between a cleanup and a user-defined handler, and
70    the phrase "exception handler" can be used to refer to either one
71    equally well. (The section "Future Directions" below discusses how
72    this will change).
73
74    Each object file that is compiled with exception handling contains
75    a static array of exception handlers named __EXCEPTION_TABLE__.
76    Each entry contains the starting and ending addresses of the
77    exception region, and the address of the handler designated for
78    that region.
79
80    At program startup each object file invokes a function named
81    __register_exceptions with the address of its local
82    __EXCEPTION_TABLE__. __register_exceptions is defined in libgcc2.c,
83    and is responsible for recording all of the exception regions into
84    one list (which is kept in a static variable named exception_table_list).
85
86    The function __throw () is actually responsible for doing the
87    throw. In the C++ frontend, __throw () is generated on a
88    per-object-file basis for each source file compiled with
89    -fexceptions. Before __throw () is invoked, the current context
90    of the throw needs to be placed in the global variable __eh_pc.
91
92    __throw () attempts to find the appropriate exception handler for the 
93    PC value stored in __eh_pc by calling __find_first_exception_table_match
94    (which is defined in libgcc2.c). If __find_first_exception_table_match
95    finds a relevant handler, __throw jumps directly to it.
96
97    If a handler for the context being thrown from can't be found,
98    __throw is responsible for unwinding the stack, determining the
99    address of the caller of the current function (which will be used
100    as the new context to throw from), and then restarting the process
101    of searching for a handler for the new context. __throw may also
102    call abort () if it is unable to unwind the stack, and can also
103    call an external library function named __terminate if it reaches
104    the top of the stack without finding an appropriate handler. (By
105    default __terminate () invokes abort (), but this behavior can be
106    changed by the user to perform some sort of cleanup behavior before
107    exiting).
108
109    Internal implementation details:
110
111    To associate a user-defined handler with a block of statements, the
112    function expand_start_try_stmts () is used to mark the start of the
113    block of statements with which the handler is to be associated
114    (which is known as a "try block"). All statements that appear
115    afterwards will be associated with the try block.
116
117    A call to expand_start_all_catch () marks the end of the try block,
118    and also marks the start of the "catch block" (the user-defined
119    handler) associated with the try block.
120
121    This user-defined handler will be invoked for *every* exception
122    thrown with the context of the try block. It is up to the handler
123    to decide whether or not it wishes to handle any given exception,
124    as there is currently no mechanism in this implementation for doing
125    this. (There are plans for conditionally processing an exception
126    based on its "type", which will provide a language-independent
127    mechanism).
128
129    If the handler chooses not to process the exception (perhaps by
130    looking at an "exception type" or some other additional data
131    supplied with the exception), it can fall through to the end of the
132    handler. expand_end_all_catch () and expand_leftover_cleanups ()
133    add additional code to the end of each handler to take care of
134    rethrowing to the outer exception handler.
135
136    The handler also has the option to continue with "normal flow of
137    code", or in other words to resume executing at the statement
138    immediately after the end of the exception region. The variable
139    caught_return_label_stack contains a stack of labels, and jumping
140    to the topmost entry's label via expand_goto () will resume normal
141    flow to the statement immediately after the end of the exception
142    region. If the handler falls through to the end, the exception will
143    be rethrown to the outer exception region.
144
145    The instructions for the catch block are kept as a separate
146    sequence, and will be emitted at the end of the function along with
147    the handlers specified via expand_eh_region_end (). The end of the
148    catch block is marked with expand_end_all_catch ().
149
150    Any data associated with the exception must currently be handled by
151    some external mechanism maintained in the frontend.  For example,
152    the C++ exception mechanism passes an arbitrary value along with
153    the exception, and this is handled in the C++ frontend by using a
154    global variable to hold the value. (This will be changing in the
155    future.)
156
157    The mechanism in C++ for handling data associated with the
158    exception is clearly not thread-safe. For a thread-based
159    environment, another mechanism must be used (possibly using a
160    per-thread allocation mechanism if the size of the area that needs
161    to be allocated isn't known at compile time.)
162
163    Internally-generated exception regions (cleanups) are marked by
164    calling expand_eh_region_start () to mark the start of the region,
165    and expand_eh_region_end (handler) is used to both designate the
166    end of the region and to associate a specified handler/cleanup with
167    the region. The rtl code in HANDLER will be invoked whenever an
168    exception occurs in the region between the calls to
169    expand_eh_region_start and expand_eh_region_end. After HANDLER is
170    executed, additional code is emitted to handle rethrowing the
171    exception to the outer exception handler. The code for HANDLER will
172    be emitted at the end of the function.
173
174    TARGET_EXPRs can also be used to designate exception regions. A
175    TARGET_EXPR gives an unwind-protect style interface commonly used
176    in functional languages such as LISP. The associated expression is
177    evaluated, and whether or not it (or any of the functions that it
178    calls) throws an exception, the protect expression is always
179    invoked. This implementation takes care of the details of
180    associating an exception table entry with the expression and
181    generating the necessary code (it actually emits the protect
182    expression twice, once for normal flow and once for the exception
183    case). As for the other handlers, the code for the exception case
184    will be emitted at the end of the function.
185
186    Cleanups can also be specified by using add_partial_entry (handler)
187    and end_protect_partials (). add_partial_entry creates the start of
188    a new exception region; HANDLER will be invoked if an exception is
189    thrown with the context of the region between the calls to
190    add_partial_entry and end_protect_partials. end_protect_partials is
191    used to mark the end of these regions. add_partial_entry can be
192    called as many times as needed before calling end_protect_partials.
193    However, end_protect_partials should only be invoked once for each
194    group of calls to add_partial_entry () as the entries are queued
195    and all of the outstanding entries are processed simultaneously
196    when end_protect_partials is invoked. Similarly to the other
197    handlers, the code for HANDLER will be emitted at the end of the
198    function.
199
200    The generated RTL for an exception region includes
201    NOTE_INSN_EH_REGION_BEG and NOTE_INSN_EH_REGION_END notes that mark
202    the start and end of the exception region. A unique label is also
203    generated at the start of the exception region, which is available
204    by looking at the ehstack variable. The topmost entry corresponds
205    to the current region.
206
207    In the current implementation, an exception can only be thrown from
208    a function call (since the mechanism used to actually throw an
209    exception involves calling __throw).  If an exception region is
210    created but no function calls occur within that region, the region
211    can be safely optimized away (along with its exception handlers)
212    since no exceptions can ever be caught in that region.
213
214    Unwinding the stack:
215
216    The details of unwinding the stack to the next frame can be rather
217    complex. While in many cases a generic __unwind_function () routine
218    can be used by the generated exception handling code to do this, it
219    is often necessary to generate inline code to do the unwinding.
220
221    Whether or not these inlined unwinders are necessary is
222    target-specific.
223
224    By default, if the target-specific backend doesn't supply a
225    definition for __unwind_function (), inlined unwinders will be used
226    instead. The main tradeoff here is in text space utilization.
227    Obviously, if inline unwinders have to be generated repeatedly,
228    this uses much more space than if a single routine is used.
229
230    However, it is simply not possible on some platforms to write a
231    generalized routine for doing stack unwinding without having some
232    form of additional data associated with each function. The current
233    implementation encodes this data in the form of additional machine
234    instructions. This is clearly not desirable, as it is extremely
235    inefficient. The next implementation will provide a set of metadata
236    for each function that will provide the needed information.
237
238    The backend macro DOESNT_NEED_UNWINDER is used to conditionalize
239    whether or not per-function unwinders are needed. If DOESNT_NEED_UNWINDER
240    is defined and has a non-zero value, a per-function unwinder is
241    not emitted for the current function.
242
243    On some platforms it is possible that neither __unwind_function ()
244    nor inlined unwinders are available. For these platforms it is not
245    possible to throw through a function call, and abort () will be
246    invoked instead of performing the throw. 
247
248    Future directions:
249
250    Currently __throw () makes no differentiation between cleanups and
251    user-defined exception regions. While this makes the implementation
252    simple, it also implies that it is impossible to determine if a
253    user-defined exception handler exists for a given exception without
254    completely unwinding the stack in the process. This is undesirable
255    from the standpoint of debugging, as ideally it would be possible
256    to trap unhandled exceptions in the debugger before the process of
257    unwinding has even started.
258
259    This problem can be solved by marking user-defined handlers in a
260    special way (probably by adding additional bits to exception_table_list).
261    A two-pass scheme could then be used by __throw () to iterate
262    through the table. The first pass would search for a relevant
263    user-defined handler for the current context of the throw, and if
264    one is found, the second pass would then invoke all needed cleanups
265    before jumping to the user-defined handler.
266
267    Many languages (including C++ and Ada) make execution of a
268    user-defined handler conditional on the "type" of the exception
269    thrown. (The type of the exception is actually the type of the data
270    that is thrown with the exception.) It will thus be necessary for
271    __throw () to be able to determine if a given user-defined
272    exception handler will actually be executed, given the type of
273    exception.
274
275    One scheme is to add additional information to exception_table_list
276    as to the types of exceptions accepted by each handler. __throw ()
277    can do the type comparisons and then determine if the handler is
278    actually going to be executed.
279
280    There is currently no significant level of debugging support
281    available, other than to place a breakpoint on __throw (). While
282    this is sufficient in most cases, it would be helpful to be able to
283    know where a given exception was going to be thrown to before it is
284    actually thrown, and to be able to choose between stopping before
285    every exception region (including cleanups), or just user-defined
286    exception regions. This should be possible to do in the two-pass
287    scheme by adding additional labels to __throw () for appropriate
288    breakpoints, and additional debugger commands could be added to
289    query various state variables to determine what actions are to be
290    performed next.
291
292    Another major problem that is being worked on is the issue with
293    stack unwinding on various platforms. Currently the only platform
294    that has support for __unwind_function () is the Sparc; all other
295    ports require per-function unwinders, which causes large amounts of
296    code bloat.
297
298    Ideally it would be possible to store a small set of metadata with
299    each function that would then make it possible to write a
300    __unwind_function () for every platform. This would eliminate the
301    need for per-function unwinders.
302
303    The main reason the data is needed is that on some platforms the
304    order and types of data stored on the stack can vary depending on
305    the type of function, its arguments and returned values, and the
306    compilation options used (optimization versus non-optimization,
307    -fomit-frame-pointer, processor variations, etc).
308
309    Unfortunately, this also means that throwing through functions that
310    aren't compiled with exception handling support will still not be
311    possible on some platforms. This problem is currently being
312    investigated, but no solutions have been found that do not imply
313    some unacceptable performance penalties.  */
314
315
316 #include "config.h"
317 #include <stdio.h>
318 #include "rtl.h"
319 #include "tree.h"
320 #include "flags.h"
321 #include "except.h"
322 #include "function.h"
323 #include "insn-flags.h"
324 #include "expr.h"
325 #include "insn-codes.h"
326 #include "regs.h"
327 #include "hard-reg-set.h"
328 #include "insn-config.h"
329 #include "recog.h"
330 #include "output.h"
331 #include "assert.h"
332
333 /* A list of labels used for exception handlers.  Created by
334    find_exception_handler_labels for the optimization passes.  */
335
336 rtx exception_handler_labels;
337
338 /* Nonzero means that __throw was invoked. 
339
340    This is used by the C++ frontend to know if code needs to be emitted
341    for __throw or not.  */
342
343 int throw_used;
344
345 /* A stack used for keeping track of the currectly active exception
346    handling region.  As each exception region is started, an entry
347    describing the region is pushed onto this stack.  The current
348    region can be found by looking at the top of the stack, and as we
349    exit regions, the corresponding entries are popped. 
350
351    Entries cannot overlap; they must be nested. So there is only one
352    entry at most that corresponds to the current instruction, and that
353    is the entry on the top of the stack.  */
354
355 struct eh_stack ehstack;
356
357 /* A queue used for tracking which exception regions have closed but
358    whose handlers have not yet been expanded. Regions are emitted in
359    groups in an attempt to improve paging performance.
360
361    As we exit a region, we enqueue a new entry. The entries are then
362    dequeued during expand_leftover_cleanups () and expand_start_all_catch (),
363
364    We should redo things so that we either take RTL for the handler,
365    or we expand the handler expressed as a tree immediately at region
366    end time.  */
367
368 struct eh_queue ehqueue;
369
370 /* Insns for all of the exception handlers for the current function.
371    They are currently emitted by the frontend code.  */
372
373 rtx catch_clauses;
374
375 /* A TREE_CHAINed list of handlers for regions that are not yet
376    closed. The TREE_VALUE of each entry contains the handler for the
377    corresponding entry on the ehstack.  */
378
379 static tree protect_list;
380
381 /* Stacks to keep track of various labels.  */
382
383 /* Keeps track of the label to resume to should one want to resume
384    normal control flow out of a handler (instead of, say, returning to
385    the caller of the current function or exiting the program).  Also
386    used as the context of a throw to rethrow an exception to the outer
387    exception region.  */
388
389 struct label_node *caught_return_label_stack = NULL;
390
391 /* A random data area for the front end's own use.  */
392
393 struct label_node *false_label_stack = NULL;
394
395 /* The rtx and the tree for the saved PC value.  */
396
397 rtx eh_saved_pc_rtx;
398 tree eh_saved_pc;
399
400 rtx expand_builtin_return_addr  PROTO((enum built_in_function, int, rtx));
401 \f
402 /* Various support routines to manipulate the various data structures
403    used by the exception handling code.  */
404
405 /* Push a label entry onto the given STACK.  */
406
407 void
408 push_label_entry (stack, rlabel, tlabel)
409      struct label_node **stack;
410      rtx rlabel;
411      tree tlabel;
412 {
413   struct label_node *newnode
414     = (struct label_node *) xmalloc (sizeof (struct label_node));
415
416   if (rlabel)
417     newnode->u.rlabel = rlabel;
418   else
419     newnode->u.tlabel = tlabel;
420   newnode->chain = *stack;
421   *stack = newnode;
422 }
423
424 /* Pop a label entry from the given STACK.  */
425
426 rtx
427 pop_label_entry (stack)
428      struct label_node **stack;
429 {
430   rtx label;
431   struct label_node *tempnode;
432
433   if (! *stack)
434     return NULL_RTX;
435
436   tempnode = *stack;
437   label = tempnode->u.rlabel;
438   *stack = (*stack)->chain;
439   free (tempnode);
440
441   return label;
442 }
443
444 /* Return the top element of the given STACK.  */
445
446 tree
447 top_label_entry (stack)
448      struct label_node **stack;
449 {
450   if (! *stack)
451     return NULL_TREE;
452
453   return (*stack)->u.tlabel;
454 }
455
456 /* Make a copy of ENTRY using xmalloc to allocate the space.  */
457
458 static struct eh_entry *
459 copy_eh_entry (entry)
460      struct eh_entry *entry;
461 {
462   struct eh_entry *newentry;
463
464   newentry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
465   bcopy ((char *) entry, (char *) newentry, sizeof (struct eh_entry));
466
467   return newentry;
468 }
469
470 /* Push a new eh_node entry onto STACK, and return the start label for
471    the entry.  */
472
473 static rtx
474 push_eh_entry (stack)
475      struct eh_stack *stack;
476 {
477   struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
478   struct eh_entry *entry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
479
480   entry->start_label = gen_label_rtx ();
481   entry->end_label = gen_label_rtx ();
482   entry->exception_handler_label = gen_label_rtx ();
483   entry->finalization = NULL_TREE;
484
485   node->entry = entry;
486   node->chain = stack->top;
487   stack->top = node;
488
489   return entry->start_label;
490 }
491
492 /* Pop an entry from the given STACK.  */
493
494 static struct eh_entry *
495 pop_eh_entry (stack)
496      struct eh_stack *stack;
497 {
498   struct eh_node *tempnode;
499   struct eh_entry *tempentry;
500   
501   tempnode = stack->top;
502   tempentry = tempnode->entry;
503   stack->top = stack->top->chain;
504   free (tempnode);
505
506   return tempentry;
507 }
508
509 /* Enqueue an ENTRY onto the given QUEUE.  */
510
511 static void
512 enqueue_eh_entry (queue, entry)
513      struct eh_queue *queue;
514      struct eh_entry *entry;
515 {
516   struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
517
518   node->entry = entry;
519   node->chain = NULL;
520
521   if (queue->head == NULL)
522     {
523       queue->head = node;
524     }
525   else
526     {
527       queue->tail->chain = node;
528     }
529   queue->tail = node;
530 }
531
532 /* Dequeue an entry from the given QUEUE.  */
533
534 static struct eh_entry *
535 dequeue_eh_entry (queue)
536      struct eh_queue *queue;
537 {
538   struct eh_node *tempnode;
539   struct eh_entry *tempentry;
540
541   if (queue->head == NULL)
542     return NULL;
543
544   tempnode = queue->head;
545   queue->head = queue->head->chain;
546
547   tempentry = tempnode->entry;
548   free (tempnode);
549
550   return tempentry;
551 }
552 \f
553 /* Routine to see if exception exception handling is turned on.
554    DO_WARN is non-zero if we want to inform the user that exception
555    handling is turned off. 
556
557    This is used to ensure that -fexceptions has been specified if the
558    compiler tries to use any exception-specific functions.  */
559
560 int
561 doing_eh (do_warn)
562      int do_warn;
563 {
564   if (! flag_exceptions)
565     {
566       static int warned = 0;
567       if (! warned && do_warn)
568         {
569           error ("exception handling disabled, use -fexceptions to enable");
570           warned = 1;
571         }
572       return 0;
573     }
574   return 1;
575 }
576
577 /* Given a return address in ADDR, determine the address we should use
578    to find the corresponding EH region.  */
579
580 rtx
581 eh_outer_context (addr)
582      rtx addr;
583 {
584   /* First mask out any unwanted bits.  */
585 #ifdef MASK_RETURN_ADDR
586   emit_insn (gen_rtx (SET, Pmode,
587                       addr,
588                       gen_rtx (AND, Pmode,
589                                addr, MASK_RETURN_ADDR)));
590 #endif
591
592   /* Then subtract out enough to get into the appropriate region.  If
593      this is defined, assume we don't need to subtract anything as it
594      is already within the correct region.  */
595 #if ! defined (RETURN_ADDR_OFFSET)
596   addr = plus_constant (addr, -1);
597 #endif
598
599   return addr;
600 }
601
602 /* Start a new exception region and push the HANDLER for the region
603    onto protect_list. All of the regions created with add_partial_entry
604    will be ended when end_protect_partials () is invoked.  */
605
606 void
607 add_partial_entry (handler)
608      tree handler;
609 {
610   expand_eh_region_start ();
611
612   /* Make sure the entry is on the correct obstack.  */
613   push_obstacks_nochange ();
614   resume_temporary_allocation ();
615   protect_list = tree_cons (NULL_TREE, handler, protect_list);
616   pop_obstacks ();
617 }
618
619 /* Output a note marking the start of an exception handling region.
620    All instructions emitted after this point are considered to be part
621    of the region until expand_eh_region_end () is invoked.  */
622
623 void
624 expand_eh_region_start ()
625 {
626   rtx note;
627
628   /* This is the old code.  */
629   if (! doing_eh (0))
630     return;
631
632 #if 0
633   /* Maybe do this to prevent jumping in and so on...  */
634   pushlevel (0);
635 #endif
636
637   note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_BEG);
638   emit_label (push_eh_entry (&ehstack));
639   NOTE_BLOCK_NUMBER (note)
640     = CODE_LABEL_NUMBER (ehstack.top->entry->exception_handler_label);
641 }
642
643 /* Output a note marking the end of the exception handling region on
644    the top of ehstack.
645
646    HANDLER is either the cleanup for the exception region, or if we're
647    marking the end of a try block, HANDLER is integer_zero_node.
648
649    HANDLER will be transformed to rtl when expand_leftover_cleanups ()
650    is invoked.  */
651
652 void
653 expand_eh_region_end (handler)
654      tree handler;
655 {
656   rtx note;
657
658   struct eh_entry *entry;
659
660   if (! doing_eh (0))
661     return;
662
663   entry = pop_eh_entry (&ehstack);
664
665   note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
666   NOTE_BLOCK_NUMBER (note) = CODE_LABEL_NUMBER (entry->exception_handler_label);
667
668   /* Emit a label marking the end of this exception region.  */
669   emit_label (entry->end_label);
670
671   /* Put in something that takes up space, as otherwise the end
672      address for this EH region could have the exact same address as
673      its outer region. This would cause us to miss the fact that
674      resuming exception handling with this PC value would be inside
675      the outer region.  */
676   emit_insn (gen_nop ());
677
678   entry->finalization = handler;
679
680   enqueue_eh_entry (&ehqueue, entry);
681
682 #if 0
683   /* Maybe do this to prevent jumping in and so on...  */
684   poplevel (1, 0, 0);
685 #endif
686 }
687
688 /* Emit a call to __throw and note that we threw something, so we know
689    we need to generate the necessary code for __throw.  
690
691    Before invoking throw, the __eh_pc variable must have been set up
692    to contain the PC being thrown from. This address is used by
693    __throw () to determine which exception region (if any) is
694    responsible for handling the exception.  */
695
696 static void
697 emit_throw ()
698 {
699 #ifdef JUMP_TO_THROW
700   emit_indirect_jump (throw_libfunc);
701 #else
702   SYMBOL_REF_USED (throw_libfunc) = 1;
703   emit_library_call (throw_libfunc, 0, VOIDmode, 0);
704 #endif
705   throw_used = 1;
706   emit_barrier ();
707 }
708
709 /* An internal throw with an indirect CONTEXT we want to throw from.
710    CONTEXT evaluates to the context of the throw.  */
711
712 static void
713 expand_internal_throw_indirect (context)
714      rtx context;
715 {
716   assemble_external (eh_saved_pc);
717   emit_move_insn (eh_saved_pc_rtx, context);
718   emit_throw ();
719 }
720
721 /* An internal throw with a direct CONTEXT we want to throw from.
722    CONTEXT must be a label; its address will be used as the context of
723    the throw.  */
724
725 void
726 expand_internal_throw (context)
727      rtx context;
728 {
729   expand_internal_throw_indirect (gen_rtx (LABEL_REF, Pmode, context));
730 }
731
732 /* Called from expand_exception_blocks and expand_end_catch_block to
733    emit any pending handlers/cleanups queued from expand_eh_region_end ().  */
734
735 void
736 expand_leftover_cleanups ()
737 {
738   struct eh_entry *entry;
739
740   while ((entry = dequeue_eh_entry (&ehqueue)) != 0)
741     {
742       rtx prev;
743
744       /* A leftover try block. Shouldn't be one here.  */
745       if (entry->finalization == integer_zero_node)
746         abort ();
747
748       /* Output the label for the start of the exception handler.  */
749       emit_label (entry->exception_handler_label);
750
751       /* And now generate the insns for the handler.  */
752       expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
753
754       prev = get_last_insn ();
755       if (! (prev && GET_CODE (prev) == BARRIER))
756         {
757           /* The below can be optimized away, and we could just fall into the
758              next EH handler, if we are certain they are nested.  */
759           /* Emit code to throw to the outer context if we fall off
760              the end of the handler.  */
761           expand_internal_throw (entry->end_label);
762         }
763
764       free (entry);
765     }
766 }
767
768 /* Called at the start of a block of try statements.  */
769 void
770 expand_start_try_stmts ()
771 {
772   if (! doing_eh (1))
773     return;
774
775   expand_eh_region_start ();
776 }
777
778 /* Generate RTL for the start of a group of catch clauses. 
779
780    It is responsible for starting a new instruction sequence for the
781    instructions in the catch block, and expanding the handlers for the
782    internally-generated exception regions nested within the try block
783    corresponding to this catch block.  */
784
785 void
786 expand_start_all_catch ()
787 {
788   struct eh_entry *entry;
789   tree label;
790
791   if (! doing_eh (1))
792     return;
793
794   /* End the try block.  */
795   expand_eh_region_end (integer_zero_node);
796
797   emit_line_note (input_filename, lineno);
798   label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
799
800   /* The label for the exception handling block that we will save.
801      This is Lresume in the documention.  */
802   expand_label (label);
803   
804   /* Put in something that takes up space, as otherwise the end
805      address for the EH region could have the exact same address as
806      the outer region, causing us to miss the fact that resuming
807      exception handling with this PC value would be inside the outer
808      region.  */
809   emit_insn (gen_nop ());
810
811   /* Push the label that points to where normal flow is resumed onto
812      the top of the label stack.  */
813   push_label_entry (&caught_return_label_stack, NULL_RTX, label);
814
815   /* Start a new sequence for all the catch blocks.  We will add this
816      to the global sequence catch_clauses when we have completed all
817      the handlers in this handler-seq.  */
818   start_sequence ();
819
820   while (1)
821     {
822       rtx prev;
823
824       entry = dequeue_eh_entry (&ehqueue);
825       /* Emit the label for the exception handler for this region, and
826          expand the code for the handler. 
827
828          Note that a catch region is handled as a side-effect here;
829          for a try block, entry->finalization will contain
830          integer_zero_node, so no code will be generated in the
831          expand_expr call below. But, the label for the handler will
832          still be emitted, so any code emitted after this point will
833          end up being the handler.  */
834       emit_label (entry->exception_handler_label);
835       expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
836
837       /* When we get down to the matching entry for this try block, stop.  */
838       if (entry->finalization == integer_zero_node)
839         {
840           /* Don't forget to free this entry.  */
841           free (entry);
842           break;
843         }
844
845       prev = get_last_insn ();
846       if (prev == NULL || GET_CODE (prev) != BARRIER)
847         {
848           /* Code to throw out to outer context when we fall off end
849              of the handler. We can't do this here for catch blocks,
850              so it's done in expand_end_all_catch () instead.
851
852              The below can be optimized away (and we could just fall
853              into the next EH handler) if we are certain they are
854              nested.  */
855
856           expand_internal_throw (entry->end_label);
857         }
858       free (entry);
859     }
860 }
861
862 /* Finish up the catch block.  At this point all the insns for the
863    catch clauses have already been generated, so we only have to add
864    them to the catch_clauses list. We also want to make sure that if
865    we fall off the end of the catch clauses that we rethrow to the
866    outer EH region.  */
867
868 void
869 expand_end_all_catch ()
870 {
871   rtx new_catch_clause;
872
873   if (! doing_eh (1))
874     return;
875
876   /* Code to throw out to outer context, if we fall off end of catch
877      handlers.  This is rethrow (Lresume, same id, same obj) in the
878      documentation. We use Lresume because we know that it will throw
879      to the correct context.
880
881      In other words, if the catch handler doesn't exit or return, we
882      do a "throw" (using the address of Lresume as the point being
883      thrown from) so that the outer EH region can then try to process
884      the exception.  */
885
886   expand_internal_throw (DECL_RTL (top_label_entry (&caught_return_label_stack)));
887
888   /* Now we have the complete catch sequence.  */
889   new_catch_clause = get_insns ();
890   end_sequence ();
891   
892   /* This level of catch blocks is done, so set up the successful
893      catch jump label for the next layer of catch blocks.  */
894   pop_label_entry (&caught_return_label_stack);
895
896   /* Add the new sequence of catches to the main one for this function.  */
897   push_to_sequence (catch_clauses);
898   emit_insns (new_catch_clause);
899   catch_clauses = get_insns ();
900   end_sequence ();
901   
902   /* Here we fall through into the continuation code.  */
903 }
904
905 /* End all the pending exception regions on protect_list. The handlers
906    will be emitted when expand_leftover_cleanups () is invoked.  */
907
908 void
909 end_protect_partials ()
910 {
911   while (protect_list)
912     {
913       expand_eh_region_end (TREE_VALUE (protect_list));
914       protect_list = TREE_CHAIN (protect_list);
915     }
916 }
917 \f
918 /* The exception table that we build that is used for looking up and
919    dispatching exceptions, the current number of entries, and its
920    maximum size before we have to extend it. 
921
922    The number in eh_table is the code label number of the exception
923    handler for the region. This is added by add_eh_table_entry () and
924    used by output_exception_table_entry ().  */
925
926 static int *eh_table;
927 static int eh_table_size;
928 static int eh_table_max_size;
929
930 /* Note the need for an exception table entry for region N.  If we
931    don't need to output an explicit exception table, avoid all of the
932    extra work.
933
934    Called from final_scan_insn when a NOTE_INSN_EH_REGION_BEG is seen.
935    N is the NOTE_BLOCK_NUMBER of the note, which comes from the code
936    label number of the exception handler for the region.  */
937
938 void
939 add_eh_table_entry (n)
940      int n;
941 {
942 #ifndef OMIT_EH_TABLE
943   if (eh_table_size >= eh_table_max_size)
944     {
945       if (eh_table)
946         {
947           eh_table_max_size += eh_table_max_size>>1;
948
949           if (eh_table_max_size < 0)
950             abort ();
951
952           if ((eh_table = (int *) realloc (eh_table,
953                                            eh_table_max_size * sizeof (int)))
954               == 0)
955             fatal ("virtual memory exhausted");
956         }
957       else
958         {
959           eh_table_max_size = 252;
960           eh_table = (int *) xmalloc (eh_table_max_size * sizeof (int));
961         }
962     }
963   eh_table[eh_table_size++] = n;
964 #endif
965 }
966
967 /* Return a non-zero value if we need to output an exception table.
968
969    On some platforms, we don't have to output a table explicitly.
970    This routine doesn't mean we don't have one.  */
971
972 int
973 exception_table_p ()
974 {
975   if (eh_table)
976     return 1;
977
978   return 0;
979 }
980
981 /* Output the entry of the exception table corresponding to to the
982    exception region numbered N to file FILE. 
983
984    N is the code label number corresponding to the handler of the
985    region.  */
986
987 static void
988 output_exception_table_entry (file, n)
989      FILE *file;
990      int n;
991 {
992   char buf[256];
993   rtx sym;
994
995   ASM_GENERATE_INTERNAL_LABEL (buf, "LEHB", n);
996   sym = gen_rtx (SYMBOL_REF, Pmode, buf);
997   assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
998
999   ASM_GENERATE_INTERNAL_LABEL (buf, "LEHE", n);
1000   sym = gen_rtx (SYMBOL_REF, Pmode, buf);
1001   assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1002
1003   ASM_GENERATE_INTERNAL_LABEL (buf, "L", n);
1004   sym = gen_rtx (SYMBOL_REF, Pmode, buf);
1005   assemble_integer (sym, POINTER_SIZE / BITS_PER_UNIT, 1);
1006
1007   putc ('\n', file);            /* blank line */
1008 }
1009
1010 /* Output the exception table if we have and need one.  */
1011
1012 void
1013 output_exception_table ()
1014 {
1015   int i;
1016   extern FILE *asm_out_file;
1017
1018   if (! doing_eh (0))
1019     return;
1020
1021   exception_section ();
1022
1023   /* Beginning marker for table.  */
1024   assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
1025   assemble_label ("__EXCEPTION_TABLE__");
1026
1027   assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1028   assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1029   assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1030   putc ('\n', asm_out_file);            /* blank line */
1031
1032   for (i = 0; i < eh_table_size; ++i)
1033     output_exception_table_entry (asm_out_file, eh_table[i]);
1034
1035   free (eh_table);
1036
1037   /* Ending marker for table.  */
1038   assemble_label ("__EXCEPTION_END__");
1039   assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1040   assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1041   assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
1042   putc ('\n', asm_out_file);            /* blank line */
1043 }
1044
1045 /* Generate code to initialize the exception table at program startup
1046    time.  */
1047
1048 void
1049 register_exception_table ()
1050 {
1051   emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__register_exceptions"), 0,
1052                      VOIDmode, 1,
1053                      gen_rtx (SYMBOL_REF, Pmode, "__EXCEPTION_TABLE__"),
1054                      Pmode);
1055 }
1056 \f
1057 /* Emit the RTL for the start of the per-function unwinder for the
1058    current function. See emit_unwinder () for further information.
1059
1060    DOESNT_NEED_UNWINDER is a target-specific macro that determines if
1061    the current function actually needs a per-function unwinder or not.
1062    By default, all functions need one.  */
1063
1064 void
1065 start_eh_unwinder ()
1066 {
1067 #ifdef DOESNT_NEED_UNWINDER
1068   if (DOESNT_NEED_UNWINDER)
1069     return;
1070 #endif
1071
1072   expand_eh_region_start ();
1073 }
1074
1075 /* Emit insns for the end of the per-function unwinder for the
1076    current function.  */
1077
1078 void
1079 end_eh_unwinder ()
1080 {
1081   tree expr;
1082   rtx return_val_rtx, ret_val, label, end, insns;
1083
1084   if (! doing_eh (0))
1085     return;
1086
1087 #ifdef DOESNT_NEED_UNWINDER
1088   if (DOESNT_NEED_UNWINDER)
1089     return;
1090 #endif
1091
1092   assemble_external (eh_saved_pc);
1093
1094   expr = make_node (RTL_EXPR);
1095   TREE_TYPE (expr) = void_type_node;
1096   RTL_EXPR_RTL (expr) = const0_rtx;
1097   TREE_SIDE_EFFECTS (expr) = 1;
1098   start_sequence_for_rtl_expr (expr);
1099
1100   /* ret_val will contain the address of the code where the call
1101      to the current function occurred.  */
1102   ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
1103                                         0, hard_frame_pointer_rtx);
1104   return_val_rtx = copy_to_reg (ret_val);
1105
1106   /* Get the address we need to use to determine what exception
1107      handler should be invoked, and store it in __eh_pc.  */
1108   return_val_rtx = eh_outer_context (return_val_rtx);
1109   emit_move_insn (eh_saved_pc_rtx, return_val_rtx);
1110   
1111   /* Either set things up so we do a return directly to __throw, or
1112      we return here instead.  */
1113 #ifdef JUMP_TO_THROW
1114   emit_move_insn (ret_val, throw_libfunc);
1115 #else
1116   label = gen_label_rtx ();
1117   emit_move_insn (ret_val, gen_rtx (LABEL_REF, Pmode, label));
1118 #endif
1119
1120 #ifdef RETURN_ADDR_OFFSET
1121   return_val_rtx = plus_constant (ret_val, -RETURN_ADDR_OFFSET);
1122   if (return_val_rtx != ret_val)
1123     emit_move_insn (ret_val, return_val_rtx);
1124 #endif
1125   
1126   end = gen_label_rtx ();
1127   emit_jump (end);  
1128
1129   RTL_EXPR_SEQUENCE (expr) = get_insns ();
1130   end_sequence ();
1131   expand_eh_region_end (expr);
1132
1133   emit_jump (end);
1134
1135 #ifndef JUMP_TO_THROW
1136   emit_label (label);
1137   emit_throw ();
1138 #endif
1139   
1140   expand_leftover_cleanups ();
1141
1142   emit_label (end);
1143 }
1144
1145 /* If necessary, emit insns for the per function unwinder for the
1146    current function.  Called after all the code that needs unwind
1147    protection is output.  
1148
1149    The unwinder takes care of catching any exceptions that have not
1150    been previously caught within the function, unwinding the stack to
1151    the next frame, and rethrowing using the address of the current
1152    function's caller as the context of the throw.
1153
1154    On some platforms __throw can do this by itself (or with the help
1155    of __unwind_function) so the per-function unwinder is
1156    unnecessary.
1157   
1158    We cannot place the unwinder into the function until after we know
1159    we are done inlining, as we don't want to have more than one
1160    unwinder per non-inlined function.  */
1161
1162 void
1163 emit_unwinder ()
1164 {
1165   rtx insns, insn;
1166
1167   start_sequence ();
1168   start_eh_unwinder ();
1169   insns = get_insns ();
1170   end_sequence ();
1171
1172   /* We place the start of the exception region associated with the
1173      per function unwinder at the top of the function.  */
1174   if (insns)
1175     emit_insns_after (insns, get_insns ());
1176
1177   start_sequence ();
1178   end_eh_unwinder ();
1179   insns = get_insns ();
1180   end_sequence ();
1181
1182   /* And we place the end of the exception region before the USE and
1183      CLOBBER insns that may come at the end of the function.  */
1184   if (insns == 0)
1185     return;
1186
1187   insn = get_last_insn ();
1188   while (GET_CODE (insn) == NOTE
1189          || (GET_CODE (insn) == INSN
1190              && (GET_CODE (PATTERN (insn)) == USE
1191                  || GET_CODE (PATTERN (insn)) == CLOBBER)))
1192     insn = PREV_INSN (insn);
1193
1194   if (GET_CODE (insn) == CODE_LABEL
1195       && GET_CODE (PREV_INSN (insn)) == BARRIER)
1196     {
1197       insn = PREV_INSN (insn);
1198     }
1199   else
1200     {
1201       rtx label = gen_label_rtx ();
1202       emit_label_after (label, insn);
1203       insn = emit_jump_insn_after (gen_jump (label), insn);
1204       insn = emit_barrier_after (insn);
1205     }
1206     
1207   emit_insns_after (insns, insn);
1208 }
1209
1210 /* Scan the current insns and build a list of handler labels. The
1211    resulting list is placed in the global variable exception_handler_labels.
1212
1213    It is called after the last exception handling region is added to
1214    the current function (when the rtl is almost all built for the
1215    current function) and before the jump optimization pass.  */
1216
1217 void
1218 find_exception_handler_labels ()
1219 {
1220   rtx insn;
1221   int max_labelno = max_label_num ();
1222   int min_labelno = get_first_label_num ();
1223   rtx *labels;
1224
1225   exception_handler_labels = NULL_RTX;
1226
1227   /* If we aren't doing exception handling, there isn't much to check.  */
1228   if (! doing_eh (0))
1229     return;
1230
1231   /* Generate a handy reference to each label.  */
1232
1233   labels = (rtx *) alloca ((max_labelno - min_labelno) * sizeof (rtx));
1234   bzero ((char *) labels, (max_labelno - min_labelno) * sizeof (rtx));
1235
1236   /* Arrange for labels to be indexed directly by CODE_LABEL_NUMBER.  */
1237   labels -= min_labelno;
1238
1239   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1240     {
1241       if (GET_CODE (insn) == CODE_LABEL)
1242         if (CODE_LABEL_NUMBER (insn) >= min_labelno
1243             && CODE_LABEL_NUMBER (insn) < max_labelno)
1244           labels[CODE_LABEL_NUMBER (insn)] = insn;
1245     }
1246
1247   /* For each start of a region, add its label to the list.  */
1248
1249   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1250     {
1251       if (GET_CODE (insn) == NOTE
1252           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1253         {
1254           rtx label = NULL_RTX;
1255
1256           if (NOTE_BLOCK_NUMBER (insn) >= min_labelno
1257               && NOTE_BLOCK_NUMBER (insn) < max_labelno)
1258             {
1259               label = labels[NOTE_BLOCK_NUMBER (insn)];
1260
1261               if (label)
1262                 exception_handler_labels
1263                   = gen_rtx (EXPR_LIST, VOIDmode,
1264                              label, exception_handler_labels);
1265               else
1266                 warning ("didn't find handler for EH region %d",
1267                          NOTE_BLOCK_NUMBER (insn));
1268             }
1269           else
1270             warning ("mismatched EH region %d", NOTE_BLOCK_NUMBER (insn));
1271         }
1272     }
1273 }
1274
1275 /* Perform sanity checking on the exception_handler_labels list.
1276
1277    Can be called after find_exception_handler_labels is called to
1278    build the list of exception handlers for the current function and
1279    before we finish processing the current function.  */
1280
1281 void
1282 check_exception_handler_labels ()
1283 {
1284   rtx insn, handler;
1285
1286   /* If we aren't doing exception handling, there isn't much to check.  */
1287   if (! doing_eh (0))
1288     return;
1289
1290   /* Ensure that the CODE_LABEL_NUMBER for the CODE_LABEL entry point
1291      in each handler corresponds to the CODE_LABEL_NUMBER of the
1292      handler.  */
1293
1294   for (handler = exception_handler_labels;
1295        handler;
1296        handler = XEXP (handler, 1))
1297     {
1298       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1299         {
1300           if (GET_CODE (insn) == CODE_LABEL)
1301             {
1302               if (CODE_LABEL_NUMBER (insn)
1303                   == CODE_LABEL_NUMBER (XEXP (handler, 0)))
1304                 {
1305                   if (insn != XEXP (handler, 0))
1306                     warning ("mismatched handler %d",
1307                              CODE_LABEL_NUMBER (insn));
1308                   break;
1309                 }
1310             }
1311         }
1312       if (insn == NULL_RTX)
1313         warning ("handler not found %d",
1314                  CODE_LABEL_NUMBER (XEXP (handler, 0)));
1315     }
1316
1317   /* Now go through and make sure that for each region there is a
1318      corresponding label.  */
1319   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1320     {
1321       if (GET_CODE (insn) == NOTE
1322           && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG ||
1323               NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
1324         {
1325           for (handler = exception_handler_labels;
1326                handler;
1327                handler = XEXP (handler, 1))
1328             {
1329               if (CODE_LABEL_NUMBER (XEXP (handler, 0))
1330                   == NOTE_BLOCK_NUMBER (insn))
1331                 break;
1332             }
1333           if (handler == NULL_RTX)
1334             warning ("region exists, no handler %d",
1335                      NOTE_BLOCK_NUMBER (insn));
1336         }
1337     }
1338 }
1339 \f
1340 /* This group of functions initializes the exception handling data
1341    structures at the start of the compilation, initializes the data
1342    structures at the start of a function, and saves and restores the
1343    exception handling data structures for the start/end of a nested
1344    function.  */
1345
1346 /* Toplevel initialization for EH things.  */ 
1347
1348 void
1349 init_eh ()
1350 {
1351   /* Generate rtl to reference the variable in which the PC of the
1352      current context is saved.  */
1353   tree type = build_pointer_type (make_node (VOID_TYPE));
1354
1355   eh_saved_pc = build_decl (VAR_DECL, get_identifier ("__eh_pc"), type);
1356   DECL_EXTERNAL (eh_saved_pc) = 1;
1357   TREE_PUBLIC (eh_saved_pc) = 1;
1358   make_decl_rtl (eh_saved_pc, NULL_PTR, 1);
1359   eh_saved_pc_rtx = DECL_RTL (eh_saved_pc);
1360 }
1361
1362 /* Initialize the per-function EH information.  */
1363
1364 void
1365 init_eh_for_function ()
1366 {
1367   ehstack.top = 0;
1368   ehqueue.head = ehqueue.tail = 0;
1369   catch_clauses = NULL_RTX;
1370   false_label_stack = 0;
1371   caught_return_label_stack = 0;
1372   protect_list = NULL_TREE;
1373 }
1374
1375 /* Save some of the per-function EH info into the save area denoted by
1376    P. 
1377
1378    This is currently called from save_stmt_status ().  */
1379
1380 void
1381 save_eh_status (p)
1382      struct function *p;
1383 {
1384   assert (p != NULL);
1385
1386   p->ehstack = ehstack;
1387   p->ehqueue = ehqueue;
1388   p->catch_clauses = catch_clauses;
1389   p->false_label_stack = false_label_stack;
1390   p->caught_return_label_stack = caught_return_label_stack;
1391   p->protect_list = protect_list;
1392
1393   init_eh ();
1394 }
1395
1396 /* Restore the per-function EH info saved into the area denoted by P.  
1397
1398    This is currently called from restore_stmt_status.  */
1399
1400 void
1401 restore_eh_status (p)
1402      struct function *p;
1403 {
1404   assert (p != NULL);
1405
1406   protect_list = p->protect_list;
1407   caught_return_label_stack = p->caught_return_label_stack;
1408   false_label_stack = p->false_label_stack;
1409   catch_clauses = p->catch_clauses;
1410   ehqueue = p->ehqueue;
1411   ehstack = p->ehstack;
1412 }
1413 \f
1414 /* This section is for the exception handling specific optimization
1415    pass.  First are the internal routines, and then the main
1416    optimization pass.  */
1417
1418 /* Determine if the given INSN can throw an exception.  */
1419
1420 static int
1421 can_throw (insn)
1422      rtx insn;
1423 {
1424   /* Calls can always potentially throw exceptions.  */
1425   if (GET_CODE (insn) == CALL_INSN)
1426     return 1;
1427
1428 #ifdef ASYNCH_EXCEPTIONS
1429   /* If we wanted asynchronous exceptions, then everything but NOTEs
1430      and CODE_LABELs could throw.  */
1431   if (GET_CODE (insn) != NOTE && GET_CODE (insn) != CODE_LABEL)
1432     return 1;
1433 #endif
1434
1435   return 0;
1436 }
1437
1438 /* Scan a exception region looking for the matching end and then
1439    remove it if possible. INSN is the start of the region, N is the
1440    region number, and DELETE_OUTER is to note if anything in this
1441    region can throw.
1442
1443    Regions are removed if they cannot possibly catch an exception.
1444    This is determined by invoking can_throw () on each insn within the
1445    region; if can_throw returns true for any of the instructions, the
1446    region can catch an exception, since there is an insn within the
1447    region that is capable of throwing an exception.
1448
1449    Returns the NOTE_INSN_EH_REGION_END corresponding to this region, or
1450    calls abort () if it can't find one.
1451
1452    Can abort if INSN is not a NOTE_INSN_EH_REGION_BEGIN, or if N doesn't
1453    correspond to the region number, or if DELETE_OUTER is NULL.  */
1454
1455 static rtx
1456 scan_region (insn, n, delete_outer)
1457      rtx insn;
1458      int n;
1459      int *delete_outer;
1460 {
1461   rtx start = insn;
1462
1463   /* Assume we can delete the region.  */
1464   int delete = 1;
1465
1466   assert (insn != NULL_RTX
1467           && GET_CODE (insn) == NOTE
1468           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
1469           && NOTE_BLOCK_NUMBER (insn) == n
1470           && delete_outer != NULL);
1471
1472   insn = NEXT_INSN (insn);
1473
1474   /* Look for the matching end.  */
1475   while (! (GET_CODE (insn) == NOTE
1476             && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
1477     {
1478       /* If anything can throw, we can't remove the region.  */
1479       if (delete && can_throw (insn))
1480         {
1481           delete = 0;
1482         }
1483
1484       /* Watch out for and handle nested regions.  */
1485       if (GET_CODE (insn) == NOTE
1486           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1487         {
1488           insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &delete);
1489         }
1490
1491       insn = NEXT_INSN (insn);
1492     }
1493
1494   /* The _BEG/_END NOTEs must match and nest.  */
1495   if (NOTE_BLOCK_NUMBER (insn) != n)
1496     abort ();
1497
1498   /* If anything in this exception region can throw, we can throw.  */
1499   if (! delete)
1500     *delete_outer = 0;
1501   else
1502     {
1503       /* Delete the start and end of the region.  */
1504       delete_insn (start);
1505       delete_insn (insn);
1506
1507       /* Only do this part if we have built the exception handler
1508          labels.  */
1509       if (exception_handler_labels)
1510         {
1511           rtx x, *prev = &exception_handler_labels;
1512
1513           /* Find it in the list of handlers.  */
1514           for (x = exception_handler_labels; x; x = XEXP (x, 1))
1515             {
1516               rtx label = XEXP (x, 0);
1517               if (CODE_LABEL_NUMBER (label) == n)
1518                 {
1519                   /* If we are the last reference to the handler,
1520                      delete it.  */
1521                   if (--LABEL_NUSES (label) == 0)
1522                     delete_insn (label);
1523
1524                   if (optimize)
1525                     {
1526                       /* Remove it from the list of exception handler
1527                          labels, if we are optimizing.  If we are not, then
1528                          leave it in the list, as we are not really going to
1529                          remove the region.  */
1530                       *prev = XEXP (x, 1);
1531                       XEXP (x, 1) = 0;
1532                       XEXP (x, 0) = 0;
1533                     }
1534
1535                   break;
1536                 }
1537               prev = &XEXP (x, 1);
1538             }
1539         }
1540     }
1541   return insn;
1542 }
1543
1544 /* Perform various interesting optimizations for exception handling
1545    code.
1546
1547    We look for empty exception regions and make them go (away). The
1548    jump optimization code will remove the handler if nothing else uses
1549    it.  */
1550
1551 void
1552 exception_optimize ()
1553 {
1554   rtx insn, regions = NULL_RTX;
1555   int n;
1556
1557   /* Remove empty regions.  */
1558   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1559     {
1560       if (GET_CODE (insn) == NOTE
1561           && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1562         {
1563           /* Since scan_region () will return the NOTE_INSN_EH_REGION_END
1564              insn, we will indirectly skip through all the insns
1565              inbetween. We are also guaranteed that the value of insn
1566              returned will be valid, as otherwise scan_region () won't
1567              return.  */
1568           insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &n);
1569         }
1570     }
1571 }