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