OSDN Git Service

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