OSDN Git Service

* doc/install.texi (Prerequisites): Update documentation of
[pf3gnuchains/gcc-fork.git] / gcc / except.c
1 /* Implements exception handling.
2    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4    Contributed by Mike Stump <mrs@cygnus.com>.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA.  */
22
23
24 /* An exception is an event that can be signaled from within a
25    function. This event can then be "caught" or "trapped" by the
26    callers of this function. This potentially allows program flow to
27    be transferred to any arbitrary code associated with a function call
28    several levels up the stack.
29
30    The intended use for this mechanism is for signaling "exceptional
31    events" in an out-of-band fashion, hence its name. The C++ language
32    (and many other OO-styled or functional languages) practically
33    requires such a mechanism, as otherwise it becomes very difficult
34    or even impossible to signal failure conditions in complex
35    situations.  The traditional C++ example is when an error occurs in
36    the process of constructing an object; without such a mechanism, it
37    is impossible to signal that the error occurs without adding global
38    state variables and error checks around every object construction.
39
40    The act of causing this event to occur is referred to as "throwing
41    an exception". (Alternate terms include "raising an exception" or
42    "signaling an exception".) The term "throw" is used because control
43    is returned to the callers of the function that is signaling the
44    exception, and thus there is the concept of "throwing" the
45    exception up the call stack.
46
47    [ Add updated documentation on how to use this.  ]  */
48
49
50 #include "config.h"
51 #include "system.h"
52 #include "coretypes.h"
53 #include "tm.h"
54 #include "rtl.h"
55 #include "tree.h"
56 #include "flags.h"
57 #include "function.h"
58 #include "expr.h"
59 #include "libfuncs.h"
60 #include "insn-config.h"
61 #include "except.h"
62 #include "integrate.h"
63 #include "hard-reg-set.h"
64 #include "basic-block.h"
65 #include "output.h"
66 #include "dwarf2asm.h"
67 #include "dwarf2out.h"
68 #include "dwarf2.h"
69 #include "toplev.h"
70 #include "hashtab.h"
71 #include "intl.h"
72 #include "ggc.h"
73 #include "tm_p.h"
74 #include "target.h"
75 #include "langhooks.h"
76 #include "cgraph.h"
77
78 /* Provide defaults for stuff that may not be defined when using
79    sjlj exceptions.  */
80 #ifndef EH_RETURN_DATA_REGNO
81 #define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
82 #endif
83
84
85 /* Nonzero means enable synchronous exceptions for non-call instructions.  */
86 int flag_non_call_exceptions;
87
88 /* Protect cleanup actions with must-not-throw regions, with a call
89    to the given failure handler.  */
90 tree (*lang_protect_cleanup_actions) (void);
91
92 /* Return true if type A catches type B.  */
93 int (*lang_eh_type_covers) (tree a, tree b);
94
95 /* Map a type to a runtime object to match type.  */
96 tree (*lang_eh_runtime_type) (tree);
97
98 /* A hash table of label to region number.  */
99
100 struct ehl_map_entry GTY(())
101 {
102   rtx label;
103   struct eh_region *region;
104 };
105
106 static GTY(()) int call_site_base;
107 static GTY ((param_is (union tree_node)))
108   htab_t type_to_runtime_map;
109
110 /* Describe the SjLj_Function_Context structure.  */
111 static GTY(()) tree sjlj_fc_type_node;
112 static int sjlj_fc_call_site_ofs;
113 static int sjlj_fc_data_ofs;
114 static int sjlj_fc_personality_ofs;
115 static int sjlj_fc_lsda_ofs;
116 static int sjlj_fc_jbuf_ofs;
117 \f
118 /* Describes one exception region.  */
119 struct eh_region GTY(())
120 {
121   /* The immediately surrounding region.  */
122   struct eh_region *outer;
123
124   /* The list of immediately contained regions.  */
125   struct eh_region *inner;
126   struct eh_region *next_peer;
127
128   /* An identifier for this region.  */
129   int region_number;
130
131   /* When a region is deleted, its parents inherit the REG_EH_REGION
132      numbers already assigned.  */
133   bitmap aka;
134
135   /* Each region does exactly one thing.  */
136   enum eh_region_type
137   { 
138     ERT_UNKNOWN = 0,
139     ERT_CLEANUP,
140     ERT_TRY,
141     ERT_CATCH,
142     ERT_ALLOWED_EXCEPTIONS,
143     ERT_MUST_NOT_THROW,
144     ERT_THROW,
145     ERT_FIXUP
146   } type;
147
148   /* Holds the action to perform based on the preceding type.  */
149   union eh_region_u {
150     /* A list of catch blocks, a surrounding try block,
151        and the label for continuing after a catch.  */
152     struct eh_region_u_try {
153       struct eh_region *catch;
154       struct eh_region *last_catch;
155       struct eh_region *prev_try;
156       rtx continue_label;
157     } GTY ((tag ("ERT_TRY"))) try;
158
159     /* The list through the catch handlers, the list of type objects
160        matched, and the list of associated filters.  */
161     struct eh_region_u_catch {
162       struct eh_region *next_catch;
163       struct eh_region *prev_catch;
164       tree type_list;
165       tree filter_list;
166     } GTY ((tag ("ERT_CATCH"))) catch;
167
168     /* A tree_list of allowed types.  */
169     struct eh_region_u_allowed {
170       tree type_list;
171       int filter;
172     } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
173
174     /* The type given by a call to "throw foo();", or discovered
175        for a throw.  */
176     struct eh_region_u_throw {
177       tree type;
178     } GTY ((tag ("ERT_THROW"))) throw;
179
180     /* Retain the cleanup expression even after expansion so that
181        we can match up fixup regions.  */
182     struct eh_region_u_cleanup {
183       tree exp;
184       struct eh_region *prev_try;
185     } GTY ((tag ("ERT_CLEANUP"))) cleanup;
186
187     /* The real region (by expression and by pointer) that fixup code
188        should live in.  */
189     struct eh_region_u_fixup {
190       tree cleanup_exp;
191       struct eh_region *real_region;
192       bool resolved;
193     } GTY ((tag ("ERT_FIXUP"))) fixup;
194   } GTY ((desc ("%0.type"))) u;
195
196   /* Entry point for this region's handler before landing pads are built.  */
197   rtx label;
198   tree tree_label;
199
200   /* Entry point for this region's handler from the runtime eh library.  */
201   rtx landing_pad;
202
203   /* Entry point for this region's handler from an inner region.  */
204   rtx post_landing_pad;
205
206   /* The RESX insn for handing off control to the next outermost handler,
207      if appropriate.  */
208   rtx resume;
209
210   /* True if something in this region may throw.  */
211   unsigned may_contain_throw : 1;
212 };
213
214 struct call_site_record GTY(())
215 {
216   rtx landing_pad;
217   int action;
218 };
219
220 /* Used to save exception status for each function.  */
221 struct eh_status GTY(())
222 {
223   /* The tree of all regions for this function.  */
224   struct eh_region *region_tree;
225
226   /* The same information as an indexable array.  */
227   struct eh_region ** GTY ((length ("%h.last_region_number"))) region_array;
228
229   /* The most recently open region.  */
230   struct eh_region *cur_region;
231
232   /* This is the region for which we are processing catch blocks.  */
233   struct eh_region *try_region;
234
235   rtx filter;
236   rtx exc_ptr;
237
238   int built_landing_pads;
239   int last_region_number;
240
241   varray_type ttype_data;
242   varray_type ehspec_data;
243   varray_type action_record_data;
244
245   htab_t GTY ((param_is (struct ehl_map_entry))) exception_handler_label_map;
246
247   struct call_site_record * GTY ((length ("%h.call_site_data_used")))
248     call_site_data;
249   int call_site_data_used;
250   int call_site_data_size;
251
252   rtx ehr_stackadj;
253   rtx ehr_handler;
254   rtx ehr_label;
255
256   rtx sjlj_fc;
257   rtx sjlj_exit_after;
258 };
259
260 \f
261 static int t2r_eq (const void *, const void *);
262 static hashval_t t2r_hash (const void *);
263 static void add_type_for_runtime (tree);
264 static tree lookup_type_for_runtime (tree);
265
266 static struct eh_region *expand_eh_region_end (void);
267
268 static void resolve_fixup_regions (void);
269 static void remove_fixup_regions (void);
270 static void remove_unreachable_regions (rtx);
271 static void convert_from_eh_region_ranges_1 (rtx *, int *, int);
272
273 static struct eh_region *duplicate_eh_region_1 (struct eh_region *,
274                                                 struct inline_remap *);
275 static void duplicate_eh_region_2 (struct eh_region *, struct eh_region **);
276 static int ttypes_filter_eq (const void *, const void *);
277 static hashval_t ttypes_filter_hash (const void *);
278 static int ehspec_filter_eq (const void *, const void *);
279 static hashval_t ehspec_filter_hash (const void *);
280 static int add_ttypes_entry (htab_t, tree);
281 static int add_ehspec_entry (htab_t, htab_t, tree);
282 static void assign_filter_values (void);
283 static void build_post_landing_pads (void);
284 static void connect_post_landing_pads (void);
285 static void dw2_build_landing_pads (void);
286
287 struct sjlj_lp_info;
288 static bool sjlj_find_directly_reachable_regions (struct sjlj_lp_info *);
289 static void sjlj_assign_call_site_values (rtx, struct sjlj_lp_info *);
290 static void sjlj_mark_call_sites (struct sjlj_lp_info *);
291 static void sjlj_emit_function_enter (rtx);
292 static void sjlj_emit_function_exit (void);
293 static void sjlj_emit_dispatch_table (rtx, struct sjlj_lp_info *);
294 static void sjlj_build_landing_pads (void);
295
296 static hashval_t ehl_hash (const void *);
297 static int ehl_eq (const void *, const void *);
298 static void add_ehl_entry (rtx, struct eh_region *);
299 static void remove_exception_handler_label (rtx);
300 static void remove_eh_handler (struct eh_region *);
301 static int for_each_eh_label_1 (void **, void *);
302
303 /* The return value of reachable_next_level.  */
304 enum reachable_code
305 {
306   /* The given exception is not processed by the given region.  */
307   RNL_NOT_CAUGHT,
308   /* The given exception may need processing by the given region.  */
309   RNL_MAYBE_CAUGHT,
310   /* The given exception is completely processed by the given region.  */
311   RNL_CAUGHT,
312   /* The given exception is completely processed by the runtime.  */
313   RNL_BLOCKED
314 };
315
316 struct reachable_info;
317 static enum reachable_code reachable_next_level (struct eh_region *, tree,
318                                                  struct reachable_info *);
319
320 static int action_record_eq (const void *, const void *);
321 static hashval_t action_record_hash (const void *);
322 static int add_action_record (htab_t, int, int);
323 static int collect_one_action_chain (htab_t, struct eh_region *);
324 static int add_call_site (rtx, int);
325
326 static void push_uleb128 (varray_type *, unsigned int);
327 static void push_sleb128 (varray_type *, int);
328 #ifndef HAVE_AS_LEB128
329 static int dw2_size_of_call_site_table (void);
330 static int sjlj_size_of_call_site_table (void);
331 #endif
332 static void dw2_output_call_site_table (void);
333 static void sjlj_output_call_site_table (void);
334
335 \f
336 /* Routine to see if exception handling is turned on.
337    DO_WARN is nonzero if we want to inform the user that exception
338    handling is turned off.
339
340    This is used to ensure that -fexceptions has been specified if the
341    compiler tries to use any exception-specific functions.  */
342
343 int
344 doing_eh (int do_warn)
345 {
346   if (! flag_exceptions)
347     {
348       static int warned = 0;
349       if (! warned && do_warn)
350         {
351           error ("exception handling disabled, use -fexceptions to enable");
352           warned = 1;
353         }
354       return 0;
355     }
356   return 1;
357 }
358
359 \f
360 void
361 init_eh (void)
362 {
363   if (! flag_exceptions)
364     return;
365
366   type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
367
368   /* Create the SjLj_Function_Context structure.  This should match
369      the definition in unwind-sjlj.c.  */
370   if (USING_SJLJ_EXCEPTIONS)
371     {
372       tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp;
373
374       sjlj_fc_type_node = lang_hooks.types.make_type (RECORD_TYPE);
375
376       f_prev = build_decl (FIELD_DECL, get_identifier ("__prev"),
377                            build_pointer_type (sjlj_fc_type_node));
378       DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node;
379
380       f_cs = build_decl (FIELD_DECL, get_identifier ("__call_site"),
381                          integer_type_node);
382       DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
383
384       tmp = build_index_type (build_int_2 (4 - 1, 0));
385       tmp = build_array_type (lang_hooks.types.type_for_mode (word_mode, 1),
386                               tmp);
387       f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp);
388       DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
389
390       f_per = build_decl (FIELD_DECL, get_identifier ("__personality"),
391                           ptr_type_node);
392       DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
393
394       f_lsda = build_decl (FIELD_DECL, get_identifier ("__lsda"),
395                            ptr_type_node);
396       DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
397
398 #ifdef DONT_USE_BUILTIN_SETJMP
399 #ifdef JMP_BUF_SIZE
400       tmp = build_int_2 (JMP_BUF_SIZE - 1, 0);
401 #else
402       /* Should be large enough for most systems, if it is not,
403          JMP_BUF_SIZE should be defined with the proper value.  It will
404          also tend to be larger than necessary for most systems, a more
405          optimal port will define JMP_BUF_SIZE.  */
406       tmp = build_int_2 (FIRST_PSEUDO_REGISTER + 2 - 1, 0);
407 #endif
408 #else
409       /* builtin_setjmp takes a pointer to 5 words.  */
410       tmp = build_int_2 (5 * BITS_PER_WORD / POINTER_SIZE - 1, 0);
411 #endif
412       tmp = build_index_type (tmp);
413       tmp = build_array_type (ptr_type_node, tmp);
414       f_jbuf = build_decl (FIELD_DECL, get_identifier ("__jbuf"), tmp);
415 #ifdef DONT_USE_BUILTIN_SETJMP
416       /* We don't know what the alignment requirements of the
417          runtime's jmp_buf has.  Overestimate.  */
418       DECL_ALIGN (f_jbuf) = BIGGEST_ALIGNMENT;
419       DECL_USER_ALIGN (f_jbuf) = 1;
420 #endif
421       DECL_FIELD_CONTEXT (f_jbuf) = sjlj_fc_type_node;
422
423       TYPE_FIELDS (sjlj_fc_type_node) = f_prev;
424       TREE_CHAIN (f_prev) = f_cs;
425       TREE_CHAIN (f_cs) = f_data;
426       TREE_CHAIN (f_data) = f_per;
427       TREE_CHAIN (f_per) = f_lsda;
428       TREE_CHAIN (f_lsda) = f_jbuf;
429
430       layout_type (sjlj_fc_type_node);
431
432       /* Cache the interesting field offsets so that we have
433          easy access from rtl.  */
434       sjlj_fc_call_site_ofs
435         = (tree_low_cst (DECL_FIELD_OFFSET (f_cs), 1)
436            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_cs), 1) / BITS_PER_UNIT);
437       sjlj_fc_data_ofs
438         = (tree_low_cst (DECL_FIELD_OFFSET (f_data), 1)
439            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_data), 1) / BITS_PER_UNIT);
440       sjlj_fc_personality_ofs
441         = (tree_low_cst (DECL_FIELD_OFFSET (f_per), 1)
442            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_per), 1) / BITS_PER_UNIT);
443       sjlj_fc_lsda_ofs
444         = (tree_low_cst (DECL_FIELD_OFFSET (f_lsda), 1)
445            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_lsda), 1) / BITS_PER_UNIT);
446       sjlj_fc_jbuf_ofs
447         = (tree_low_cst (DECL_FIELD_OFFSET (f_jbuf), 1)
448            + tree_low_cst (DECL_FIELD_BIT_OFFSET (f_jbuf), 1) / BITS_PER_UNIT);
449     }
450 }
451
452 void
453 init_eh_for_function (void)
454 {
455   cfun->eh = ggc_alloc_cleared (sizeof (struct eh_status));
456 }
457 \f
458 /* Routines to generate the exception tree somewhat directly.  
459    These are used from tree-eh.c when processing exception related
460    nodes during tree optimization.  */
461
462 static struct eh_region *
463 gen_eh_region (enum eh_region_type type, struct eh_region *outer)
464 {
465   struct eh_region *new;
466
467 #ifdef ENABLE_CHECKING
468   if (! doing_eh (0))
469     abort ();
470 #endif
471
472   /* Insert a new blank region as a leaf in the tree.  */
473   new = ggc_alloc_cleared (sizeof (*new));
474   new->type = type;
475   new->outer = outer;
476   if (outer)
477     {
478       new->next_peer = outer->inner;
479       outer->inner = new;
480     }
481   else
482     {
483       new->next_peer = cfun->eh->region_tree;
484       cfun->eh->region_tree = new;
485     }
486
487   new->region_number = ++cfun->eh->last_region_number;
488
489   return new;
490 }
491
492 struct eh_region *
493 gen_eh_region_cleanup (struct eh_region *outer, struct eh_region *prev_try)
494 {
495   struct eh_region *cleanup = gen_eh_region (ERT_CLEANUP, outer);
496   cleanup->u.cleanup.prev_try = prev_try;
497   return cleanup;
498 }
499
500 struct eh_region *
501 gen_eh_region_try (struct eh_region *outer)
502 {
503   return gen_eh_region (ERT_TRY, outer);
504 }
505
506 struct eh_region *
507 gen_eh_region_catch (struct eh_region *t, tree type_or_list)
508 {
509   struct eh_region *c, *l;
510   tree type_list, type_node;
511
512   /* Ensure to always end up with a type list to normalize further
513      processing, then register each type against the runtime types map.  */
514   type_list = type_or_list;
515   if (type_or_list)
516     {
517       if (TREE_CODE (type_or_list) != TREE_LIST)
518         type_list = tree_cons (NULL_TREE, type_or_list, NULL_TREE);
519
520       type_node = type_list;
521       for (; type_node; type_node = TREE_CHAIN (type_node))
522         add_type_for_runtime (TREE_VALUE (type_node));
523     }
524
525   c = gen_eh_region (ERT_CATCH, t->outer);
526   c->u.catch.type_list = type_list;
527   l = t->u.try.last_catch;
528   c->u.catch.prev_catch = l;
529   if (l)
530     l->u.catch.next_catch = c;
531   else
532     t->u.try.catch = c;
533   t->u.try.last_catch = c;
534
535   return c;
536 }
537
538 struct eh_region *
539 gen_eh_region_allowed (struct eh_region *outer, tree allowed)
540 {
541   struct eh_region *region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
542   region->u.allowed.type_list = allowed;
543
544   for (; allowed ; allowed = TREE_CHAIN (allowed))
545     add_type_for_runtime (TREE_VALUE (allowed));
546
547   return region;
548 }
549
550 struct eh_region *
551 gen_eh_region_must_not_throw (struct eh_region *outer)
552 {
553   return gen_eh_region (ERT_MUST_NOT_THROW, outer);
554 }
555
556 int
557 get_eh_region_number (struct eh_region *region)
558 {
559   return region->region_number;
560 }
561
562 bool
563 get_eh_region_may_contain_throw (struct eh_region *region)
564 {
565   return region->may_contain_throw;
566 }
567
568 tree
569 get_eh_region_tree_label (struct eh_region *region)
570 {
571   return region->tree_label;
572 }
573
574 void
575 set_eh_region_tree_label (struct eh_region *region, tree lab)
576 {
577   region->tree_label = lab;
578 }
579 \f
580 /* Start an exception handling region.  All instructions emitted
581    after this point are considered to be part of the region until
582    expand_eh_region_end is invoked.  */
583
584 void
585 expand_eh_region_start (void)
586 {
587   struct eh_region *new;
588   rtx note;
589
590   if (! doing_eh (0))
591     return;
592
593   new = gen_eh_region (ERT_UNKNOWN, cfun->eh->cur_region);
594   cfun->eh->cur_region = new;
595
596   /* Create a note marking the start of this region.  */
597   note = emit_note (NOTE_INSN_EH_REGION_BEG);
598   NOTE_EH_HANDLER (note) = new->region_number;
599 }
600
601 /* Common code to end a region.  Returns the region just ended.  */
602
603 static struct eh_region *
604 expand_eh_region_end (void)
605 {
606   struct eh_region *cur_region = cfun->eh->cur_region;
607   rtx note;
608
609   /* Create a note marking the end of this region.  */
610   note = emit_note (NOTE_INSN_EH_REGION_END);
611   NOTE_EH_HANDLER (note) = cur_region->region_number;
612
613   /* Pop.  */
614   cfun->eh->cur_region = cur_region->outer;
615
616   return cur_region;
617 }
618
619 /* Expand HANDLER, which is the operand 1 of a TRY_CATCH_EXPR.  Catch
620    blocks and C++ exception-specifications are handled specially.  */
621
622 void
623 expand_eh_handler (tree handler)
624 {
625   tree inner = expr_first (handler);
626
627   switch (TREE_CODE (inner))
628     {
629     case CATCH_EXPR:
630       expand_start_all_catch ();
631       expand_expr (handler, const0_rtx, VOIDmode, 0);
632       expand_end_all_catch ();
633       break;
634
635     case EH_FILTER_EXPR:
636       if (EH_FILTER_MUST_NOT_THROW (handler))
637         expand_eh_region_end_must_not_throw (EH_FILTER_FAILURE (handler));
638       else
639         expand_eh_region_end_allowed (EH_FILTER_TYPES (handler),
640                                       EH_FILTER_FAILURE (handler));
641       break;
642
643     default:
644       expand_eh_region_end_cleanup (handler);
645       break;
646     }
647 }
648
649 /* End an exception handling region for a cleanup.  HANDLER is an
650    expression to expand for the cleanup.  */
651
652 void
653 expand_eh_region_end_cleanup (tree handler)
654 {
655   struct eh_region *region;
656   tree protect_cleanup_actions;
657   rtx around_label;
658   rtx data_save[2];
659
660   if (! doing_eh (0))
661     return;
662
663   region = expand_eh_region_end ();
664   region->type = ERT_CLEANUP;
665   region->label = gen_label_rtx ();
666   region->u.cleanup.exp = handler;
667   region->u.cleanup.prev_try = cfun->eh->try_region;
668
669   around_label = gen_label_rtx ();
670   emit_jump (around_label);
671
672   emit_label (region->label);
673
674   if (flag_non_call_exceptions || region->may_contain_throw)
675     {
676       /* Give the language a chance to specify an action to be taken if an
677          exception is thrown that would propagate out of the HANDLER.  */
678       protect_cleanup_actions
679         = (lang_protect_cleanup_actions
680            ? (*lang_protect_cleanup_actions) ()
681            : NULL_TREE);
682
683       if (protect_cleanup_actions)
684         expand_eh_region_start ();
685
686       /* In case this cleanup involves an inline destructor with a try block in
687          it, we need to save the EH return data registers around it.  */
688       data_save[0] = gen_reg_rtx (ptr_mode);
689       emit_move_insn (data_save[0], get_exception_pointer (cfun));
690       data_save[1] = gen_reg_rtx (word_mode);
691       emit_move_insn (data_save[1], get_exception_filter (cfun));
692
693       expand_expr (handler, const0_rtx, VOIDmode, 0);
694
695       emit_move_insn (cfun->eh->exc_ptr, data_save[0]);
696       emit_move_insn (cfun->eh->filter, data_save[1]);
697
698       if (protect_cleanup_actions)
699         expand_eh_region_end_must_not_throw (protect_cleanup_actions);
700
701       /* We need any stack adjustment complete before the around_label.  */
702       do_pending_stack_adjust ();
703     }
704
705   /* We delay the generation of the _Unwind_Resume until we generate
706      landing pads.  We emit a marker here so as to get good control
707      flow data in the meantime.  */
708   region->resume
709     = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
710   emit_barrier ();
711
712   emit_label (around_label);
713 }
714
715 void
716 expand_resx_expr (tree exp)
717 {
718   int region_nr = TREE_INT_CST_LOW (TREE_OPERAND (exp, 0));
719   struct eh_region *reg = cfun->eh->region_array[region_nr];
720
721   reg->resume = emit_jump_insn (gen_rtx_RESX (VOIDmode, region_nr));
722   emit_barrier ();
723 }
724
725 /* End an exception handling region for a try block, and prepares
726    for subsequent calls to expand_start_catch.  */
727
728 void
729 expand_start_all_catch (void)
730 {
731   struct eh_region *region;
732
733   if (! doing_eh (1))
734     return;
735
736   region = expand_eh_region_end ();
737   region->type = ERT_TRY;
738   region->u.try.prev_try = cfun->eh->try_region;
739   region->u.try.continue_label = gen_label_rtx ();
740
741   cfun->eh->try_region = region;
742
743   emit_jump (region->u.try.continue_label);
744 }
745
746 /* Begin a catch clause.  TYPE is the type caught, a list of such
747    types, (in the case of Java) an ADDR_EXPR which points to the
748    runtime type to match, or null if this is a catch-all
749    clause. Providing a type list enables to associate the catch region
750    with potentially several exception types, which is useful e.g. for
751    Ada.  */
752
753 void
754 expand_start_catch (tree type_or_list)
755 {
756   struct eh_region *c;
757   rtx note;
758
759   if (! doing_eh (0))
760     return;
761
762   c = gen_eh_region_catch (cfun->eh->try_region, type_or_list);
763   cfun->eh->cur_region = c;
764
765   c->label = gen_label_rtx ();
766   emit_label (c->label);
767
768   note = emit_note (NOTE_INSN_EH_REGION_BEG);
769   NOTE_EH_HANDLER (note) = c->region_number;
770 }
771
772 /* End a catch clause.  Control will resume after the try/catch block.  */
773
774 void
775 expand_end_catch (void)
776 {
777   if (! doing_eh (0))
778     return;
779
780   expand_eh_region_end ();
781   emit_jump (cfun->eh->try_region->u.try.continue_label);
782 }
783
784 /* End a sequence of catch handlers for a try block.  */
785
786 void
787 expand_end_all_catch (void)
788 {
789   struct eh_region *try_region;
790
791   if (! doing_eh (0))
792     return;
793
794   try_region = cfun->eh->try_region;
795   cfun->eh->try_region = try_region->u.try.prev_try;
796
797   emit_label (try_region->u.try.continue_label);
798 }
799
800 /* End an exception region for an exception type filter.  ALLOWED is a
801    TREE_LIST of types to be matched by the runtime.  FAILURE is an
802    expression to invoke if a mismatch occurs.
803
804    ??? We could use these semantics for calls to rethrow, too; if we can
805    see the surrounding catch clause, we know that the exception we're
806    rethrowing satisfies the "filter" of the catch type.  */
807
808 void
809 expand_eh_region_end_allowed (tree allowed, tree failure)
810 {
811   struct eh_region *region;
812   rtx around_label;
813
814   if (! doing_eh (0))
815     return;
816
817   region = expand_eh_region_end ();
818   region->type = ERT_ALLOWED_EXCEPTIONS;
819   region->u.allowed.type_list = allowed;
820   region->label = gen_label_rtx ();
821
822   for (; allowed ; allowed = TREE_CHAIN (allowed))
823     add_type_for_runtime (TREE_VALUE (allowed));
824
825   /* We must emit the call to FAILURE here, so that if this function
826      throws a different exception, that it will be processed by the
827      correct region.  */
828
829   around_label = gen_label_rtx ();
830   emit_jump (around_label);
831
832   emit_label (region->label);
833   expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
834   /* We must adjust the stack before we reach the AROUND_LABEL because
835      the call to FAILURE does not occur on all paths to the
836      AROUND_LABEL.  */
837   do_pending_stack_adjust ();
838
839   emit_label (around_label);
840 }
841
842 /* End an exception region for a must-not-throw filter.  FAILURE is an
843    expression invoke if an uncaught exception propagates this far.
844
845    This is conceptually identical to expand_eh_region_end_allowed with
846    an empty allowed list (if you passed "std::terminate" instead of
847    "__cxa_call_unexpected"), but they are represented differently in
848    the C++ LSDA.  */
849
850 void
851 expand_eh_region_end_must_not_throw (tree failure)
852 {
853   struct eh_region *region;
854   rtx around_label;
855
856   if (! doing_eh (0))
857     return;
858
859   region = expand_eh_region_end ();
860   region->type = ERT_MUST_NOT_THROW;
861   region->label = gen_label_rtx ();
862
863   /* We must emit the call to FAILURE here, so that if this function
864      throws a different exception, that it will be processed by the
865      correct region.  */
866
867   around_label = gen_label_rtx ();
868   emit_jump (around_label);
869
870   emit_label (region->label);
871   expand_expr (failure, const0_rtx, VOIDmode, EXPAND_NORMAL);
872
873   emit_label (around_label);
874 }
875
876 /* End an exception region for a throw.  No handling goes on here,
877    but it's the easiest way for the front-end to indicate what type
878    is being thrown.  */
879
880 void
881 expand_eh_region_end_throw (tree type)
882 {
883   struct eh_region *region;
884
885   if (! doing_eh (0))
886     return;
887
888   region = expand_eh_region_end ();
889   region->type = ERT_THROW;
890   region->u.throw.type = type;
891 }
892
893 /* End a fixup region.  Within this region the cleanups for the immediately
894    enclosing region are _not_ run.  This is used for goto cleanup to avoid
895    destroying an object twice.
896
897    This would be an extraordinarily simple prospect, were it not for the
898    fact that we don't actually know what the immediately enclosing region
899    is.  This surprising fact is because expand_cleanups is currently
900    generating a sequence that it will insert somewhere else.  We collect
901    the proper notion of "enclosing" in convert_from_eh_region_ranges.  */
902
903 void
904 expand_eh_region_end_fixup (tree handler)
905 {
906   struct eh_region *fixup;
907
908   if (! doing_eh (0))
909     return;
910
911   fixup = expand_eh_region_end ();
912   fixup->type = ERT_FIXUP;
913   fixup->u.fixup.cleanup_exp = handler;
914 }
915
916 /* Note that the current EH region (if any) may contain a throw, or a
917    call to a function which itself may contain a throw.  */
918
919 void
920 note_eh_region_may_contain_throw (struct eh_region *region)
921 {
922   while (region && !region->may_contain_throw)
923     {
924       region->may_contain_throw = 1;
925       region = region->outer;
926     }
927 }
928
929 void
930 note_current_region_may_contain_throw (void)
931 {
932   note_eh_region_may_contain_throw (cfun->eh->cur_region);
933 }
934
935
936 /* Return an rtl expression for a pointer to the exception object
937    within a handler.  */
938
939 rtx
940 get_exception_pointer (struct function *fun)
941 {
942   rtx exc_ptr = fun->eh->exc_ptr;
943   if (fun == cfun && ! exc_ptr)
944     {
945       exc_ptr = gen_reg_rtx (ptr_mode);
946       fun->eh->exc_ptr = exc_ptr;
947     }
948   return exc_ptr;
949 }
950
951 /* Return an rtl expression for the exception dispatch filter
952    within a handler.  */
953
954 rtx
955 get_exception_filter (struct function *fun)
956 {
957   rtx filter = fun->eh->filter;
958   if (fun == cfun && ! filter)
959     {
960       filter = gen_reg_rtx (word_mode);
961       fun->eh->filter = filter;
962     }
963   return filter;
964 }
965 \f
966 /* This section is for the exception handling specific optimization pass.  */
967
968 /* Random access the exception region tree.  It's just as simple to
969    collect the regions this way as in expand_eh_region_start, but
970    without having to realloc memory.  */
971
972 void
973 collect_eh_region_array (void)
974 {
975   struct eh_region **array, *i;
976
977   i = cfun->eh->region_tree;
978   if (! i)
979     return;
980
981   array = ggc_alloc_cleared ((cfun->eh->last_region_number + 1)
982                              * sizeof (*array));
983   cfun->eh->region_array = array;
984
985   while (1)
986     {
987       array[i->region_number] = i;
988
989       /* If there are sub-regions, process them.  */
990       if (i->inner)
991         i = i->inner;
992       /* If there are peers, process them.  */
993       else if (i->next_peer)
994         i = i->next_peer;
995       /* Otherwise, step back up the tree to the next peer.  */
996       else
997         {
998           do {
999             i = i->outer;
1000             if (i == NULL)
1001               return;
1002           } while (i->next_peer == NULL);
1003           i = i->next_peer;
1004         }
1005     }
1006 }
1007
1008 static void
1009 resolve_one_fixup_region (struct eh_region *fixup)
1010 {
1011   struct eh_region *cleanup, *real;
1012   int j, n;
1013
1014   n = cfun->eh->last_region_number;
1015   cleanup = 0;
1016
1017   for (j = 1; j <= n; ++j)
1018     {
1019       cleanup = cfun->eh->region_array[j];
1020       if (cleanup && cleanup->type == ERT_CLEANUP
1021           && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
1022         break;
1023     }
1024   if (j > n)
1025     abort ();
1026
1027   real = cleanup->outer;
1028   if (real && real->type == ERT_FIXUP)
1029     {
1030       if (!real->u.fixup.resolved)
1031         resolve_one_fixup_region (real);
1032       real = real->u.fixup.real_region;
1033     }
1034
1035   fixup->u.fixup.real_region = real;
1036   fixup->u.fixup.resolved = true;
1037 }
1038
1039 static void
1040 resolve_fixup_regions (void)
1041 {
1042   int i, n = cfun->eh->last_region_number;
1043
1044   for (i = 1; i <= n; ++i)
1045     {
1046       struct eh_region *fixup = cfun->eh->region_array[i];
1047
1048       if (!fixup || fixup->type != ERT_FIXUP || fixup->u.fixup.resolved)
1049         continue;
1050
1051       resolve_one_fixup_region (fixup);
1052     }
1053 }
1054
1055 /* Now that we've discovered what region actually encloses a fixup,
1056    we can shuffle pointers and remove them from the tree.  */
1057
1058 static void
1059 remove_fixup_regions (void)
1060 {
1061   int i;
1062   rtx insn, note;
1063   struct eh_region *fixup;
1064
1065   /* Walk the insn chain and adjust the REG_EH_REGION numbers
1066      for instructions referencing fixup regions.  This is only
1067      strictly necessary for fixup regions with no parent, but
1068      doesn't hurt to do it for all regions.  */
1069   for (insn = get_insns(); insn ; insn = NEXT_INSN (insn))
1070     if (INSN_P (insn)
1071         && (note = find_reg_note (insn, REG_EH_REGION, NULL))
1072         && INTVAL (XEXP (note, 0)) > 0
1073         && (fixup = cfun->eh->region_array[INTVAL (XEXP (note, 0))])
1074         && fixup->type == ERT_FIXUP)
1075       {
1076         if (fixup->u.fixup.real_region)
1077           XEXP (note, 0) = GEN_INT (fixup->u.fixup.real_region->region_number);
1078         else
1079           remove_note (insn, note);
1080       }
1081
1082   /* Remove the fixup regions from the tree.  */
1083   for (i = cfun->eh->last_region_number; i > 0; --i)
1084     {
1085       fixup = cfun->eh->region_array[i];
1086       if (! fixup)
1087         continue;
1088
1089       /* Allow GC to maybe free some memory.  */
1090       if (fixup->type == ERT_CLEANUP)
1091         fixup->u.cleanup.exp = NULL_TREE;
1092
1093       if (fixup->type != ERT_FIXUP)
1094         continue;
1095
1096       if (fixup->inner)
1097         {
1098           struct eh_region *parent, *p, **pp;
1099
1100           parent = fixup->u.fixup.real_region;
1101
1102           /* Fix up the children's parent pointers; find the end of
1103              the list.  */
1104           for (p = fixup->inner; ; p = p->next_peer)
1105             {
1106               p->outer = parent;
1107               if (! p->next_peer)
1108                 break;
1109             }
1110
1111           /* In the tree of cleanups, only outer-inner ordering matters.
1112              So link the children back in anywhere at the correct level.  */
1113           if (parent)
1114             pp = &parent->inner;
1115           else
1116             pp = &cfun->eh->region_tree;
1117           p->next_peer = *pp;
1118           *pp = fixup->inner;
1119           fixup->inner = NULL;
1120         }
1121
1122       remove_eh_handler (fixup);
1123     }
1124 }
1125
1126 /* Remove all regions whose labels are not reachable from insns.  */
1127
1128 static void
1129 remove_unreachable_regions (rtx insns)
1130 {
1131   int i, *uid_region_num;
1132   bool *reachable;
1133   struct eh_region *r;
1134   rtx insn;
1135
1136   uid_region_num = xcalloc (get_max_uid (), sizeof(int));
1137   reachable = xcalloc (cfun->eh->last_region_number + 1, sizeof(bool));
1138
1139   for (i = cfun->eh->last_region_number; i > 0; --i)
1140     {
1141       r = cfun->eh->region_array[i];
1142       if (!r || r->region_number != i)
1143         continue;
1144
1145       if (r->resume)
1146         {
1147           if (uid_region_num[INSN_UID (r->resume)])
1148             abort ();
1149           uid_region_num[INSN_UID (r->resume)] = i;
1150         }
1151       if (r->label)
1152         {
1153           if (uid_region_num[INSN_UID (r->label)])
1154             abort ();
1155           uid_region_num[INSN_UID (r->label)] = i;
1156         }
1157     }
1158
1159   for (insn = insns; insn; insn = NEXT_INSN (insn))
1160     reachable[uid_region_num[INSN_UID (insn)]] = true;
1161
1162   for (i = cfun->eh->last_region_number; i > 0; --i)
1163     {
1164       r = cfun->eh->region_array[i];
1165       if (r && r->region_number == i && !reachable[i])
1166         {
1167           bool kill_it = true;
1168           switch (r->type)
1169             {
1170             case ERT_THROW:
1171               /* Don't remove ERT_THROW regions if their outer region
1172                  is reachable.  */
1173               if (r->outer && reachable[r->outer->region_number])
1174                 kill_it = false;
1175               break;
1176
1177             case ERT_MUST_NOT_THROW:
1178               /* MUST_NOT_THROW regions are implementable solely in the
1179                  runtime, but their existence continues to affect calls
1180                  within that region.  Never delete them here.  */
1181               kill_it = false;
1182               break;
1183
1184             case ERT_TRY:
1185               {
1186                 /* TRY regions are reachable if any of its CATCH regions
1187                    are reachable.  */
1188                 struct eh_region *c;
1189                 for (c = r->u.try.catch; c ; c = c->u.catch.next_catch)
1190                   if (reachable[c->region_number])
1191                     {
1192                       kill_it = false;
1193                       break;
1194                     }
1195                 break;
1196               }
1197
1198             default:
1199               break;
1200             }
1201               
1202           if (kill_it)
1203             remove_eh_handler (r);
1204         }
1205     }
1206
1207   free (reachable);
1208   free (uid_region_num);
1209 }
1210
1211 /* Turn NOTE_INSN_EH_REGION notes into REG_EH_REGION notes for each
1212    can_throw instruction in the region.  */
1213
1214 static void
1215 convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur)
1216 {
1217   int *sp = orig_sp;
1218   rtx insn, next;
1219
1220   for (insn = *pinsns; insn ; insn = next)
1221     {
1222       next = NEXT_INSN (insn);
1223       if (GET_CODE (insn) == NOTE)
1224         {
1225           int kind = NOTE_LINE_NUMBER (insn);
1226           if (kind == NOTE_INSN_EH_REGION_BEG
1227               || kind == NOTE_INSN_EH_REGION_END)
1228             {
1229               if (kind == NOTE_INSN_EH_REGION_BEG)
1230                 {
1231                   struct eh_region *r;
1232
1233                   *sp++ = cur;
1234                   cur = NOTE_EH_HANDLER (insn);
1235
1236                   r = cfun->eh->region_array[cur];
1237                   if (r->type == ERT_FIXUP)
1238                     {
1239                       r = r->u.fixup.real_region;
1240                       cur = r ? r->region_number : 0;
1241                     }
1242                   else if (r->type == ERT_CATCH)
1243                     {
1244                       r = r->outer;
1245                       cur = r ? r->region_number : 0;
1246                     }
1247                 }
1248               else
1249                 cur = *--sp;
1250
1251               if (insn == *pinsns)
1252                 *pinsns = next;
1253               remove_insn (insn);
1254               continue;
1255             }
1256         }
1257       else if (INSN_P (insn))
1258         {
1259           if (cur > 0
1260               && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
1261               /* Calls can always potentially throw exceptions, unless
1262                  they have a REG_EH_REGION note with a value of 0 or less.
1263                  Which should be the only possible kind so far.  */
1264               && (GET_CODE (insn) == CALL_INSN
1265                   /* If we wanted exceptions for non-call insns, then
1266                      any may_trap_p instruction could throw.  */
1267                   || (flag_non_call_exceptions
1268                       && GET_CODE (PATTERN (insn)) != CLOBBER
1269                       && GET_CODE (PATTERN (insn)) != USE
1270                       && may_trap_p (PATTERN (insn)))))
1271             {
1272               REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur),
1273                                                   REG_NOTES (insn));
1274             }
1275         }
1276     }
1277
1278   if (sp != orig_sp)
1279     abort ();
1280 }
1281
1282 static void
1283 collect_rtl_labels_from_trees (void)
1284 {
1285   int i, n = cfun->eh->last_region_number;
1286   for (i = 1; i <= n; ++i)
1287     {
1288       struct eh_region *reg = cfun->eh->region_array[i];
1289       if (reg && reg->tree_label)
1290         reg->label = DECL_RTL_IF_SET (reg->tree_label);
1291     }
1292 }
1293
1294 void
1295 convert_from_eh_region_ranges (void)
1296 {
1297   rtx insns = get_insns ();
1298
1299   if (cfun->eh->region_array)
1300     {
1301       /* If the region array already exists, assume we're coming from
1302          optimize_function_tree.  In this case all we need to do is
1303          collect the rtl labels that correspond to the tree labels
1304          that we allocated earlier.  */
1305       collect_rtl_labels_from_trees ();
1306     }
1307   else
1308     {
1309       int *stack;
1310
1311       collect_eh_region_array ();
1312       resolve_fixup_regions ();
1313
1314       stack = xmalloc (sizeof (int) * (cfun->eh->last_region_number + 1));
1315       convert_from_eh_region_ranges_1 (&insns, stack, 0);
1316       free (stack);
1317
1318       remove_fixup_regions ();
1319     }
1320
1321   remove_unreachable_regions (insns);
1322 }
1323
1324 static void
1325 add_ehl_entry (rtx label, struct eh_region *region)
1326 {
1327   struct ehl_map_entry **slot, *entry;
1328
1329   LABEL_PRESERVE_P (label) = 1;
1330
1331   entry = ggc_alloc (sizeof (*entry));
1332   entry->label = label;
1333   entry->region = region;
1334
1335   slot = (struct ehl_map_entry **)
1336     htab_find_slot (cfun->eh->exception_handler_label_map, entry, INSERT);
1337
1338   /* Before landing pad creation, each exception handler has its own
1339      label.  After landing pad creation, the exception handlers may
1340      share landing pads.  This is ok, since maybe_remove_eh_handler
1341      only requires the 1-1 mapping before landing pad creation.  */
1342   if (*slot && !cfun->eh->built_landing_pads)
1343     abort ();
1344
1345   *slot = entry;
1346 }
1347
1348 void
1349 find_exception_handler_labels (void)
1350 {
1351   int i;
1352
1353   if (cfun->eh->exception_handler_label_map)
1354     htab_empty (cfun->eh->exception_handler_label_map);
1355   else
1356     {
1357       /* ??? The expansion factor here (3/2) must be greater than the htab
1358          occupancy factor (4/3) to avoid unnecessary resizing.  */
1359       cfun->eh->exception_handler_label_map
1360         = htab_create_ggc (cfun->eh->last_region_number * 3 / 2,
1361                            ehl_hash, ehl_eq, NULL);
1362     }
1363
1364   if (cfun->eh->region_tree == NULL)
1365     return;
1366
1367   for (i = cfun->eh->last_region_number; i > 0; --i)
1368     {
1369       struct eh_region *region = cfun->eh->region_array[i];
1370       rtx lab;
1371
1372       if (! region || region->region_number != i)
1373         continue;
1374       if (cfun->eh->built_landing_pads)
1375         lab = region->landing_pad;
1376       else
1377         lab = region->label;
1378
1379       if (lab)
1380         add_ehl_entry (lab, region);
1381     }
1382
1383   /* For sjlj exceptions, need the return label to remain live until
1384      after landing pad generation.  */
1385   if (USING_SJLJ_EXCEPTIONS && ! cfun->eh->built_landing_pads)
1386     add_ehl_entry (return_label, NULL);
1387 }
1388
1389 bool
1390 current_function_has_exception_handlers (void)
1391 {
1392   int i;
1393
1394   for (i = cfun->eh->last_region_number; i > 0; --i)
1395     {
1396       struct eh_region *region = cfun->eh->region_array[i];
1397
1398       if (! region || region->region_number != i)
1399         continue;
1400       if (region->type != ERT_THROW)
1401         return true;
1402     }
1403
1404   return false;
1405 }
1406 \f
1407 static struct eh_region *
1408 duplicate_eh_region_1 (struct eh_region *o, struct inline_remap *map)
1409 {
1410   struct eh_region *n = ggc_alloc_cleared (sizeof (struct eh_region));
1411
1412   n->region_number = o->region_number + cfun->eh->last_region_number;
1413   n->type = o->type;
1414
1415   switch (n->type)
1416     {
1417     case ERT_CLEANUP:
1418     case ERT_MUST_NOT_THROW:
1419       break;
1420
1421     case ERT_TRY:
1422       if (o->u.try.continue_label)
1423         n->u.try.continue_label
1424           = get_label_from_map (map,
1425                                 CODE_LABEL_NUMBER (o->u.try.continue_label));
1426       break;
1427
1428     case ERT_CATCH:
1429       n->u.catch.type_list = o->u.catch.type_list;
1430       break;
1431
1432     case ERT_ALLOWED_EXCEPTIONS:
1433       n->u.allowed.type_list = o->u.allowed.type_list;
1434       break;
1435
1436     case ERT_THROW:
1437       n->u.throw.type = o->u.throw.type;
1438
1439     default:
1440       abort ();
1441     }
1442
1443   if (o->label)
1444     n->label = get_label_from_map (map, CODE_LABEL_NUMBER (o->label));
1445   if (o->resume)
1446     {
1447       n->resume = map->insn_map[INSN_UID (o->resume)];
1448       if (n->resume == NULL)
1449         abort ();
1450     }
1451
1452   return n;
1453 }
1454
1455 static void
1456 duplicate_eh_region_2 (struct eh_region *o, struct eh_region **n_array)
1457 {
1458   struct eh_region *n = n_array[o->region_number];
1459
1460   switch (n->type)
1461     {
1462     case ERT_TRY:
1463       n->u.try.catch = n_array[o->u.try.catch->region_number];
1464       n->u.try.last_catch = n_array[o->u.try.last_catch->region_number];
1465       break;
1466
1467     case ERT_CATCH:
1468       if (o->u.catch.next_catch)
1469         n->u.catch.next_catch = n_array[o->u.catch.next_catch->region_number];
1470       if (o->u.catch.prev_catch)
1471         n->u.catch.prev_catch = n_array[o->u.catch.prev_catch->region_number];
1472       break;
1473
1474     default:
1475       break;
1476     }
1477
1478   if (o->outer)
1479     n->outer = n_array[o->outer->region_number];
1480   if (o->inner)
1481     n->inner = n_array[o->inner->region_number];
1482   if (o->next_peer)
1483     n->next_peer = n_array[o->next_peer->region_number];
1484 }
1485
1486 int
1487 duplicate_eh_regions (struct function *ifun, struct inline_remap *map)
1488 {
1489   int ifun_last_region_number = ifun->eh->last_region_number;
1490   struct eh_region **n_array, *root, *cur;
1491   int i;
1492
1493   if (ifun_last_region_number == 0)
1494     return 0;
1495
1496   n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
1497
1498   for (i = 1; i <= ifun_last_region_number; ++i)
1499     {
1500       cur = ifun->eh->region_array[i];
1501       if (!cur || cur->region_number != i)
1502         continue;
1503       n_array[i] = duplicate_eh_region_1 (cur, map);
1504     }
1505   for (i = 1; i <= ifun_last_region_number; ++i)
1506     {
1507       cur = ifun->eh->region_array[i];
1508       if (!cur || cur->region_number != i)
1509         continue;
1510       duplicate_eh_region_2 (cur, n_array);
1511     }
1512
1513   root = n_array[ifun->eh->region_tree->region_number];
1514   cur = cfun->eh->cur_region;
1515   if (cur)
1516     {
1517       struct eh_region *p = cur->inner;
1518       if (p)
1519         {
1520           while (p->next_peer)
1521             p = p->next_peer;
1522           p->next_peer = root;
1523         }
1524       else
1525         cur->inner = root;
1526
1527       for (i = 1; i <= ifun_last_region_number; ++i)
1528         if (n_array[i] && n_array[i]->outer == NULL)
1529           n_array[i]->outer = cur;
1530     }
1531   else
1532     {
1533       struct eh_region *p = cfun->eh->region_tree;
1534       if (p)
1535         {
1536           while (p->next_peer)
1537             p = p->next_peer;
1538           p->next_peer = root;
1539         }
1540       else
1541         cfun->eh->region_tree = root;
1542     }
1543
1544   free (n_array);
1545
1546   i = cfun->eh->last_region_number;
1547   cfun->eh->last_region_number = i + ifun_last_region_number;
1548   return i;
1549 }
1550
1551 \f
1552 static int
1553 t2r_eq (const void *pentry, const void *pdata)
1554 {
1555   tree entry = (tree) pentry;
1556   tree data = (tree) pdata;
1557
1558   return TREE_PURPOSE (entry) == data;
1559 }
1560
1561 static hashval_t
1562 t2r_hash (const void *pentry)
1563 {
1564   tree entry = (tree) pentry;
1565   return TREE_HASH (TREE_PURPOSE (entry));
1566 }
1567
1568 static void
1569 add_type_for_runtime (tree type)
1570 {
1571   tree *slot;
1572
1573   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1574                                             TREE_HASH (type), INSERT);
1575   if (*slot == NULL)
1576     {
1577       tree runtime = (*lang_eh_runtime_type) (type);
1578       *slot = tree_cons (type, runtime, NULL_TREE);
1579     }
1580 }
1581
1582 static tree
1583 lookup_type_for_runtime (tree type)
1584 {
1585   tree *slot;
1586
1587   slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
1588                                             TREE_HASH (type), NO_INSERT);
1589
1590   /* We should have always inserted the data earlier.  */
1591   return TREE_VALUE (*slot);
1592 }
1593
1594 \f
1595 /* Represent an entry in @TTypes for either catch actions
1596    or exception filter actions.  */
1597 struct ttypes_filter GTY(())
1598 {
1599   tree t;
1600   int filter;
1601 };
1602
1603 /* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
1604    (a tree) for a @TTypes type node we are thinking about adding.  */
1605
1606 static int
1607 ttypes_filter_eq (const void *pentry, const void *pdata)
1608 {
1609   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1610   tree data = (tree) pdata;
1611
1612   return entry->t == data;
1613 }
1614
1615 static hashval_t
1616 ttypes_filter_hash (const void *pentry)
1617 {
1618   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1619   return TREE_HASH (entry->t);
1620 }
1621
1622 /* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
1623    exception specification list we are thinking about adding.  */
1624 /* ??? Currently we use the type lists in the order given.  Someone
1625    should put these in some canonical order.  */
1626
1627 static int
1628 ehspec_filter_eq (const void *pentry, const void *pdata)
1629 {
1630   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1631   const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
1632
1633   return type_list_equal (entry->t, data->t);
1634 }
1635
1636 /* Hash function for exception specification lists.  */
1637
1638 static hashval_t
1639 ehspec_filter_hash (const void *pentry)
1640 {
1641   const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
1642   hashval_t h = 0;
1643   tree list;
1644
1645   for (list = entry->t; list ; list = TREE_CHAIN (list))
1646     h = (h << 5) + (h >> 27) + TREE_HASH (TREE_VALUE (list));
1647   return h;
1648 }
1649
1650 /* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH
1651    to speed up the search.  Return the filter value to be used.  */
1652
1653 static int
1654 add_ttypes_entry (htab_t ttypes_hash, tree type)
1655 {
1656   struct ttypes_filter **slot, *n;
1657
1658   slot = (struct ttypes_filter **)
1659     htab_find_slot_with_hash (ttypes_hash, type, TREE_HASH (type), INSERT);
1660
1661   if ((n = *slot) == NULL)
1662     {
1663       /* Filter value is a 1 based table index.  */
1664
1665       n = xmalloc (sizeof (*n));
1666       n->t = type;
1667       n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1;
1668       *slot = n;
1669
1670       VARRAY_PUSH_TREE (cfun->eh->ttype_data, type);
1671     }
1672
1673   return n->filter;
1674 }
1675
1676 /* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
1677    to speed up the search.  Return the filter value to be used.  */
1678
1679 static int
1680 add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list)
1681 {
1682   struct ttypes_filter **slot, *n;
1683   struct ttypes_filter dummy;
1684
1685   dummy.t = list;
1686   slot = (struct ttypes_filter **)
1687     htab_find_slot (ehspec_hash, &dummy, INSERT);
1688
1689   if ((n = *slot) == NULL)
1690     {
1691       /* Filter value is a -1 based byte index into a uleb128 buffer.  */
1692
1693       n = xmalloc (sizeof (*n));
1694       n->t = list;
1695       n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1);
1696       *slot = n;
1697
1698       /* Look up each type in the list and encode its filter
1699          value as a uleb128.  Terminate the list with 0.  */
1700       for (; list ; list = TREE_CHAIN (list))
1701         push_uleb128 (&cfun->eh->ehspec_data,
1702                       add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
1703       VARRAY_PUSH_UCHAR (cfun->eh->ehspec_data, 0);
1704     }
1705
1706   return n->filter;
1707 }
1708
1709 /* Generate the action filter values to be used for CATCH and
1710    ALLOWED_EXCEPTIONS regions.  When using dwarf2 exception regions,
1711    we use lots of landing pads, and so every type or list can share
1712    the same filter value, which saves table space.  */
1713
1714 static void
1715 assign_filter_values (void)
1716 {
1717   int i;
1718   htab_t ttypes, ehspec;
1719
1720   VARRAY_TREE_INIT (cfun->eh->ttype_data, 16, "ttype_data");
1721   VARRAY_UCHAR_INIT (cfun->eh->ehspec_data, 64, "ehspec_data");
1722
1723   ttypes = htab_create (31, ttypes_filter_hash, ttypes_filter_eq, free);
1724   ehspec = htab_create (31, ehspec_filter_hash, ehspec_filter_eq, free);
1725
1726   for (i = cfun->eh->last_region_number; i > 0; --i)
1727     {
1728       struct eh_region *r = cfun->eh->region_array[i];
1729
1730       /* Mind we don't process a region more than once.  */
1731       if (!r || r->region_number != i)
1732         continue;
1733
1734       switch (r->type)
1735         {
1736         case ERT_CATCH:
1737           /* Whatever type_list is (NULL or true list), we build a list
1738              of filters for the region.  */
1739           r->u.catch.filter_list = NULL_TREE;
1740
1741           if (r->u.catch.type_list != NULL)
1742             {
1743               /* Get a filter value for each of the types caught and store
1744                  them in the region's dedicated list.  */
1745               tree tp_node = r->u.catch.type_list;
1746
1747               for (;tp_node; tp_node = TREE_CHAIN (tp_node))
1748                 {
1749                   int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
1750                   tree flt_node = build_int_2 (flt, 0);
1751
1752                   r->u.catch.filter_list
1753                     = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
1754                 }
1755             }
1756           else
1757             {
1758               /* Get a filter value for the NULL list also since it will need
1759                  an action record anyway.  */
1760               int flt = add_ttypes_entry (ttypes, NULL);
1761               tree flt_node = build_int_2 (flt, 0);
1762
1763               r->u.catch.filter_list
1764                 = tree_cons (NULL_TREE, flt_node, r->u.catch.filter_list);
1765             }
1766
1767           break;
1768
1769         case ERT_ALLOWED_EXCEPTIONS:
1770           r->u.allowed.filter
1771             = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
1772           break;
1773
1774         default:
1775           break;
1776         }
1777     }
1778
1779   htab_delete (ttypes);
1780   htab_delete (ehspec);
1781 }
1782
1783 /* Emit SEQ into basic block just before INSN (that is assumed to be
1784    first instruction of some existing BB and return the newly
1785    produced block.  */
1786 static basic_block
1787 emit_to_new_bb_before (rtx seq, rtx insn)
1788 {
1789   rtx last;
1790   basic_block bb;
1791   edge e;
1792
1793   /* If there happens to be an fallthru edge (possibly created by cleanup_cfg
1794      call), we don't want it to go into newly created landing pad or other EH 
1795      construct.  */
1796   for (e = BLOCK_FOR_INSN (insn)->pred; e; e = e->pred_next)
1797     if (e->flags & EDGE_FALLTHRU)
1798       force_nonfallthru (e);
1799   last = emit_insn_before (seq, insn);
1800   if (GET_CODE (last) == BARRIER)
1801     last = PREV_INSN (last);
1802   bb = create_basic_block (seq, last, BLOCK_FOR_INSN (insn)->prev_bb);
1803   update_bb_for_insn (bb);
1804   bb->flags |= BB_SUPERBLOCK;
1805   return bb;
1806 }
1807
1808 /* Generate the code to actually handle exceptions, which will follow the
1809    landing pads.  */
1810
1811 static void
1812 build_post_landing_pads (void)
1813 {
1814   int i;
1815
1816   for (i = cfun->eh->last_region_number; i > 0; --i)
1817     {
1818       struct eh_region *region = cfun->eh->region_array[i];
1819       rtx seq;
1820
1821       /* Mind we don't process a region more than once.  */
1822       if (!region || region->region_number != i)
1823         continue;
1824
1825       switch (region->type)
1826         {
1827         case ERT_TRY:
1828           /* ??? Collect the set of all non-overlapping catch handlers
1829                all the way up the chain until blocked by a cleanup.  */
1830           /* ??? Outer try regions can share landing pads with inner
1831              try regions if the types are completely non-overlapping,
1832              and there are no intervening cleanups.  */
1833
1834           region->post_landing_pad = gen_label_rtx ();
1835
1836           start_sequence ();
1837
1838           emit_label (region->post_landing_pad);
1839
1840           /* ??? It is mighty inconvenient to call back into the
1841              switch statement generation code in expand_end_case.
1842              Rapid prototyping sez a sequence of ifs.  */
1843           {
1844             struct eh_region *c;
1845             for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
1846               {
1847                 if (c->u.catch.type_list == NULL)
1848                   emit_jump (c->label);
1849                 else
1850                   {
1851                     /* Need for one cmp/jump per type caught. Each type
1852                        list entry has a matching entry in the filter list
1853                        (see assign_filter_values).  */
1854                     tree tp_node = c->u.catch.type_list;
1855                     tree flt_node = c->u.catch.filter_list;
1856
1857                     for (; tp_node; )
1858                       {
1859                         emit_cmp_and_jump_insns
1860                           (cfun->eh->filter,
1861                            GEN_INT (tree_low_cst (TREE_VALUE (flt_node), 0)),
1862                            EQ, NULL_RTX, word_mode, 0, c->label);
1863
1864                         tp_node = TREE_CHAIN (tp_node);
1865                         flt_node = TREE_CHAIN (flt_node);
1866                       }
1867                   }
1868               }
1869           }
1870
1871           /* We delay the generation of the _Unwind_Resume until we generate
1872              landing pads.  We emit a marker here so as to get good control
1873              flow data in the meantime.  */
1874           region->resume
1875             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1876           emit_barrier ();
1877
1878           seq = get_insns ();
1879           end_sequence ();
1880
1881           emit_to_new_bb_before (seq, region->u.try.catch->label);
1882
1883           break;
1884
1885         case ERT_ALLOWED_EXCEPTIONS:
1886           region->post_landing_pad = gen_label_rtx ();
1887
1888           start_sequence ();
1889
1890           emit_label (region->post_landing_pad);
1891
1892           emit_cmp_and_jump_insns (cfun->eh->filter,
1893                                    GEN_INT (region->u.allowed.filter),
1894                                    EQ, NULL_RTX, word_mode, 0, region->label);
1895
1896           /* We delay the generation of the _Unwind_Resume until we generate
1897              landing pads.  We emit a marker here so as to get good control
1898              flow data in the meantime.  */
1899           region->resume
1900             = emit_jump_insn (gen_rtx_RESX (VOIDmode, region->region_number));
1901           emit_barrier ();
1902
1903           seq = get_insns ();
1904           end_sequence ();
1905
1906           emit_to_new_bb_before (seq, region->label);
1907           break;
1908
1909         case ERT_CLEANUP:
1910         case ERT_MUST_NOT_THROW:
1911           region->post_landing_pad = region->label;
1912           break;
1913
1914         case ERT_CATCH:
1915         case ERT_THROW:
1916           /* Nothing to do.  */
1917           break;
1918
1919         default:
1920           abort ();
1921         }
1922     }
1923 }
1924
1925 /* Replace RESX patterns with jumps to the next handler if any, or calls to
1926    _Unwind_Resume otherwise.  */
1927
1928 static void
1929 connect_post_landing_pads (void)
1930 {
1931   int i;
1932
1933   for (i = cfun->eh->last_region_number; i > 0; --i)
1934     {
1935       struct eh_region *region = cfun->eh->region_array[i];
1936       struct eh_region *outer;
1937       rtx seq;
1938       rtx barrier;
1939
1940       /* Mind we don't process a region more than once.  */
1941       if (!region || region->region_number != i)
1942         continue;
1943
1944       /* If there is no RESX, or it has been deleted by flow, there's
1945          nothing to fix up.  */
1946       if (! region->resume || INSN_DELETED_P (region->resume))
1947         continue;
1948
1949       /* Search for another landing pad in this function.  */
1950       for (outer = region->outer; outer ; outer = outer->outer)
1951         if (outer->post_landing_pad)
1952           break;
1953
1954       start_sequence ();
1955
1956       if (outer)
1957         {
1958           edge e;
1959           basic_block src, dest;
1960
1961           emit_jump (outer->post_landing_pad);
1962           src = BLOCK_FOR_INSN (region->resume);
1963           dest = BLOCK_FOR_INSN (outer->post_landing_pad);
1964           while (src->succ)
1965             remove_edge (src->succ);
1966           e = make_edge (src, dest, 0);
1967           e->probability = REG_BR_PROB_BASE;
1968           e->count = src->count;
1969         }
1970       else
1971         {
1972           emit_library_call (unwind_resume_libfunc, LCT_THROW,
1973                              VOIDmode, 1, cfun->eh->exc_ptr, ptr_mode);
1974
1975           /* What we just emitted was a throwing libcall, so it got a
1976              barrier automatically added after it.  If the last insn in
1977              the libcall sequence isn't the barrier, it's because the
1978              target emits multiple insns for a call, and there are insns
1979              after the actual call insn (which are redundant and would be
1980              optimized away).  The barrier is inserted exactly after the
1981              call insn, so let's go get that and delete the insns after
1982              it, because below we need the barrier to be the last insn in
1983              the sequence.  */
1984           delete_insns_since (NEXT_INSN (last_call_insn ()));
1985         }
1986
1987       seq = get_insns ();
1988       end_sequence ();
1989       barrier = emit_insn_before (seq, region->resume);
1990       /* Avoid duplicate barrier.  */
1991       if (GET_CODE (barrier) != BARRIER)
1992         abort ();
1993       delete_insn (barrier);
1994       delete_insn (region->resume);
1995
1996       /* ??? From tree-ssa we can wind up with catch regions whose
1997          label is not instantiated, but whose resx is present.  Now
1998          that we've dealt with the resx, kill the region.  */
1999       if (region->label == NULL && region->type == ERT_CLEANUP)
2000         remove_eh_handler (region);
2001     }
2002 }
2003
2004 \f
2005 static void
2006 dw2_build_landing_pads (void)
2007 {
2008   int i;
2009   unsigned int j;
2010
2011   for (i = cfun->eh->last_region_number; i > 0; --i)
2012     {
2013       struct eh_region *region = cfun->eh->region_array[i];
2014       rtx seq;
2015       basic_block bb;
2016       bool clobbers_hard_regs = false;
2017       edge e;
2018
2019       /* Mind we don't process a region more than once.  */
2020       if (!region || region->region_number != i)
2021         continue;
2022
2023       if (region->type != ERT_CLEANUP
2024           && region->type != ERT_TRY
2025           && region->type != ERT_ALLOWED_EXCEPTIONS)
2026         continue;
2027
2028       start_sequence ();
2029
2030       region->landing_pad = gen_label_rtx ();
2031       emit_label (region->landing_pad);
2032
2033 #ifdef HAVE_exception_receiver
2034       if (HAVE_exception_receiver)
2035         emit_insn (gen_exception_receiver ());
2036       else
2037 #endif
2038 #ifdef HAVE_nonlocal_goto_receiver
2039         if (HAVE_nonlocal_goto_receiver)
2040           emit_insn (gen_nonlocal_goto_receiver ());
2041         else
2042 #endif
2043           { /* Nothing */ }
2044
2045       /* If the eh_return data registers are call-saved, then we
2046          won't have considered them clobbered from the call that
2047          threw.  Kill them now.  */
2048       for (j = 0; ; ++j)
2049         {
2050           unsigned r = EH_RETURN_DATA_REGNO (j);
2051           if (r == INVALID_REGNUM)
2052             break;
2053           if (! call_used_regs[r])
2054             {
2055               emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, r)));
2056               clobbers_hard_regs = true;
2057             }
2058         }
2059
2060       if (clobbers_hard_regs)
2061         {
2062           /* @@@ This is a kludge.  Not all machine descriptions define a
2063              blockage insn, but we must not allow the code we just generated
2064              to be reordered by scheduling.  So emit an ASM_INPUT to act as
2065              blockage insn.  */
2066           emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
2067         }
2068
2069       emit_move_insn (cfun->eh->exc_ptr,
2070                       gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
2071       emit_move_insn (cfun->eh->filter,
2072                       gen_rtx_REG (word_mode, EH_RETURN_DATA_REGNO (1)));
2073
2074       seq = get_insns ();
2075       end_sequence ();
2076
2077       bb = emit_to_new_bb_before (seq, region->post_landing_pad);
2078       e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
2079       e->count = bb->count;
2080       e->probability = REG_BR_PROB_BASE;
2081     }
2082 }
2083
2084 \f
2085 struct sjlj_lp_info
2086 {
2087   int directly_reachable;
2088   int action_index;
2089   int dispatch_index;
2090   int call_site_index;
2091 };
2092
2093 static bool
2094 sjlj_find_directly_reachable_regions (struct sjlj_lp_info *lp_info)
2095 {
2096   rtx insn;
2097   bool found_one = false;
2098
2099   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
2100     {
2101       struct eh_region *region;
2102       enum reachable_code rc;
2103       tree type_thrown;
2104       rtx note;
2105
2106       if (! INSN_P (insn))
2107         continue;
2108
2109       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2110       if (!note || INTVAL (XEXP (note, 0)) <= 0)
2111         continue;
2112
2113       region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2114
2115       type_thrown = NULL_TREE;
2116       if (region->type == ERT_THROW)
2117         {
2118           type_thrown = region->u.throw.type;
2119           region = region->outer;
2120         }
2121
2122       /* Find the first containing region that might handle the exception.
2123          That's the landing pad to which we will transfer control.  */
2124       rc = RNL_NOT_CAUGHT;
2125       for (; region; region = region->outer)
2126         {
2127           rc = reachable_next_level (region, type_thrown, NULL);
2128           if (rc != RNL_NOT_CAUGHT)
2129             break;
2130         }
2131       if (rc == RNL_MAYBE_CAUGHT || rc == RNL_CAUGHT)
2132         {
2133           lp_info[region->region_number].directly_reachable = 1;
2134           found_one = true;
2135         }
2136     }
2137
2138   return found_one;
2139 }
2140
2141 static void
2142 sjlj_assign_call_site_values (rtx dispatch_label, struct sjlj_lp_info *lp_info)
2143 {
2144   htab_t ar_hash;
2145   int i, index;
2146
2147   /* First task: build the action table.  */
2148
2149   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
2150   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
2151
2152   for (i = cfun->eh->last_region_number; i > 0; --i)
2153     if (lp_info[i].directly_reachable)
2154       {
2155         struct eh_region *r = cfun->eh->region_array[i];
2156         r->landing_pad = dispatch_label;
2157         lp_info[i].action_index = collect_one_action_chain (ar_hash, r);
2158         if (lp_info[i].action_index != -1)
2159           cfun->uses_eh_lsda = 1;
2160       }
2161
2162   htab_delete (ar_hash);
2163
2164   /* Next: assign dispatch values.  In dwarf2 terms, this would be the
2165      landing pad label for the region.  For sjlj though, there is one
2166      common landing pad from which we dispatch to the post-landing pads.
2167
2168      A region receives a dispatch index if it is directly reachable
2169      and requires in-function processing.  Regions that share post-landing
2170      pads may share dispatch indices.  */
2171   /* ??? Post-landing pad sharing doesn't actually happen at the moment
2172      (see build_post_landing_pads) so we don't bother checking for it.  */
2173
2174   index = 0;
2175   for (i = cfun->eh->last_region_number; i > 0; --i)
2176     if (lp_info[i].directly_reachable)
2177       lp_info[i].dispatch_index = index++;
2178
2179   /* Finally: assign call-site values.  If dwarf2 terms, this would be
2180      the region number assigned by convert_to_eh_region_ranges, but
2181      handles no-action and must-not-throw differently.  */
2182
2183   call_site_base = 1;
2184   for (i = cfun->eh->last_region_number; i > 0; --i)
2185     if (lp_info[i].directly_reachable)
2186       {
2187         int action = lp_info[i].action_index;
2188
2189         /* Map must-not-throw to otherwise unused call-site index 0.  */
2190         if (action == -2)
2191           index = 0;
2192         /* Map no-action to otherwise unused call-site index -1.  */
2193         else if (action == -1)
2194           index = -1;
2195         /* Otherwise, look it up in the table.  */
2196         else
2197           index = add_call_site (GEN_INT (lp_info[i].dispatch_index), action);
2198
2199         lp_info[i].call_site_index = index;
2200       }
2201 }
2202
2203 static void
2204 sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
2205 {
2206   int last_call_site = -2;
2207   rtx insn, mem;
2208
2209   for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
2210     {
2211       struct eh_region *region;
2212       int this_call_site;
2213       rtx note, before, p;
2214
2215       /* Reset value tracking at extended basic block boundaries.  */
2216       if (GET_CODE (insn) == CODE_LABEL)
2217         last_call_site = -2;
2218
2219       if (! INSN_P (insn))
2220         continue;
2221
2222       note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2223       if (!note)
2224         {
2225           /* Calls (and trapping insns) without notes are outside any
2226              exception handling region in this function.  Mark them as
2227              no action.  */
2228           if (GET_CODE (insn) == CALL_INSN
2229               || (flag_non_call_exceptions
2230                   && may_trap_p (PATTERN (insn))))
2231             this_call_site = -1;
2232           else
2233             continue;
2234         }
2235       else
2236         {
2237           /* Calls that are known to not throw need not be marked.  */
2238           if (INTVAL (XEXP (note, 0)) <= 0)
2239             continue;
2240
2241           region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
2242           this_call_site = lp_info[region->region_number].call_site_index;
2243         }
2244
2245       if (this_call_site == last_call_site)
2246         continue;
2247
2248       /* Don't separate a call from it's argument loads.  */
2249       before = insn;
2250       if (GET_CODE (insn) == CALL_INSN)
2251         before = find_first_parameter_load (insn, NULL_RTX);
2252
2253       start_sequence ();
2254       mem = adjust_address (cfun->eh->sjlj_fc, TYPE_MODE (integer_type_node),
2255                             sjlj_fc_call_site_ofs);
2256       emit_move_insn (mem, GEN_INT (this_call_site));
2257       p = get_insns ();
2258       end_sequence ();
2259
2260       emit_insn_before (p, before);
2261       last_call_site = this_call_site;
2262     }
2263 }
2264
2265 /* Construct the SjLj_Function_Context.  */
2266
2267 static void
2268 sjlj_emit_function_enter (rtx dispatch_label)
2269 {
2270   rtx fn_begin, fc, mem, seq;
2271
2272   fc = cfun->eh->sjlj_fc;
2273
2274   start_sequence ();
2275
2276   /* We're storing this libcall's address into memory instead of
2277      calling it directly.  Thus, we must call assemble_external_libcall
2278      here, as we can not depend on emit_library_call to do it for us.  */
2279   assemble_external_libcall (eh_personality_libfunc);
2280   mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
2281   emit_move_insn (mem, eh_personality_libfunc);
2282
2283   mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
2284   if (cfun->uses_eh_lsda)
2285     {
2286       char buf[20];
2287       rtx sym;
2288
2289       ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", current_function_funcdef_no);
2290       sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
2291       SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
2292       emit_move_insn (mem, sym);
2293     }
2294   else
2295     emit_move_insn (mem, const0_rtx);
2296
2297 #ifdef DONT_USE_BUILTIN_SETJMP
2298   {
2299     rtx x, note;
2300     x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
2301                                  TYPE_MODE (integer_type_node), 1,
2302                                  plus_constant (XEXP (fc, 0),
2303                                                 sjlj_fc_jbuf_ofs), Pmode);
2304
2305     note = emit_note (NOTE_INSN_EXPECTED_VALUE);
2306     NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx);
2307
2308     emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
2309                              TYPE_MODE (integer_type_node), 0, dispatch_label);
2310   }
2311 #else
2312   expand_builtin_setjmp_setup (plus_constant (XEXP (fc, 0), sjlj_fc_jbuf_ofs),
2313                                dispatch_label);
2314 #endif
2315
2316   emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
2317                      1, XEXP (fc, 0), Pmode);
2318
2319   seq = get_insns ();
2320   end_sequence ();
2321
2322   /* ??? Instead of doing this at the beginning of the function,
2323      do this in a block that is at loop level 0 and dominates all
2324      can_throw_internal instructions.  */
2325
2326   for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
2327     if (GET_CODE (fn_begin) == NOTE
2328         && (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG
2329             || NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_BASIC_BLOCK))
2330       break;
2331   if (NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
2332     insert_insn_on_edge (seq, ENTRY_BLOCK_PTR->succ);
2333   else
2334     {
2335       rtx last = BB_END (ENTRY_BLOCK_PTR->succ->dest);
2336       for (; ; fn_begin = NEXT_INSN (fn_begin))
2337         if ((GET_CODE (fn_begin) == NOTE
2338              && NOTE_LINE_NUMBER (fn_begin) == NOTE_INSN_FUNCTION_BEG)
2339             || fn_begin == last)
2340           break;
2341       emit_insn_after (seq, fn_begin);
2342     }
2343 }
2344
2345 /* Call back from expand_function_end to know where we should put
2346    the call to unwind_sjlj_unregister_libfunc if needed.  */
2347
2348 void
2349 sjlj_emit_function_exit_after (rtx after)
2350 {
2351   cfun->eh->sjlj_exit_after = after;
2352 }
2353
2354 static void
2355 sjlj_emit_function_exit (void)
2356 {
2357   rtx seq;
2358   edge e;
2359
2360   start_sequence ();
2361
2362   emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
2363                      1, XEXP (cfun->eh->sjlj_fc, 0), Pmode);
2364
2365   seq = get_insns ();
2366   end_sequence ();
2367
2368   /* ??? Really this can be done in any block at loop level 0 that
2369      post-dominates all can_throw_internal instructions.  This is
2370      the last possible moment.  */
2371
2372   for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
2373     if (e->flags & EDGE_FALLTHRU)
2374       break;
2375   if (e)
2376     {
2377       rtx insn;
2378
2379       /* Figure out whether the place we are supposed to insert libcall
2380          is inside the last basic block or after it.  In the other case
2381          we need to emit to edge.  */
2382       if (e->src->next_bb != EXIT_BLOCK_PTR)
2383         abort ();
2384       for (insn = NEXT_INSN (BB_END (e->src)); insn; insn = NEXT_INSN (insn))
2385         if (insn == cfun->eh->sjlj_exit_after)
2386           break;
2387       if (insn)
2388         insert_insn_on_edge (seq, e);
2389       else
2390         {
2391           insn = cfun->eh->sjlj_exit_after;
2392           if (GET_CODE (insn) == CODE_LABEL)
2393             insn = NEXT_INSN (insn);
2394           emit_insn_after (seq, insn);
2395         }
2396     }
2397 }
2398
2399 static void
2400 sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
2401 {
2402   int i, first_reachable;
2403   rtx mem, dispatch, seq, fc;
2404   rtx before;
2405   basic_block bb;
2406   edge e;
2407
2408   fc = cfun->eh->sjlj_fc;
2409
2410   start_sequence ();
2411
2412   emit_label (dispatch_label);
2413
2414 #ifndef DONT_USE_BUILTIN_SETJMP
2415   expand_builtin_setjmp_receiver (dispatch_label);
2416 #endif
2417
2418   /* Load up dispatch index, exc_ptr and filter values from the
2419      function context.  */
2420   mem = adjust_address (fc, TYPE_MODE (integer_type_node),
2421                         sjlj_fc_call_site_ofs);
2422   dispatch = copy_to_reg (mem);
2423
2424   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs);
2425   if (word_mode != ptr_mode)
2426     {
2427 #ifdef POINTERS_EXTEND_UNSIGNED
2428       mem = convert_memory_address (ptr_mode, mem);
2429 #else
2430       mem = convert_to_mode (ptr_mode, mem, 0);
2431 #endif
2432     }
2433   emit_move_insn (cfun->eh->exc_ptr, mem);
2434
2435   mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs + UNITS_PER_WORD);
2436   emit_move_insn (cfun->eh->filter, mem);
2437
2438   /* Jump to one of the directly reachable regions.  */
2439   /* ??? This really ought to be using a switch statement.  */
2440
2441   first_reachable = 0;
2442   for (i = cfun->eh->last_region_number; i > 0; --i)
2443     {
2444       if (! lp_info[i].directly_reachable)
2445         continue;
2446
2447       if (! first_reachable)
2448         {
2449           first_reachable = i;
2450           continue;
2451         }
2452
2453       emit_cmp_and_jump_insns (dispatch, GEN_INT (lp_info[i].dispatch_index),
2454                                EQ, NULL_RTX, TYPE_MODE (integer_type_node), 0,
2455                                cfun->eh->region_array[i]->post_landing_pad);
2456     }
2457
2458   seq = get_insns ();
2459   end_sequence ();
2460
2461   before = cfun->eh->region_array[first_reachable]->post_landing_pad;
2462
2463   bb = emit_to_new_bb_before (seq, before);
2464   e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
2465   e->count = bb->count;
2466   e->probability = REG_BR_PROB_BASE;
2467 }
2468
2469 static void
2470 sjlj_build_landing_pads (void)
2471 {
2472   struct sjlj_lp_info *lp_info;
2473
2474   lp_info = xcalloc (cfun->eh->last_region_number + 1,
2475                      sizeof (struct sjlj_lp_info));
2476
2477   if (sjlj_find_directly_reachable_regions (lp_info))
2478     {
2479       rtx dispatch_label = gen_label_rtx ();
2480
2481       cfun->eh->sjlj_fc
2482         = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
2483                               int_size_in_bytes (sjlj_fc_type_node),
2484                               TYPE_ALIGN (sjlj_fc_type_node));
2485
2486       sjlj_assign_call_site_values (dispatch_label, lp_info);
2487       sjlj_mark_call_sites (lp_info);
2488
2489       sjlj_emit_function_enter (dispatch_label);
2490       sjlj_emit_dispatch_table (dispatch_label, lp_info);
2491       sjlj_emit_function_exit ();
2492     }
2493
2494   free (lp_info);
2495 }
2496
2497 void
2498 finish_eh_generation (void)
2499 {
2500   basic_block bb;
2501
2502   /* Nothing to do if no regions created.  */
2503   if (cfun->eh->region_tree == NULL)
2504     return;
2505
2506   /* The object here is to provide find_basic_blocks with detailed
2507      information (via reachable_handlers) on how exception control
2508      flows within the function.  In this first pass, we can include
2509      type information garnered from ERT_THROW and ERT_ALLOWED_EXCEPTIONS
2510      regions, and hope that it will be useful in deleting unreachable
2511      handlers.  Subsequently, we will generate landing pads which will
2512      connect many of the handlers, and then type information will not
2513      be effective.  Still, this is a win over previous implementations.  */
2514
2515   cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
2516
2517   /* These registers are used by the landing pads.  Make sure they
2518      have been generated.  */
2519   get_exception_pointer (cfun);
2520   get_exception_filter (cfun);
2521
2522   /* Construct the landing pads.  */
2523
2524   assign_filter_values ();
2525   build_post_landing_pads ();
2526   connect_post_landing_pads ();
2527   if (USING_SJLJ_EXCEPTIONS)
2528     sjlj_build_landing_pads ();
2529   else
2530     dw2_build_landing_pads ();
2531
2532   cfun->eh->built_landing_pads = 1;
2533
2534   /* We've totally changed the CFG.  Start over.  */
2535   find_exception_handler_labels ();
2536   break_superblocks ();
2537   if (USING_SJLJ_EXCEPTIONS)
2538     commit_edge_insertions ();
2539   FOR_EACH_BB (bb)
2540     {
2541       edge e, next;
2542       bool eh = false;
2543       for (e = bb->succ; e; e = next)
2544         {
2545           next = e->succ_next;
2546           if (e->flags & EDGE_EH)
2547             {
2548               remove_edge (e);
2549               eh = true;
2550             }
2551         }
2552       if (eh)
2553         rtl_make_eh_edge (NULL, bb, BB_END (bb));
2554     }
2555   cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
2556 }
2557 \f
2558 static hashval_t
2559 ehl_hash (const void *pentry)
2560 {
2561   struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
2562
2563   /* 2^32 * ((sqrt(5) - 1) / 2) */
2564   const hashval_t scaled_golden_ratio = 0x9e3779b9;
2565   return CODE_LABEL_NUMBER (entry->label) * scaled_golden_ratio;
2566 }
2567
2568 static int
2569 ehl_eq (const void *pentry, const void *pdata)
2570 {
2571   struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
2572   struct ehl_map_entry *data = (struct ehl_map_entry *) pdata;
2573
2574   return entry->label == data->label;
2575 }
2576
2577 /* This section handles removing dead code for flow.  */
2578
2579 /* Remove LABEL from exception_handler_label_map.  */
2580
2581 static void
2582 remove_exception_handler_label (rtx label)
2583 {
2584   struct ehl_map_entry **slot, tmp;
2585
2586   /* If exception_handler_label_map was not built yet,
2587      there is nothing to do.  */
2588   if (cfun->eh->exception_handler_label_map == NULL)
2589     return;
2590
2591   tmp.label = label;
2592   slot = (struct ehl_map_entry **)
2593     htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
2594   if (! slot)
2595     abort ();
2596
2597   htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
2598 }
2599
2600 /* Splice REGION from the region tree etc.  */
2601
2602 static void
2603 remove_eh_handler (struct eh_region *region)
2604 {
2605   struct eh_region **pp, **pp_start, *p, *outer, *inner;
2606   rtx lab;
2607
2608   /* For the benefit of efficiently handling REG_EH_REGION notes,
2609      replace this region in the region array with its containing
2610      region.  Note that previous region deletions may result in
2611      multiple copies of this region in the array, so we have a
2612      list of alternate numbers by which we are known.  */
2613
2614   outer = region->outer;
2615   cfun->eh->region_array[region->region_number] = outer;
2616   if (region->aka)
2617     {
2618       int i;
2619       EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i,
2620         { cfun->eh->region_array[i] = outer; });
2621     }
2622
2623   if (outer)
2624     {
2625       if (!outer->aka)
2626         outer->aka = BITMAP_GGC_ALLOC ();
2627       if (region->aka)
2628         bitmap_a_or_b (outer->aka, outer->aka, region->aka);
2629       bitmap_set_bit (outer->aka, region->region_number);
2630     }
2631
2632   if (cfun->eh->built_landing_pads)
2633     lab = region->landing_pad;
2634   else
2635     lab = region->label;
2636   if (lab)
2637     remove_exception_handler_label (lab);
2638
2639   if (outer)
2640     pp_start = &outer->inner;
2641   else
2642     pp_start = &cfun->eh->region_tree;
2643   for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
2644     continue;
2645   *pp = region->next_peer;
2646
2647   inner = region->inner;
2648   if (inner)
2649     {
2650       for (p = inner; p->next_peer ; p = p->next_peer)
2651         p->outer = outer;
2652       p->outer = outer;
2653
2654       p->next_peer = *pp_start;
2655       *pp_start = inner;
2656     }
2657
2658   if (region->type == ERT_CATCH)
2659     {
2660       struct eh_region *try, *next, *prev;
2661
2662       for (try = region->next_peer;
2663            try->type == ERT_CATCH;
2664            try = try->next_peer)
2665         continue;
2666       if (try->type != ERT_TRY)
2667         abort ();
2668
2669       next = region->u.catch.next_catch;
2670       prev = region->u.catch.prev_catch;
2671
2672       if (next)
2673         next->u.catch.prev_catch = prev;
2674       else
2675         try->u.try.last_catch = prev;
2676       if (prev)
2677         prev->u.catch.next_catch = next;
2678       else
2679         {
2680           try->u.try.catch = next;
2681           if (! next)
2682             remove_eh_handler (try);
2683         }
2684     }
2685 }
2686
2687 /* LABEL heads a basic block that is about to be deleted.  If this
2688    label corresponds to an exception region, we may be able to
2689    delete the region.  */
2690
2691 void
2692 maybe_remove_eh_handler (rtx label)
2693 {
2694   struct ehl_map_entry **slot, tmp;
2695   struct eh_region *region;
2696
2697   /* ??? After generating landing pads, it's not so simple to determine
2698      if the region data is completely unused.  One must examine the
2699      landing pad and the post landing pad, and whether an inner try block
2700      is referencing the catch handlers directly.  */
2701   if (cfun->eh->built_landing_pads)
2702     return;
2703
2704   tmp.label = label;
2705   slot = (struct ehl_map_entry **)
2706     htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
2707   if (! slot)
2708     return;
2709   region = (*slot)->region;
2710   if (! region)
2711     return;
2712
2713   /* Flow will want to remove MUST_NOT_THROW regions as unreachable
2714      because there is no path to the fallback call to terminate.
2715      But the region continues to affect call-site data until there
2716      are no more contained calls, which we don't see here.  */
2717   if (region->type == ERT_MUST_NOT_THROW)
2718     {
2719       htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
2720       region->label = NULL_RTX;
2721     }
2722   else
2723     remove_eh_handler (region);
2724 }
2725
2726 /* Invokes CALLBACK for every exception handler label.  Only used by old
2727    loop hackery; should not be used by new code.  */
2728
2729 void
2730 for_each_eh_label (void (*callback) (rtx))
2731 {
2732   htab_traverse (cfun->eh->exception_handler_label_map, for_each_eh_label_1,
2733                  (void *) &callback);
2734 }
2735
2736 static int
2737 for_each_eh_label_1 (void **pentry, void *data)
2738 {
2739   struct ehl_map_entry *entry = *(struct ehl_map_entry **)pentry;
2740   void (*callback) (rtx) = *(void (**) (rtx)) data;
2741
2742   (*callback) (entry->label);
2743   return 1;
2744 }
2745
2746 /* Invoke CALLBACK for every exception region in the current function.  */
2747
2748 void
2749 for_each_eh_region (void (*callback) (struct eh_region *))
2750 {
2751   int i, n = cfun->eh->last_region_number;
2752   for (i = 1; i <= n; ++i)
2753     {
2754       struct eh_region *region = cfun->eh->region_array[i];
2755       if (region)
2756         (*callback) (region);
2757     }
2758 }
2759 \f
2760 /* This section describes CFG exception edges for flow.  */
2761
2762 /* For communicating between calls to reachable_next_level.  */
2763 struct reachable_info
2764 {
2765   tree types_caught;
2766   tree types_allowed;
2767   void (*callback) (struct eh_region *, void *);
2768   void *callback_data;
2769   bool saw_any_handlers;
2770 };
2771
2772 /* A subroutine of reachable_next_level.  Return true if TYPE, or a
2773    base class of TYPE, is in HANDLED.  */
2774
2775 int
2776 check_handled (tree handled, tree type)
2777 {
2778   tree t;
2779
2780   /* We can check for exact matches without front-end help.  */
2781   if (! lang_eh_type_covers)
2782     {
2783       for (t = handled; t ; t = TREE_CHAIN (t))
2784         if (TREE_VALUE (t) == type)
2785           return 1;
2786     }
2787   else
2788     {
2789       for (t = handled; t ; t = TREE_CHAIN (t))
2790         if ((*lang_eh_type_covers) (TREE_VALUE (t), type))
2791           return 1;
2792     }
2793
2794   return 0;
2795 }
2796
2797 /* A subroutine of reachable_next_level.  If we are collecting a list
2798    of handlers, add one.  After landing pad generation, reference
2799    it instead of the handlers themselves.  Further, the handlers are
2800    all wired together, so by referencing one, we've got them all.
2801    Before landing pad generation we reference each handler individually.
2802
2803    LP_REGION contains the landing pad; REGION is the handler.  */
2804
2805 static void
2806 add_reachable_handler (struct reachable_info *info,
2807                        struct eh_region *lp_region, struct eh_region *region)
2808 {
2809   if (! info)
2810     return;
2811
2812   info->saw_any_handlers = true;
2813
2814   if (cfun->eh->built_landing_pads)
2815     info->callback (lp_region, info->callback_data);
2816   else
2817     info->callback (region, info->callback_data);
2818 }
2819
2820 /* Process one level of exception regions for reachability.
2821    If TYPE_THROWN is non-null, then it is the *exact* type being
2822    propagated.  If INFO is non-null, then collect handler labels
2823    and caught/allowed type information between invocations.  */
2824
2825 static enum reachable_code
2826 reachable_next_level (struct eh_region *region, tree type_thrown,
2827                       struct reachable_info *info)
2828 {
2829   switch (region->type)
2830     {
2831     case ERT_CLEANUP:
2832       /* Before landing-pad generation, we model control flow
2833          directly to the individual handlers.  In this way we can
2834          see that catch handler types may shadow one another.  */
2835       add_reachable_handler (info, region, region);
2836       return RNL_MAYBE_CAUGHT;
2837
2838     case ERT_TRY:
2839       {
2840         struct eh_region *c;
2841         enum reachable_code ret = RNL_NOT_CAUGHT;
2842
2843         for (c = region->u.try.catch; c ; c = c->u.catch.next_catch)
2844           {
2845             /* A catch-all handler ends the search.  */
2846             if (c->u.catch.type_list == NULL)
2847               {
2848                 add_reachable_handler (info, region, c);
2849                 return RNL_CAUGHT;
2850               }
2851
2852             if (type_thrown)
2853               {
2854                 /* If we have at least one type match, end the search.  */
2855                 tree tp_node = c->u.catch.type_list;
2856
2857                 for (; tp_node; tp_node = TREE_CHAIN (tp_node))
2858                   {
2859                     tree type = TREE_VALUE (tp_node);
2860
2861                     if (type == type_thrown
2862                         || (lang_eh_type_covers
2863                             && (*lang_eh_type_covers) (type, type_thrown)))
2864                       {
2865                         add_reachable_handler (info, region, c);
2866                         return RNL_CAUGHT;
2867                       }
2868                   }
2869
2870                 /* If we have definitive information of a match failure,
2871                    the catch won't trigger.  */
2872                 if (lang_eh_type_covers)
2873                   return RNL_NOT_CAUGHT;
2874               }
2875
2876             /* At this point, we either don't know what type is thrown or
2877                don't have front-end assistance to help deciding if it is
2878                covered by one of the types in the list for this region.
2879
2880                We'd then like to add this region to the list of reachable
2881                handlers since it is indeed potentially reachable based on the
2882                information we have.
2883
2884                Actually, this handler is for sure not reachable if all the
2885                types it matches have already been caught. That is, it is only
2886                potentially reachable if at least one of the types it catches
2887                has not been previously caught.  */
2888
2889             if (! info)
2890               ret = RNL_MAYBE_CAUGHT;
2891             else
2892               {
2893                 tree tp_node = c->u.catch.type_list;
2894                 bool maybe_reachable = false;
2895
2896                 /* Compute the potential reachability of this handler and
2897                    update the list of types caught at the same time.  */
2898                 for (; tp_node; tp_node = TREE_CHAIN (tp_node))
2899                   {
2900                     tree type = TREE_VALUE (tp_node);
2901
2902                     if (! check_handled (info->types_caught, type))
2903                       {
2904                         info->types_caught
2905                           = tree_cons (NULL, type, info->types_caught);
2906
2907                         maybe_reachable = true;
2908                       }
2909                   }
2910
2911                 if (maybe_reachable)
2912                   {
2913                     add_reachable_handler (info, region, c);
2914
2915                     /* ??? If the catch type is a base class of every allowed
2916                        type, then we know we can stop the search.  */
2917                     ret = RNL_MAYBE_CAUGHT;
2918                   }
2919               }
2920           }
2921
2922         return ret;
2923       }
2924
2925     case ERT_ALLOWED_EXCEPTIONS:
2926       /* An empty list of types definitely ends the search.  */
2927       if (region->u.allowed.type_list == NULL_TREE)
2928         {
2929           add_reachable_handler (info, region, region);
2930           return RNL_CAUGHT;
2931         }
2932
2933       /* Collect a list of lists of allowed types for use in detecting
2934          when a catch may be transformed into a catch-all.  */
2935       if (info)
2936         info->types_allowed = tree_cons (NULL_TREE,
2937                                          region->u.allowed.type_list,
2938                                          info->types_allowed);
2939
2940       /* If we have definitive information about the type hierarchy,
2941          then we can tell if the thrown type will pass through the
2942          filter.  */
2943       if (type_thrown && lang_eh_type_covers)
2944         {
2945           if (check_handled (region->u.allowed.type_list, type_thrown))
2946             return RNL_NOT_CAUGHT;
2947           else
2948             {
2949               add_reachable_handler (info, region, region);
2950               return RNL_CAUGHT;
2951             }
2952         }
2953
2954       add_reachable_handler (info, region, region);
2955       return RNL_MAYBE_CAUGHT;
2956
2957     case ERT_CATCH:
2958       /* Catch regions are handled by their controlling try region.  */
2959       return RNL_NOT_CAUGHT;
2960
2961     case ERT_MUST_NOT_THROW:
2962       /* Here we end our search, since no exceptions may propagate.
2963          If we've touched down at some landing pad previous, then the
2964          explicit function call we generated may be used.  Otherwise
2965          the call is made by the runtime.  */
2966       if (info && info->saw_any_handlers)
2967         {
2968           add_reachable_handler (info, region, region);
2969           return RNL_CAUGHT;
2970         }
2971       else
2972         return RNL_BLOCKED;
2973
2974     case ERT_THROW:
2975     case ERT_FIXUP:
2976     case ERT_UNKNOWN:
2977       /* Shouldn't see these here.  */
2978       break;
2979     }
2980
2981   abort ();
2982 }
2983
2984 /* Invoke CALLBACK on each region reachable from REGION_NUMBER.  */
2985
2986 void
2987 foreach_reachable_handler (int region_number, bool is_resx,
2988                            void (*callback) (struct eh_region *, void *),
2989                            void *callback_data)
2990 {
2991   struct reachable_info info;
2992   struct eh_region *region;
2993   tree type_thrown;
2994
2995   memset (&info, 0, sizeof (info));
2996   info.callback = callback;
2997   info.callback_data = callback_data;
2998
2999   region = cfun->eh->region_array[region_number];
3000
3001   type_thrown = NULL_TREE;
3002   if (is_resx)
3003     {
3004       /* A RESX leaves a region instead of entering it.  Thus the
3005          region itself may have been deleted out from under us.  */
3006       if (region == NULL)
3007         return;
3008       region = region->outer;
3009     }
3010   else if (region->type == ERT_THROW)
3011     {
3012       type_thrown = region->u.throw.type;
3013       region = region->outer;
3014     }
3015
3016   while (region)
3017     {
3018       if (reachable_next_level (region, type_thrown, &info) >= RNL_CAUGHT)
3019         break;
3020       /* If we have processed one cleanup, there is no point in
3021          processing any more of them.  Each cleanup will have an edge
3022          to the next outer cleanup region, so the flow graph will be
3023          accurate.  */
3024       if (region->type == ERT_CLEANUP)
3025         region = region->u.cleanup.prev_try;
3026       else
3027         region = region->outer;
3028     }
3029 }
3030
3031 /* Retrieve a list of labels of exception handlers which can be
3032    reached by a given insn.  */
3033
3034 static void
3035 arh_to_landing_pad (struct eh_region *region, void *data)
3036 {
3037   rtx *p_handlers = data;
3038   if (! *p_handlers)
3039     *p_handlers = alloc_INSN_LIST (region->landing_pad, NULL_RTX);
3040 }
3041
3042 static void
3043 arh_to_label (struct eh_region *region, void *data)
3044 {
3045   rtx *p_handlers = data;
3046   *p_handlers = alloc_INSN_LIST (region->label, *p_handlers);
3047 }
3048
3049 rtx
3050 reachable_handlers (rtx insn)
3051 {
3052   bool is_resx = false;
3053   rtx handlers = NULL;
3054   int region_number;
3055
3056   if (GET_CODE (insn) == JUMP_INSN
3057       && GET_CODE (PATTERN (insn)) == RESX)
3058     {
3059       region_number = XINT (PATTERN (insn), 0);
3060       is_resx = true;
3061     }
3062   else
3063     {
3064       rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3065       if (!note || INTVAL (XEXP (note, 0)) <= 0)
3066         return NULL;
3067       region_number = INTVAL (XEXP (note, 0));
3068     }
3069
3070   foreach_reachable_handler (region_number, is_resx,
3071                              (cfun->eh->built_landing_pads
3072                               ? arh_to_landing_pad
3073                               : arh_to_label),
3074                              &handlers);
3075
3076   return handlers;
3077 }
3078
3079 /* Determine if the given INSN can throw an exception that is caught
3080    within the function.  */
3081
3082 bool
3083 can_throw_internal_1 (int region_number)
3084 {
3085   struct eh_region *region;
3086   tree type_thrown;
3087
3088   region = cfun->eh->region_array[region_number];
3089
3090   type_thrown = NULL_TREE;
3091   if (region->type == ERT_THROW)
3092     {
3093       type_thrown = region->u.throw.type;
3094       region = region->outer;
3095     }
3096
3097   /* If this exception is ignored by each and every containing region,
3098      then control passes straight out.  The runtime may handle some
3099      regions, which also do not require processing internally.  */
3100   for (; region; region = region->outer)
3101     {
3102       enum reachable_code how = reachable_next_level (region, type_thrown, 0);
3103       if (how == RNL_BLOCKED)
3104         return false;
3105       if (how != RNL_NOT_CAUGHT)
3106         return true;
3107     }
3108
3109   return false;
3110 }
3111
3112 bool
3113 can_throw_internal (rtx insn)
3114 {
3115   rtx note;
3116
3117   if (! INSN_P (insn))
3118     return false;
3119
3120   if (GET_CODE (insn) == INSN
3121       && GET_CODE (PATTERN (insn)) == SEQUENCE)
3122     insn = XVECEXP (PATTERN (insn), 0, 0);
3123
3124   /* Every insn that might throw has an EH_REGION note.  */
3125   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3126   if (!note || INTVAL (XEXP (note, 0)) <= 0)
3127     return false;
3128
3129   return can_throw_internal_1 (INTVAL (XEXP (note, 0)));
3130 }
3131
3132 /* Determine if the given INSN can throw an exception that is
3133    visible outside the function.  */
3134
3135 bool
3136 can_throw_external_1 (int region_number)
3137 {
3138   struct eh_region *region;
3139   tree type_thrown;
3140
3141   region = cfun->eh->region_array[region_number];
3142
3143   type_thrown = NULL_TREE;
3144   if (region->type == ERT_THROW)
3145     {
3146       type_thrown = region->u.throw.type;
3147       region = region->outer;
3148     }
3149
3150   /* If the exception is caught or blocked by any containing region,
3151      then it is not seen by any calling function.  */
3152   for (; region ; region = region->outer)
3153     if (reachable_next_level (region, type_thrown, NULL) >= RNL_CAUGHT)
3154       return false;
3155
3156   return true;
3157 }
3158
3159 bool
3160 can_throw_external (rtx insn)
3161 {
3162   rtx note;
3163
3164   if (! INSN_P (insn))
3165     return false;
3166
3167   if (GET_CODE (insn) == INSN
3168       && GET_CODE (PATTERN (insn)) == SEQUENCE)
3169     insn = XVECEXP (PATTERN (insn), 0, 0);
3170
3171   note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3172   if (!note)
3173     {
3174       /* Calls (and trapping insns) without notes are outside any
3175          exception handling region in this function.  We have to
3176          assume it might throw.  Given that the front end and middle
3177          ends mark known NOTHROW functions, this isn't so wildly
3178          inaccurate.  */
3179       return (GET_CODE (insn) == CALL_INSN
3180               || (flag_non_call_exceptions
3181                   && may_trap_p (PATTERN (insn))));
3182     }
3183   if (INTVAL (XEXP (note, 0)) <= 0)
3184     return false;
3185
3186   return can_throw_external_1 (INTVAL (XEXP (note, 0)));
3187 }
3188
3189 /* Set current_function_nothrow and cfun->all_throwers_are_sibcalls.  */
3190
3191 void
3192 set_nothrow_function_flags (void)
3193 {
3194   rtx insn;
3195
3196   current_function_nothrow = 1;
3197
3198   /* Assume cfun->all_throwers_are_sibcalls until we encounter
3199      something that can throw an exception.  We specifically exempt
3200      CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
3201      and can't throw.  Most CALL_INSNs are not SIBLING_CALL_P, so this
3202      is optimistic.  */
3203
3204   cfun->all_throwers_are_sibcalls = 1;
3205
3206   if (! flag_exceptions)
3207     return;
3208
3209   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
3210     if (can_throw_external (insn))
3211       {
3212         current_function_nothrow = 0;
3213
3214         if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn))
3215           {
3216             cfun->all_throwers_are_sibcalls = 0;
3217             return;
3218           }
3219       }
3220
3221   for (insn = current_function_epilogue_delay_list; insn;
3222        insn = XEXP (insn, 1))
3223     if (can_throw_external (insn))
3224       {
3225         current_function_nothrow = 0;
3226
3227         if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn))
3228           {
3229             cfun->all_throwers_are_sibcalls = 0;
3230             return;
3231           }
3232       }
3233 }
3234
3235 \f
3236 /* Various hooks for unwind library.  */
3237
3238 /* Do any necessary initialization to access arbitrary stack frames.
3239    On the SPARC, this means flushing the register windows.  */
3240
3241 void
3242 expand_builtin_unwind_init (void)
3243 {
3244   /* Set this so all the registers get saved in our frame; we need to be
3245      able to copy the saved values for any registers from frames we unwind.  */
3246   current_function_has_nonlocal_label = 1;
3247
3248 #ifdef SETUP_FRAME_ADDRESSES
3249   SETUP_FRAME_ADDRESSES ();
3250 #endif
3251 }
3252
3253 rtx
3254 expand_builtin_eh_return_data_regno (tree arglist)
3255 {
3256   tree which = TREE_VALUE (arglist);
3257   unsigned HOST_WIDE_INT iwhich;
3258
3259   if (TREE_CODE (which) != INTEGER_CST)
3260     {
3261       error ("argument of `__builtin_eh_return_regno' must be constant");
3262       return constm1_rtx;
3263     }
3264
3265   iwhich = tree_low_cst (which, 1);
3266   iwhich = EH_RETURN_DATA_REGNO (iwhich);
3267   if (iwhich == INVALID_REGNUM)
3268     return constm1_rtx;
3269
3270 #ifdef DWARF_FRAME_REGNUM
3271   iwhich = DWARF_FRAME_REGNUM (iwhich);
3272 #else
3273   iwhich = DBX_REGISTER_NUMBER (iwhich);
3274 #endif
3275
3276   return GEN_INT (iwhich);
3277 }
3278
3279 /* Given a value extracted from the return address register or stack slot,
3280    return the actual address encoded in that value.  */
3281
3282 rtx
3283 expand_builtin_extract_return_addr (tree addr_tree)
3284 {
3285   rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
3286
3287   if (GET_MODE (addr) != Pmode
3288       && GET_MODE (addr) != VOIDmode)
3289     {
3290 #ifdef POINTERS_EXTEND_UNSIGNED
3291       addr = convert_memory_address (Pmode, addr);
3292 #else
3293       addr = convert_to_mode (Pmode, addr, 0);
3294 #endif
3295     }
3296
3297   /* First mask out any unwanted bits.  */
3298 #ifdef MASK_RETURN_ADDR
3299   expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
3300 #endif
3301
3302   /* Then adjust to find the real return address.  */
3303 #if defined (RETURN_ADDR_OFFSET)
3304   addr = plus_constant (addr, RETURN_ADDR_OFFSET);
3305 #endif
3306
3307   return addr;
3308 }
3309
3310 /* Given an actual address in addr_tree, do any necessary encoding
3311    and return the value to be stored in the return address register or
3312    stack slot so the epilogue will return to that address.  */
3313
3314 rtx
3315 expand_builtin_frob_return_addr (tree addr_tree)
3316 {
3317   rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
3318
3319   addr = convert_memory_address (Pmode, addr);
3320
3321 #ifdef RETURN_ADDR_OFFSET
3322   addr = force_reg (Pmode, addr);
3323   addr = plus_constant (addr, -RETURN_ADDR_OFFSET);
3324 #endif
3325
3326   return addr;
3327 }
3328
3329 /* Set up the epilogue with the magic bits we'll need to return to the
3330    exception handler.  */
3331
3332 void
3333 expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED,
3334                           tree handler_tree)
3335 {
3336   rtx tmp;
3337
3338 #ifdef EH_RETURN_STACKADJ_RTX
3339   tmp = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
3340   tmp = convert_memory_address (Pmode, tmp);
3341   if (!cfun->eh->ehr_stackadj)
3342     cfun->eh->ehr_stackadj = copy_to_reg (tmp);
3343   else if (tmp != cfun->eh->ehr_stackadj)
3344     emit_move_insn (cfun->eh->ehr_stackadj, tmp);
3345 #endif
3346
3347   tmp = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
3348   tmp = convert_memory_address (Pmode, tmp);
3349   if (!cfun->eh->ehr_handler)
3350     cfun->eh->ehr_handler = copy_to_reg (tmp);
3351   else if (tmp != cfun->eh->ehr_handler)
3352     emit_move_insn (cfun->eh->ehr_handler, tmp);
3353
3354   if (!cfun->eh->ehr_label)
3355     cfun->eh->ehr_label = gen_label_rtx ();
3356   emit_jump (cfun->eh->ehr_label);
3357 }
3358
3359 void
3360 expand_eh_return (void)
3361 {
3362   rtx around_label;
3363
3364   if (! cfun->eh->ehr_label)
3365     return;
3366
3367   current_function_calls_eh_return = 1;
3368
3369 #ifdef EH_RETURN_STACKADJ_RTX
3370   emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx);
3371 #endif
3372
3373   around_label = gen_label_rtx ();
3374   emit_jump (around_label);
3375
3376   emit_label (cfun->eh->ehr_label);
3377   clobber_return_register ();
3378
3379 #ifdef EH_RETURN_STACKADJ_RTX
3380   emit_move_insn (EH_RETURN_STACKADJ_RTX, cfun->eh->ehr_stackadj);
3381 #endif
3382
3383 #ifdef HAVE_eh_return
3384   if (HAVE_eh_return)
3385     emit_insn (gen_eh_return (cfun->eh->ehr_handler));
3386   else
3387 #endif
3388     {
3389 #ifdef EH_RETURN_HANDLER_RTX
3390       emit_move_insn (EH_RETURN_HANDLER_RTX, cfun->eh->ehr_handler);
3391 #else
3392       error ("__builtin_eh_return not supported on this target");
3393 #endif
3394     }
3395
3396   emit_label (around_label);
3397 }
3398
3399 /* Convert a ptr_mode address ADDR_TREE to a Pmode address controlled by
3400    POINTERS_EXTEND_UNSIGNED and return it.  */
3401
3402 rtx
3403 expand_builtin_extend_pointer (tree addr_tree)
3404 {
3405   rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
3406   int extend;
3407
3408 #ifdef POINTERS_EXTEND_UNSIGNED
3409   extend = POINTERS_EXTEND_UNSIGNED;
3410 #else
3411   /* The previous EH code did an unsigned extend by default, so we do this also
3412      for consistency.  */
3413   extend = 1;
3414 #endif
3415
3416   return convert_modes (word_mode, ptr_mode, addr, extend);
3417 }
3418 \f
3419 /* In the following functions, we represent entries in the action table
3420    as 1-based indices.  Special cases are:
3421
3422          0:     null action record, non-null landing pad; implies cleanups
3423         -1:     null action record, null landing pad; implies no action
3424         -2:     no call-site entry; implies must_not_throw
3425         -3:     we have yet to process outer regions
3426
3427    Further, no special cases apply to the "next" field of the record.
3428    For next, 0 means end of list.  */
3429
3430 struct action_record
3431 {
3432   int offset;
3433   int filter;
3434   int next;
3435 };
3436
3437 static int
3438 action_record_eq (const void *pentry, const void *pdata)
3439 {
3440   const struct action_record *entry = (const struct action_record *) pentry;
3441   const struct action_record *data = (const struct action_record *) pdata;
3442   return entry->filter == data->filter && entry->next == data->next;
3443 }
3444
3445 static hashval_t
3446 action_record_hash (const void *pentry)
3447 {
3448   const struct action_record *entry = (const struct action_record *) pentry;
3449   return entry->next * 1009 + entry->filter;
3450 }
3451
3452 static int
3453 add_action_record (htab_t ar_hash, int filter, int next)
3454 {
3455   struct action_record **slot, *new, tmp;
3456
3457   tmp.filter = filter;
3458   tmp.next = next;
3459   slot = (struct action_record **) htab_find_slot (ar_hash, &tmp, INSERT);
3460
3461   if ((new = *slot) == NULL)
3462     {
3463       new = xmalloc (sizeof (*new));
3464       new->offset = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
3465       new->filter = filter;
3466       new->next = next;
3467       *slot = new;
3468
3469       /* The filter value goes in untouched.  The link to the next
3470          record is a "self-relative" byte offset, or zero to indicate
3471          that there is no next record.  So convert the absolute 1 based
3472          indices we've been carrying around into a displacement.  */
3473
3474       push_sleb128 (&cfun->eh->action_record_data, filter);
3475       if (next)
3476         next -= VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
3477       push_sleb128 (&cfun->eh->action_record_data, next);
3478     }
3479
3480   return new->offset;
3481 }
3482
3483 static int
3484 collect_one_action_chain (htab_t ar_hash, struct eh_region *region)
3485 {
3486   struct eh_region *c;
3487   int next;
3488
3489   /* If we've reached the top of the region chain, then we have
3490      no actions, and require no landing pad.  */
3491   if (region == NULL)
3492     return -1;
3493
3494   switch (region->type)
3495     {
3496     case ERT_CLEANUP:
3497       /* A cleanup adds a zero filter to the beginning of the chain, but
3498          there are special cases to look out for.  If there are *only*
3499          cleanups along a path, then it compresses to a zero action.
3500          Further, if there are multiple cleanups along a path, we only
3501          need to represent one of them, as that is enough to trigger
3502          entry to the landing pad at runtime.  */
3503       next = collect_one_action_chain (ar_hash, region->outer);
3504       if (next <= 0)
3505         return 0;
3506       for (c = region->outer; c ; c = c->outer)
3507         if (c->type == ERT_CLEANUP)
3508           return next;
3509       return add_action_record (ar_hash, 0, next);
3510
3511     case ERT_TRY:
3512       /* Process the associated catch regions in reverse order.
3513          If there's a catch-all handler, then we don't need to
3514          search outer regions.  Use a magic -3 value to record
3515          that we haven't done the outer search.  */
3516       next = -3;
3517       for (c = region->u.try.last_catch; c ; c = c->u.catch.prev_catch)
3518         {
3519           if (c->u.catch.type_list == NULL)
3520             {
3521               /* Retrieve the filter from the head of the filter list
3522                  where we have stored it (see assign_filter_values).  */
3523               int filter
3524                 = TREE_INT_CST_LOW (TREE_VALUE (c->u.catch.filter_list));
3525
3526               next = add_action_record (ar_hash, filter, 0);
3527             }
3528           else
3529             {
3530               /* Once the outer search is done, trigger an action record for
3531                  each filter we have.  */
3532               tree flt_node;
3533
3534               if (next == -3)
3535                 {
3536                   next = collect_one_action_chain (ar_hash, region->outer);
3537
3538                   /* If there is no next action, terminate the chain.  */
3539                   if (next == -1)
3540                     next = 0;
3541                   /* If all outer actions are cleanups or must_not_throw,
3542                      we'll have no action record for it, since we had wanted
3543                      to encode these states in the call-site record directly.
3544                      Add a cleanup action to the chain to catch these.  */
3545                   else if (next <= 0)
3546                     next = add_action_record (ar_hash, 0, 0);
3547                 }
3548
3549               flt_node = c->u.catch.filter_list;
3550               for (; flt_node; flt_node = TREE_CHAIN (flt_node))
3551                 {
3552                   int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
3553                   next = add_action_record (ar_hash, filter, next);
3554                 }
3555             }
3556         }
3557       return next;
3558
3559     case ERT_ALLOWED_EXCEPTIONS:
3560       /* An exception specification adds its filter to the
3561          beginning of the chain.  */
3562       next = collect_one_action_chain (ar_hash, region->outer);
3563
3564       /* If there is no next action, terminate the chain.  */
3565       if (next == -1)
3566         next = 0;
3567       /* If all outer actions are cleanups or must_not_throw,
3568          we'll have no action record for it, since we had wanted
3569          to encode these states in the call-site record directly.
3570          Add a cleanup action to the chain to catch these.  */
3571       else if (next <= 0)
3572         next = add_action_record (ar_hash, 0, 0);
3573       
3574       return add_action_record (ar_hash, region->u.allowed.filter, next);
3575
3576     case ERT_MUST_NOT_THROW:
3577       /* A must-not-throw region with no inner handlers or cleanups
3578          requires no call-site entry.  Note that this differs from
3579          the no handler or cleanup case in that we do require an lsda
3580          to be generated.  Return a magic -2 value to record this.  */
3581       return -2;
3582
3583     case ERT_CATCH:
3584     case ERT_THROW:
3585       /* CATCH regions are handled in TRY above.  THROW regions are
3586          for optimization information only and produce no output.  */
3587       return collect_one_action_chain (ar_hash, region->outer);
3588
3589     default:
3590       abort ();
3591     }
3592 }
3593
3594 static int
3595 add_call_site (rtx landing_pad, int action)
3596 {
3597   struct call_site_record *data = cfun->eh->call_site_data;
3598   int used = cfun->eh->call_site_data_used;
3599   int size = cfun->eh->call_site_data_size;
3600
3601   if (used >= size)
3602     {
3603       size = (size ? size * 2 : 64);
3604       data = ggc_realloc (data, sizeof (*data) * size);
3605       cfun->eh->call_site_data = data;
3606       cfun->eh->call_site_data_size = size;
3607     }
3608
3609   data[used].landing_pad = landing_pad;
3610   data[used].action = action;
3611
3612   cfun->eh->call_site_data_used = used + 1;
3613
3614   return used + call_site_base;
3615 }
3616
3617 /* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
3618    The new note numbers will not refer to region numbers, but
3619    instead to call site entries.  */
3620
3621 void
3622 convert_to_eh_region_ranges (void)
3623 {
3624   rtx insn, iter, note;
3625   htab_t ar_hash;
3626   int last_action = -3;
3627   rtx last_action_insn = NULL_RTX;
3628   rtx last_landing_pad = NULL_RTX;
3629   rtx first_no_action_insn = NULL_RTX;
3630   int call_site = 0;
3631
3632   if (USING_SJLJ_EXCEPTIONS || cfun->eh->region_tree == NULL)
3633     return;
3634
3635   VARRAY_UCHAR_INIT (cfun->eh->action_record_data, 64, "action_record_data");
3636
3637   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
3638
3639   for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
3640     if (INSN_P (iter))
3641       {
3642         struct eh_region *region;
3643         int this_action;
3644         rtx this_landing_pad;
3645
3646         insn = iter;
3647         if (GET_CODE (insn) == INSN
3648             && GET_CODE (PATTERN (insn)) == SEQUENCE)
3649           insn = XVECEXP (PATTERN (insn), 0, 0);
3650
3651         note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3652         if (!note)
3653           {
3654             if (! (GET_CODE (insn) == CALL_INSN
3655                    || (flag_non_call_exceptions
3656                        && may_trap_p (PATTERN (insn)))))
3657               continue;
3658             this_action = -1;
3659             region = NULL;
3660           }
3661         else
3662           {
3663             if (INTVAL (XEXP (note, 0)) <= 0)
3664               continue;
3665             region = cfun->eh->region_array[INTVAL (XEXP (note, 0))];
3666             this_action = collect_one_action_chain (ar_hash, region);
3667           }
3668
3669         /* Existence of catch handlers, or must-not-throw regions
3670            implies that an lsda is needed (even if empty).  */
3671         if (this_action != -1)
3672           cfun->uses_eh_lsda = 1;
3673
3674         /* Delay creation of region notes for no-action regions
3675            until we're sure that an lsda will be required.  */
3676         else if (last_action == -3)
3677           {
3678             first_no_action_insn = iter;
3679             last_action = -1;
3680           }
3681
3682         /* Cleanups and handlers may share action chains but not
3683            landing pads.  Collect the landing pad for this region.  */
3684         if (this_action >= 0)
3685           {
3686             struct eh_region *o;
3687             for (o = region; ! o->landing_pad ; o = o->outer)
3688               continue;
3689             this_landing_pad = o->landing_pad;
3690           }
3691         else
3692           this_landing_pad = NULL_RTX;
3693
3694         /* Differing actions or landing pads implies a change in call-site
3695            info, which implies some EH_REGION note should be emitted.  */
3696         if (last_action != this_action
3697             || last_landing_pad != this_landing_pad)
3698           {
3699             /* If we'd not seen a previous action (-3) or the previous
3700                action was must-not-throw (-2), then we do not need an
3701                end note.  */
3702             if (last_action >= -1)
3703               {
3704                 /* If we delayed the creation of the begin, do it now.  */
3705                 if (first_no_action_insn)
3706                   {
3707                     call_site = add_call_site (NULL_RTX, 0);
3708                     note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
3709                                              first_no_action_insn);
3710                     NOTE_EH_HANDLER (note) = call_site;
3711                     first_no_action_insn = NULL_RTX;
3712                   }
3713
3714                 note = emit_note_after (NOTE_INSN_EH_REGION_END,
3715                                         last_action_insn);
3716                 NOTE_EH_HANDLER (note) = call_site;
3717               }
3718
3719             /* If the new action is must-not-throw, then no region notes
3720                are created.  */
3721             if (this_action >= -1)
3722               {
3723                 call_site = add_call_site (this_landing_pad,
3724                                            this_action < 0 ? 0 : this_action);
3725                 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
3726                 NOTE_EH_HANDLER (note) = call_site;
3727               }
3728
3729             last_action = this_action;
3730             last_landing_pad = this_landing_pad;
3731           }
3732         last_action_insn = iter;
3733       }
3734
3735   if (last_action >= -1 && ! first_no_action_insn)
3736     {
3737       note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
3738       NOTE_EH_HANDLER (note) = call_site;
3739     }
3740
3741   htab_delete (ar_hash);
3742 }
3743
3744 \f
3745 static void
3746 push_uleb128 (varray_type *data_area, unsigned int value)
3747 {
3748   do
3749     {
3750       unsigned char byte = value & 0x7f;
3751       value >>= 7;
3752       if (value)
3753         byte |= 0x80;
3754       VARRAY_PUSH_UCHAR (*data_area, byte);
3755     }
3756   while (value);
3757 }
3758
3759 static void
3760 push_sleb128 (varray_type *data_area, int value)
3761 {
3762   unsigned char byte;
3763   int more;
3764
3765   do
3766     {
3767       byte = value & 0x7f;
3768       value >>= 7;
3769       more = ! ((value == 0 && (byte & 0x40) == 0)
3770                 || (value == -1 && (byte & 0x40) != 0));
3771       if (more)
3772         byte |= 0x80;
3773       VARRAY_PUSH_UCHAR (*data_area, byte);
3774     }
3775   while (more);
3776 }
3777
3778 \f
3779 #ifndef HAVE_AS_LEB128
3780 static int
3781 dw2_size_of_call_site_table (void)
3782 {
3783   int n = cfun->eh->call_site_data_used;
3784   int size = n * (4 + 4 + 4);
3785   int i;
3786
3787   for (i = 0; i < n; ++i)
3788     {
3789       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3790       size += size_of_uleb128 (cs->action);
3791     }
3792
3793   return size;
3794 }
3795
3796 static int
3797 sjlj_size_of_call_site_table (void)
3798 {
3799   int n = cfun->eh->call_site_data_used;
3800   int size = 0;
3801   int i;
3802
3803   for (i = 0; i < n; ++i)
3804     {
3805       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3806       size += size_of_uleb128 (INTVAL (cs->landing_pad));
3807       size += size_of_uleb128 (cs->action);
3808     }
3809
3810   return size;
3811 }
3812 #endif
3813
3814 static void
3815 dw2_output_call_site_table (void)
3816 {
3817   const char *const function_start_lab
3818     = IDENTIFIER_POINTER (current_function_func_begin_label);
3819   int n = cfun->eh->call_site_data_used;
3820   int i;
3821
3822   for (i = 0; i < n; ++i)
3823     {
3824       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3825       char reg_start_lab[32];
3826       char reg_end_lab[32];
3827       char landing_pad_lab[32];
3828
3829       ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
3830       ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
3831
3832       if (cs->landing_pad)
3833         ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
3834                                      CODE_LABEL_NUMBER (cs->landing_pad));
3835
3836       /* ??? Perhaps use insn length scaling if the assembler supports
3837          generic arithmetic.  */
3838       /* ??? Perhaps use attr_length to choose data1 or data2 instead of
3839          data4 if the function is small enough.  */
3840 #ifdef HAVE_AS_LEB128
3841       dw2_asm_output_delta_uleb128 (reg_start_lab, function_start_lab,
3842                                     "region %d start", i);
3843       dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
3844                                     "length");
3845       if (cs->landing_pad)
3846         dw2_asm_output_delta_uleb128 (landing_pad_lab, function_start_lab,
3847                                       "landing pad");
3848       else
3849         dw2_asm_output_data_uleb128 (0, "landing pad");
3850 #else
3851       dw2_asm_output_delta (4, reg_start_lab, function_start_lab,
3852                             "region %d start", i);
3853       dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
3854       if (cs->landing_pad)
3855         dw2_asm_output_delta (4, landing_pad_lab, function_start_lab,
3856                               "landing pad");
3857       else
3858         dw2_asm_output_data (4, 0, "landing pad");
3859 #endif
3860       dw2_asm_output_data_uleb128 (cs->action, "action");
3861     }
3862
3863   call_site_base += n;
3864 }
3865
3866 static void
3867 sjlj_output_call_site_table (void)
3868 {
3869   int n = cfun->eh->call_site_data_used;
3870   int i;
3871
3872   for (i = 0; i < n; ++i)
3873     {
3874       struct call_site_record *cs = &cfun->eh->call_site_data[i];
3875
3876       dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
3877                                    "region %d landing pad", i);
3878       dw2_asm_output_data_uleb128 (cs->action, "action");
3879     }
3880
3881   call_site_base += n;
3882 }
3883
3884 /* Tell assembler to switch to the section for the exception handling
3885    table.  */
3886
3887 void
3888 default_exception_section (void)
3889 {
3890   if (targetm.have_named_sections)
3891     {
3892       int flags;
3893 #ifdef HAVE_LD_RO_RW_SECTION_MIXING
3894       int tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3895
3896       flags = (! flag_pic
3897                || ((tt_format & 0x70) != DW_EH_PE_absptr
3898                    && (tt_format & 0x70) != DW_EH_PE_aligned))
3899               ? 0 : SECTION_WRITE;
3900 #else
3901       flags = SECTION_WRITE;
3902 #endif
3903       named_section_flags (".gcc_except_table", flags);
3904     }
3905   else if (flag_pic)
3906     data_section ();
3907   else
3908     readonly_data_section ();
3909 }
3910
3911 void
3912 output_function_exception_table (void)
3913 {
3914   int tt_format, cs_format, lp_format, i, n;
3915 #ifdef HAVE_AS_LEB128
3916   char ttype_label[32];
3917   char cs_after_size_label[32];
3918   char cs_end_label[32];
3919 #else
3920   int call_site_len;
3921 #endif
3922   int have_tt_data;
3923   int tt_format_size = 0;
3924
3925   /* Not all functions need anything.  */
3926   if (! cfun->uses_eh_lsda)
3927     return;
3928
3929 #ifdef IA64_UNWIND_INFO
3930   fputs ("\t.personality\t", asm_out_file);
3931   output_addr_const (asm_out_file, eh_personality_libfunc);
3932   fputs ("\n\t.handlerdata\n", asm_out_file);
3933   /* Note that varasm still thinks we're in the function's code section.
3934      The ".endp" directive that will immediately follow will take us back.  */
3935 #else
3936   targetm.asm_out.exception_section ();
3937 #endif
3938
3939   have_tt_data = (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) > 0
3940                   || VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) > 0);
3941
3942   /* Indicate the format of the @TType entries.  */
3943   if (! have_tt_data)
3944     tt_format = DW_EH_PE_omit;
3945   else
3946     {
3947       tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
3948 #ifdef HAVE_AS_LEB128
3949       ASM_GENERATE_INTERNAL_LABEL (ttype_label, "LLSDATT",
3950                                    current_function_funcdef_no);
3951 #endif
3952       tt_format_size = size_of_encoded_value (tt_format);
3953
3954       assemble_align (tt_format_size * BITS_PER_UNIT);
3955     }
3956
3957   targetm.asm_out.internal_label (asm_out_file, "LLSDA",
3958                              current_function_funcdef_no);
3959
3960   /* The LSDA header.  */
3961
3962   /* Indicate the format of the landing pad start pointer.  An omitted
3963      field implies @LPStart == @Start.  */
3964   /* Currently we always put @LPStart == @Start.  This field would
3965      be most useful in moving the landing pads completely out of
3966      line to another section, but it could also be used to minimize
3967      the size of uleb128 landing pad offsets.  */
3968   lp_format = DW_EH_PE_omit;
3969   dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
3970                        eh_data_format_name (lp_format));
3971
3972   /* @LPStart pointer would go here.  */
3973
3974   dw2_asm_output_data (1, tt_format, "@TType format (%s)",
3975                        eh_data_format_name (tt_format));
3976
3977 #ifndef HAVE_AS_LEB128
3978   if (USING_SJLJ_EXCEPTIONS)
3979     call_site_len = sjlj_size_of_call_site_table ();
3980   else
3981     call_site_len = dw2_size_of_call_site_table ();
3982 #endif
3983
3984   /* A pc-relative 4-byte displacement to the @TType data.  */
3985   if (have_tt_data)
3986     {
3987 #ifdef HAVE_AS_LEB128
3988       char ttype_after_disp_label[32];
3989       ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label, "LLSDATTD",
3990                                    current_function_funcdef_no);
3991       dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
3992                                     "@TType base offset");
3993       ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
3994 #else
3995       /* Ug.  Alignment queers things.  */
3996       unsigned int before_disp, after_disp, last_disp, disp;
3997
3998       before_disp = 1 + 1;
3999       after_disp = (1 + size_of_uleb128 (call_site_len)
4000                     + call_site_len
4001                     + VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data)
4002                     + (VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data)
4003                        * tt_format_size));
4004
4005       disp = after_disp;
4006       do
4007         {
4008           unsigned int disp_size, pad;
4009
4010           last_disp = disp;
4011           disp_size = size_of_uleb128 (disp);
4012           pad = before_disp + disp_size + after_disp;
4013           if (pad % tt_format_size)
4014             pad = tt_format_size - (pad % tt_format_size);
4015           else
4016             pad = 0;
4017           disp = after_disp + pad;
4018         }
4019       while (disp != last_disp);
4020
4021       dw2_asm_output_data_uleb128 (disp, "@TType base offset");
4022 #endif
4023     }
4024
4025   /* Indicate the format of the call-site offsets.  */
4026 #ifdef HAVE_AS_LEB128
4027   cs_format = DW_EH_PE_uleb128;
4028 #else
4029   cs_format = DW_EH_PE_udata4;
4030 #endif
4031   dw2_asm_output_data (1, cs_format, "call-site format (%s)",
4032                        eh_data_format_name (cs_format));
4033
4034 #ifdef HAVE_AS_LEB128
4035   ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label, "LLSDACSB",
4036                                current_function_funcdef_no);
4037   ASM_GENERATE_INTERNAL_LABEL (cs_end_label, "LLSDACSE",
4038                                current_function_funcdef_no);
4039   dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
4040                                 "Call-site table length");
4041   ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
4042   if (USING_SJLJ_EXCEPTIONS)
4043     sjlj_output_call_site_table ();
4044   else
4045     dw2_output_call_site_table ();
4046   ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
4047 #else
4048   dw2_asm_output_data_uleb128 (call_site_len,"Call-site table length");
4049   if (USING_SJLJ_EXCEPTIONS)
4050     sjlj_output_call_site_table ();
4051   else
4052     dw2_output_call_site_table ();
4053 #endif
4054
4055   /* ??? Decode and interpret the data for flag_debug_asm.  */
4056   n = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data);
4057   for (i = 0; i < n; ++i)
4058     dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->action_record_data, i),
4059                          (i ? NULL : "Action record table"));
4060
4061   if (have_tt_data)
4062     assemble_align (tt_format_size * BITS_PER_UNIT);
4063
4064   i = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data);
4065   while (i-- > 0)
4066     {
4067       tree type = VARRAY_TREE (cfun->eh->ttype_data, i);
4068       rtx value;
4069
4070       if (type == NULL_TREE)
4071         value = const0_rtx;
4072       else
4073         {
4074           struct cgraph_varpool_node *node;
4075
4076           type = lookup_type_for_runtime (type);
4077           value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
4078
4079           /* Let cgraph know that the rtti decl is used.  Not all of the
4080              paths below go through assemble_integer, which would take
4081              care of this for us.  */
4082           STRIP_NOPS (type);
4083           if (TREE_CODE (type) == ADDR_EXPR)
4084             {
4085               type = TREE_OPERAND (type, 0);
4086               node = cgraph_varpool_node (type);
4087               if (node)
4088                 cgraph_varpool_mark_needed_node (node);
4089             }
4090           else if (TREE_CODE (type) != INTEGER_CST)
4091             abort ();
4092         }
4093
4094       if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
4095         assemble_integer (value, tt_format_size,
4096                           tt_format_size * BITS_PER_UNIT, 1);
4097       else
4098         dw2_asm_output_encoded_addr_rtx (tt_format, value, NULL);
4099     }
4100
4101 #ifdef HAVE_AS_LEB128
4102   if (have_tt_data)
4103       ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
4104 #endif
4105
4106   /* ??? Decode and interpret the data for flag_debug_asm.  */
4107   n = VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data);
4108   for (i = 0; i < n; ++i)
4109     dw2_asm_output_data (1, VARRAY_UCHAR (cfun->eh->ehspec_data, i),
4110                          (i ? NULL : "Exception specification table"));
4111
4112   function_section (current_function_decl);
4113 }
4114
4115 #include "gt-except.h"