OSDN Git Service

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