(sne): Modified to use negc instead of xor.
[official-gcc.git] / gcc / except.c
blob4d8d1bc9a29afdd9ea4afdfde86b8c3c6fcf3c88
1 /* Implements exception handling.
2 Copyright (C) 1989, 92-95, 1996 Free Software Foundation, Inc.
3 Contributed by Mike Stump <mrs@cygnus.com>.
5 This file is part of GNU CC.
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.
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.
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. */
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.
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.
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.
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.
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.
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.
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).
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.
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).
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.
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.
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).
109 Internal implementation details:
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.
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.
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).
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.
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.
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 ().
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.)
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.)
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.
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.
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.
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.
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.
214 Unwinding the stack:
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.
221 Whether or not these inlined unwinders are necessary is
222 target-specific.
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.
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.
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.
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.
248 Future directions:
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.
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.
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.
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.
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.
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.
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.
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).
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. */
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"
333 /* A list of labels used for exception handlers. Created by
334 find_exception_handler_labels for the optimization passes. */
336 rtx exception_handler_labels;
338 /* Nonzero means that __throw was invoked.
340 This is used by the C++ frontend to know if code needs to be emitted
341 for __throw or not. */
343 int throw_used;
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.
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. */
355 struct eh_stack ehstack;
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.
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 (),
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. */
368 struct eh_queue ehqueue;
370 /* Insns for all of the exception handlers for the current function.
371 They are currently emitted by the frontend code. */
373 rtx catch_clauses;
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. */
379 static tree protect_list;
381 /* Stacks to keep track of various labels. */
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. */
389 struct label_node *caught_return_label_stack = NULL;
391 /* A random data area for the front end's own use. */
393 struct label_node *false_label_stack = NULL;
395 /* The rtx and the tree for the saved PC value. */
397 rtx eh_saved_pc_rtx;
398 tree eh_saved_pc;
400 rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
402 /* Various support routines to manipulate the various data structures
403 used by the exception handling code. */
405 /* Push a label entry onto the given STACK. */
407 void
408 push_label_entry (stack, rlabel, tlabel)
409 struct label_node **stack;
410 rtx rlabel;
411 tree tlabel;
413 struct label_node *newnode
414 = (struct label_node *) xmalloc (sizeof (struct label_node));
416 if (rlabel)
417 newnode->u.rlabel = rlabel;
418 else
419 newnode->u.tlabel = tlabel;
420 newnode->chain = *stack;
421 *stack = newnode;
424 /* Pop a label entry from the given STACK. */
427 pop_label_entry (stack)
428 struct label_node **stack;
430 rtx label;
431 struct label_node *tempnode;
433 if (! *stack)
434 return NULL_RTX;
436 tempnode = *stack;
437 label = tempnode->u.rlabel;
438 *stack = (*stack)->chain;
439 free (tempnode);
441 return label;
444 /* Return the top element of the given STACK. */
446 tree
447 top_label_entry (stack)
448 struct label_node **stack;
450 if (! *stack)
451 return NULL_TREE;
453 return (*stack)->u.tlabel;
456 /* Make a copy of ENTRY using xmalloc to allocate the space. */
458 static struct eh_entry *
459 copy_eh_entry (entry)
460 struct eh_entry *entry;
462 struct eh_entry *newentry;
464 newentry = (struct eh_entry *) xmalloc (sizeof (struct eh_entry));
465 bcopy ((char *) entry, (char *) newentry, sizeof (struct eh_entry));
467 return newentry;
470 /* Push a new eh_node entry onto STACK, and return the start label for
471 the entry. */
473 static rtx
474 push_eh_entry (stack)
475 struct eh_stack *stack;
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));
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;
485 node->entry = entry;
486 node->chain = stack->top;
487 stack->top = node;
489 return entry->start_label;
492 /* Pop an entry from the given STACK. */
494 static struct eh_entry *
495 pop_eh_entry (stack)
496 struct eh_stack *stack;
498 struct eh_node *tempnode;
499 struct eh_entry *tempentry;
501 tempnode = stack->top;
502 tempentry = tempnode->entry;
503 stack->top = stack->top->chain;
504 free (tempnode);
506 return tempentry;
509 /* Enqueue an ENTRY onto the given QUEUE. */
511 static void
512 enqueue_eh_entry (queue, entry)
513 struct eh_queue *queue;
514 struct eh_entry *entry;
516 struct eh_node *node = (struct eh_node *) xmalloc (sizeof (struct eh_node));
518 node->entry = entry;
519 node->chain = NULL;
521 if (queue->head == NULL)
523 queue->head = node;
525 else
527 queue->tail->chain = node;
529 queue->tail = node;
532 /* Dequeue an entry from the given QUEUE. */
534 static struct eh_entry *
535 dequeue_eh_entry (queue)
536 struct eh_queue *queue;
538 struct eh_node *tempnode;
539 struct eh_entry *tempentry;
541 if (queue->head == NULL)
542 return NULL;
544 tempnode = queue->head;
545 queue->head = queue->head->chain;
547 tempentry = tempnode->entry;
548 free (tempnode);
550 return tempentry;
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.
557 This is used to ensure that -fexceptions has been specified if the
558 compiler tries to use any exception-specific functions. */
561 doing_eh (do_warn)
562 int do_warn;
564 if (! flag_exceptions)
566 static int warned = 0;
567 if (! warned && do_warn)
569 error ("exception handling disabled, use -fexceptions to enable");
570 warned = 1;
572 return 0;
574 return 1;
577 /* Given a return address in ADDR, determine the address we should use
578 to find the corresponding EH region. */
581 eh_outer_context (addr)
582 rtx addr;
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
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
599 return addr;
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. */
606 void
607 add_partial_entry (handler)
608 tree handler;
610 expand_eh_region_start ();
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 ();
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. */
623 void
624 expand_eh_region_start ()
626 rtx note;
628 /* This is the old code. */
629 if (! doing_eh (0))
630 return;
632 #if 0
633 /* Maybe do this to prevent jumping in and so on... */
634 pushlevel (0);
635 #endif
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);
643 /* Output a note marking the end of the exception handling region on
644 the top of ehstack.
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.
649 HANDLER will be transformed to rtl when expand_leftover_cleanups ()
650 is invoked. */
652 void
653 expand_eh_region_end (handler)
654 tree handler;
656 rtx note;
658 struct eh_entry *entry;
660 if (! doing_eh (0))
661 return;
663 entry = pop_eh_entry (&ehstack);
665 note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
666 NOTE_BLOCK_NUMBER (note) = CODE_LABEL_NUMBER (entry->exception_handler_label);
668 /* Emit a label marking the end of this exception region. */
669 emit_label (entry->end_label);
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 ());
678 entry->finalization = handler;
680 enqueue_eh_entry (&ehqueue, entry);
682 #if 0
683 /* Maybe do this to prevent jumping in and so on... */
684 poplevel (1, 0, 0);
685 #endif
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.
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. */
696 static void
697 emit_throw ()
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 ();
709 /* An internal throw with an indirect CONTEXT we want to throw from.
710 CONTEXT evaluates to the context of the throw. */
712 static void
713 expand_internal_throw_indirect (context)
714 rtx context;
716 assemble_external (eh_saved_pc);
717 emit_move_insn (eh_saved_pc_rtx, context);
718 emit_throw ();
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. */
725 void
726 expand_internal_throw (context)
727 rtx context;
729 expand_internal_throw_indirect (gen_rtx (LABEL_REF, Pmode, context));
732 /* Called from expand_exception_blocks and expand_end_catch_block to
733 emit any pending handlers/cleanups queued from expand_eh_region_end (). */
735 void
736 expand_leftover_cleanups ()
738 struct eh_entry *entry;
740 while ((entry = dequeue_eh_entry (&ehqueue)) != 0)
742 rtx prev;
744 /* A leftover try block. Shouldn't be one here. */
745 if (entry->finalization == integer_zero_node)
746 abort ();
748 /* Output the label for the start of the exception handler. */
749 emit_label (entry->exception_handler_label);
751 /* And now generate the insns for the handler. */
752 expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
754 prev = get_last_insn ();
755 if (! (prev && GET_CODE (prev) == BARRIER))
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);
764 free (entry);
768 /* Called at the start of a block of try statements. */
769 void
770 expand_start_try_stmts ()
772 if (! doing_eh (1))
773 return;
775 expand_eh_region_start ();
778 /* Generate RTL for the start of a group of catch clauses.
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. */
785 void
786 expand_start_all_catch ()
788 struct eh_entry *entry;
789 tree label;
791 if (! doing_eh (1))
792 return;
794 /* End the try block. */
795 expand_eh_region_end (integer_zero_node);
797 emit_line_note (input_filename, lineno);
798 label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
800 /* The label for the exception handling block that we will save.
801 This is Lresume in the documention. */
802 expand_label (label);
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 ());
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);
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 ();
820 while (1)
822 rtx prev;
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.
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);
837 /* When we get down to the matching entry for this try block, stop. */
838 if (entry->finalization == integer_zero_node)
840 /* Don't forget to free this entry. */
841 free (entry);
842 break;
845 prev = get_last_insn ();
846 if (prev == NULL || GET_CODE (prev) != BARRIER)
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.
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. */
856 expand_internal_throw (entry->end_label);
858 free (entry);
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. */
868 void
869 expand_end_all_catch ()
871 rtx new_catch_clause;
873 if (! doing_eh (1))
874 return;
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.
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. */
886 expand_internal_throw (DECL_RTL (top_label_entry (&caught_return_label_stack)));
888 /* Now we have the complete catch sequence. */
889 new_catch_clause = get_insns ();
890 end_sequence ();
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);
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 ();
902 /* Here we fall through into the continuation code. */
905 /* End all the pending exception regions on protect_list. The handlers
906 will be emitted when expand_leftover_cleanups () is invoked. */
908 void
909 end_protect_partials ()
911 while (protect_list)
913 expand_eh_region_end (TREE_VALUE (protect_list));
914 protect_list = TREE_CHAIN (protect_list);
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.
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 (). */
926 static int *eh_table;
927 static int eh_table_size;
928 static int eh_table_max_size;
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.
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. */
938 void
939 add_eh_table_entry (n)
940 int n;
942 #ifndef OMIT_EH_TABLE
943 if (eh_table_size >= eh_table_max_size)
945 if (eh_table)
947 eh_table_max_size += eh_table_max_size>>1;
949 if (eh_table_max_size < 0)
950 abort ();
952 if ((eh_table = (int *) realloc (eh_table,
953 eh_table_max_size * sizeof (int)))
954 == 0)
955 fatal ("virtual memory exhausted");
957 else
959 eh_table_max_size = 252;
960 eh_table = (int *) xmalloc (eh_table_max_size * sizeof (int));
963 eh_table[eh_table_size++] = n;
964 #endif
967 /* Return a non-zero value if we need to output an exception table.
969 On some platforms, we don't have to output a table explicitly.
970 This routine doesn't mean we don't have one. */
973 exception_table_p ()
975 if (eh_table)
976 return 1;
978 return 0;
981 /* Output the entry of the exception table corresponding to to the
982 exception region numbered N to file FILE.
984 N is the code label number corresponding to the handler of the
985 region. */
987 static void
988 output_exception_table_entry (file, n)
989 FILE *file;
990 int n;
992 char buf[256];
993 rtx sym;
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);
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);
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);
1007 putc ('\n', file); /* blank line */
1010 /* Output the exception table if we have and need one. */
1012 void
1013 output_exception_table ()
1015 int i;
1016 extern FILE *asm_out_file;
1018 if (! doing_eh (0))
1019 return;
1021 exception_section ();
1023 /* Beginning marker for table. */
1024 assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
1025 assemble_label ("__EXCEPTION_TABLE__");
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 */
1032 for (i = 0; i < eh_table_size; ++i)
1033 output_exception_table_entry (asm_out_file, eh_table[i]);
1035 free (eh_table);
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 */
1045 /* Generate code to initialize the exception table at program startup
1046 time. */
1048 void
1049 register_exception_table ()
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);
1057 /* Emit the RTL for the start of the per-function unwinder for the
1058 current function. See emit_unwinder () for further information.
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. */
1064 void
1065 start_eh_unwinder ()
1067 #ifdef DOESNT_NEED_UNWINDER
1068 if (DOESNT_NEED_UNWINDER)
1069 return;
1070 #endif
1072 expand_eh_region_start ();
1075 /* Emit insns for the end of the per-function unwinder for the
1076 current function. */
1078 void
1079 end_eh_unwinder ()
1081 tree expr;
1082 rtx return_val_rtx, ret_val, label, end, insns;
1084 if (! doing_eh (0))
1085 return;
1087 #ifdef DOESNT_NEED_UNWINDER
1088 if (DOESNT_NEED_UNWINDER)
1089 return;
1090 #endif
1092 assemble_external (eh_saved_pc);
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);
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);
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);
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
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
1126 end = gen_label_rtx ();
1127 emit_jump (end);
1129 RTL_EXPR_SEQUENCE (expr) = get_insns ();
1130 end_sequence ();
1131 expand_eh_region_end (expr);
1133 emit_jump (end);
1135 #ifndef JUMP_TO_THROW
1136 emit_label (label);
1137 emit_throw ();
1138 #endif
1140 expand_leftover_cleanups ();
1142 emit_label (end);
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.
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.
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.
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. */
1162 void
1163 emit_unwinder ()
1165 rtx insns, insn;
1167 start_sequence ();
1168 start_eh_unwinder ();
1169 insns = get_insns ();
1170 end_sequence ();
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 ());
1177 start_sequence ();
1178 end_eh_unwinder ();
1179 insns = get_insns ();
1180 end_sequence ();
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;
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);
1194 if (GET_CODE (insn) == CODE_LABEL
1195 && GET_CODE (PREV_INSN (insn)) == BARRIER)
1197 insn = PREV_INSN (insn);
1199 else
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);
1207 emit_insns_after (insns, insn);
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.
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. */
1217 void
1218 find_exception_handler_labels ()
1220 rtx insn;
1221 int max_labelno = max_label_num ();
1222 int min_labelno = get_first_label_num ();
1223 rtx *labels;
1225 exception_handler_labels = NULL_RTX;
1227 /* If we aren't doing exception handling, there isn't much to check. */
1228 if (! doing_eh (0))
1229 return;
1231 /* Generate a handy reference to each label. */
1233 labels = (rtx *) alloca ((max_labelno - min_labelno) * sizeof (rtx));
1234 bzero ((char *) labels, (max_labelno - min_labelno) * sizeof (rtx));
1236 /* Arrange for labels to be indexed directly by CODE_LABEL_NUMBER. */
1237 labels -= min_labelno;
1239 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
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;
1247 /* For each start of a region, add its label to the list. */
1249 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1251 if (GET_CODE (insn) == NOTE
1252 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1254 rtx label = NULL_RTX;
1256 if (NOTE_BLOCK_NUMBER (insn) >= min_labelno
1257 && NOTE_BLOCK_NUMBER (insn) < max_labelno)
1259 label = labels[NOTE_BLOCK_NUMBER (insn)];
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));
1269 else
1270 warning ("mismatched EH region %d", NOTE_BLOCK_NUMBER (insn));
1275 /* Perform sanity checking on the exception_handler_labels list.
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. */
1281 void
1282 check_exception_handler_labels ()
1284 rtx insn, handler;
1286 /* If we aren't doing exception handling, there isn't much to check. */
1287 if (! doing_eh (0))
1288 return;
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. */
1294 for (handler = exception_handler_labels;
1295 handler;
1296 handler = XEXP (handler, 1))
1298 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1300 if (GET_CODE (insn) == CODE_LABEL)
1302 if (CODE_LABEL_NUMBER (insn)
1303 == CODE_LABEL_NUMBER (XEXP (handler, 0)))
1305 if (insn != XEXP (handler, 0))
1306 warning ("mismatched handler %d",
1307 CODE_LABEL_NUMBER (insn));
1308 break;
1312 if (insn == NULL_RTX)
1313 warning ("handler not found %d",
1314 CODE_LABEL_NUMBER (XEXP (handler, 0)));
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))
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))
1325 for (handler = exception_handler_labels;
1326 handler;
1327 handler = XEXP (handler, 1))
1329 if (CODE_LABEL_NUMBER (XEXP (handler, 0))
1330 == NOTE_BLOCK_NUMBER (insn))
1331 break;
1333 if (handler == NULL_RTX)
1334 warning ("region exists, no handler %d",
1335 NOTE_BLOCK_NUMBER (insn));
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. */
1346 /* Toplevel initialization for EH things. */
1348 void
1349 init_eh ()
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));
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);
1362 /* Initialize the per-function EH information. */
1364 void
1365 init_eh_for_function ()
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;
1375 /* Save some of the per-function EH info into the save area denoted by
1378 This is currently called from save_stmt_status (). */
1380 void
1381 save_eh_status (p)
1382 struct function *p;
1384 assert (p != NULL);
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;
1393 init_eh ();
1396 /* Restore the per-function EH info saved into the area denoted by P.
1398 This is currently called from restore_stmt_status. */
1400 void
1401 restore_eh_status (p)
1402 struct function *p;
1404 assert (p != NULL);
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;
1414 /* This section is for the exception handling specific optimization
1415 pass. First are the internal routines, and then the main
1416 optimization pass. */
1418 /* Determine if the given INSN can throw an exception. */
1420 static int
1421 can_throw (insn)
1422 rtx insn;
1424 /* Calls can always potentially throw exceptions. */
1425 if (GET_CODE (insn) == CALL_INSN)
1426 return 1;
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
1435 return 0;
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.
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.
1449 Returns the NOTE_INSN_EH_REGION_END corresponding to this region, or
1450 calls abort () if it can't find one.
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. */
1455 static rtx
1456 scan_region (insn, n, delete_outer)
1457 rtx insn;
1458 int n;
1459 int *delete_outer;
1461 rtx start = insn;
1463 /* Assume we can delete the region. */
1464 int delete = 1;
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);
1472 insn = NEXT_INSN (insn);
1474 /* Look for the matching end. */
1475 while (! (GET_CODE (insn) == NOTE
1476 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
1478 /* If anything can throw, we can't remove the region. */
1479 if (delete && can_throw (insn))
1481 delete = 0;
1484 /* Watch out for and handle nested regions. */
1485 if (GET_CODE (insn) == NOTE
1486 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
1488 insn = scan_region (insn, NOTE_BLOCK_NUMBER (insn), &delete);
1491 insn = NEXT_INSN (insn);
1494 /* The _BEG/_END NOTEs must match and nest. */
1495 if (NOTE_BLOCK_NUMBER (insn) != n)
1496 abort ();
1498 /* If anything in this exception region can throw, we can throw. */
1499 if (! delete)
1500 *delete_outer = 0;
1501 else
1503 /* Delete the start and end of the region. */
1504 delete_insn (start);
1505 delete_insn (insn);
1507 /* Only do this part if we have built the exception handler
1508 labels. */
1509 if (exception_handler_labels)
1511 rtx x, *prev = &exception_handler_labels;
1513 /* Find it in the list of handlers. */
1514 for (x = exception_handler_labels; x; x = XEXP (x, 1))
1516 rtx label = XEXP (x, 0);
1517 if (CODE_LABEL_NUMBER (label) == n)
1519 /* If we are the last reference to the handler,
1520 delete it. */
1521 if (--LABEL_NUSES (label) == 0)
1522 delete_insn (label);
1524 if (optimize)
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;
1535 break;
1537 prev = &XEXP (x, 1);
1541 return insn;
1544 /* Perform various interesting optimizations for exception handling
1545 code.
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. */
1551 void
1552 exception_optimize ()
1554 rtx insn, regions = NULL_RTX;
1555 int n;
1557 /* Remove empty regions. */
1558 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1560 if (GET_CODE (insn) == NOTE
1561 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
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);