OSDN Git Service

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