OSDN Git Service

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