OSDN Git Service

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