OSDN Git Service

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