OSDN Git Service

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