]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/except.c
2013-11-19 Catherine Moore <clm@codesourcery.com>
[thirdparty/gcc.git] / gcc / except.c
CommitLineData
97bb6c17 1/* Implements exception handling.
711789cc 2 Copyright (C) 1989-2013 Free Software Foundation, Inc.
97ecdf3e 3 Contributed by Mike Stump <mrs@cygnus.com>.
4
f12b58b3 5This file is part of GCC.
97ecdf3e 6
f12b58b3 7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
8c4c00c1 9Software Foundation; either version 3, or (at your option) any later
f12b58b3 10version.
97ecdf3e 11
f12b58b3 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
97ecdf3e 16
17You should have received a copy of the GNU General Public License
8c4c00c1 18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
97ecdf3e 20
21
e38def9c 22/* An exception is an event that can be "thrown" from within a
23 function. This event can then be "caught" by the callers of
24 the function.
25
26 The representation of exceptions changes several times during
27 the compilation process:
28
29 In the beginning, in the front end, we have the GENERIC trees
30 TRY_CATCH_EXPR, TRY_FINALLY_EXPR, WITH_CLEANUP_EXPR,
31 CLEANUP_POINT_EXPR, CATCH_EXPR, and EH_FILTER_EXPR.
32
33 During initial gimplification (gimplify.c) these are lowered
34 to the GIMPLE_TRY, GIMPLE_CATCH, and GIMPLE_EH_FILTER nodes.
35 The WITH_CLEANUP_EXPR and CLEANUP_POINT_EXPR nodes are converted
36 into GIMPLE_TRY_FINALLY nodes; the others are a more direct 1-1
37 conversion.
38
39 During pass_lower_eh (tree-eh.c) we record the nested structure
40 of the TRY nodes in EH_REGION nodes in CFUN->EH->REGION_TREE.
596981c8 41 We expand the eh_protect_cleanup_actions langhook into MUST_NOT_THROW
e38def9c 42 regions at this time. We can then flatten the statements within
43 the TRY nodes to straight-line code. Statements that had been within
44 TRY nodes that can throw are recorded within CFUN->EH->THROW_STMT_TABLE,
45 so that we may remember what action is supposed to be taken if
46 a given statement does throw. During this lowering process,
47 we create an EH_LANDING_PAD node for each EH_REGION that has
48 some code within the function that needs to be executed if a
48e1416a 49 throw does happen. We also create RESX statements that are
e38def9c 50 used to transfer control from an inner EH_REGION to an outer
51 EH_REGION. We also create EH_DISPATCH statements as placeholders
52 for a runtime type comparison that should be made in order to
53 select the action to perform among different CATCH and EH_FILTER
54 regions.
55
56 During pass_lower_eh_dispatch (tree-eh.c), which is run after
57 all inlining is complete, we are able to run assign_filter_values,
58 which allows us to map the set of types manipulated by all of the
59 CATCH and EH_FILTER regions to a set of integers. This set of integers
60 will be how the exception runtime communicates with the code generated
61 within the function. We then expand the GIMPLE_EH_DISPATCH statements
62 to a switch or conditional branches that use the argument provided by
63 the runtime (__builtin_eh_filter) and the set of integers we computed
64 in assign_filter_values.
65
66 During pass_lower_resx (tree-eh.c), which is run near the end
67 of optimization, we expand RESX statements. If the eh region
68 that is outer to the RESX statement is a MUST_NOT_THROW, then
69 the RESX expands to some form of abort statement. If the eh
70 region that is outer to the RESX statement is within the current
71 function, then the RESX expands to a bookkeeping call
72 (__builtin_eh_copy_values) and a goto. Otherwise, the next
73 handler for the exception must be within a function somewhere
74 up the call chain, so we call back into the exception runtime
75 (__builtin_unwind_resume).
48e1416a 76
e38def9c 77 During pass_expand (cfgexpand.c), we generate REG_EH_REGION notes
78 that create an rtl to eh_region mapping that corresponds to the
79 gimple to eh_region mapping that had been recorded in the
80 THROW_STMT_TABLE.
81
1dd4980f 82 Then, via finish_eh_generation, we generate the real landing pads
e38def9c 83 to which the runtime will actually transfer control. These new
84 landing pads perform whatever bookkeeping is needed by the target
85 backend in order to resume execution within the current function.
86 Each of these new landing pads falls through into the post_landing_pad
87 label which had been used within the CFG up to this point. All
88 exception edges within the CFG are redirected to the new landing pads.
89 If the target uses setjmp to implement exceptions, the various extra
90 calls into the runtime to register and unregister the current stack
91 frame are emitted at this time.
92
93 During pass_convert_to_eh_region_ranges (except.c), we transform
48e1416a 94 the REG_EH_REGION notes attached to individual insns into
e38def9c 95 non-overlapping ranges of insns bounded by NOTE_INSN_EH_REGION_BEG
96 and NOTE_INSN_EH_REGION_END. Each insn within such ranges has the
97 same associated action within the exception region tree, meaning
98 that (1) the exception is caught by the same landing pad within the
99 current function, (2) the exception is blocked by the runtime with
100 a MUST_NOT_THROW region, or (3) the exception is not handled at all
101 within the current function.
102
103 Finally, during assembly generation, we call
104 output_function_exception_table (except.c) to emit the tables with
105 which the exception runtime can determine if a given stack frame
106 handles a given exception, and if so what filter value to provide
107 to the function when the non-local control transfer is effected.
108 If the target uses dwarf2 unwinding to implement exceptions, then
109 output_call_frame_info (dwarf2out.c) emits the required unwind data. */
97ecdf3e 110
111
112#include "config.h"
405711de 113#include "system.h"
805e22b2 114#include "coretypes.h"
115#include "tm.h"
97ecdf3e 116#include "rtl.h"
117#include "tree.h"
9ed99284 118#include "stringpool.h"
119#include "stor-layout.h"
97ecdf3e 120#include "flags.h"
97ecdf3e 121#include "function.h"
97ecdf3e 122#include "expr.h"
d8fc4d0b 123#include "libfuncs.h"
97ecdf3e 124#include "insn-config.h"
df4b504c 125#include "except.h"
df4b504c 126#include "hard-reg-set.h"
127#include "basic-block.h"
97ecdf3e 128#include "output.h"
df4b504c 129#include "dwarf2asm.h"
130#include "dwarf2out.h"
bde36f4a 131#include "dwarf2.h"
12874aaf 132#include "toplev.h"
d9dd21a8 133#include "hash-table.h"
723766b6 134#include "intl.h"
a7b0c170 135#include "ggc.h"
075136a2 136#include "tm_p.h"
02c8b767 137#include "target.h"
218e3e4e 138#include "common/common-target.h"
a1f71e15 139#include "langhooks.h"
3b919cde 140#include "cgraph.h"
b4ba5e9d 141#include "diagnostic.h"
ce084dfc 142#include "tree-pretty-print.h"
77fce4cd 143#include "tree-pass.h"
073c1fd5 144#include "gimple.h"
79f958cb 145#include "cfgloop.h"
df4b504c 146
147/* Provide defaults for stuff that may not be defined when using
148 sjlj exceptions. */
df4b504c 149#ifndef EH_RETURN_DATA_REGNO
150#define EH_RETURN_DATA_REGNO(N) INVALID_REGNUM
98ad18c5 151#endif
152
252cc619 153static GTY(()) int call_site_base;
1f3233d1 154static GTY ((param_is (union tree_node)))
155 htab_t type_to_runtime_map;
df4b504c 156
157/* Describe the SjLj_Function_Context structure. */
1f3233d1 158static GTY(()) tree sjlj_fc_type_node;
df4b504c 159static int sjlj_fc_call_site_ofs;
160static int sjlj_fc_data_ofs;
161static int sjlj_fc_personality_ofs;
162static int sjlj_fc_lsda_ofs;
163static int sjlj_fc_jbuf_ofs;
164\f
318077fa 165
26dbec0a 166struct GTY(()) call_site_record_d
1f3233d1 167{
168 rtx landing_pad;
169 int action;
170};
d9dd21a8 171
172/* In the following structure and associated functions,
173 we represent entries in the action table as 1-based indices.
174 Special cases are:
175
176 0: null action record, non-null landing pad; implies cleanups
177 -1: null action record, null landing pad; implies no action
178 -2: no call-site entry; implies must_not_throw
179 -3: we have yet to process outer regions
180
181 Further, no special cases apply to the "next" field of the record.
182 For next, 0 means end of list. */
183
184struct action_record
185{
186 int offset;
187 int filter;
188 int next;
189};
190
191/* Hashtable helpers. */
192
193struct action_record_hasher : typed_free_remove <action_record>
194{
195 typedef action_record value_type;
196 typedef action_record compare_type;
197 static inline hashval_t hash (const value_type *);
198 static inline bool equal (const value_type *, const compare_type *);
199};
200
201inline hashval_t
202action_record_hasher::hash (const value_type *entry)
203{
204 return entry->next * 1009 + entry->filter;
205}
206
207inline bool
208action_record_hasher::equal (const value_type *entry, const compare_type *data)
209{
210 return entry->filter == data->filter && entry->next == data->next;
211}
212
213typedef hash_table <action_record_hasher> action_hash_type;
df4b504c 214\f
e38def9c 215static bool get_eh_region_and_lp_from_rtx (const_rtx, eh_region *,
216 eh_landing_pad *);
217
35cb5232 218static int t2r_eq (const void *, const void *);
219static hashval_t t2r_hash (const void *);
35cb5232 220
35cb5232 221static void dw2_build_landing_pads (void);
df4b504c 222
d9dd21a8 223static int collect_one_action_chain (action_hash_type, eh_region);
33b1ed32 224static int add_call_site (rtx, int, int);
35cb5232 225
f1f41a6c 226static void push_uleb128 (vec<uchar, va_gc> **, unsigned int);
227static void push_sleb128 (vec<uchar, va_gc> **, int);
df4b504c 228#ifndef HAVE_AS_LEB128
2142a70c 229static int dw2_size_of_call_site_table (int);
35cb5232 230static int sjlj_size_of_call_site_table (void);
df4b504c 231#endif
33b1ed32 232static void dw2_output_call_site_table (int, int);
35cb5232 233static void sjlj_output_call_site_table (void);
d63ea2f2 234
df4b504c 235\f
236void
35cb5232 237init_eh (void)
97ecdf3e 238{
df4b504c 239 if (! flag_exceptions)
240 return;
97ecdf3e 241
1f3233d1 242 type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
97ecdf3e 243
df4b504c 244 /* Create the SjLj_Function_Context structure. This should match
245 the definition in unwind-sjlj.c. */
218e3e4e 246 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
df4b504c 247 {
248 tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp;
97ecdf3e 249
dc24ddbd 250 sjlj_fc_type_node = lang_hooks.types.make_type (RECORD_TYPE);
011a7f23 251
0b35068b 252 f_prev = build_decl (BUILTINS_LOCATION,
e60a6f7b 253 FIELD_DECL, get_identifier ("__prev"),
df4b504c 254 build_pointer_type (sjlj_fc_type_node));
255 DECL_FIELD_CONTEXT (f_prev) = sjlj_fc_type_node;
011a7f23 256
0b35068b 257 f_cs = build_decl (BUILTINS_LOCATION,
e60a6f7b 258 FIELD_DECL, get_identifier ("__call_site"),
df4b504c 259 integer_type_node);
260 DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node;
97ecdf3e 261
7002a1c8 262 tmp = build_index_type (size_int (4 - 1));
1bd43494 263 tmp = build_array_type (lang_hooks.types.type_for_mode
264 (targetm.unwind_word_mode (), 1),
771d21fa 265 tmp);
0b35068b 266 f_data = build_decl (BUILTINS_LOCATION,
e60a6f7b 267 FIELD_DECL, get_identifier ("__data"), tmp);
df4b504c 268 DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node;
011a7f23 269
0b35068b 270 f_per = build_decl (BUILTINS_LOCATION,
e60a6f7b 271 FIELD_DECL, get_identifier ("__personality"),
df4b504c 272 ptr_type_node);
273 DECL_FIELD_CONTEXT (f_per) = sjlj_fc_type_node;
97ecdf3e 274
0b35068b 275 f_lsda = build_decl (BUILTINS_LOCATION,
e60a6f7b 276 FIELD_DECL, get_identifier ("__lsda"),
df4b504c 277 ptr_type_node);
278 DECL_FIELD_CONTEXT (f_lsda) = sjlj_fc_type_node;
ed74c60e 279
df4b504c 280#ifdef DONT_USE_BUILTIN_SETJMP
281#ifdef JMP_BUF_SIZE
7002a1c8 282 tmp = size_int (JMP_BUF_SIZE - 1);
df4b504c 283#else
284 /* Should be large enough for most systems, if it is not,
285 JMP_BUF_SIZE should be defined with the proper value. It will
286 also tend to be larger than necessary for most systems, a more
287 optimal port will define JMP_BUF_SIZE. */
7002a1c8 288 tmp = size_int (FIRST_PSEUDO_REGISTER + 2 - 1);
df4b504c 289#endif
290#else
5b8192c3 291 /* builtin_setjmp takes a pointer to 5 words. */
7002a1c8 292 tmp = size_int (5 * BITS_PER_WORD / POINTER_SIZE - 1);
df4b504c 293#endif
294 tmp = build_index_type (tmp);
295 tmp = build_array_type (ptr_type_node, tmp);
0b35068b 296 f_jbuf = build_decl (BUILTINS_LOCATION,
e60a6f7b 297 FIELD_DECL, get_identifier ("__jbuf"), tmp);
df4b504c 298#ifdef DONT_USE_BUILTIN_SETJMP
299 /* We don't know what the alignment requirements of the
300 runtime's jmp_buf has. Overestimate. */
301 DECL_ALIGN (f_jbuf) = BIGGEST_ALIGNMENT;
302 DECL_USER_ALIGN (f_jbuf) = 1;
303#endif
304 DECL_FIELD_CONTEXT (f_jbuf) = sjlj_fc_type_node;
305
306 TYPE_FIELDS (sjlj_fc_type_node) = f_prev;
307 TREE_CHAIN (f_prev) = f_cs;
308 TREE_CHAIN (f_cs) = f_data;
309 TREE_CHAIN (f_data) = f_per;
310 TREE_CHAIN (f_per) = f_lsda;
311 TREE_CHAIN (f_lsda) = f_jbuf;
312
313 layout_type (sjlj_fc_type_node);
314
315 /* Cache the interesting field offsets so that we have
316 easy access from rtl. */
317 sjlj_fc_call_site_ofs
6a0712d4 318 = (tree_to_uhwi (DECL_FIELD_OFFSET (f_cs))
319 + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (f_cs)) / BITS_PER_UNIT);
df4b504c 320 sjlj_fc_data_ofs
6a0712d4 321 = (tree_to_uhwi (DECL_FIELD_OFFSET (f_data))
322 + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (f_data)) / BITS_PER_UNIT);
df4b504c 323 sjlj_fc_personality_ofs
6a0712d4 324 = (tree_to_uhwi (DECL_FIELD_OFFSET (f_per))
325 + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (f_per)) / BITS_PER_UNIT);
df4b504c 326 sjlj_fc_lsda_ofs
6a0712d4 327 = (tree_to_uhwi (DECL_FIELD_OFFSET (f_lsda))
328 + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (f_lsda)) / BITS_PER_UNIT);
df4b504c 329 sjlj_fc_jbuf_ofs
6a0712d4 330 = (tree_to_uhwi (DECL_FIELD_OFFSET (f_jbuf))
331 + tree_to_uhwi (DECL_FIELD_BIT_OFFSET (f_jbuf)) / BITS_PER_UNIT);
df4b504c 332 }
97ecdf3e 333}
334
df4b504c 335void
35cb5232 336init_eh_for_function (void)
97ecdf3e 337{
ba72912a 338 cfun->eh = ggc_alloc_cleared_eh_status ();
e38def9c 339
340 /* Make sure zero'th entries are used. */
f1f41a6c 341 vec_safe_push (cfun->eh->region_array, (eh_region)0);
342 vec_safe_push (cfun->eh->lp_array, (eh_landing_pad)0);
8f8dcce4 343}
df4b504c 344\f
b215c058 345/* Routines to generate the exception tree somewhat directly.
4ee9c684 346 These are used from tree-eh.c when processing exception related
347 nodes during tree optimization. */
348
e38def9c 349static eh_region
350gen_eh_region (enum eh_region_type type, eh_region outer)
4ee9c684 351{
e38def9c 352 eh_region new_eh;
4ee9c684 353
4ee9c684 354 /* Insert a new blank region as a leaf in the tree. */
ba72912a 355 new_eh = ggc_alloc_cleared_eh_region_d ();
6659485c 356 new_eh->type = type;
357 new_eh->outer = outer;
4ee9c684 358 if (outer)
359 {
6659485c 360 new_eh->next_peer = outer->inner;
361 outer->inner = new_eh;
4ee9c684 362 }
363 else
364 {
6659485c 365 new_eh->next_peer = cfun->eh->region_tree;
366 cfun->eh->region_tree = new_eh;
4ee9c684 367 }
368
f1f41a6c 369 new_eh->index = vec_safe_length (cfun->eh->region_array);
370 vec_safe_push (cfun->eh->region_array, new_eh);
4ee9c684 371
471eff36 372 /* Copy the language's notion of whether to use __cxa_end_cleanup. */
373 if (targetm.arm_eabi_unwinder && lang_hooks.eh_use_cxa_end_cleanup)
374 new_eh->use_cxa_end_cleanup = true;
375
6659485c 376 return new_eh;
4ee9c684 377}
378
e38def9c 379eh_region
380gen_eh_region_cleanup (eh_region outer)
4ee9c684 381{
e38def9c 382 return gen_eh_region (ERT_CLEANUP, outer);
4ee9c684 383}
384
e38def9c 385eh_region
386gen_eh_region_try (eh_region outer)
4ee9c684 387{
388 return gen_eh_region (ERT_TRY, outer);
389}
390
e38def9c 391eh_catch
392gen_eh_region_catch (eh_region t, tree type_or_list)
4ee9c684 393{
e38def9c 394 eh_catch c, l;
4ee9c684 395 tree type_list, type_node;
396
e38def9c 397 gcc_assert (t->type == ERT_TRY);
398
4ee9c684 399 /* Ensure to always end up with a type list to normalize further
400 processing, then register each type against the runtime types map. */
401 type_list = type_or_list;
402 if (type_or_list)
403 {
404 if (TREE_CODE (type_or_list) != TREE_LIST)
405 type_list = tree_cons (NULL_TREE, type_or_list, NULL_TREE);
406
407 type_node = type_list;
408 for (; type_node; type_node = TREE_CHAIN (type_node))
409 add_type_for_runtime (TREE_VALUE (type_node));
410 }
411
ba72912a 412 c = ggc_alloc_cleared_eh_catch_d ();
e38def9c 413 c->type_list = type_list;
f4e36c33 414 l = t->u.eh_try.last_catch;
e38def9c 415 c->prev_catch = l;
4ee9c684 416 if (l)
e38def9c 417 l->next_catch = c;
4ee9c684 418 else
e38def9c 419 t->u.eh_try.first_catch = c;
f4e36c33 420 t->u.eh_try.last_catch = c;
4ee9c684 421
422 return c;
423}
424
e38def9c 425eh_region
426gen_eh_region_allowed (eh_region outer, tree allowed)
4ee9c684 427{
e38def9c 428 eh_region region = gen_eh_region (ERT_ALLOWED_EXCEPTIONS, outer);
4ee9c684 429 region->u.allowed.type_list = allowed;
430
431 for (; allowed ; allowed = TREE_CHAIN (allowed))
432 add_type_for_runtime (TREE_VALUE (allowed));
433
434 return region;
435}
436
e38def9c 437eh_region
438gen_eh_region_must_not_throw (eh_region outer)
4ee9c684 439{
440 return gen_eh_region (ERT_MUST_NOT_THROW, outer);
441}
442
e38def9c 443eh_landing_pad
444gen_eh_landing_pad (eh_region region)
4ee9c684 445{
ba72912a 446 eh_landing_pad lp = ggc_alloc_cleared_eh_landing_pad_d ();
4ee9c684 447
e38def9c 448 lp->next_lp = region->landing_pads;
449 lp->region = region;
f1f41a6c 450 lp->index = vec_safe_length (cfun->eh->lp_array);
e38def9c 451 region->landing_pads = lp;
452
f1f41a6c 453 vec_safe_push (cfun->eh->lp_array, lp);
e38def9c 454
455 return lp;
4ee9c684 456}
457
e38def9c 458eh_region
459get_eh_region_from_number_fn (struct function *ifun, int i)
4ee9c684 460{
f1f41a6c 461 return (*ifun->eh->region_array)[i];
4ee9c684 462}
463
e38def9c 464eh_region
465get_eh_region_from_number (int i)
3bd82487 466{
e38def9c 467 return get_eh_region_from_number_fn (cfun, i);
3bd82487 468}
469
e38def9c 470eh_landing_pad
471get_eh_landing_pad_from_number_fn (struct function *ifun, int i)
4ee9c684 472{
f1f41a6c 473 return (*ifun->eh->lp_array)[i];
4ee9c684 474}
4ee9c684 475
e38def9c 476eh_landing_pad
477get_eh_landing_pad_from_number (int i)
478{
479 return get_eh_landing_pad_from_number_fn (cfun, i);
4ee9c684 480}
481
e38def9c 482eh_region
483get_eh_region_from_lp_number_fn (struct function *ifun, int i)
95cedffb 484{
e38def9c 485 if (i < 0)
f1f41a6c 486 return (*ifun->eh->region_array)[-i];
e38def9c 487 else if (i == 0)
488 return NULL;
489 else
95cedffb 490 {
e38def9c 491 eh_landing_pad lp;
f1f41a6c 492 lp = (*ifun->eh->lp_array)[i];
e38def9c 493 return lp->region;
95cedffb 494 }
495}
496
e38def9c 497eh_region
498get_eh_region_from_lp_number (int i)
97ecdf3e 499{
e38def9c 500 return get_eh_region_from_lp_number_fn (cfun, i);
df4b504c 501}
e38def9c 502\f
503/* Returns true if the current function has exception handling regions. */
97ecdf3e 504
e38def9c 505bool
506current_function_has_exception_handlers (void)
1639c6db 507{
e38def9c 508 return cfun->eh->region_tree != NULL;
1639c6db 509}
df4b504c 510\f
e38def9c 511/* A subroutine of duplicate_eh_regions. Copy the eh_region tree at OLD.
512 Root it at OUTER, and apply LP_OFFSET to the lp numbers. */
732992fa 513
e38def9c 514struct duplicate_eh_regions_data
732992fa 515{
e38def9c 516 duplicate_eh_regions_map label_map;
517 void *label_map_data;
518 struct pointer_map_t *eh_map;
519};
732992fa 520
e38def9c 521static void
522duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
523 eh_region old_r, eh_region outer)
524{
525 eh_landing_pad old_lp, new_lp;
526 eh_region new_r;
527 void **slot;
732992fa 528
e38def9c 529 new_r = gen_eh_region (old_r->type, outer);
530 slot = pointer_map_insert (data->eh_map, (void *)old_r);
531 gcc_assert (*slot == NULL);
532 *slot = (void *)new_r;
732992fa 533
e38def9c 534 switch (old_r->type)
df4b504c 535 {
e38def9c 536 case ERT_CLEANUP:
537 break;
df4b504c 538
e38def9c 539 case ERT_TRY:
540 {
541 eh_catch oc, nc;
542 for (oc = old_r->u.eh_try.first_catch; oc ; oc = oc->next_catch)
543 {
544 /* We should be doing all our region duplication before and
545 during inlining, which is before filter lists are created. */
546 gcc_assert (oc->filter_list == NULL);
547 nc = gen_eh_region_catch (new_r, oc->type_list);
548 nc->label = data->label_map (oc->label, data->label_map_data);
549 }
550 }
551 break;
8591d03a 552
e38def9c 553 case ERT_ALLOWED_EXCEPTIONS:
554 new_r->u.allowed.type_list = old_r->u.allowed.type_list;
c90b5d40 555 if (old_r->u.allowed.label)
556 new_r->u.allowed.label
557 = data->label_map (old_r->u.allowed.label, data->label_map_data);
558 else
559 new_r->u.allowed.label = NULL_TREE;
e38def9c 560 break;
f491db07 561
e38def9c 562 case ERT_MUST_NOT_THROW:
5169661d 563 new_r->u.must_not_throw.failure_loc =
564 LOCATION_LOCUS (old_r->u.must_not_throw.failure_loc);
565 new_r->u.must_not_throw.failure_decl =
566 old_r->u.must_not_throw.failure_decl;
e38def9c 567 break;
568 }
4c5fcca6 569
e38def9c 570 for (old_lp = old_r->landing_pads; old_lp ; old_lp = old_lp->next_lp)
f491db07 571 {
e38def9c 572 /* Don't bother copying unused landing pads. */
573 if (old_lp->post_landing_pad == NULL)
574 continue;
4c5fcca6 575
e38def9c 576 new_lp = gen_eh_landing_pad (new_r);
577 slot = pointer_map_insert (data->eh_map, (void *)old_lp);
578 gcc_assert (*slot == NULL);
579 *slot = (void *)new_lp;
580
581 new_lp->post_landing_pad
582 = data->label_map (old_lp->post_landing_pad, data->label_map_data);
583 EH_LANDING_PAD_NR (new_lp->post_landing_pad) = new_lp->index;
f491db07 584 }
e38def9c 585
471eff36 586 /* Make sure to preserve the original use of __cxa_end_cleanup. */
587 new_r->use_cxa_end_cleanup = old_r->use_cxa_end_cleanup;
588
e38def9c 589 for (old_r = old_r->inner; old_r ; old_r = old_r->next_peer)
590 duplicate_eh_regions_1 (data, old_r, new_r);
4c5fcca6 591}
f491db07 592
e38def9c 593/* Duplicate the EH regions from IFUN rooted at COPY_REGION into
594 the current function and root the tree below OUTER_REGION.
595 The special case of COPY_REGION of NULL means all regions.
596 Remap labels using MAP/MAP_DATA callback. Return a pointer map
597 that allows the caller to remap uses of both EH regions and
598 EH landing pads. */
686e094c 599
e38def9c 600struct pointer_map_t *
601duplicate_eh_regions (struct function *ifun,
602 eh_region copy_region, int outer_lp,
603 duplicate_eh_regions_map map, void *map_data)
686e094c 604{
e38def9c 605 struct duplicate_eh_regions_data data;
606 eh_region outer_region;
686e094c 607
e38def9c 608#ifdef ENABLE_CHECKING
609 verify_eh_tree (ifun);
610#endif
927a6b6b 611
e38def9c 612 data.label_map = map;
613 data.label_map_data = map_data;
614 data.eh_map = pointer_map_create ();
927a6b6b 615
e38def9c 616 outer_region = get_eh_region_from_lp_number (outer_lp);
48e1416a 617
e38def9c 618 /* Copy all the regions in the subtree. */
619 if (copy_region)
620 duplicate_eh_regions_1 (&data, copy_region, outer_region);
621 else
927a6b6b 622 {
e38def9c 623 eh_region r;
624 for (r = ifun->eh->region_tree; r ; r = r->next_peer)
625 duplicate_eh_regions_1 (&data, r, outer_region);
927a6b6b 626 }
927a6b6b 627
e38def9c 628#ifdef ENABLE_CHECKING
629 verify_eh_tree (cfun);
630#endif
927a6b6b 631
e38def9c 632 return data.eh_map;
927a6b6b 633}
634
e38def9c 635/* Return the region that is outer to both REGION_A and REGION_B in IFUN. */
927a6b6b 636
e38def9c 637eh_region
638eh_region_outermost (struct function *ifun, eh_region region_a,
639 eh_region region_b)
927a6b6b 640{
e38def9c 641 sbitmap b_outer;
642
643 gcc_assert (ifun->eh->region_array);
644 gcc_assert (ifun->eh->region_tree);
927a6b6b 645
9af5ce0c 646 b_outer = sbitmap_alloc (ifun->eh->region_array->length ());
53c5d9d4 647 bitmap_clear (b_outer);
927a6b6b 648
e38def9c 649 do
650 {
08b7917c 651 bitmap_set_bit (b_outer, region_b->index);
e38def9c 652 region_b = region_b->outer;
653 }
654 while (region_b);
927a6b6b 655
e38def9c 656 do
927a6b6b 657 {
08b7917c 658 if (bitmap_bit_p (b_outer, region_a->index))
927a6b6b 659 break;
e38def9c 660 region_a = region_a->outer;
927a6b6b 661 }
e38def9c 662 while (region_a);
927a6b6b 663
e38def9c 664 sbitmap_free (b_outer);
665 return region_a;
666}
667\f
927a6b6b 668static int
e38def9c 669t2r_eq (const void *pentry, const void *pdata)
927a6b6b 670{
e38def9c 671 const_tree const entry = (const_tree) pentry;
672 const_tree const data = (const_tree) pdata;
927a6b6b 673
e38def9c 674 return TREE_PURPOSE (entry) == data;
675}
927a6b6b 676
e38def9c 677static hashval_t
678t2r_hash (const void *pentry)
927a6b6b 679{
e38def9c 680 const_tree const entry = (const_tree) pentry;
681 return TREE_HASH (TREE_PURPOSE (entry));
682}
927a6b6b 683
e38def9c 684void
685add_type_for_runtime (tree type)
686{
687 tree *slot;
927a6b6b 688
e38def9c 689 /* If TYPE is NOP_EXPR, it means that it already is a runtime type. */
690 if (TREE_CODE (type) == NOP_EXPR)
691 return;
927a6b6b 692
e38def9c 693 slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
694 TREE_HASH (type), INSERT);
695 if (*slot == NULL)
927a6b6b 696 {
e38def9c 697 tree runtime = lang_hooks.eh_runtime_type (type);
698 *slot = tree_cons (type, runtime, NULL_TREE);
927a6b6b 699 }
927a6b6b 700}
701
e38def9c 702tree
703lookup_type_for_runtime (tree type)
4c5fcca6 704{
e38def9c 705 tree *slot;
f491db07 706
e38def9c 707 /* If TYPE is NOP_EXPR, it means that it already is a runtime type. */
708 if (TREE_CODE (type) == NOP_EXPR)
709 return type;
4c5fcca6 710
e38def9c 711 slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
712 TREE_HASH (type), NO_INSERT);
f491db07 713
e38def9c 714 /* We should have always inserted the data earlier. */
715 return TREE_VALUE (*slot);
716}
b215c058 717
e38def9c 718\f
719/* Represent an entry in @TTypes for either catch actions
720 or exception filter actions. */
a641ee36 721struct ttypes_filter {
e38def9c 722 tree t;
723 int filter;
724};
686e094c 725
d9dd21a8 726/* Helper for ttypes_filter hashing. */
727
728struct ttypes_filter_hasher : typed_free_remove <ttypes_filter>
729{
730 typedef ttypes_filter value_type;
731 typedef tree_node compare_type;
732 static inline hashval_t hash (const value_type *);
733 static inline bool equal (const value_type *, const compare_type *);
734};
735
e38def9c 736/* Compare ENTRY (a ttypes_filter entry in the hash table) with DATA
737 (a tree) for a @TTypes type node we are thinking about adding. */
686e094c 738
d9dd21a8 739inline bool
740ttypes_filter_hasher::equal (const value_type *entry, const compare_type *data)
e38def9c 741{
df4b504c 742 return entry->t == data;
506b6864 743}
744
d9dd21a8 745inline hashval_t
746ttypes_filter_hasher::hash (const value_type *entry)
df4b504c 747{
908e5f41 748 return TREE_HASH (entry->t);
df4b504c 749}
97ecdf3e 750
d9dd21a8 751typedef hash_table <ttypes_filter_hasher> ttypes_hash_type;
752
753
754/* Helper for ehspec hashing. */
755
756struct ehspec_hasher : typed_free_remove <ttypes_filter>
757{
758 typedef ttypes_filter value_type;
759 typedef ttypes_filter compare_type;
760 static inline hashval_t hash (const value_type *);
761 static inline bool equal (const value_type *, const compare_type *);
762};
763
df4b504c 764/* Compare ENTRY with DATA (both struct ttypes_filter) for a @TTypes
765 exception specification list we are thinking about adding. */
766/* ??? Currently we use the type lists in the order given. Someone
767 should put these in some canonical order. */
768
d9dd21a8 769inline bool
770ehspec_hasher::equal (const value_type *entry, const compare_type *data)
97ecdf3e 771{
df4b504c 772 return type_list_equal (entry->t, data->t);
97ecdf3e 773}
774
df4b504c 775/* Hash function for exception specification lists. */
97ecdf3e 776
d9dd21a8 777inline hashval_t
778ehspec_hasher::hash (const value_type *entry)
97ecdf3e 779{
df4b504c 780 hashval_t h = 0;
781 tree list;
782
783 for (list = entry->t; list ; list = TREE_CHAIN (list))
908e5f41 784 h = (h << 5) + (h >> 27) + TREE_HASH (TREE_VALUE (list));
df4b504c 785 return h;
97ecdf3e 786}
787
d9dd21a8 788typedef hash_table <ehspec_hasher> ehspec_hash_type;
789
790
e38def9c 791/* Add TYPE (which may be NULL) to cfun->eh->ttype_data, using TYPES_HASH
908e5f41 792 to speed up the search. Return the filter value to be used. */
97ecdf3e 793
df4b504c 794static int
d9dd21a8 795add_ttypes_entry (ttypes_hash_type ttypes_hash, tree type)
97ecdf3e 796{
df4b504c 797 struct ttypes_filter **slot, *n;
97ecdf3e 798
d9dd21a8 799 slot = ttypes_hash.find_slot_with_hash (type, (hashval_t) TREE_HASH (type),
800 INSERT);
df4b504c 801
802 if ((n = *slot) == NULL)
97ecdf3e 803 {
df4b504c 804 /* Filter value is a 1 based table index. */
97bb6c17 805
4c36ffe6 806 n = XNEW (struct ttypes_filter);
df4b504c 807 n->t = type;
f1f41a6c 808 n->filter = vec_safe_length (cfun->eh->ttype_data) + 1;
df4b504c 809 *slot = n;
810
f1f41a6c 811 vec_safe_push (cfun->eh->ttype_data, type);
97ecdf3e 812 }
df4b504c 813
814 return n->filter;
97ecdf3e 815}
816
e38def9c 817/* Add LIST to cfun->eh->ehspec_data, using EHSPEC_HASH and TYPES_HASH
df4b504c 818 to speed up the search. Return the filter value to be used. */
819
820static int
d9dd21a8 821add_ehspec_entry (ehspec_hash_type ehspec_hash, ttypes_hash_type ttypes_hash,
822 tree list)
97bb6c17 823{
df4b504c 824 struct ttypes_filter **slot, *n;
825 struct ttypes_filter dummy;
97bb6c17 826
df4b504c 827 dummy.t = list;
d9dd21a8 828 slot = ehspec_hash.find_slot (&dummy, INSERT);
df4b504c 829
830 if ((n = *slot) == NULL)
831 {
e38def9c 832 int len;
833
834 if (targetm.arm_eabi_unwinder)
f1f41a6c 835 len = vec_safe_length (cfun->eh->ehspec_data.arm_eabi);
e38def9c 836 else
f1f41a6c 837 len = vec_safe_length (cfun->eh->ehspec_data.other);
e38def9c 838
df4b504c 839 /* Filter value is a -1 based byte index into a uleb128 buffer. */
840
4c36ffe6 841 n = XNEW (struct ttypes_filter);
df4b504c 842 n->t = list;
e38def9c 843 n->filter = -(len + 1);
df4b504c 844 *slot = n;
845
1774763d 846 /* Generate a 0 terminated list of filter values. */
df4b504c 847 for (; list ; list = TREE_CHAIN (list))
1774763d 848 {
849 if (targetm.arm_eabi_unwinder)
f1f41a6c 850 vec_safe_push (cfun->eh->ehspec_data.arm_eabi, TREE_VALUE (list));
1774763d 851 else
852 {
853 /* Look up each type in the list and encode its filter
854 value as a uleb128. */
e38def9c 855 push_uleb128 (&cfun->eh->ehspec_data.other,
856 add_ttypes_entry (ttypes_hash, TREE_VALUE (list)));
5c15c916 857 }
df4b504c 858 }
e38def9c 859 if (targetm.arm_eabi_unwinder)
f1f41a6c 860 vec_safe_push (cfun->eh->ehspec_data.arm_eabi, NULL_TREE);
e38def9c 861 else
f1f41a6c 862 vec_safe_push (cfun->eh->ehspec_data.other, (uchar)0);
df4b504c 863 }
e38def9c 864
865 return n->filter;
df4b504c 866}
6c74b671 867
e38def9c 868/* Generate the action filter values to be used for CATCH and
869 ALLOWED_EXCEPTIONS regions. When using dwarf2 exception regions,
870 we use lots of landing pads, and so every type or list can share
871 the same filter value, which saves table space. */
1639c6db 872
e38def9c 873void
874assign_filter_values (void)
6c74b671 875{
df4b504c 876 int i;
d9dd21a8 877 ttypes_hash_type ttypes;
878 ehspec_hash_type ehspec;
e38def9c 879 eh_region r;
880 eh_catch c;
1228f0d8 881
f1f41a6c 882 vec_alloc (cfun->eh->ttype_data, 16);
e38def9c 883 if (targetm.arm_eabi_unwinder)
f1f41a6c 884 vec_alloc (cfun->eh->ehspec_data.arm_eabi, 64);
e38def9c 885 else
f1f41a6c 886 vec_alloc (cfun->eh->ehspec_data.other, 64);
6c74b671 887
d9dd21a8 888 ttypes.create (31);
889 ehspec.create (31);
6c74b671 890
f1f41a6c 891 for (i = 1; vec_safe_iterate (cfun->eh->region_array, i, &r); ++i)
e38def9c 892 {
893 if (r == NULL)
df4b504c 894 continue;
1228f0d8 895
e38def9c 896 switch (r->type)
54f7a985 897 {
e38def9c 898 case ERT_TRY:
899 for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
504e084a 900 {
e38def9c 901 /* Whatever type_list is (NULL or true list), we build a list
902 of filters for the region. */
903 c->filter_list = NULL_TREE;
904
905 if (c->type_list != NULL)
906 {
907 /* Get a filter value for each of the types caught and store
908 them in the region's dedicated list. */
909 tree tp_node = c->type_list;
910
911 for ( ; tp_node; tp_node = TREE_CHAIN (tp_node))
912 {
913 int flt = add_ttypes_entry (ttypes, TREE_VALUE (tp_node));
7002a1c8 914 tree flt_node = build_int_cst (integer_type_node, flt);
e38def9c 915
916 c->filter_list
917 = tree_cons (NULL_TREE, flt_node, c->filter_list);
918 }
919 }
920 else
921 {
922 /* Get a filter value for the NULL list also since it
923 will need an action record anyway. */
924 int flt = add_ttypes_entry (ttypes, NULL);
7002a1c8 925 tree flt_node = build_int_cst (integer_type_node, flt);
e38def9c 926
927 c->filter_list
928 = tree_cons (NULL_TREE, flt_node, NULL);
929 }
504e084a 930 }
e38def9c 931 break;
504e084a 932
e38def9c 933 case ERT_ALLOWED_EXCEPTIONS:
934 r->u.allowed.filter
935 = add_ehspec_entry (ehspec, ttypes, r->u.allowed.type_list);
936 break;
4ee9c684 937
e38def9c 938 default:
939 break;
940 }
df4b504c 941 }
e38def9c 942
d9dd21a8 943 ttypes.dispose ();
944 ehspec.dispose ();
df4b504c 945}
946
e38def9c 947/* Emit SEQ into basic block just before INSN (that is assumed to be
948 first instruction of some existing BB and return the newly
949 produced block. */
950static basic_block
951emit_to_new_bb_before (rtx seq, rtx insn)
952{
953 rtx last;
79f958cb 954 basic_block bb, prev_bb;
e38def9c 955 edge e;
956 edge_iterator ei;
957
958 /* If there happens to be a fallthru edge (possibly created by cleanup_cfg
959 call), we don't want it to go into newly created landing pad or other EH
960 construct. */
961 for (ei = ei_start (BLOCK_FOR_INSN (insn)->preds); (e = ei_safe_edge (ei)); )
962 if (e->flags & EDGE_FALLTHRU)
963 force_nonfallthru (e);
964 else
965 ei_next (&ei);
966 last = emit_insn_before (seq, insn);
967 if (BARRIER_P (last))
968 last = PREV_INSN (last);
79f958cb 969 prev_bb = BLOCK_FOR_INSN (insn)->prev_bb;
970 bb = create_basic_block (seq, last, prev_bb);
e38def9c 971 update_bb_for_insn (bb);
972 bb->flags |= BB_SUPERBLOCK;
973 return bb;
974}
df4b504c 975\f
f59cbcbf 976/* A subroutine of dw2_build_landing_pads, also used for edge splitting
977 at the rtl level. Emit the code required by the target at a landing
978 pad for the given region. */
979
980void
981expand_dw2_landing_pad_for_region (eh_region region)
982{
983#ifdef HAVE_exception_receiver
984 if (HAVE_exception_receiver)
985 emit_insn (gen_exception_receiver ());
986 else
987#endif
988#ifdef HAVE_nonlocal_goto_receiver
989 if (HAVE_nonlocal_goto_receiver)
990 emit_insn (gen_nonlocal_goto_receiver ());
991 else
992#endif
993 { /* Nothing */ }
994
995 if (region->exc_ptr_reg)
996 emit_move_insn (region->exc_ptr_reg,
997 gen_rtx_REG (ptr_mode, EH_RETURN_DATA_REGNO (0)));
998 if (region->filter_reg)
999 emit_move_insn (region->filter_reg,
1000 gen_rtx_REG (targetm.eh_return_filter_mode (),
1001 EH_RETURN_DATA_REGNO (1)));
1002}
1003
e38def9c 1004/* Expand the extra code needed at landing pads for dwarf2 unwinding. */
1005
df4b504c 1006static void
35cb5232 1007dw2_build_landing_pads (void)
97ecdf3e 1008{
97b330ca 1009 int i;
e38def9c 1010 eh_landing_pad lp;
f59cbcbf 1011 int e_flags = EDGE_FALLTHRU;
1012
1013 /* If we're going to partition blocks, we need to be able to add
1014 new landing pads later, which means that we need to hold on to
1015 the post-landing-pad block. Prevent it from being merged away.
1016 We'll remove this bit after partitioning. */
1017 if (flag_reorder_blocks_and_partition)
1018 e_flags |= EDGE_PRESERVE;
97ecdf3e 1019
f1f41a6c 1020 for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
df4b504c 1021 {
54f7a985 1022 basic_block bb;
e38def9c 1023 rtx seq;
54f7a985 1024 edge e;
97ecdf3e 1025
e38def9c 1026 if (lp == NULL || lp->post_landing_pad == NULL)
927a6b6b 1027 continue;
1028
df4b504c 1029 start_sequence ();
97ecdf3e 1030
e38def9c 1031 lp->landing_pad = gen_label_rtx ();
1032 emit_label (lp->landing_pad);
c242f3f7 1033 LABEL_PRESERVE_P (lp->landing_pad) = 1;
97ecdf3e 1034
f59cbcbf 1035 expand_dw2_landing_pad_for_region (lp->region);
011a7f23 1036
df4b504c 1037 seq = get_insns ();
1038 end_sequence ();
64db8f62 1039
e38def9c 1040 bb = emit_to_new_bb_before (seq, label_rtx (lp->post_landing_pad));
f59cbcbf 1041 e = make_edge (bb, bb->next_bb, e_flags);
54f7a985 1042 e->count = bb->count;
1043 e->probability = REG_BR_PROB_BASE;
99cc6bba 1044 if (current_loops)
1045 {
1046 struct loop *loop = bb->next_bb->loop_father;
1047 /* If we created a pre-header block, add the new block to the
1048 outer loop, otherwise to the loop itself. */
1049 if (bb->next_bb == loop->header)
1050 add_bb_to_loop (bb, loop_outer (loop));
1051 else
1052 add_bb_to_loop (bb, loop);
1053 }
df4b504c 1054 }
97ecdf3e 1055}
1056
df4b504c 1057\f
f1f41a6c 1058static vec<int> sjlj_lp_call_site_index;
97bb6c17 1059
e38def9c 1060/* Process all active landing pads. Assign each one a compact dispatch
1061 index, and a call-site index. */
23ceb7b2 1062
e38def9c 1063static int
1064sjlj_assign_call_site_values (void)
23ceb7b2 1065{
d9dd21a8 1066 action_hash_type ar_hash;
e38def9c 1067 int i, disp_index;
1068 eh_landing_pad lp;
df4b504c 1069
f1f41a6c 1070 vec_alloc (crtl->eh.action_record_data, 64);
d9dd21a8 1071 ar_hash.create (31);
df4b504c 1072
e38def9c 1073 disp_index = 0;
1074 call_site_base = 1;
f1f41a6c 1075 for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
e38def9c 1076 if (lp && lp->post_landing_pad)
d63ea2f2 1077 {
e38def9c 1078 int action, call_site;
318077fa 1079
e38def9c 1080 /* First: build the action table. */
1081 action = collect_one_action_chain (ar_hash, lp->region);
df4b504c 1082
e38def9c 1083 /* Next: assign call-site values. If dwarf2 terms, this would be
1084 the region number assigned by convert_to_eh_region_ranges, but
1085 handles no-action and must-not-throw differently. */
df4b504c 1086 /* Map must-not-throw to otherwise unused call-site index 0. */
1087 if (action == -2)
e38def9c 1088 call_site = 0;
df4b504c 1089 /* Map no-action to otherwise unused call-site index -1. */
1090 else if (action == -1)
e38def9c 1091 call_site = -1;
df4b504c 1092 /* Otherwise, look it up in the table. */
1093 else
e38def9c 1094 call_site = add_call_site (GEN_INT (disp_index), action, 0);
f1f41a6c 1095 sjlj_lp_call_site_index[i] = call_site;
df4b504c 1096
e38def9c 1097 disp_index++;
df4b504c 1098 }
e38def9c 1099
d9dd21a8 1100 ar_hash.dispose ();
e38def9c 1101
1102 return disp_index;
97ecdf3e 1103}
8591d03a 1104
e38def9c 1105/* Emit code to record the current call-site index before every
1106 insn that can throw. */
1107
df4b504c 1108static void
e38def9c 1109sjlj_mark_call_sites (void)
8591d03a 1110{
df4b504c 1111 int last_call_site = -2;
1112 rtx insn, mem;
1113
df4b504c 1114 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
8591d03a 1115 {
e38def9c 1116 eh_landing_pad lp;
1117 eh_region r;
1118 bool nothrow;
df4b504c 1119 int this_call_site;
e38def9c 1120 rtx before, p;
8591d03a 1121
df4b504c 1122 /* Reset value tracking at extended basic block boundaries. */
6d7dc5b9 1123 if (LABEL_P (insn))
df4b504c 1124 last_call_site = -2;
8591d03a 1125
df4b504c 1126 if (! INSN_P (insn))
1127 continue;
8591d03a 1128
e38def9c 1129 nothrow = get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1130 if (nothrow)
0f656a57 1131 continue;
e38def9c 1132 if (lp)
f1f41a6c 1133 this_call_site = sjlj_lp_call_site_index[lp->index];
e38def9c 1134 else if (r == NULL)
df4b504c 1135 {
1136 /* Calls (and trapping insns) without notes are outside any
1137 exception handling region in this function. Mark them as
1138 no action. */
e38def9c 1139 this_call_site = -1;
df4b504c 1140 }
1141 else
e38def9c 1142 {
1143 gcc_assert (r->type == ERT_MUST_NOT_THROW);
1144 this_call_site = 0;
1145 }
8591d03a 1146
e5aa6e8b 1147 if (this_call_site != -1)
1148 crtl->uses_eh_lsda = 1;
1149
df4b504c 1150 if (this_call_site == last_call_site)
1151 continue;
1152
1153 /* Don't separate a call from it's argument loads. */
1154 before = insn;
6d7dc5b9 1155 if (CALL_P (insn))
ff385626 1156 before = find_first_parameter_load (insn, NULL_RTX);
97ecdf3e 1157
df4b504c 1158 start_sequence ();
4dd3de56 1159 mem = adjust_address (crtl->eh.sjlj_fc, TYPE_MODE (integer_type_node),
82832d9a 1160 sjlj_fc_call_site_ofs);
d11aedc7 1161 emit_move_insn (mem, gen_int_mode (this_call_site, GET_MODE (mem)));
df4b504c 1162 p = get_insns ();
1163 end_sequence ();
97bb6c17 1164
31d3e01c 1165 emit_insn_before (p, before);
df4b504c 1166 last_call_site = this_call_site;
1167 }
1168}
97ecdf3e 1169
df4b504c 1170/* Construct the SjLj_Function_Context. */
1171
1172static void
35cb5232 1173sjlj_emit_function_enter (rtx dispatch_label)
97ecdf3e 1174{
df4b504c 1175 rtx fn_begin, fc, mem, seq;
d2099aed 1176 bool fn_begin_outside_block;
58d82cd0 1177 rtx personality = get_personality_function (current_function_decl);
97ecdf3e 1178
4dd3de56 1179 fc = crtl->eh.sjlj_fc;
97ecdf3e 1180
df4b504c 1181 start_sequence ();
de46d199 1182
b52a90a7 1183 /* We're storing this libcall's address into memory instead of
1184 calling it directly. Thus, we must call assemble_external_libcall
1185 here, as we can not depend on emit_library_call to do it for us. */
58d82cd0 1186 assemble_external_libcall (personality);
e513d163 1187 mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
58d82cd0 1188 emit_move_insn (mem, personality);
df4b504c 1189
e513d163 1190 mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
18d50ae6 1191 if (crtl->uses_eh_lsda)
df4b504c 1192 {
1193 char buf[20];
134c13b5 1194 rtx sym;
1195
4781f9b9 1196 ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", current_function_funcdef_no);
134c13b5 1197 sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1198 SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
1199 emit_move_insn (mem, sym);
de46d199 1200 }
df4b504c 1201 else
1202 emit_move_insn (mem, const0_rtx);
1ed5443b 1203
e5aa6e8b 1204 if (dispatch_label)
1205 {
df4b504c 1206#ifdef DONT_USE_BUILTIN_SETJMP
72b3292b 1207 rtx x;
e5aa6e8b 1208 x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
1209 TYPE_MODE (integer_type_node), 1,
29c05e22 1210 plus_constant (Pmode, XEXP (fc, 0),
e5aa6e8b 1211 sjlj_fc_jbuf_ofs), Pmode);
1212
1213 emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
1214 TYPE_MODE (integer_type_node), 0,
584abc98 1215 dispatch_label, REG_BR_PROB_BASE / 100);
e5aa6e8b 1216#else
29c05e22 1217 expand_builtin_setjmp_setup (plus_constant (Pmode, XEXP (fc, 0),
e5aa6e8b 1218 sjlj_fc_jbuf_ofs),
1219 dispatch_label);
97ecdf3e 1220#endif
e5aa6e8b 1221 }
97ecdf3e 1222
df4b504c 1223 emit_library_call (unwind_sjlj_register_libfunc, LCT_NORMAL, VOIDmode,
1224 1, XEXP (fc, 0), Pmode);
97bb6c17 1225
df4b504c 1226 seq = get_insns ();
1227 end_sequence ();
97ecdf3e 1228
df4b504c 1229 /* ??? Instead of doing this at the beginning of the function,
1230 do this in a block that is at loop level 0 and dominates all
1231 can_throw_internal instructions. */
97ecdf3e 1232
d2099aed 1233 fn_begin_outside_block = true;
df4b504c 1234 for (fn_begin = get_insns (); ; fn_begin = NEXT_INSN (fn_begin))
d2099aed 1235 if (NOTE_P (fn_begin))
1236 {
ad4583d9 1237 if (NOTE_KIND (fn_begin) == NOTE_INSN_FUNCTION_BEG)
d2099aed 1238 break;
ad4583d9 1239 else if (NOTE_INSN_BASIC_BLOCK_P (fn_begin))
d2099aed 1240 fn_begin_outside_block = false;
1241 }
1242
1243 if (fn_begin_outside_block)
ea091dfd 1244 insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR));
54f7a985 1245 else
d2099aed 1246 emit_insn_after (seq, fn_begin);
97ecdf3e 1247}
1248
df4b504c 1249/* Call back from expand_function_end to know where we should put
1250 the call to unwind_sjlj_unregister_libfunc if needed. */
97bb6c17 1251
df4b504c 1252void
35cb5232 1253sjlj_emit_function_exit_after (rtx after)
df4b504c 1254{
4dd3de56 1255 crtl->eh.sjlj_exit_after = after;
df4b504c 1256}
97ecdf3e 1257
1258static void
35cb5232 1259sjlj_emit_function_exit (void)
df4b504c 1260{
b2ee26d5 1261 rtx seq, insn;
97ecdf3e 1262
df4b504c 1263 start_sequence ();
fbba5463 1264
df4b504c 1265 emit_library_call (unwind_sjlj_unregister_libfunc, LCT_NORMAL, VOIDmode,
4dd3de56 1266 1, XEXP (crtl->eh.sjlj_fc, 0), Pmode);
d63ea2f2 1267
df4b504c 1268 seq = get_insns ();
1269 end_sequence ();
97ecdf3e 1270
df4b504c 1271 /* ??? Really this can be done in any block at loop level 0 that
1272 post-dominates all can_throw_internal instructions. This is
1273 the last possible moment. */
011a7f23 1274
b2ee26d5 1275 insn = crtl->eh.sjlj_exit_after;
1276 if (LABEL_P (insn))
1277 insn = NEXT_INSN (insn);
54f7a985 1278
b2ee26d5 1279 emit_insn_after (seq, insn);
011a7f23 1280}
1281
df4b504c 1282static void
e38def9c 1283sjlj_emit_dispatch_table (rtx dispatch_label, int num_dispatch)
fbba5463 1284{
1bd43494 1285 enum machine_mode unwind_word_mode = targetm.unwind_word_mode ();
1286 enum machine_mode filter_mode = targetm.eh_return_filter_mode ();
e38def9c 1287 eh_landing_pad lp;
1288 rtx mem, seq, fc, before, exc_ptr_reg, filter_reg;
1289 rtx first_reachable_label;
54f7a985 1290 basic_block bb;
e38def9c 1291 eh_region r;
54f7a985 1292 edge e;
e38def9c 1293 int i, disp_index;
1e094109 1294 vec<tree> dispatch_labels = vNULL;
df4b504c 1295
4dd3de56 1296 fc = crtl->eh.sjlj_fc;
df4b504c 1297
1298 start_sequence ();
1299
1300 emit_label (dispatch_label);
1ed5443b 1301
df4b504c 1302#ifndef DONT_USE_BUILTIN_SETJMP
1303 expand_builtin_setjmp_receiver (dispatch_label);
df4b504c 1304
e38def9c 1305 /* The caller of expand_builtin_setjmp_receiver is responsible for
1306 making sure that the label doesn't vanish. The only other caller
1307 is the expander for __builtin_setjmp_receiver, which places this
1308 label on the nonlocal_goto_label list. Since we're modeling these
1309 CFG edges more exactly, we can use the forced_labels list instead. */
1310 LABEL_PRESERVE_P (dispatch_label) = 1;
1311 forced_labels
1312 = gen_rtx_EXPR_LIST (VOIDmode, dispatch_label, forced_labels);
1313#endif
df4b504c 1314
e38def9c 1315 /* Load up exc_ptr and filter values from the function context. */
1bd43494 1316 mem = adjust_address (fc, unwind_word_mode, sjlj_fc_data_ofs);
1317 if (unwind_word_mode != ptr_mode)
df4b504c 1318 {
1319#ifdef POINTERS_EXTEND_UNSIGNED
a64908cd 1320 mem = convert_memory_address (ptr_mode, mem);
df4b504c 1321#else
a64908cd 1322 mem = convert_to_mode (ptr_mode, mem, 0);
df4b504c 1323#endif
1324 }
e38def9c 1325 exc_ptr_reg = force_reg (ptr_mode, mem);
df4b504c 1326
1bd43494 1327 mem = adjust_address (fc, unwind_word_mode,
1328 sjlj_fc_data_ofs + GET_MODE_SIZE (unwind_word_mode));
1329 if (unwind_word_mode != filter_mode)
1330 mem = convert_to_mode (filter_mode, mem, 0);
e38def9c 1331 filter_reg = force_reg (filter_mode, mem);
97ecdf3e 1332
df4b504c 1333 /* Jump to one of the directly reachable regions. */
df4b504c 1334
e38def9c 1335 disp_index = 0;
1336 first_reachable_label = NULL;
1337
1338 /* If there's exactly one call site in the function, don't bother
1339 generating a switch statement. */
e38def9c 1340 if (num_dispatch > 1)
f1f41a6c 1341 dispatch_labels.create (num_dispatch);
e38def9c 1342
f1f41a6c 1343 for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
e38def9c 1344 if (lp && lp->post_landing_pad)
1345 {
1346 rtx seq2, label;
1347
1348 start_sequence ();
1349
1350 lp->landing_pad = dispatch_label;
1351
1352 if (num_dispatch > 1)
1353 {
b6e3dd65 1354 tree t_label, case_elt, t;
e38def9c 1355
1356 t_label = create_artificial_label (UNKNOWN_LOCATION);
b6e3dd65 1357 t = build_int_cst (integer_type_node, disp_index);
1358 case_elt = build_case_label (t, NULL, t_label);
f1f41a6c 1359 dispatch_labels.quick_push (case_elt);
e38def9c 1360 label = label_rtx (t_label);
1361 }
1362 else
1363 label = gen_label_rtx ();
1364
1365 if (disp_index == 0)
1366 first_reachable_label = label;
1367 emit_label (label);
1368
1369 r = lp->region;
1370 if (r->exc_ptr_reg)
1371 emit_move_insn (r->exc_ptr_reg, exc_ptr_reg);
1372 if (r->filter_reg)
1373 emit_move_insn (r->filter_reg, filter_reg);
1374
1375 seq2 = get_insns ();
1376 end_sequence ();
1377
1378 before = label_rtx (lp->post_landing_pad);
1379 bb = emit_to_new_bb_before (seq2, before);
1380 e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
1381 e->count = bb->count;
1382 e->probability = REG_BR_PROB_BASE;
a4575f9d 1383 if (current_loops)
1384 {
1385 struct loop *loop = bb->next_bb->loop_father;
1386 /* If we created a pre-header block, add the new block to the
1387 outer loop, otherwise to the loop itself. */
1388 if (bb->next_bb == loop->header)
1389 add_bb_to_loop (bb, loop_outer (loop));
1390 else
1391 add_bb_to_loop (bb, loop);
1392 /* ??? For multiple dispatches we will end up with edges
1393 from the loop tree root into this loop, making it a
1394 multiple-entry loop. Discard all affected loops. */
1395 if (num_dispatch > 1)
1396 {
1397 for (loop = bb->loop_father;
1398 loop_outer (loop); loop = loop_outer (loop))
1399 {
1400 loop->header = NULL;
1401 loop->latch = NULL;
1402 }
1403 }
1404 }
d63ea2f2 1405
e38def9c 1406 disp_index++;
1407 }
1408 gcc_assert (disp_index == num_dispatch);
1409
1410 if (num_dispatch > 1)
1411 {
49a70175 1412 rtx disp = adjust_address (fc, TYPE_MODE (integer_type_node),
1413 sjlj_fc_call_site_ofs);
af68b5a9 1414 expand_sjlj_dispatch_table (disp, dispatch_labels);
173f0bec 1415 }
011a7f23 1416
df4b504c 1417 seq = get_insns ();
1418 end_sequence ();
97ecdf3e 1419
e38def9c 1420 bb = emit_to_new_bb_before (seq, first_reachable_label);
1421 if (num_dispatch == 1)
1422 {
1423 e = make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
1424 e->count = bb->count;
1425 e->probability = REG_BR_PROB_BASE;
a4575f9d 1426 if (current_loops)
1427 {
1428 struct loop *loop = bb->next_bb->loop_father;
1429 /* If we created a pre-header block, add the new block to the
1430 outer loop, otherwise to the loop itself. */
1431 if (bb->next_bb == loop->header)
1432 add_bb_to_loop (bb, loop_outer (loop));
1433 else
1434 add_bb_to_loop (bb, loop);
1435 }
1436 }
1437 else
1438 {
1439 /* We are not wiring up edges here, but as the dispatcher call
1440 is at function begin simply associate the block with the
1441 outermost (non-)loop. */
1442 if (current_loops)
1443 add_bb_to_loop (bb, current_loops->tree_root);
e38def9c 1444 }
fbba5463 1445}
1446
df4b504c 1447static void
35cb5232 1448sjlj_build_landing_pads (void)
fbba5463 1449{
e38def9c 1450 int num_dispatch;
fbba5463 1451
f1f41a6c 1452 num_dispatch = vec_safe_length (cfun->eh->lp_array);
e38def9c 1453 if (num_dispatch == 0)
1454 return;
f1f41a6c 1455 sjlj_lp_call_site_index.safe_grow_cleared (num_dispatch);
fbba5463 1456
e38def9c 1457 num_dispatch = sjlj_assign_call_site_values ();
1458 if (num_dispatch > 0)
df4b504c 1459 {
1460 rtx dispatch_label = gen_label_rtx ();
c9b50df7 1461 int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
1462 TYPE_MODE (sjlj_fc_type_node),
1463 TYPE_ALIGN (sjlj_fc_type_node));
4dd3de56 1464 crtl->eh.sjlj_fc
df4b504c 1465 = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
1466 int_size_in_bytes (sjlj_fc_type_node),
c9b50df7 1467 align);
97ecdf3e 1468
e38def9c 1469 sjlj_mark_call_sites ();
df4b504c 1470 sjlj_emit_function_enter (dispatch_label);
e38def9c 1471 sjlj_emit_dispatch_table (dispatch_label, num_dispatch);
df4b504c 1472 sjlj_emit_function_exit ();
1473 }
173f0bec 1474
e5aa6e8b 1475 /* If we do not have any landing pads, we may still need to register a
1476 personality routine and (empty) LSDA to handle must-not-throw regions. */
1477 else if (function_needs_eh_personality (cfun) != eh_personality_none)
1478 {
1479 int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node,
1480 TYPE_MODE (sjlj_fc_type_node),
1481 TYPE_ALIGN (sjlj_fc_type_node));
1482 crtl->eh.sjlj_fc
1483 = assign_stack_local (TYPE_MODE (sjlj_fc_type_node),
1484 int_size_in_bytes (sjlj_fc_type_node),
1485 align);
1486
1487 sjlj_mark_call_sites ();
1488 sjlj_emit_function_enter (NULL_RTX);
1489 sjlj_emit_function_exit ();
1490 }
1491
f1f41a6c 1492 sjlj_lp_call_site_index.release ();
97ecdf3e 1493}
fbba5463 1494
2ea77971 1495/* After initial rtl generation, call back to finish generating
1496 exception support code. */
1497
1dd4980f 1498void
35cb5232 1499finish_eh_generation (void)
fbba5463 1500{
54f7a985 1501 basic_block bb;
1502
df4b504c 1503 /* Construct the landing pads. */
218e3e4e 1504 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
df4b504c 1505 sjlj_build_landing_pads ();
1506 else
1507 dw2_build_landing_pads ();
54f7a985 1508 break_superblocks ();
e38def9c 1509
218e3e4e 1510 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ
126b6848 1511 /* Kludge for Alpha (see alpha_gp_save_rtx). */
8a1586ba 1512 || single_succ_edge (ENTRY_BLOCK_PTR)->insns.r)
54f7a985 1513 commit_edge_insertions ();
e38def9c 1514
1515 /* Redirect all EH edges from the post_landing_pad to the landing pad. */
54f7a985 1516 FOR_EACH_BB (bb)
1517 {
e38def9c 1518 eh_landing_pad lp;
cd665a06 1519 edge_iterator ei;
e38def9c 1520 edge e;
3d1eacdb 1521
e38def9c 1522 lp = get_eh_landing_pad_from_rtx (BB_END (bb));
8f8dcce4 1523
e38def9c 1524 FOR_EACH_EDGE (e, ei, bb->succs)
1525 if (e->flags & EDGE_EH)
1526 break;
0cc4271a 1527
e38def9c 1528 /* We should not have generated any new throwing insns during this
1529 pass, and we should not have lost any EH edges, so we only need
1530 to handle two cases here:
1531 (1) reachable handler and an existing edge to post-landing-pad,
1532 (2) no reachable handler and no edge. */
1533 gcc_assert ((lp != NULL) == (e != NULL));
1534 if (lp != NULL)
0cc4271a 1535 {
e38def9c 1536 gcc_assert (BB_HEAD (e->dest) == label_rtx (lp->post_landing_pad));
98b4572e 1537
e38def9c 1538 redirect_edge_succ (e, BLOCK_FOR_INSN (lp->landing_pad));
1539 e->flags |= (CALL_P (BB_END (bb))
1540 ? EDGE_ABNORMAL | EDGE_ABNORMAL_CALL
1541 : EDGE_ABNORMAL);
df4b504c 1542 }
1543 }
97ecdf3e 1544}
e38def9c 1545\f
1546/* This section handles removing dead code for flow. */
4c5fcca6 1547
1548void
e38def9c 1549remove_eh_landing_pad (eh_landing_pad lp)
4c5fcca6 1550{
e38def9c 1551 eh_landing_pad *pp;
4c5fcca6 1552
e38def9c 1553 for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp)
1554 continue;
1555 *pp = lp->next_lp;
48e1416a 1556
e38def9c 1557 if (lp->post_landing_pad)
1558 EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
f1f41a6c 1559 (*cfun->eh->lp_array)[lp->index] = NULL;
4c5fcca6 1560}
1561
390f4a4b 1562/* Splice the EH region at PP from the region tree. */
3d1eacdb 1563
390f4a4b 1564static void
1565remove_eh_handler_splicer (eh_region *pp)
3d1eacdb 1566{
390f4a4b 1567 eh_region region = *pp;
e38def9c 1568 eh_landing_pad lp;
3d1eacdb 1569
e38def9c 1570 for (lp = region->landing_pads; lp ; lp = lp->next_lp)
48d5ef93 1571 {
e38def9c 1572 if (lp->post_landing_pad)
1573 EH_LANDING_PAD_NR (lp->post_landing_pad) = 0;
f1f41a6c 1574 (*cfun->eh->lp_array)[lp->index] = NULL;
48d5ef93 1575 }
bf6102ae 1576
e38def9c 1577 if (region->inner)
bf6102ae 1578 {
390f4a4b 1579 eh_region p, outer;
1580 outer = region->outer;
1581
e38def9c 1582 *pp = p = region->inner;
1583 do
1584 {
1585 p->outer = outer;
1586 pp = &p->next_peer;
1587 p = *pp;
1588 }
1589 while (p);
bf6102ae 1590 }
e38def9c 1591 *pp = region->next_peer;
a7b0c170 1592
f1f41a6c 1593 (*cfun->eh->region_array)[region->index] = NULL;
e38def9c 1594}
a7b0c170 1595
390f4a4b 1596/* Splice a single EH region REGION from the region tree.
1597
1598 To unlink REGION, we need to find the pointer to it with a relatively
1599 expensive search in REGION's outer region. If you are going to
1600 remove a number of handlers, using remove_unreachable_eh_regions may
1601 be a better option. */
1602
1603void
1604remove_eh_handler (eh_region region)
1605{
1606 eh_region *pp, *pp_start, p, outer;
1607
1608 outer = region->outer;
1609 if (outer)
1610 pp_start = &outer->inner;
1611 else
1612 pp_start = &cfun->eh->region_tree;
1613 for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp)
1614 continue;
1615
1616 remove_eh_handler_splicer (pp);
1617}
1618
1619/* Worker for remove_unreachable_eh_regions.
1620 PP is a pointer to the region to start a region tree depth-first
1621 search from. R_REACHABLE is the set of regions that have to be
1622 preserved. */
1623
1624static void
1625remove_unreachable_eh_regions_worker (eh_region *pp, sbitmap r_reachable)
1626{
1627 while (*pp)
1628 {
1629 eh_region region = *pp;
1630 remove_unreachable_eh_regions_worker (&region->inner, r_reachable);
1631 if (!bitmap_bit_p (r_reachable, region->index))
1632 remove_eh_handler_splicer (pp);
1633 else
1634 pp = &region->next_peer;
1635 }
1636}
1637
1638/* Splice all EH regions *not* marked in R_REACHABLE from the region tree.
1639 Do this by traversing the EH tree top-down and splice out regions that
1640 are not marked. By removing regions from the leaves, we avoid costly
1641 searches in the region tree. */
1642
1643void
1644remove_unreachable_eh_regions (sbitmap r_reachable)
1645{
1646 remove_unreachable_eh_regions_worker (&cfun->eh->region_tree, r_reachable);
1647}
1648
e38def9c 1649/* Invokes CALLBACK for every exception handler landing pad label.
1650 Only used by reload hackery; should not be used by new code. */
a7b0c170 1651
e38def9c 1652void
1653for_each_eh_label (void (*callback) (rtx))
a7b0c170 1654{
e38def9c 1655 eh_landing_pad lp;
1656 int i;
df4b504c 1657
f1f41a6c 1658 for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
d3a0267f 1659 {
e38def9c 1660 if (lp)
34e5cced 1661 {
e38def9c 1662 rtx lab = lp->landing_pad;
1663 if (lab && LABEL_P (lab))
1664 (*callback) (lab);
34e5cced 1665 }
df4b504c 1666 }
a7b0c170 1667}
e38def9c 1668\f
1669/* Create the REG_EH_REGION note for INSN, given its ECF_FLAGS for a
48e1416a 1670 call insn.
e38def9c 1671
1672 At the gimple level, we use LP_NR
1673 > 0 : The statement transfers to landing pad LP_NR
1674 = 0 : The statement is outside any EH region
1675 < 0 : The statement is within MUST_NOT_THROW region -LP_NR.
1676
1677 At the rtl level, we use LP_NR
1678 > 0 : The insn transfers to landing pad LP_NR
1679 = 0 : The insn cannot throw
1680 < 0 : The insn is within MUST_NOT_THROW region -LP_NR
1681 = INT_MIN : The insn cannot throw or execute a nonlocal-goto.
1682 missing note: The insn is outside any EH region.
1683
1684 ??? This difference probably ought to be avoided. We could stand
1685 to record nothrow for arbitrary gimple statements, and so avoid
1686 some moderately complex lookups in stmt_could_throw_p. Perhaps
1687 NOTHROW should be mapped on both sides to INT_MIN. Perhaps the
1688 no-nonlocal-goto property should be recorded elsewhere as a bit
1689 on the call_insn directly. Perhaps we should make more use of
1690 attaching the trees to call_insns (reachable via symbol_ref in
1691 direct call cases) and just pull the data out of the trees. */
a7b0c170 1692
e38def9c 1693void
1694make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr)
a7b0c170 1695{
e38def9c 1696 rtx value;
1697 if (ecf_flags & ECF_NOTHROW)
1698 value = const0_rtx;
1699 else if (lp_nr != 0)
1700 value = GEN_INT (lp_nr);
df4b504c 1701 else
e38def9c 1702 return;
1703 add_reg_note (insn, REG_EH_REGION, value);
a7b0c170 1704}
1705
e38def9c 1706/* Create a REG_EH_REGION note for a CALL_INSN that cannot throw
1707 nor perform a non-local goto. Replace the region note if it
1708 already exists. */
a7b0c170 1709
e38def9c 1710void
1711make_reg_eh_region_note_nothrow_nononlocal (rtx insn)
a7b0c170 1712{
e38def9c 1713 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1714 rtx intmin = GEN_INT (INT_MIN);
df4b504c 1715
e38def9c 1716 if (note != 0)
1717 XEXP (note, 0) = intmin;
1718 else
1719 add_reg_note (insn, REG_EH_REGION, intmin);
1720}
c788feb1 1721
e38def9c 1722/* Return true if INSN could throw, assuming no REG_EH_REGION note
1723 to the contrary. */
c788feb1 1724
e38def9c 1725bool
1726insn_could_throw_p (const_rtx insn)
1727{
827c9a9e 1728 if (!flag_exceptions)
1729 return false;
e38def9c 1730 if (CALL_P (insn))
1731 return true;
cbeb677e 1732 if (INSN_P (insn) && cfun->can_throw_non_call_exceptions)
e38def9c 1733 return may_trap_p (PATTERN (insn));
1734 return false;
1735}
0de999f1 1736
e38def9c 1737/* Copy an REG_EH_REGION note to each insn that might throw beginning
1738 at FIRST and ending at LAST. NOTE_OR_INSN is either the source insn
1739 to look for a note, or the note itself. */
0de999f1 1740
e38def9c 1741void
1742copy_reg_eh_region_note_forward (rtx note_or_insn, rtx first, rtx last)
1743{
1744 rtx insn, note = note_or_insn;
c788feb1 1745
e38def9c 1746 if (INSN_P (note_or_insn))
1747 {
1748 note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX);
1749 if (note == NULL)
1750 return;
c788feb1 1751 }
e38def9c 1752 note = XEXP (note, 0);
1753
1754 for (insn = first; insn != last ; insn = NEXT_INSN (insn))
1755 if (!find_reg_note (insn, REG_EH_REGION, NULL_RTX)
1756 && insn_could_throw_p (insn))
1757 add_reg_note (insn, REG_EH_REGION, note);
3c3bb268 1758}
97ecdf3e 1759
e38def9c 1760/* Likewise, but iterate backward. */
97ecdf3e 1761
4ee9c684 1762void
e38def9c 1763copy_reg_eh_region_note_backward (rtx note_or_insn, rtx last, rtx first)
97ecdf3e 1764{
e38def9c 1765 rtx insn, note = note_or_insn;
f929a98a 1766
e38def9c 1767 if (INSN_P (note_or_insn))
385df8c5 1768 {
e38def9c 1769 note = find_reg_note (note_or_insn, REG_EH_REGION, NULL_RTX);
1770 if (note == NULL)
4ee9c684 1771 return;
df4b504c 1772 }
e38def9c 1773 note = XEXP (note, 0);
8b4f3d64 1774
e38def9c 1775 for (insn = last; insn != first; insn = PREV_INSN (insn))
1776 if (insn_could_throw_p (insn))
1777 add_reg_note (insn, REG_EH_REGION, note);
4ee9c684 1778}
1779
4ee9c684 1780
e38def9c 1781/* Extract all EH information from INSN. Return true if the insn
1782 was marked NOTHROW. */
4ee9c684 1783
e38def9c 1784static bool
1785get_eh_region_and_lp_from_rtx (const_rtx insn, eh_region *pr,
1786 eh_landing_pad *plp)
4ee9c684 1787{
e38def9c 1788 eh_landing_pad lp = NULL;
1789 eh_region r = NULL;
1790 bool ret = false;
1791 rtx note;
1792 int lp_nr;
4ee9c684 1793
e38def9c 1794 if (! INSN_P (insn))
1795 goto egress;
1796
1797 if (NONJUMP_INSN_P (insn)
1798 && GET_CODE (PATTERN (insn)) == SEQUENCE)
1799 insn = XVECEXP (PATTERN (insn), 0, 0);
4ee9c684 1800
e38def9c 1801 note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1802 if (!note)
4ee9c684 1803 {
e38def9c 1804 ret = !insn_could_throw_p (insn);
1805 goto egress;
4ee9c684 1806 }
e38def9c 1807
1808 lp_nr = INTVAL (XEXP (note, 0));
1809 if (lp_nr == 0 || lp_nr == INT_MIN)
4ee9c684 1810 {
e38def9c 1811 ret = true;
1812 goto egress;
4ee9c684 1813 }
35cb5232 1814
e38def9c 1815 if (lp_nr < 0)
f1f41a6c 1816 r = (*cfun->eh->region_array)[-lp_nr];
e38def9c 1817 else
1818 {
f1f41a6c 1819 lp = (*cfun->eh->lp_array)[lp_nr];
e38def9c 1820 r = lp->region;
1821 }
4ee9c684 1822
e38def9c 1823 egress:
1824 *plp = lp;
1825 *pr = r;
1826 return ret;
f929a98a 1827}
1828
e38def9c 1829/* Return the landing pad to which INSN may go, or NULL if it does not
1830 have a reachable landing pad within this function. */
97ecdf3e 1831
e38def9c 1832eh_landing_pad
1833get_eh_landing_pad_from_rtx (const_rtx insn)
97ecdf3e 1834{
e38def9c 1835 eh_landing_pad lp;
1836 eh_region r;
4ee9c684 1837
e38def9c 1838 get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1839 return lp;
1840}
4ee9c684 1841
e38def9c 1842/* Return the region to which INSN may go, or NULL if it does not
1843 have a reachable region within this function. */
4ee9c684 1844
e38def9c 1845eh_region
1846get_eh_region_from_rtx (const_rtx insn)
1847{
1848 eh_landing_pad lp;
1849 eh_region r;
4ee9c684 1850
e38def9c 1851 get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1852 return r;
4ee9c684 1853}
1854
e38def9c 1855/* Return true if INSN throws and is caught by something in this function. */
1856
4ee9c684 1857bool
7ecb5bb2 1858can_throw_internal (const_rtx insn)
4ee9c684 1859{
e38def9c 1860 return get_eh_landing_pad_from_rtx (insn) != NULL;
1861}
1862
1863/* Return true if INSN throws and escapes from the current function. */
1864
1865bool
1866can_throw_external (const_rtx insn)
1867{
1868 eh_landing_pad lp;
1869 eh_region r;
1870 bool nothrow;
d63ea2f2 1871
df4b504c 1872 if (! INSN_P (insn))
1873 return false;
97bb6c17 1874
6d7dc5b9 1875 if (NONJUMP_INSN_P (insn)
df4b504c 1876 && GET_CODE (PATTERN (insn)) == SEQUENCE)
e38def9c 1877 {
1878 rtx seq = PATTERN (insn);
1879 int i, n = XVECLEN (seq, 0);
97ecdf3e 1880
e38def9c 1881 for (i = 0; i < n; i++)
1882 if (can_throw_external (XVECEXP (seq, 0, i)))
1883 return true;
4ee9c684 1884
e38def9c 1885 return false;
1886 }
4ee9c684 1887
e38def9c 1888 nothrow = get_eh_region_and_lp_from_rtx (insn, &r, &lp);
4ee9c684 1889
e38def9c 1890 /* If we can't throw, we obviously can't throw external. */
1891 if (nothrow)
1892 return false;
97ecdf3e 1893
e38def9c 1894 /* If we have an internal landing pad, then we're not external. */
1895 if (lp != NULL)
1896 return false;
97ecdf3e 1897
e38def9c 1898 /* If we're not within an EH region, then we are external. */
1899 if (r == NULL)
1900 return true;
97ecdf3e 1901
e38def9c 1902 /* The only thing that ought to be left is MUST_NOT_THROW regions,
1903 which don't always have landing pads. */
1904 gcc_assert (r->type == ERT_MUST_NOT_THROW);
1905 return false;
df4b504c 1906}
97ecdf3e 1907
e38def9c 1908/* Return true if INSN cannot throw at all. */
1909
df4b504c 1910bool
e38def9c 1911insn_nothrow_p (const_rtx insn)
97ecdf3e 1912{
e38def9c 1913 eh_landing_pad lp;
1914 eh_region r;
97ecdf3e 1915
df4b504c 1916 if (! INSN_P (insn))
e38def9c 1917 return true;
e4bbf4c1 1918
6d7dc5b9 1919 if (NONJUMP_INSN_P (insn)
df4b504c 1920 && GET_CODE (PATTERN (insn)) == SEQUENCE)
80621b93 1921 {
1922 rtx seq = PATTERN (insn);
1923 int i, n = XVECLEN (seq, 0);
1924
1925 for (i = 0; i < n; i++)
e38def9c 1926 if (!insn_nothrow_p (XVECEXP (seq, 0, i)))
1927 return false;
80621b93 1928
e38def9c 1929 return true;
80621b93 1930 }
df4b504c 1931
e38def9c 1932 return get_eh_region_and_lp_from_rtx (insn, &r, &lp);
1933}
1934
1935/* Return true if INSN can perform a non-local goto. */
1936/* ??? This test is here in this file because it (ab)uses REG_EH_REGION. */
1937
1938bool
1939can_nonlocal_goto (const_rtx insn)
1940{
1941 if (nonlocal_goto_handler_labels && CALL_P (insn))
df4b504c 1942 {
e38def9c 1943 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
1944 if (!note || INTVAL (XEXP (note, 0)) != INT_MIN)
1945 return true;
df4b504c 1946 }
e38def9c 1947 return false;
97ecdf3e 1948}
e38def9c 1949\f
18d50ae6 1950/* Set TREE_NOTHROW and crtl->all_throwers_are_sibcalls. */
ed74c60e 1951
16fcf0f4 1952static unsigned int
35cb5232 1953set_nothrow_function_flags (void)
da5038a3 1954{
1955 rtx insn;
35cb5232 1956
b0d29d1c 1957 crtl->nothrow = 1;
da5038a3 1958
18d50ae6 1959 /* Assume crtl->all_throwers_are_sibcalls until we encounter
04396483 1960 something that can throw an exception. We specifically exempt
1961 CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
1962 and can't throw. Most CALL_INSNs are not SIBLING_CALL_P, so this
1963 is optimistic. */
da5038a3 1964
18d50ae6 1965 crtl->all_throwers_are_sibcalls = 1;
04396483 1966
b0d29d1c 1967 /* If we don't know that this implementation of the function will
1968 actually be used, then we must not set TREE_NOTHROW, since
1969 callers must not assume that this function does not throw. */
1970 if (TREE_NOTHROW (current_function_decl))
1971 return 0;
1972
04396483 1973 if (! flag_exceptions)
2a1990e9 1974 return 0;
35cb5232 1975
da5038a3 1976 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
df4b504c 1977 if (can_throw_external (insn))
04396483 1978 {
b0d29d1c 1979 crtl->nothrow = 0;
04396483 1980
6d7dc5b9 1981 if (!CALL_P (insn) || !SIBLING_CALL_P (insn))
04396483 1982 {
18d50ae6 1983 crtl->all_throwers_are_sibcalls = 0;
2a1990e9 1984 return 0;
04396483 1985 }
1986 }
1987
b0d29d1c 1988 if (crtl->nothrow
fd6a3c41 1989 && (cgraph_function_body_availability (cgraph_get_node
a883441f 1990 (current_function_decl))
b0d29d1c 1991 >= AVAIL_AVAILABLE))
a883441f 1992 {
fd6a3c41 1993 struct cgraph_node *node = cgraph_get_node (current_function_decl);
17b28e52 1994 struct cgraph_edge *e;
1995 for (e = node->callers; e; e = e->next_caller)
1996 e->can_throw_external = false;
16fcf0f4 1997 cgraph_set_nothrow_flag (node, true);
a883441f 1998
1999 if (dump_file)
2000 fprintf (dump_file, "Marking function nothrow: %s\n\n",
2001 current_function_name ());
2002 }
2a1990e9 2003 return 0;
da5038a3 2004}
df4b504c 2005
cbe8bda8 2006namespace {
2007
2008const pass_data pass_data_set_nothrow_function_flags =
2009{
2010 RTL_PASS, /* type */
2011 "nothrow", /* name */
2012 OPTGROUP_NONE, /* optinfo_flags */
2013 false, /* has_gate */
2014 true, /* has_execute */
2015 TV_NONE, /* tv_id */
2016 0, /* properties_required */
2017 0, /* properties_provided */
2018 0, /* properties_destroyed */
2019 0, /* todo_flags_start */
2020 0, /* todo_flags_finish */
77fce4cd 2021};
2022
cbe8bda8 2023class pass_set_nothrow_function_flags : public rtl_opt_pass
2024{
2025public:
9af5ce0c 2026 pass_set_nothrow_function_flags (gcc::context *ctxt)
2027 : rtl_opt_pass (pass_data_set_nothrow_function_flags, ctxt)
cbe8bda8 2028 {}
2029
2030 /* opt_pass methods: */
2031 unsigned int execute () { return set_nothrow_function_flags (); }
2032
2033}; // class pass_set_nothrow_function_flags
2034
2035} // anon namespace
2036
2037rtl_opt_pass *
2038make_pass_set_nothrow_function_flags (gcc::context *ctxt)
2039{
2040 return new pass_set_nothrow_function_flags (ctxt);
2041}
2042
e38def9c 2043\f
2044/* Various hooks for unwind library. */
2045
2046/* Expand the EH support builtin functions:
2047 __builtin_eh_pointer and __builtin_eh_filter. */
2048
2049static eh_region
2050expand_builtin_eh_common (tree region_nr_t)
2051{
2052 HOST_WIDE_INT region_nr;
2053 eh_region region;
2054
35ec552a 2055 gcc_assert (tree_fits_shwi_p (region_nr_t));
fcb97e84 2056 region_nr = tree_to_shwi (region_nr_t);
e38def9c 2057
f1f41a6c 2058 region = (*cfun->eh->region_array)[region_nr];
e38def9c 2059
2060 /* ??? We shouldn't have been able to delete a eh region without
2061 deleting all the code that depended on it. */
2062 gcc_assert (region != NULL);
2063
2064 return region;
2065}
2066
2067/* Expand to the exc_ptr value from the given eh region. */
2068
2069rtx
2070expand_builtin_eh_pointer (tree exp)
2071{
2072 eh_region region
2073 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
2074 if (region->exc_ptr_reg == NULL)
2075 region->exc_ptr_reg = gen_reg_rtx (ptr_mode);
2076 return region->exc_ptr_reg;
2077}
2078
2079/* Expand to the filter value from the given eh region. */
2080
2081rtx
2082expand_builtin_eh_filter (tree exp)
2083{
2084 eh_region region
2085 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
2086 if (region->filter_reg == NULL)
2087 region->filter_reg = gen_reg_rtx (targetm.eh_return_filter_mode ());
2088 return region->filter_reg;
2089}
2090
2091/* Copy the exc_ptr and filter values from one landing pad's registers
2092 to another. This is used to inline the resx statement. */
2093
2094rtx
2095expand_builtin_eh_copy_values (tree exp)
2096{
2097 eh_region dst
2098 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 0));
2099 eh_region src
2100 = expand_builtin_eh_common (CALL_EXPR_ARG (exp, 1));
2101 enum machine_mode fmode = targetm.eh_return_filter_mode ();
2102
2103 if (dst->exc_ptr_reg == NULL)
2104 dst->exc_ptr_reg = gen_reg_rtx (ptr_mode);
2105 if (src->exc_ptr_reg == NULL)
2106 src->exc_ptr_reg = gen_reg_rtx (ptr_mode);
2107
2108 if (dst->filter_reg == NULL)
2109 dst->filter_reg = gen_reg_rtx (fmode);
2110 if (src->filter_reg == NULL)
2111 src->filter_reg = gen_reg_rtx (fmode);
2112
2113 emit_move_insn (dst->exc_ptr_reg, src->exc_ptr_reg);
2114 emit_move_insn (dst->filter_reg, src->filter_reg);
2115
2116 return const0_rtx;
2117}
447a9eb9 2118
2119/* Do any necessary initialization to access arbitrary stack frames.
2120 On the SPARC, this means flushing the register windows. */
2121
2122void
35cb5232 2123expand_builtin_unwind_init (void)
447a9eb9 2124{
2125 /* Set this so all the registers get saved in our frame; we need to be
6312a35e 2126 able to copy the saved values for any registers from frames we unwind. */
18d50ae6 2127 crtl->saves_all_registers = 1;
447a9eb9 2128
2129#ifdef SETUP_FRAME_ADDRESSES
2130 SETUP_FRAME_ADDRESSES ();
2131#endif
2132}
2133
e38def9c 2134/* Map a non-negative number to an eh return data register number; expands
2135 to -1 if no return data register is associated with the input number.
2136 At least the inputs 0 and 1 must be mapped; the target may provide more. */
2137
df4b504c 2138rtx
c2f47e15 2139expand_builtin_eh_return_data_regno (tree exp)
df4b504c 2140{
c2f47e15 2141 tree which = CALL_EXPR_ARG (exp, 0);
df4b504c 2142 unsigned HOST_WIDE_INT iwhich;
2143
2144 if (TREE_CODE (which) != INTEGER_CST)
2145 {
eb586f2c 2146 error ("argument of %<__builtin_eh_return_regno%> must be constant");
df4b504c 2147 return constm1_rtx;
2148 }
2149
6a0712d4 2150 iwhich = tree_to_uhwi (which);
df4b504c 2151 iwhich = EH_RETURN_DATA_REGNO (iwhich);
2152 if (iwhich == INVALID_REGNUM)
2153 return constm1_rtx;
2154
2155#ifdef DWARF_FRAME_REGNUM
2156 iwhich = DWARF_FRAME_REGNUM (iwhich);
2157#else
2158 iwhich = DBX_REGISTER_NUMBER (iwhich);
2159#endif
2160
1ed5443b 2161 return GEN_INT (iwhich);
df4b504c 2162}
2163
447a9eb9 2164/* Given a value extracted from the return address register or stack slot,
2165 return the actual address encoded in that value. */
2166
2167rtx
35cb5232 2168expand_builtin_extract_return_addr (tree addr_tree)
447a9eb9 2169{
1db6d067 2170 rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
df4b504c 2171
52a14611 2172 if (GET_MODE (addr) != Pmode
2173 && GET_MODE (addr) != VOIDmode)
2174 {
2175#ifdef POINTERS_EXTEND_UNSIGNED
2176 addr = convert_memory_address (Pmode, addr);
2177#else
2178 addr = convert_to_mode (Pmode, addr, 0);
2179#endif
2180 }
2181
df4b504c 2182 /* First mask out any unwanted bits. */
2183#ifdef MASK_RETURN_ADDR
6de9716c 2184 expand_and (Pmode, addr, MASK_RETURN_ADDR, addr);
df4b504c 2185#endif
2186
2187 /* Then adjust to find the real return address. */
2188#if defined (RETURN_ADDR_OFFSET)
29c05e22 2189 addr = plus_constant (Pmode, addr, RETURN_ADDR_OFFSET);
df4b504c 2190#endif
2191
2192 return addr;
447a9eb9 2193}
2194
2195/* Given an actual address in addr_tree, do any necessary encoding
2196 and return the value to be stored in the return address register or
2197 stack slot so the epilogue will return to that address. */
2198
2199rtx
35cb5232 2200expand_builtin_frob_return_addr (tree addr_tree)
447a9eb9 2201{
1db6d067 2202 rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
df4b504c 2203
85d654dd 2204 addr = convert_memory_address (Pmode, addr);
be275a4a 2205
447a9eb9 2206#ifdef RETURN_ADDR_OFFSET
df4b504c 2207 addr = force_reg (Pmode, addr);
29c05e22 2208 addr = plus_constant (Pmode, addr, -RETURN_ADDR_OFFSET);
447a9eb9 2209#endif
df4b504c 2210
447a9eb9 2211 return addr;
2212}
2213
df4b504c 2214/* Set up the epilogue with the magic bits we'll need to return to the
2215 exception handler. */
447a9eb9 2216
df4b504c 2217void
35cb5232 2218expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED,
2219 tree handler_tree)
447a9eb9 2220{
cd4e2223 2221 rtx tmp;
447a9eb9 2222
cd4e2223 2223#ifdef EH_RETURN_STACKADJ_RTX
4dd3de56 2224 tmp = expand_expr (stackadj_tree, crtl->eh.ehr_stackadj,
1db6d067 2225 VOIDmode, EXPAND_NORMAL);
85d654dd 2226 tmp = convert_memory_address (Pmode, tmp);
4dd3de56 2227 if (!crtl->eh.ehr_stackadj)
2228 crtl->eh.ehr_stackadj = copy_to_reg (tmp);
2229 else if (tmp != crtl->eh.ehr_stackadj)
2230 emit_move_insn (crtl->eh.ehr_stackadj, tmp);
be275a4a 2231#endif
2232
4dd3de56 2233 tmp = expand_expr (handler_tree, crtl->eh.ehr_handler,
1db6d067 2234 VOIDmode, EXPAND_NORMAL);
85d654dd 2235 tmp = convert_memory_address (Pmode, tmp);
4dd3de56 2236 if (!crtl->eh.ehr_handler)
2237 crtl->eh.ehr_handler = copy_to_reg (tmp);
2238 else if (tmp != crtl->eh.ehr_handler)
2239 emit_move_insn (crtl->eh.ehr_handler, tmp);
447a9eb9 2240
4dd3de56 2241 if (!crtl->eh.ehr_label)
2242 crtl->eh.ehr_label = gen_label_rtx ();
2243 emit_jump (crtl->eh.ehr_label);
173f0bec 2244}
2245
e38def9c 2246/* Expand __builtin_eh_return. This exit path from the function loads up
2247 the eh return data registers, adjusts the stack, and branches to a
2248 given PC other than the normal return address. */
2249
ec37ccb4 2250void
35cb5232 2251expand_eh_return (void)
447a9eb9 2252{
cd4e2223 2253 rtx around_label;
447a9eb9 2254
4dd3de56 2255 if (! crtl->eh.ehr_label)
ec37ccb4 2256 return;
447a9eb9 2257
18d50ae6 2258 crtl->calls_eh_return = 1;
447a9eb9 2259
cd4e2223 2260#ifdef EH_RETURN_STACKADJ_RTX
2261 emit_move_insn (EH_RETURN_STACKADJ_RTX, const0_rtx);
2262#endif
2263
df4b504c 2264 around_label = gen_label_rtx ();
df4b504c 2265 emit_jump (around_label);
447a9eb9 2266
4dd3de56 2267 emit_label (crtl->eh.ehr_label);
df4b504c 2268 clobber_return_register ();
447a9eb9 2269
cd4e2223 2270#ifdef EH_RETURN_STACKADJ_RTX
4dd3de56 2271 emit_move_insn (EH_RETURN_STACKADJ_RTX, crtl->eh.ehr_stackadj);
cd4e2223 2272#endif
2273
df4b504c 2274#ifdef HAVE_eh_return
2275 if (HAVE_eh_return)
4dd3de56 2276 emit_insn (gen_eh_return (crtl->eh.ehr_handler));
df4b504c 2277 else
ec37ccb4 2278#endif
df4b504c 2279 {
cd4e2223 2280#ifdef EH_RETURN_HANDLER_RTX
4dd3de56 2281 emit_move_insn (EH_RETURN_HANDLER_RTX, crtl->eh.ehr_handler);
cd4e2223 2282#else
2283 error ("__builtin_eh_return not supported on this target");
2284#endif
df4b504c 2285 }
ec37ccb4 2286
df4b504c 2287 emit_label (around_label);
ec37ccb4 2288}
26093bf4 2289
2290/* Convert a ptr_mode address ADDR_TREE to a Pmode address controlled by
2291 POINTERS_EXTEND_UNSIGNED and return it. */
2292
2293rtx
2294expand_builtin_extend_pointer (tree addr_tree)
2295{
1db6d067 2296 rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, EXPAND_NORMAL);
26093bf4 2297 int extend;
2298
2299#ifdef POINTERS_EXTEND_UNSIGNED
2300 extend = POINTERS_EXTEND_UNSIGNED;
2301#else
2302 /* The previous EH code did an unsigned extend by default, so we do this also
2303 for consistency. */
2304 extend = 1;
2305#endif
2306
1bd43494 2307 return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend);
26093bf4 2308}
cac66fd5 2309\f
df4b504c 2310static int
d9dd21a8 2311add_action_record (action_hash_type ar_hash, int filter, int next)
cac66fd5 2312{
6659485c 2313 struct action_record **slot, *new_ar, tmp;
df4b504c 2314
2315 tmp.filter = filter;
2316 tmp.next = next;
d9dd21a8 2317 slot = ar_hash.find_slot (&tmp, INSERT);
cac66fd5 2318
6659485c 2319 if ((new_ar = *slot) == NULL)
cac66fd5 2320 {
6659485c 2321 new_ar = XNEW (struct action_record);
f1f41a6c 2322 new_ar->offset = crtl->eh.action_record_data->length () + 1;
6659485c 2323 new_ar->filter = filter;
2324 new_ar->next = next;
2325 *slot = new_ar;
df4b504c 2326
2327 /* The filter value goes in untouched. The link to the next
2328 record is a "self-relative" byte offset, or zero to indicate
2329 that there is no next record. So convert the absolute 1 based
4a82352a 2330 indices we've been carrying around into a displacement. */
df4b504c 2331
4dd3de56 2332 push_sleb128 (&crtl->eh.action_record_data, filter);
df4b504c 2333 if (next)
f1f41a6c 2334 next -= crtl->eh.action_record_data->length () + 1;
4dd3de56 2335 push_sleb128 (&crtl->eh.action_record_data, next);
cac66fd5 2336 }
cac66fd5 2337
6659485c 2338 return new_ar->offset;
df4b504c 2339}
cac66fd5 2340
df4b504c 2341static int
d9dd21a8 2342collect_one_action_chain (action_hash_type ar_hash, eh_region region)
cac66fd5 2343{
df4b504c 2344 int next;
cac66fd5 2345
df4b504c 2346 /* If we've reached the top of the region chain, then we have
2347 no actions, and require no landing pad. */
2348 if (region == NULL)
2349 return -1;
2350
2351 switch (region->type)
cac66fd5 2352 {
df4b504c 2353 case ERT_CLEANUP:
e38def9c 2354 {
2355 eh_region r;
2356 /* A cleanup adds a zero filter to the beginning of the chain, but
2357 there are special cases to look out for. If there are *only*
2358 cleanups along a path, then it compresses to a zero action.
2359 Further, if there are multiple cleanups along a path, we only
2360 need to represent one of them, as that is enough to trigger
2361 entry to the landing pad at runtime. */
2362 next = collect_one_action_chain (ar_hash, region->outer);
2363 if (next <= 0)
2364 return 0;
2365 for (r = region->outer; r ; r = r->outer)
2366 if (r->type == ERT_CLEANUP)
2367 return next;
2368 return add_action_record (ar_hash, 0, next);
2369 }
df4b504c 2370
2371 case ERT_TRY:
e38def9c 2372 {
2373 eh_catch c;
2374
2375 /* Process the associated catch regions in reverse order.
2376 If there's a catch-all handler, then we don't need to
2377 search outer regions. Use a magic -3 value to record
2378 that we haven't done the outer search. */
2379 next = -3;
2380 for (c = region->u.eh_try.last_catch; c ; c = c->prev_catch)
2381 {
2382 if (c->type_list == NULL)
2383 {
2384 /* Retrieve the filter from the head of the filter list
2385 where we have stored it (see assign_filter_values). */
2386 int filter = TREE_INT_CST_LOW (TREE_VALUE (c->filter_list));
2387 next = add_action_record (ar_hash, filter, 0);
2388 }
2389 else
2390 {
2391 /* Once the outer search is done, trigger an action record for
2392 each filter we have. */
2393 tree flt_node;
5c15c916 2394
e38def9c 2395 if (next == -3)
2396 {
2397 next = collect_one_action_chain (ar_hash, region->outer);
2398
2399 /* If there is no next action, terminate the chain. */
2400 if (next == -1)
2401 next = 0;
2402 /* If all outer actions are cleanups or must_not_throw,
2403 we'll have no action record for it, since we had wanted
2404 to encode these states in the call-site record directly.
2405 Add a cleanup action to the chain to catch these. */
2406 else if (next <= 0)
2407 next = add_action_record (ar_hash, 0, 0);
2408 }
1ed5443b 2409
e38def9c 2410 flt_node = c->filter_list;
2411 for (; flt_node; flt_node = TREE_CHAIN (flt_node))
2412 {
2413 int filter = TREE_INT_CST_LOW (TREE_VALUE (flt_node));
2414 next = add_action_record (ar_hash, filter, next);
2415 }
2416 }
2417 }
2418 return next;
2419 }
df4b504c 2420
2421 case ERT_ALLOWED_EXCEPTIONS:
2422 /* An exception specification adds its filter to the
2423 beginning of the chain. */
2424 next = collect_one_action_chain (ar_hash, region->outer);
3ec8c2a1 2425
2426 /* If there is no next action, terminate the chain. */
2427 if (next == -1)
2428 next = 0;
2429 /* If all outer actions are cleanups or must_not_throw,
2430 we'll have no action record for it, since we had wanted
2431 to encode these states in the call-site record directly.
2432 Add a cleanup action to the chain to catch these. */
2433 else if (next <= 0)
2434 next = add_action_record (ar_hash, 0, 0);
b215c058 2435
3ec8c2a1 2436 return add_action_record (ar_hash, region->u.allowed.filter, next);
df4b504c 2437
2438 case ERT_MUST_NOT_THROW:
2439 /* A must-not-throw region with no inner handlers or cleanups
2440 requires no call-site entry. Note that this differs from
2441 the no handler or cleanup case in that we do require an lsda
2442 to be generated. Return a magic -2 value to record this. */
2443 return -2;
cac66fd5 2444 }
e38def9c 2445
2446 gcc_unreachable ();
cac66fd5 2447}
2448
df4b504c 2449static int
33b1ed32 2450add_call_site (rtx landing_pad, int action, int section)
cac66fd5 2451{
4dd3de56 2452 call_site_record record;
e38def9c 2453
ba72912a 2454 record = ggc_alloc_call_site_record_d ();
4dd3de56 2455 record->landing_pad = landing_pad;
2456 record->action = action;
cac66fd5 2457
f1f41a6c 2458 vec_safe_push (crtl->eh.call_site_record_v[section], record);
cac66fd5 2459
f1f41a6c 2460 return call_site_base + crtl->eh.call_site_record_v[section]->length () - 1;
cac66fd5 2461}
2462
df4b504c 2463/* Turn REG_EH_REGION notes back into NOTE_INSN_EH_REGION notes.
2464 The new note numbers will not refer to region numbers, but
2465 instead to call site entries. */
cac66fd5 2466
e38def9c 2467static unsigned int
35cb5232 2468convert_to_eh_region_ranges (void)
cac66fd5 2469{
df4b504c 2470 rtx insn, iter, note;
d9dd21a8 2471 action_hash_type ar_hash;
df4b504c 2472 int last_action = -3;
2473 rtx last_action_insn = NULL_RTX;
2474 rtx last_landing_pad = NULL_RTX;
2475 rtx first_no_action_insn = NULL_RTX;
97b330ca 2476 int call_site = 0;
33b1ed32 2477 int cur_sec = 0;
2478 rtx section_switch_note = NULL_RTX;
2479 rtx first_no_action_insn_before_switch = NULL_RTX;
2480 rtx last_no_action_insn_before_switch = NULL_RTX;
33b1ed32 2481 int saved_call_site_base = call_site_base;
cac66fd5 2482
f1f41a6c 2483 vec_alloc (crtl->eh.action_record_data, 64);
cac66fd5 2484
d9dd21a8 2485 ar_hash.create (31);
cac66fd5 2486
df4b504c 2487 for (iter = get_insns (); iter ; iter = NEXT_INSN (iter))
2488 if (INSN_P (iter))
2489 {
e38def9c 2490 eh_landing_pad lp;
2491 eh_region region;
2492 bool nothrow;
df4b504c 2493 int this_action;
2494 rtx this_landing_pad;
cac66fd5 2495
df4b504c 2496 insn = iter;
6d7dc5b9 2497 if (NONJUMP_INSN_P (insn)
df4b504c 2498 && GET_CODE (PATTERN (insn)) == SEQUENCE)
2499 insn = XVECEXP (PATTERN (insn), 0, 0);
da5038a3 2500
e38def9c 2501 nothrow = get_eh_region_and_lp_from_rtx (insn, &region, &lp);
2502 if (nothrow)
2503 continue;
2504 if (region)
2505 this_action = collect_one_action_chain (ar_hash, region);
df4b504c 2506 else
e38def9c 2507 this_action = -1;
df4b504c 2508
2509 /* Existence of catch handlers, or must-not-throw regions
2510 implies that an lsda is needed (even if empty). */
2511 if (this_action != -1)
18d50ae6 2512 crtl->uses_eh_lsda = 1;
df4b504c 2513
2514 /* Delay creation of region notes for no-action regions
2515 until we're sure that an lsda will be required. */
2516 else if (last_action == -3)
2517 {
2518 first_no_action_insn = iter;
2519 last_action = -1;
2520 }
da5038a3 2521
df4b504c 2522 if (this_action >= 0)
e38def9c 2523 this_landing_pad = lp->landing_pad;
df4b504c 2524 else
2525 this_landing_pad = NULL_RTX;
da5038a3 2526
df4b504c 2527 /* Differing actions or landing pads implies a change in call-site
2528 info, which implies some EH_REGION note should be emitted. */
2529 if (last_action != this_action
2530 || last_landing_pad != this_landing_pad)
2531 {
e30ff7b1 2532 /* If there is a queued no-action region in the other section
2533 with hot/cold partitioning, emit it now. */
2534 if (first_no_action_insn_before_switch)
2535 {
2536 gcc_assert (this_action != -1
2537 && last_action == (first_no_action_insn
2538 ? -1 : -3));
2539 call_site = add_call_site (NULL_RTX, 0, 0);
2540 note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
2541 first_no_action_insn_before_switch);
2542 NOTE_EH_HANDLER (note) = call_site;
2543 note = emit_note_after (NOTE_INSN_EH_REGION_END,
2544 last_no_action_insn_before_switch);
2545 NOTE_EH_HANDLER (note) = call_site;
2546 gcc_assert (last_action != -3
2547 || (last_action_insn
2548 == last_no_action_insn_before_switch));
2549 first_no_action_insn_before_switch = NULL_RTX;
2550 last_no_action_insn_before_switch = NULL_RTX;
2551 call_site_base++;
2552 }
df4b504c 2553 /* If we'd not seen a previous action (-3) or the previous
2554 action was must-not-throw (-2), then we do not need an
2555 end note. */
2556 if (last_action >= -1)
2557 {
2558 /* If we delayed the creation of the begin, do it now. */
2559 if (first_no_action_insn)
2560 {
33b1ed32 2561 call_site = add_call_site (NULL_RTX, 0, cur_sec);
df4b504c 2562 note = emit_note_before (NOTE_INSN_EH_REGION_BEG,
2563 first_no_action_insn);
2564 NOTE_EH_HANDLER (note) = call_site;
2565 first_no_action_insn = NULL_RTX;
2566 }
2567
2568 note = emit_note_after (NOTE_INSN_EH_REGION_END,
2569 last_action_insn);
2570 NOTE_EH_HANDLER (note) = call_site;
2571 }
2572
2573 /* If the new action is must-not-throw, then no region notes
2574 are created. */
2575 if (this_action >= -1)
2576 {
1ed5443b 2577 call_site = add_call_site (this_landing_pad,
33b1ed32 2578 this_action < 0 ? 0 : this_action,
2579 cur_sec);
df4b504c 2580 note = emit_note_before (NOTE_INSN_EH_REGION_BEG, iter);
2581 NOTE_EH_HANDLER (note) = call_site;
2582 }
2583
2584 last_action = this_action;
2585 last_landing_pad = this_landing_pad;
2586 }
2587 last_action_insn = iter;
2588 }
33b1ed32 2589 else if (NOTE_P (iter)
2590 && NOTE_KIND (iter) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
2591 {
2592 gcc_assert (section_switch_note == NULL_RTX);
2593 gcc_assert (flag_reorder_blocks_and_partition);
2594 section_switch_note = iter;
2595 if (first_no_action_insn)
2596 {
2597 first_no_action_insn_before_switch = first_no_action_insn;
2598 last_no_action_insn_before_switch = last_action_insn;
2599 first_no_action_insn = NULL_RTX;
2600 gcc_assert (last_action == -1);
2601 last_action = -3;
2602 }
2603 /* Force closing of current EH region before section switch and
2604 opening a new one afterwards. */
2605 else if (last_action != -3)
2606 last_landing_pad = pc_rtx;
f1f41a6c 2607 if (crtl->eh.call_site_record_v[cur_sec])
2608 call_site_base += crtl->eh.call_site_record_v[cur_sec]->length ();
33b1ed32 2609 cur_sec++;
2b15d2ba 2610 gcc_assert (crtl->eh.call_site_record_v[cur_sec] == NULL);
f1f41a6c 2611 vec_alloc (crtl->eh.call_site_record_v[cur_sec], 10);
33b1ed32 2612 }
da5038a3 2613
df4b504c 2614 if (last_action >= -1 && ! first_no_action_insn)
da5038a3 2615 {
df4b504c 2616 note = emit_note_after (NOTE_INSN_EH_REGION_END, last_action_insn);
2617 NOTE_EH_HANDLER (note) = call_site;
da5038a3 2618 }
2619
33b1ed32 2620 call_site_base = saved_call_site_base;
2621
d9dd21a8 2622 ar_hash.dispose ();
2a1990e9 2623 return 0;
df4b504c 2624}
da5038a3 2625
e38def9c 2626static bool
2627gate_convert_to_eh_region_ranges (void)
2628{
2629 /* Nothing to do for SJLJ exceptions or if no regions created. */
de2ca00d 2630 if (cfun->eh->region_tree == NULL)
2631 return false;
218e3e4e 2632 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
cc7d6aed 2633 return false;
2634 return true;
e38def9c 2635}
2636
cbe8bda8 2637namespace {
2638
2639const pass_data pass_data_convert_to_eh_region_ranges =
2640{
2641 RTL_PASS, /* type */
2642 "eh_ranges", /* name */
2643 OPTGROUP_NONE, /* optinfo_flags */
2644 true, /* has_gate */
2645 true, /* has_execute */
2646 TV_NONE, /* tv_id */
2647 0, /* properties_required */
2648 0, /* properties_provided */
2649 0, /* properties_destroyed */
2650 0, /* todo_flags_start */
2651 0, /* todo_flags_finish */
77fce4cd 2652};
cbe8bda8 2653
2654class pass_convert_to_eh_region_ranges : public rtl_opt_pass
2655{
2656public:
9af5ce0c 2657 pass_convert_to_eh_region_ranges (gcc::context *ctxt)
2658 : rtl_opt_pass (pass_data_convert_to_eh_region_ranges, ctxt)
cbe8bda8 2659 {}
2660
2661 /* opt_pass methods: */
2662 bool gate () { return gate_convert_to_eh_region_ranges (); }
2663 unsigned int execute () { return convert_to_eh_region_ranges (); }
2664
2665}; // class pass_convert_to_eh_region_ranges
2666
2667} // anon namespace
2668
2669rtl_opt_pass *
2670make_pass_convert_to_eh_region_ranges (gcc::context *ctxt)
2671{
2672 return new pass_convert_to_eh_region_ranges (ctxt);
2673}
df4b504c 2674\f
2675static void
f1f41a6c 2676push_uleb128 (vec<uchar, va_gc> **data_area, unsigned int value)
df4b504c 2677{
2678 do
2679 {
2680 unsigned char byte = value & 0x7f;
2681 value >>= 7;
2682 if (value)
2683 byte |= 0x80;
f1f41a6c 2684 vec_safe_push (*data_area, byte);
df4b504c 2685 }
2686 while (value);
2687}
da5038a3 2688
df4b504c 2689static void
f1f41a6c 2690push_sleb128 (vec<uchar, va_gc> **data_area, int value)
df4b504c 2691{
2692 unsigned char byte;
2693 int more;
da5038a3 2694
df4b504c 2695 do
da5038a3 2696 {
df4b504c 2697 byte = value & 0x7f;
2698 value >>= 7;
2699 more = ! ((value == 0 && (byte & 0x40) == 0)
2700 || (value == -1 && (byte & 0x40) != 0));
2701 if (more)
2702 byte |= 0x80;
f1f41a6c 2703 vec_safe_push (*data_area, byte);
da5038a3 2704 }
df4b504c 2705 while (more);
2706}
da5038a3 2707
df4b504c 2708\f
df4b504c 2709#ifndef HAVE_AS_LEB128
2710static int
33b1ed32 2711dw2_size_of_call_site_table (int section)
da5038a3 2712{
f1f41a6c 2713 int n = vec_safe_length (crtl->eh.call_site_record_v[section]);
df4b504c 2714 int size = n * (4 + 4 + 4);
2715 int i;
da5038a3 2716
df4b504c 2717 for (i = 0; i < n; ++i)
2718 {
26dbec0a 2719 struct call_site_record_d *cs =
f1f41a6c 2720 (*crtl->eh.call_site_record_v[section])[i];
df4b504c 2721 size += size_of_uleb128 (cs->action);
2722 }
8b4f3d64 2723
df4b504c 2724 return size;
2725}
2726
2727static int
35cb5232 2728sjlj_size_of_call_site_table (void)
df4b504c 2729{
f1f41a6c 2730 int n = vec_safe_length (crtl->eh.call_site_record_v[0]);
df4b504c 2731 int size = 0;
2732 int i;
cac66fd5 2733
df4b504c 2734 for (i = 0; i < n; ++i)
da5038a3 2735 {
26dbec0a 2736 struct call_site_record_d *cs =
f1f41a6c 2737 (*crtl->eh.call_site_record_v[0])[i];
df4b504c 2738 size += size_of_uleb128 (INTVAL (cs->landing_pad));
2739 size += size_of_uleb128 (cs->action);
da5038a3 2740 }
df4b504c 2741
2742 return size;
2743}
2744#endif
2745
2746static void
33b1ed32 2747dw2_output_call_site_table (int cs_format, int section)
df4b504c 2748{
f1f41a6c 2749 int n = vec_safe_length (crtl->eh.call_site_record_v[section]);
df4b504c 2750 int i;
33b1ed32 2751 const char *begin;
2752
2753 if (section == 0)
2754 begin = current_function_func_begin_label;
2755 else if (first_function_block_is_cold)
2756 begin = crtl->subsections.hot_section_label;
2757 else
2758 begin = crtl->subsections.cold_section_label;
df4b504c 2759
2760 for (i = 0; i < n; ++i)
da5038a3 2761 {
f1f41a6c 2762 struct call_site_record_d *cs = (*crtl->eh.call_site_record_v[section])[i];
df4b504c 2763 char reg_start_lab[32];
2764 char reg_end_lab[32];
2765 char landing_pad_lab[32];
2766
2767 ASM_GENERATE_INTERNAL_LABEL (reg_start_lab, "LEHB", call_site_base + i);
2768 ASM_GENERATE_INTERNAL_LABEL (reg_end_lab, "LEHE", call_site_base + i);
2769
2770 if (cs->landing_pad)
2771 ASM_GENERATE_INTERNAL_LABEL (landing_pad_lab, "L",
2772 CODE_LABEL_NUMBER (cs->landing_pad));
2773
2774 /* ??? Perhaps use insn length scaling if the assembler supports
2775 generic arithmetic. */
2776 /* ??? Perhaps use attr_length to choose data1 or data2 instead of
2777 data4 if the function is small enough. */
33b1ed32 2778 if (cs_format == DW_EH_PE_uleb128)
2779 {
2780 dw2_asm_output_delta_uleb128 (reg_start_lab, begin,
2781 "region %d start", i);
2782 dw2_asm_output_delta_uleb128 (reg_end_lab, reg_start_lab,
2783 "length");
2784 if (cs->landing_pad)
2785 dw2_asm_output_delta_uleb128 (landing_pad_lab, begin,
2786 "landing pad");
2787 else
2788 dw2_asm_output_data_uleb128 (0, "landing pad");
2789 }
df4b504c 2790 else
33b1ed32 2791 {
2792 dw2_asm_output_delta (4, reg_start_lab, begin,
2793 "region %d start", i);
2794 dw2_asm_output_delta (4, reg_end_lab, reg_start_lab, "length");
2795 if (cs->landing_pad)
2796 dw2_asm_output_delta (4, landing_pad_lab, begin,
2797 "landing pad");
2798 else
2799 dw2_asm_output_data (4, 0, "landing pad");
2800 }
df4b504c 2801 dw2_asm_output_data_uleb128 (cs->action, "action");
da5038a3 2802 }
2803
df4b504c 2804 call_site_base += n;
2805}
2806
2807static void
35cb5232 2808sjlj_output_call_site_table (void)
df4b504c 2809{
f1f41a6c 2810 int n = vec_safe_length (crtl->eh.call_site_record_v[0]);
df4b504c 2811 int i;
da5038a3 2812
df4b504c 2813 for (i = 0; i < n; ++i)
da5038a3 2814 {
f1f41a6c 2815 struct call_site_record_d *cs = (*crtl->eh.call_site_record_v[0])[i];
b9cf3f63 2816
df4b504c 2817 dw2_asm_output_data_uleb128 (INTVAL (cs->landing_pad),
2818 "region %d landing pad", i);
2819 dw2_asm_output_data_uleb128 (cs->action, "action");
2820 }
b9cf3f63 2821
df4b504c 2822 call_site_base += n;
da5038a3 2823}
2824
2943ce06 2825/* Switch to the section that should be used for exception tables. */
d5720b0c 2826
2943ce06 2827static void
0a011112 2828switch_to_exception_section (const char * ARG_UNUSED (fnname))
d5720b0c 2829{
f1d76faf 2830 section *s;
2831
2832 if (exception_section)
2833 s = exception_section;
2834 else
d5720b0c 2835 {
f1d76faf 2836 /* Compute the section and cache it into exception_section,
2837 unless it depends on the function name. */
218e3e4e 2838 if (targetm_common.have_named_sections)
51601538 2839 {
2943ce06 2840 int flags;
2841
2842 if (EH_TABLES_CAN_BE_READ_ONLY)
2843 {
2844 int tt_format =
2845 ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
2846 flags = ((! flag_pic
2847 || ((tt_format & 0x70) != DW_EH_PE_absptr
2848 && (tt_format & 0x70) != DW_EH_PE_aligned))
2849 ? 0 : SECTION_WRITE);
2850 }
2851 else
2852 flags = SECTION_WRITE;
f1d76faf 2853
0a011112 2854#ifdef HAVE_LD_EH_GC_SECTIONS
1b15c18e 2855 if (flag_function_sections
2856 || (DECL_ONE_ONLY (current_function_decl) && HAVE_COMDAT_GROUP))
0a011112 2857 {
2457c754 2858 char *section_name = XNEWVEC (char, strlen (fnname) + 32);
1b15c18e 2859 /* The EH table must match the code section, so only mark
2860 it linkonce if we have COMDAT groups to tie them together. */
2861 if (DECL_ONE_ONLY (current_function_decl) && HAVE_COMDAT_GROUP)
2862 flags |= SECTION_LINKONCE;
0a011112 2863 sprintf (section_name, ".gcc_except_table.%s", fnname);
1b15c18e 2864 s = get_section (section_name, flags, current_function_decl);
0a011112 2865 free (section_name);
2866 }
2867 else
2868#endif
f1d76faf 2869 exception_section
2870 = s = get_section (".gcc_except_table", flags, NULL);
51601538 2871 }
2872 else
f1d76faf 2873 exception_section
2874 = s = flag_pic ? data_section : readonly_data_section;
d5720b0c 2875 }
f1d76faf 2876
2877 switch_to_section (s);
d5720b0c 2878}
2879
1774763d 2880
2881/* Output a reference from an exception table to the type_info object TYPE.
554f2707 2882 TT_FORMAT and TT_FORMAT_SIZE describe the DWARF encoding method used for
1774763d 2883 the value. */
2884
2885static void
2886output_ttype (tree type, int tt_format, int tt_format_size)
2887{
2888 rtx value;
6659485c 2889 bool is_public = true;
1774763d 2890
2891 if (type == NULL_TREE)
2892 value = const0_rtx;
2893 else
2894 {
7bfefa9d 2895 /* FIXME lto. pass_ipa_free_lang_data changes all types to
2896 runtime types so TYPE should already be a runtime type
2897 reference. When pass_ipa_free_lang data is made a default
2898 pass, we can then remove the call to lookup_type_for_runtime
2899 below. */
2900 if (TYPE_P (type))
2901 type = lookup_type_for_runtime (type);
2902
3669a8aa 2903 value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
1774763d 2904
2905 /* Let cgraph know that the rtti decl is used. Not all of the
2906 paths below go through assemble_integer, which would take
2907 care of this for us. */
2908 STRIP_NOPS (type);
2909 if (TREE_CODE (type) == ADDR_EXPR)
2910 {
2911 type = TREE_OPERAND (type, 0);
2912 if (TREE_CODE (type) == VAR_DECL)
ff2a5ada 2913 is_public = TREE_PUBLIC (type);
1774763d 2914 }
6276113b 2915 else
2916 gcc_assert (TREE_CODE (type) == INTEGER_CST);
1774763d 2917 }
2918
2919 /* Allow the target to override the type table entry format. */
2920 if (targetm.asm_out.ttype (value))
2921 return;
2922
2923 if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
2924 assemble_integer (value, tt_format_size,
2925 tt_format_size * BITS_PER_UNIT, 1);
2926 else
6659485c 2927 dw2_asm_output_encoded_addr_rtx (tt_format, value, is_public, NULL);
1774763d 2928}
2929
33b1ed32 2930static void
37966699 2931output_one_function_exception_table (int section)
df4b504c 2932{
e38def9c 2933 int tt_format, cs_format, lp_format, i;
df4b504c 2934#ifdef HAVE_AS_LEB128
2935 char ttype_label[32];
2936 char cs_after_size_label[32];
2937 char cs_end_label[32];
2938#else
2939 int call_site_len;
2940#endif
2941 int have_tt_data;
97b330ca 2942 int tt_format_size = 0;
da5038a3 2943
f1f41a6c 2944 have_tt_data = (vec_safe_length (cfun->eh->ttype_data)
e38def9c 2945 || (targetm.arm_eabi_unwinder
f1f41a6c 2946 ? vec_safe_length (cfun->eh->ehspec_data.arm_eabi)
2947 : vec_safe_length (cfun->eh->ehspec_data.other)));
df4b504c 2948
631413ff 2949 /* Indicate the format of the @TType entries. */
2950 if (! have_tt_data)
2951 tt_format = DW_EH_PE_omit;
2952 else
2953 {
2954 tt_format = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/1);
2955#ifdef HAVE_AS_LEB128
33b1ed32 2956 ASM_GENERATE_INTERNAL_LABEL (ttype_label,
2957 section ? "LLSDATTC" : "LLSDATT",
4781f9b9 2958 current_function_funcdef_no);
631413ff 2959#endif
2960 tt_format_size = size_of_encoded_value (tt_format);
2961
4aa1f91c 2962 assemble_align (tt_format_size * BITS_PER_UNIT);
631413ff 2963 }
df4b504c 2964
33b1ed32 2965 targetm.asm_out.internal_label (asm_out_file, section ? "LLSDAC" : "LLSDA",
2966 current_function_funcdef_no);
df4b504c 2967
2968 /* The LSDA header. */
2969
2970 /* Indicate the format of the landing pad start pointer. An omitted
2971 field implies @LPStart == @Start. */
2972 /* Currently we always put @LPStart == @Start. This field would
2973 be most useful in moving the landing pads completely out of
2974 line to another section, but it could also be used to minimize
2975 the size of uleb128 landing pad offsets. */
ad5818ae 2976 lp_format = DW_EH_PE_omit;
2977 dw2_asm_output_data (1, lp_format, "@LPStart format (%s)",
2978 eh_data_format_name (lp_format));
df4b504c 2979
2980 /* @LPStart pointer would go here. */
2981
ad5818ae 2982 dw2_asm_output_data (1, tt_format, "@TType format (%s)",
2983 eh_data_format_name (tt_format));
df4b504c 2984
2985#ifndef HAVE_AS_LEB128
218e3e4e 2986 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
df4b504c 2987 call_site_len = sjlj_size_of_call_site_table ();
2988 else
33b1ed32 2989 call_site_len = dw2_size_of_call_site_table (section);
df4b504c 2990#endif
2991
2992 /* A pc-relative 4-byte displacement to the @TType data. */
2993 if (have_tt_data)
2994 {
2995#ifdef HAVE_AS_LEB128
2996 char ttype_after_disp_label[32];
33b1ed32 2997 ASM_GENERATE_INTERNAL_LABEL (ttype_after_disp_label,
2998 section ? "LLSDATTDC" : "LLSDATTD",
4781f9b9 2999 current_function_funcdef_no);
df4b504c 3000 dw2_asm_output_delta_uleb128 (ttype_label, ttype_after_disp_label,
3001 "@TType base offset");
3002 ASM_OUTPUT_LABEL (asm_out_file, ttype_after_disp_label);
3003#else
3004 /* Ug. Alignment queers things. */
631413ff 3005 unsigned int before_disp, after_disp, last_disp, disp;
df4b504c 3006
df4b504c 3007 before_disp = 1 + 1;
3008 after_disp = (1 + size_of_uleb128 (call_site_len)
3009 + call_site_len
f1f41a6c 3010 + vec_safe_length (crtl->eh.action_record_data)
3011 + (vec_safe_length (cfun->eh->ttype_data)
631413ff 3012 * tt_format_size));
df4b504c 3013
3014 disp = after_disp;
3015 do
da5038a3 3016 {
df4b504c 3017 unsigned int disp_size, pad;
3018
3019 last_disp = disp;
3020 disp_size = size_of_uleb128 (disp);
3021 pad = before_disp + disp_size + after_disp;
631413ff 3022 if (pad % tt_format_size)
3023 pad = tt_format_size - (pad % tt_format_size);
df4b504c 3024 else
3025 pad = 0;
3026 disp = after_disp + pad;
da5038a3 3027 }
df4b504c 3028 while (disp != last_disp);
3029
3030 dw2_asm_output_data_uleb128 (disp, "@TType base offset");
3031#endif
da5038a3 3032 }
da5038a3 3033
df4b504c 3034 /* Indicate the format of the call-site offsets. */
3035#ifdef HAVE_AS_LEB128
ad5818ae 3036 cs_format = DW_EH_PE_uleb128;
df4b504c 3037#else
ad5818ae 3038 cs_format = DW_EH_PE_udata4;
df4b504c 3039#endif
ad5818ae 3040 dw2_asm_output_data (1, cs_format, "call-site format (%s)",
3041 eh_data_format_name (cs_format));
df4b504c 3042
3043#ifdef HAVE_AS_LEB128
33b1ed32 3044 ASM_GENERATE_INTERNAL_LABEL (cs_after_size_label,
3045 section ? "LLSDACSBC" : "LLSDACSB",
4781f9b9 3046 current_function_funcdef_no);
33b1ed32 3047 ASM_GENERATE_INTERNAL_LABEL (cs_end_label,
3048 section ? "LLSDACSEC" : "LLSDACSE",
4781f9b9 3049 current_function_funcdef_no);
df4b504c 3050 dw2_asm_output_delta_uleb128 (cs_end_label, cs_after_size_label,
3051 "Call-site table length");
3052 ASM_OUTPUT_LABEL (asm_out_file, cs_after_size_label);
218e3e4e 3053 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
df4b504c 3054 sjlj_output_call_site_table ();
3055 else
33b1ed32 3056 dw2_output_call_site_table (cs_format, section);
df4b504c 3057 ASM_OUTPUT_LABEL (asm_out_file, cs_end_label);
3058#else
33b1ed32 3059 dw2_asm_output_data_uleb128 (call_site_len, "Call-site table length");
218e3e4e 3060 if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
df4b504c 3061 sjlj_output_call_site_table ();
3062 else
33b1ed32 3063 dw2_output_call_site_table (cs_format, section);
df4b504c 3064#endif
3065
3066 /* ??? Decode and interpret the data for flag_debug_asm. */
e38def9c 3067 {
3068 uchar uc;
f1f41a6c 3069 FOR_EACH_VEC_ELT (*crtl->eh.action_record_data, i, uc)
e38def9c 3070 dw2_asm_output_data (1, uc, i ? NULL : "Action record table");
3071 }
da5038a3 3072
df4b504c 3073 if (have_tt_data)
4aa1f91c 3074 assemble_align (tt_format_size * BITS_PER_UNIT);
da5038a3 3075
f1f41a6c 3076 i = vec_safe_length (cfun->eh->ttype_data);
df4b504c 3077 while (i-- > 0)
da5038a3 3078 {
f1f41a6c 3079 tree type = (*cfun->eh->ttype_data)[i];
1774763d 3080 output_ttype (type, tt_format, tt_format_size);
da5038a3 3081 }
df4b504c 3082
3083#ifdef HAVE_AS_LEB128
3084 if (have_tt_data)
3085 ASM_OUTPUT_LABEL (asm_out_file, ttype_label);
3086#endif
3087
3088 /* ??? Decode and interpret the data for flag_debug_asm. */
e38def9c 3089 if (targetm.arm_eabi_unwinder)
1774763d 3090 {
e38def9c 3091 tree type;
3092 for (i = 0;
f1f41a6c 3093 vec_safe_iterate (cfun->eh->ehspec_data.arm_eabi, i, &type); ++i)
e38def9c 3094 output_ttype (type, tt_format, tt_format_size);
3095 }
3096 else
3097 {
3098 uchar uc;
3099 for (i = 0;
f1f41a6c 3100 vec_safe_iterate (cfun->eh->ehspec_data.other, i, &uc); ++i)
e38def9c 3101 dw2_asm_output_data (1, uc,
3102 i ? NULL : "Exception specification table");
1774763d 3103 }
33b1ed32 3104}
3105
3106void
37966699 3107output_function_exception_table (const char *fnname)
33b1ed32 3108{
58d82cd0 3109 rtx personality = get_personality_function (current_function_decl);
3110
33b1ed32 3111 /* Not all functions need anything. */
3112 if (! crtl->uses_eh_lsda)
3113 return;
3114
58d82cd0 3115 if (personality)
37966699 3116 {
3117 assemble_external_libcall (personality);
3118
3119 if (targetm.asm_out.emit_except_personality)
3120 targetm.asm_out.emit_except_personality (personality);
3121 }
3122
3123 switch_to_exception_section (fnname);
3124
3125 /* If the target wants a label to begin the table, emit it here. */
3126 targetm.asm_out.emit_except_table_label (asm_out_file);
33b1ed32 3127
37966699 3128 output_one_function_exception_table (0);
f1f41a6c 3129 if (crtl->eh.call_site_record_v[1])
37966699 3130 output_one_function_exception_table (1);
df4b504c 3131
2f14b1f9 3132 switch_to_section (current_function_section ());
da5038a3 3133}
1f3233d1 3134
b3f1469f 3135void
3136set_eh_throw_stmt_table (struct function *fun, struct htab *table)
3137{
3138 fun->eh->throw_stmt_table = table;
3139}
3140
3141htab_t
3142get_eh_throw_stmt_table (struct function *fun)
3143{
3144 return fun->eh->throw_stmt_table;
3145}
e38def9c 3146\f
3147/* Determine if the function needs an EH personality function. */
58d82cd0 3148
3149enum eh_personality_kind
3150function_needs_eh_personality (struct function *fn)
3151{
58d82cd0 3152 enum eh_personality_kind kind = eh_personality_none;
e38def9c 3153 eh_region i;
58d82cd0 3154
e38def9c 3155 FOR_ALL_EH_REGION_FN (i, fn)
58d82cd0 3156 {
3157 switch (i->type)
3158 {
58d82cd0 3159 case ERT_CLEANUP:
3160 /* Can do with any personality including the generic C one. */
3161 kind = eh_personality_any;
3162 break;
3163
e38def9c 3164 case ERT_TRY:
58d82cd0 3165 case ERT_ALLOWED_EXCEPTIONS:
3166 /* Always needs a EH personality function. The generic C
3167 personality doesn't handle these even for empty type lists. */
3168 return eh_personality_lang;
3169
e38def9c 3170 case ERT_MUST_NOT_THROW:
3171 /* Always needs a EH personality function. The language may specify
3172 what abort routine that must be used, e.g. std::terminate. */
58d82cd0 3173 return eh_personality_lang;
3174 }
58d82cd0 3175 }
3176
3177 return kind;
3178}
e38def9c 3179\f
b4ba5e9d 3180/* Dump EH information to OUT. */
bb22691b 3181
b215c058 3182void
bb22691b 3183dump_eh_tree (FILE * out, struct function *fun)
b4ba5e9d 3184{
e38def9c 3185 eh_region i;
b4ba5e9d 3186 int depth = 0;
e38def9c 3187 static const char *const type_name[] = {
3188 "cleanup", "try", "allowed_exceptions", "must_not_throw"
3189 };
b4ba5e9d 3190
3191 i = fun->eh->region_tree;
bb22691b 3192 if (!i)
b4ba5e9d 3193 return;
3194
3195 fprintf (out, "Eh tree:\n");
3196 while (1)
3197 {
3198 fprintf (out, " %*s %i %s", depth * 2, "",
e38def9c 3199 i->index, type_name[(int) i->type]);
3200
3201 if (i->landing_pads)
98b64106 3202 {
e38def9c 3203 eh_landing_pad lp;
3204
3205 fprintf (out, " land:");
3206 if (current_ir_type () == IR_GIMPLE)
3207 {
3208 for (lp = i->landing_pads; lp ; lp = lp->next_lp)
3209 {
3210 fprintf (out, "{%i,", lp->index);
3211 print_generic_expr (out, lp->post_landing_pad, 0);
3212 fputc ('}', out);
3213 if (lp->next_lp)
3214 fputc (',', out);
3215 }
3216 }
3217 else
504e084a 3218 {
6b8f34b9 3219 for (lp = i->landing_pads; lp ; lp = lp->next_lp)
e38def9c 3220 {
3221 fprintf (out, "{%i,", lp->index);
3222 if (lp->landing_pad)
3223 fprintf (out, "%i%s,", INSN_UID (lp->landing_pad),
3224 NOTE_P (lp->landing_pad) ? "(del)" : "");
3225 else
3226 fprintf (out, "(nil),");
3227 if (lp->post_landing_pad)
3228 {
3229 rtx lab = label_rtx (lp->post_landing_pad);
3230 fprintf (out, "%i%s}", INSN_UID (lab),
3231 NOTE_P (lab) ? "(del)" : "");
3232 }
3233 else
3234 fprintf (out, "(nil)}");
3235 if (lp->next_lp)
3236 fputc (',', out);
3237 }
504e084a 3238 }
98b64106 3239 }
e38def9c 3240
bb22691b 3241 switch (i->type)
3242 {
3243 case ERT_CLEANUP:
e38def9c 3244 case ERT_MUST_NOT_THROW:
bb22691b 3245 break;
3246
3247 case ERT_TRY:
3248 {
e38def9c 3249 eh_catch c;
3250 fprintf (out, " catch:");
3251 for (c = i->u.eh_try.first_catch; c; c = c->next_catch)
3252 {
3253 fputc ('{', out);
3254 if (c->label)
3255 {
3256 fprintf (out, "lab:");
3257 print_generic_expr (out, c->label, 0);
3258 fputc (';', out);
3259 }
3260 print_generic_expr (out, c->type_list, 0);
3261 fputc ('}', out);
3262 if (c->next_catch)
3263 fputc (',', out);
3264 }
bb22691b 3265 }
3266 break;
3267
bb22691b 3268 case ERT_ALLOWED_EXCEPTIONS:
98b64106 3269 fprintf (out, " filter :%i types:", i->u.allowed.filter);
bb22691b 3270 print_generic_expr (out, i->u.allowed.type_list, 0);
3271 break;
bb22691b 3272 }
e38def9c 3273 fputc ('\n', out);
3274
b4ba5e9d 3275 /* If there are sub-regions, process them. */
3276 if (i->inner)
3277 i = i->inner, depth++;
3278 /* If there are peers, process them. */
3279 else if (i->next_peer)
3280 i = i->next_peer;
3281 /* Otherwise, step back up the tree to the next peer. */
3282 else
3283 {
bb22691b 3284 do
3285 {
3286 i = i->outer;
3287 depth--;
3288 if (i == NULL)
3289 return;
3290 }
3291 while (i->next_peer == NULL);
b4ba5e9d 3292 i = i->next_peer;
3293 }
3294 }
3295}
3296
576cc2fe 3297/* Dump the EH tree for FN on stderr. */
3298
4b987fac 3299DEBUG_FUNCTION void
576cc2fe 3300debug_eh_tree (struct function *fn)
3301{
3302 dump_eh_tree (stderr, fn);
3303}
3304
98b64106 3305/* Verify invariants on EH datastructures. */
3306
4b987fac 3307DEBUG_FUNCTION void
b4ba5e9d 3308verify_eh_tree (struct function *fun)
3309{
e38def9c 3310 eh_region r, outer;
3311 int nvisited_lp, nvisited_r;
3312 int count_lp, count_r, depth, i;
3313 eh_landing_pad lp;
b4ba5e9d 3314 bool err = false;
b4ba5e9d 3315
b8c0c866 3316 if (!fun->eh->region_tree)
b4ba5e9d 3317 return;
e38def9c 3318
3319 count_r = 0;
f1f41a6c 3320 for (i = 1; vec_safe_iterate (fun->eh->region_array, i, &r); ++i)
e38def9c 3321 if (r)
b4ba5e9d 3322 {
e38def9c 3323 if (r->index == i)
3324 count_r++;
3325 else
b4ba5e9d 3326 {
e38def9c 3327 error ("region_array is corrupted for region %i", r->index);
b4ba5e9d 3328 err = true;
3329 }
3330 }
3331
e38def9c 3332 count_lp = 0;
f1f41a6c 3333 for (i = 1; vec_safe_iterate (fun->eh->lp_array, i, &lp); ++i)
e38def9c 3334 if (lp)
3335 {
3336 if (lp->index == i)
3337 count_lp++;
3338 else
3339 {
3340 error ("lp_array is corrupted for lp %i", lp->index);
3341 err = true;
3342 }
3343 }
3344
3345 depth = nvisited_lp = nvisited_r = 0;
3346 outer = NULL;
3347 r = fun->eh->region_tree;
b4ba5e9d 3348 while (1)
3349 {
f1f41a6c 3350 if ((*fun->eh->region_array)[r->index] != r)
b4ba5e9d 3351 {
e38def9c 3352 error ("region_array is corrupted for region %i", r->index);
b4ba5e9d 3353 err = true;
3354 }
e38def9c 3355 if (r->outer != outer)
b4ba5e9d 3356 {
e38def9c 3357 error ("outer block of region %i is wrong", r->index);
b4ba5e9d 3358 err = true;
3359 }
e38def9c 3360 if (depth < 0)
b4ba5e9d 3361 {
e38def9c 3362 error ("negative nesting depth of region %i", r->index);
b4ba5e9d 3363 err = true;
3364 }
e38def9c 3365 nvisited_r++;
3366
3367 for (lp = r->landing_pads; lp ; lp = lp->next_lp)
b4ba5e9d 3368 {
f1f41a6c 3369 if ((*fun->eh->lp_array)[lp->index] != lp)
e38def9c 3370 {
3371 error ("lp_array is corrupted for lp %i", lp->index);
3372 err = true;
3373 }
3374 if (lp->region != r)
3375 {
3376 error ("region of lp %i is wrong", lp->index);
3377 err = true;
3378 }
3379 nvisited_lp++;
b4ba5e9d 3380 }
e38def9c 3381
3382 if (r->inner)
3383 outer = r, r = r->inner, depth++;
3384 else if (r->next_peer)
3385 r = r->next_peer;
b4ba5e9d 3386 else
3387 {
b8c0c866 3388 do
3389 {
e38def9c 3390 r = r->outer;
3391 if (r == NULL)
3392 goto region_done;
b8c0c866 3393 depth--;
e38def9c 3394 outer = r->outer;
b8c0c866 3395 }
e38def9c 3396 while (r->next_peer == NULL);
3397 r = r->next_peer;
b4ba5e9d 3398 }
3399 }
e38def9c 3400 region_done:
3401 if (depth != 0)
3402 {
3403 error ("tree list ends on depth %i", depth);
3404 err = true;
3405 }
3406 if (count_r != nvisited_r)
3407 {
3408 error ("region_array does not match region_tree");
3409 err = true;
3410 }
3411 if (count_lp != nvisited_lp)
3412 {
3413 error ("lp_array does not match region_tree");
3414 err = true;
3415 }
1774763d 3416
e38def9c 3417 if (err)
3418 {
3419 dump_eh_tree (stderr, fun);
3420 internal_error ("verify_eh_tree failed");
3421 }
1774763d 3422}
77fce4cd 3423\f
1f3233d1 3424#include "gt-except.h"