tree-eh.c (operation_could_trap_helper_p): Handle conversions like ordinary operations.
[platform/upstream/gcc.git] / gcc / tree-eh.c
1 /* Exception handling semantics and decomposition for trees.
2    Copyright (C) 2003-2014 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "hash-table.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "expr.h"
27 #include "calls.h"
28 #include "flags.h"
29 #include "hashtab.h"
30 #include "hash-set.h"
31 #include "vec.h"
32 #include "machmode.h"
33 #include "hard-reg-set.h"
34 #include "input.h"
35 #include "function.h"
36 #include "except.h"
37 #include "predict.h"
38 #include "dominance.h"
39 #include "cfg.h"
40 #include "cfganal.h"
41 #include "cfgcleanup.h"
42 #include "basic-block.h"
43 #include "tree-ssa-alias.h"
44 #include "internal-fn.h"
45 #include "tree-eh.h"
46 #include "gimple-expr.h"
47 #include "is-a.h"
48 #include "gimple.h"
49 #include "gimple-iterator.h"
50 #include "gimple-ssa.h"
51 #include "hash-map.h"
52 #include "plugin-api.h"
53 #include "ipa-ref.h"
54 #include "cgraph.h"
55 #include "tree-cfg.h"
56 #include "tree-phinodes.h"
57 #include "ssa-iterators.h"
58 #include "stringpool.h"
59 #include "tree-ssanames.h"
60 #include "tree-into-ssa.h"
61 #include "tree-ssa.h"
62 #include "tree-inline.h"
63 #include "tree-pass.h"
64 #include "langhooks.h"
65 #include "diagnostic-core.h"
66 #include "target.h"
67 #include "cfgloop.h"
68 #include "gimple-low.h"
69
70 /* In some instances a tree and a gimple need to be stored in a same table,
71    i.e. in hash tables. This is a structure to do this. */
72 typedef union {tree *tp; tree t; gimple g;} treemple;
73
74 /* Misc functions used in this file.  */
75
76 /* Remember and lookup EH landing pad data for arbitrary statements.
77    Really this means any statement that could_throw_p.  We could
78    stuff this information into the stmt_ann data structure, but:
79
80    (1) We absolutely rely on this information being kept until
81    we get to rtl.  Once we're done with lowering here, if we lose
82    the information there's no way to recover it!
83
84    (2) There are many more statements that *cannot* throw as
85    compared to those that can.  We should be saving some amount
86    of space by only allocating memory for those that can throw.  */
87
88 /* Add statement T in function IFUN to landing pad NUM.  */
89
90 static void
91 add_stmt_to_eh_lp_fn (struct function *ifun, gimple t, int num)
92 {
93   gcc_assert (num != 0);
94
95   if (!get_eh_throw_stmt_table (ifun))
96     set_eh_throw_stmt_table (ifun, hash_map<gimple, int>::create_ggc (31));
97
98   gcc_assert (!get_eh_throw_stmt_table (ifun)->put (t, num));
99 }
100
101 /* Add statement T in the current function (cfun) to EH landing pad NUM.  */
102
103 void
104 add_stmt_to_eh_lp (gimple t, int num)
105 {
106   add_stmt_to_eh_lp_fn (cfun, t, num);
107 }
108
109 /* Add statement T to the single EH landing pad in REGION.  */
110
111 static void
112 record_stmt_eh_region (eh_region region, gimple t)
113 {
114   if (region == NULL)
115     return;
116   if (region->type == ERT_MUST_NOT_THROW)
117     add_stmt_to_eh_lp_fn (cfun, t, -region->index);
118   else
119     {
120       eh_landing_pad lp = region->landing_pads;
121       if (lp == NULL)
122         lp = gen_eh_landing_pad (region);
123       else
124         gcc_assert (lp->next_lp == NULL);
125       add_stmt_to_eh_lp_fn (cfun, t, lp->index);
126     }
127 }
128
129
130 /* Remove statement T in function IFUN from its EH landing pad.  */
131
132 bool
133 remove_stmt_from_eh_lp_fn (struct function *ifun, gimple t)
134 {
135   if (!get_eh_throw_stmt_table (ifun))
136     return false;
137
138   if (!get_eh_throw_stmt_table (ifun)->get (t))
139     return false;
140
141   get_eh_throw_stmt_table (ifun)->remove (t);
142       return true;
143 }
144
145
146 /* Remove statement T in the current function (cfun) from its
147    EH landing pad.  */
148
149 bool
150 remove_stmt_from_eh_lp (gimple t)
151 {
152   return remove_stmt_from_eh_lp_fn (cfun, t);
153 }
154
155 /* Determine if statement T is inside an EH region in function IFUN.
156    Positive numbers indicate a landing pad index; negative numbers
157    indicate a MUST_NOT_THROW region index; zero indicates that the
158    statement is not recorded in the region table.  */
159
160 int
161 lookup_stmt_eh_lp_fn (struct function *ifun, gimple t)
162 {
163   if (ifun->eh->throw_stmt_table == NULL)
164     return 0;
165
166   int *lp_nr = ifun->eh->throw_stmt_table->get (t);
167   return lp_nr ? *lp_nr : 0;
168 }
169
170 /* Likewise, but always use the current function.  */
171
172 int
173 lookup_stmt_eh_lp (gimple t)
174 {
175   /* We can get called from initialized data when -fnon-call-exceptions
176      is on; prevent crash.  */
177   if (!cfun)
178     return 0;
179   return lookup_stmt_eh_lp_fn (cfun, t);
180 }
181
182 /* First pass of EH node decomposition.  Build up a tree of GIMPLE_TRY_FINALLY
183    nodes and LABEL_DECL nodes.  We will use this during the second phase to
184    determine if a goto leaves the body of a TRY_FINALLY_EXPR node.  */
185
186 struct finally_tree_node
187 {
188   /* When storing a GIMPLE_TRY, we have to record a gimple.  However
189      when deciding whether a GOTO to a certain LABEL_DECL (which is a
190      tree) leaves the TRY block, its necessary to record a tree in
191      this field.  Thus a treemple is used. */
192   treemple child;
193   gimple parent;
194 };
195
196 /* Hashtable helpers.  */
197
198 struct finally_tree_hasher : typed_free_remove <finally_tree_node>
199 {
200   typedef finally_tree_node value_type;
201   typedef finally_tree_node compare_type;
202   static inline hashval_t hash (const value_type *);
203   static inline bool equal (const value_type *, const compare_type *);
204 };
205
206 inline hashval_t
207 finally_tree_hasher::hash (const value_type *v)
208 {
209   return (intptr_t)v->child.t >> 4;
210 }
211
212 inline bool
213 finally_tree_hasher::equal (const value_type *v, const compare_type *c)
214 {
215   return v->child.t == c->child.t;
216 }
217
218 /* Note that this table is *not* marked GTY.  It is short-lived.  */
219 static hash_table<finally_tree_hasher> *finally_tree;
220
221 static void
222 record_in_finally_tree (treemple child, gimple parent)
223 {
224   struct finally_tree_node *n;
225   finally_tree_node **slot;
226
227   n = XNEW (struct finally_tree_node);
228   n->child = child;
229   n->parent = parent;
230
231   slot = finally_tree->find_slot (n, INSERT);
232   gcc_assert (!*slot);
233   *slot = n;
234 }
235
236 static void
237 collect_finally_tree (gimple stmt, gimple region);
238
239 /* Go through the gimple sequence.  Works with collect_finally_tree to
240    record all GIMPLE_LABEL and GIMPLE_TRY statements. */
241
242 static void
243 collect_finally_tree_1 (gimple_seq seq, gimple region)
244 {
245   gimple_stmt_iterator gsi;
246
247   for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
248     collect_finally_tree (gsi_stmt (gsi), region);
249 }
250
251 static void
252 collect_finally_tree (gimple stmt, gimple region)
253 {
254   treemple temp;
255
256   switch (gimple_code (stmt))
257     {
258     case GIMPLE_LABEL:
259       temp.t = gimple_label_label (stmt);
260       record_in_finally_tree (temp, region);
261       break;
262
263     case GIMPLE_TRY:
264       if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
265         {
266           temp.g = stmt;
267           record_in_finally_tree (temp, region);
268           collect_finally_tree_1 (gimple_try_eval (stmt), stmt);
269           collect_finally_tree_1 (gimple_try_cleanup (stmt), region);
270         }
271       else if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH)
272         {
273           collect_finally_tree_1 (gimple_try_eval (stmt), region);
274           collect_finally_tree_1 (gimple_try_cleanup (stmt), region);
275         }
276       break;
277
278     case GIMPLE_CATCH:
279       collect_finally_tree_1 (gimple_catch_handler (stmt), region);
280       break;
281
282     case GIMPLE_EH_FILTER:
283       collect_finally_tree_1 (gimple_eh_filter_failure (stmt), region);
284       break;
285
286     case GIMPLE_EH_ELSE:
287       collect_finally_tree_1 (gimple_eh_else_n_body (stmt), region);
288       collect_finally_tree_1 (gimple_eh_else_e_body (stmt), region);
289       break;
290
291     default:
292       /* A type, a decl, or some kind of statement that we're not
293          interested in.  Don't walk them.  */
294       break;
295     }
296 }
297
298
299 /* Use the finally tree to determine if a jump from START to TARGET
300    would leave the try_finally node that START lives in.  */
301
302 static bool
303 outside_finally_tree (treemple start, gimple target)
304 {
305   struct finally_tree_node n, *p;
306
307   do
308     {
309       n.child = start;
310       p = finally_tree->find (&n);
311       if (!p)
312         return true;
313       start.g = p->parent;
314     }
315   while (start.g != target);
316
317   return false;
318 }
319
320 /* Second pass of EH node decomposition.  Actually transform the GIMPLE_TRY
321    nodes into a set of gotos, magic labels, and eh regions.
322    The eh region creation is straight-forward, but frobbing all the gotos
323    and such into shape isn't.  */
324
325 /* The sequence into which we record all EH stuff.  This will be
326    placed at the end of the function when we're all done.  */
327 static gimple_seq eh_seq;
328
329 /* Record whether an EH region contains something that can throw,
330    indexed by EH region number.  */
331 static bitmap eh_region_may_contain_throw_map;
332
333 /* The GOTO_QUEUE is is an array of GIMPLE_GOTO and GIMPLE_RETURN
334    statements that are seen to escape this GIMPLE_TRY_FINALLY node.
335    The idea is to record a gimple statement for everything except for
336    the conditionals, which get their labels recorded. Since labels are
337    of type 'tree', we need this node to store both gimple and tree
338    objects.  REPL_STMT is the sequence used to replace the goto/return
339    statement.  CONT_STMT is used to store the statement that allows
340    the return/goto to jump to the original destination. */
341
342 struct goto_queue_node
343 {
344   treemple stmt;
345   location_t location;
346   gimple_seq repl_stmt;
347   gimple cont_stmt;
348   int index;
349   /* This is used when index >= 0 to indicate that stmt is a label (as
350      opposed to a goto stmt).  */
351   int is_label;
352 };
353
354 /* State of the world while lowering.  */
355
356 struct leh_state
357 {
358   /* What's "current" while constructing the eh region tree.  These
359      correspond to variables of the same name in cfun->eh, which we
360      don't have easy access to.  */
361   eh_region cur_region;
362
363   /* What's "current" for the purposes of __builtin_eh_pointer.  For
364      a CATCH, this is the associated TRY.  For an EH_FILTER, this is
365      the associated ALLOWED_EXCEPTIONS, etc.  */
366   eh_region ehp_region;
367
368   /* Processing of TRY_FINALLY requires a bit more state.  This is
369      split out into a separate structure so that we don't have to
370      copy so much when processing other nodes.  */
371   struct leh_tf_state *tf;
372 };
373
374 struct leh_tf_state
375 {
376   /* Pointer to the GIMPLE_TRY_FINALLY node under discussion.  The
377      try_finally_expr is the original GIMPLE_TRY_FINALLY.  We need to retain
378      this so that outside_finally_tree can reliably reference the tree used
379      in the collect_finally_tree data structures.  */
380   gimple try_finally_expr;
381   gimple top_p;
382
383   /* While lowering a top_p usually it is expanded into multiple statements,
384      thus we need the following field to store them. */
385   gimple_seq top_p_seq;
386
387   /* The state outside this try_finally node.  */
388   struct leh_state *outer;
389
390   /* The exception region created for it.  */
391   eh_region region;
392
393   /* The goto queue.  */
394   struct goto_queue_node *goto_queue;
395   size_t goto_queue_size;
396   size_t goto_queue_active;
397
398   /* Pointer map to help in searching goto_queue when it is large.  */
399   hash_map<gimple, goto_queue_node *> *goto_queue_map;
400
401   /* The set of unique labels seen as entries in the goto queue.  */
402   vec<tree> dest_array;
403
404   /* A label to be added at the end of the completed transformed
405      sequence.  It will be set if may_fallthru was true *at one time*,
406      though subsequent transformations may have cleared that flag.  */
407   tree fallthru_label;
408
409   /* True if it is possible to fall out the bottom of the try block.
410      Cleared if the fallthru is converted to a goto.  */
411   bool may_fallthru;
412
413   /* True if any entry in goto_queue is a GIMPLE_RETURN.  */
414   bool may_return;
415
416   /* True if the finally block can receive an exception edge.
417      Cleared if the exception case is handled by code duplication.  */
418   bool may_throw;
419 };
420
421 static gimple_seq lower_eh_must_not_throw (struct leh_state *, gimple);
422
423 /* Search for STMT in the goto queue.  Return the replacement,
424    or null if the statement isn't in the queue.  */
425
426 #define LARGE_GOTO_QUEUE 20
427
428 static void lower_eh_constructs_1 (struct leh_state *state, gimple_seq *seq);
429
430 static gimple_seq
431 find_goto_replacement (struct leh_tf_state *tf, treemple stmt)
432 {
433   unsigned int i;
434
435   if (tf->goto_queue_active < LARGE_GOTO_QUEUE)
436     {
437       for (i = 0; i < tf->goto_queue_active; i++)
438         if ( tf->goto_queue[i].stmt.g == stmt.g)
439           return tf->goto_queue[i].repl_stmt;
440       return NULL;
441     }
442
443   /* If we have a large number of entries in the goto_queue, create a
444      pointer map and use that for searching.  */
445
446   if (!tf->goto_queue_map)
447     {
448       tf->goto_queue_map = new hash_map<gimple, goto_queue_node *>;
449       for (i = 0; i < tf->goto_queue_active; i++)
450         {
451           bool existed = tf->goto_queue_map->put (tf->goto_queue[i].stmt.g,
452                                                   &tf->goto_queue[i]);
453           gcc_assert (!existed);
454         }
455     }
456
457   goto_queue_node **slot = tf->goto_queue_map->get (stmt.g);
458   if (slot != NULL)
459     return ((*slot)->repl_stmt);
460
461   return NULL;
462 }
463
464 /* A subroutine of replace_goto_queue_1.  Handles the sub-clauses of a
465    lowered GIMPLE_COND.  If, by chance, the replacement is a simple goto,
466    then we can just splat it in, otherwise we add the new stmts immediately
467    after the GIMPLE_COND and redirect.  */
468
469 static void
470 replace_goto_queue_cond_clause (tree *tp, struct leh_tf_state *tf,
471                                 gimple_stmt_iterator *gsi)
472 {
473   tree label;
474   gimple_seq new_seq;
475   treemple temp;
476   location_t loc = gimple_location (gsi_stmt (*gsi));
477
478   temp.tp = tp;
479   new_seq = find_goto_replacement (tf, temp);
480   if (!new_seq)
481     return;
482
483   if (gimple_seq_singleton_p (new_seq)
484       && gimple_code (gimple_seq_first_stmt (new_seq)) == GIMPLE_GOTO)
485     {
486       *tp = gimple_goto_dest (gimple_seq_first_stmt (new_seq));
487       return;
488     }
489
490   label = create_artificial_label (loc);
491   /* Set the new label for the GIMPLE_COND */
492   *tp = label;
493
494   gsi_insert_after (gsi, gimple_build_label (label), GSI_CONTINUE_LINKING);
495   gsi_insert_seq_after (gsi, gimple_seq_copy (new_seq), GSI_CONTINUE_LINKING);
496 }
497
498 /* The real work of replace_goto_queue.  Returns with TSI updated to
499    point to the next statement.  */
500
501 static void replace_goto_queue_stmt_list (gimple_seq *, struct leh_tf_state *);
502
503 static void
504 replace_goto_queue_1 (gimple stmt, struct leh_tf_state *tf,
505                       gimple_stmt_iterator *gsi)
506 {
507   gimple_seq seq;
508   treemple temp;
509   temp.g = NULL;
510
511   switch (gimple_code (stmt))
512     {
513     case GIMPLE_GOTO:
514     case GIMPLE_RETURN:
515       temp.g = stmt;
516       seq = find_goto_replacement (tf, temp);
517       if (seq)
518         {
519           gsi_insert_seq_before (gsi, gimple_seq_copy (seq), GSI_SAME_STMT);
520           gsi_remove (gsi, false);
521           return;
522         }
523       break;
524
525     case GIMPLE_COND:
526       replace_goto_queue_cond_clause (gimple_op_ptr (stmt, 2), tf, gsi);
527       replace_goto_queue_cond_clause (gimple_op_ptr (stmt, 3), tf, gsi);
528       break;
529
530     case GIMPLE_TRY:
531       replace_goto_queue_stmt_list (gimple_try_eval_ptr (stmt), tf);
532       replace_goto_queue_stmt_list (gimple_try_cleanup_ptr (stmt), tf);
533       break;
534     case GIMPLE_CATCH:
535       replace_goto_queue_stmt_list (gimple_catch_handler_ptr (stmt), tf);
536       break;
537     case GIMPLE_EH_FILTER:
538       replace_goto_queue_stmt_list (gimple_eh_filter_failure_ptr (stmt), tf);
539       break;
540     case GIMPLE_EH_ELSE:
541       replace_goto_queue_stmt_list (gimple_eh_else_n_body_ptr (stmt), tf);
542       replace_goto_queue_stmt_list (gimple_eh_else_e_body_ptr (stmt), tf);
543       break;
544
545     default:
546       /* These won't have gotos in them.  */
547       break;
548     }
549
550   gsi_next (gsi);
551 }
552
553 /* A subroutine of replace_goto_queue.  Handles GIMPLE_SEQ.  */
554
555 static void
556 replace_goto_queue_stmt_list (gimple_seq *seq, struct leh_tf_state *tf)
557 {
558   gimple_stmt_iterator gsi = gsi_start (*seq);
559
560   while (!gsi_end_p (gsi))
561     replace_goto_queue_1 (gsi_stmt (gsi), tf, &gsi);
562 }
563
564 /* Replace all goto queue members.  */
565
566 static void
567 replace_goto_queue (struct leh_tf_state *tf)
568 {
569   if (tf->goto_queue_active == 0)
570     return;
571   replace_goto_queue_stmt_list (&tf->top_p_seq, tf);
572   replace_goto_queue_stmt_list (&eh_seq, tf);
573 }
574
575 /* Add a new record to the goto queue contained in TF. NEW_STMT is the
576    data to be added, IS_LABEL indicates whether NEW_STMT is a label or
577    a gimple return. */
578
579 static void
580 record_in_goto_queue (struct leh_tf_state *tf,
581                       treemple new_stmt,
582                       int index,
583                       bool is_label,
584                       location_t location)
585 {
586   size_t active, size;
587   struct goto_queue_node *q;
588
589   gcc_assert (!tf->goto_queue_map);
590
591   active = tf->goto_queue_active;
592   size = tf->goto_queue_size;
593   if (active >= size)
594     {
595       size = (size ? size * 2 : 32);
596       tf->goto_queue_size = size;
597       tf->goto_queue
598          = XRESIZEVEC (struct goto_queue_node, tf->goto_queue, size);
599     }
600
601   q = &tf->goto_queue[active];
602   tf->goto_queue_active = active + 1;
603
604   memset (q, 0, sizeof (*q));
605   q->stmt = new_stmt;
606   q->index = index;
607   q->location = location;
608   q->is_label = is_label;
609 }
610
611 /* Record the LABEL label in the goto queue contained in TF.
612    TF is not null.  */
613
614 static void
615 record_in_goto_queue_label (struct leh_tf_state *tf, treemple stmt, tree label,
616                             location_t location)
617 {
618   int index;
619   treemple temp, new_stmt;
620
621   if (!label)
622     return;
623
624   /* Computed and non-local gotos do not get processed.  Given
625      their nature we can neither tell whether we've escaped the
626      finally block nor redirect them if we knew.  */
627   if (TREE_CODE (label) != LABEL_DECL)
628     return;
629
630   /* No need to record gotos that don't leave the try block.  */
631   temp.t = label;
632   if (!outside_finally_tree (temp, tf->try_finally_expr))
633     return;
634
635   if (! tf->dest_array.exists ())
636     {
637       tf->dest_array.create (10);
638       tf->dest_array.quick_push (label);
639       index = 0;
640     }
641   else
642     {
643       int n = tf->dest_array.length ();
644       for (index = 0; index < n; ++index)
645         if (tf->dest_array[index] == label)
646           break;
647       if (index == n)
648         tf->dest_array.safe_push (label);
649     }
650
651   /* In the case of a GOTO we want to record the destination label,
652      since with a GIMPLE_COND we have an easy access to the then/else
653      labels. */
654   new_stmt = stmt;
655   record_in_goto_queue (tf, new_stmt, index, true, location);
656 }
657
658 /* For any GIMPLE_GOTO or GIMPLE_RETURN, decide whether it leaves a try_finally
659    node, and if so record that fact in the goto queue associated with that
660    try_finally node.  */
661
662 static void
663 maybe_record_in_goto_queue (struct leh_state *state, gimple stmt)
664 {
665   struct leh_tf_state *tf = state->tf;
666   treemple new_stmt;
667
668   if (!tf)
669     return;
670
671   switch (gimple_code (stmt))
672     {
673     case GIMPLE_COND:
674       new_stmt.tp = gimple_op_ptr (stmt, 2);
675       record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt),
676                                   EXPR_LOCATION (*new_stmt.tp));
677       new_stmt.tp = gimple_op_ptr (stmt, 3);
678       record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt),
679                                   EXPR_LOCATION (*new_stmt.tp));
680       break;
681     case GIMPLE_GOTO:
682       new_stmt.g = stmt;
683       record_in_goto_queue_label (tf, new_stmt, gimple_goto_dest (stmt),
684                                   gimple_location (stmt));
685       break;
686
687     case GIMPLE_RETURN:
688       tf->may_return = true;
689       new_stmt.g = stmt;
690       record_in_goto_queue (tf, new_stmt, -1, false, gimple_location (stmt));
691       break;
692
693     default:
694       gcc_unreachable ();
695     }
696 }
697
698
699 #ifdef ENABLE_CHECKING
700 /* We do not process GIMPLE_SWITCHes for now.  As long as the original source
701    was in fact structured, and we've not yet done jump threading, then none
702    of the labels will leave outer GIMPLE_TRY_FINALLY nodes. Verify this.  */
703
704 static void
705 verify_norecord_switch_expr (struct leh_state *state, gimple switch_expr)
706 {
707   struct leh_tf_state *tf = state->tf;
708   size_t i, n;
709
710   if (!tf)
711     return;
712
713   n = gimple_switch_num_labels (switch_expr);
714
715   for (i = 0; i < n; ++i)
716     {
717       treemple temp;
718       tree lab = CASE_LABEL (gimple_switch_label (switch_expr, i));
719       temp.t = lab;
720       gcc_assert (!outside_finally_tree (temp, tf->try_finally_expr));
721     }
722 }
723 #else
724 #define verify_norecord_switch_expr(state, switch_expr)
725 #endif
726
727 /* Redirect a RETURN_EXPR pointed to by Q to FINLAB.  If MOD is
728    non-null, insert it before the new branch.  */
729
730 static void
731 do_return_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod)
732 {
733   gimple x;
734
735   /* In the case of a return, the queue node must be a gimple statement.  */
736   gcc_assert (!q->is_label);
737
738   /* Note that the return value may have already been computed, e.g.,
739
740         int x;
741         int foo (void)
742         {
743           x = 0;
744           try {
745             return x;
746           } finally {
747             x++;
748           }
749         }
750
751      should return 0, not 1.  We don't have to do anything to make
752      this happens because the return value has been placed in the
753      RESULT_DECL already.  */
754
755   q->cont_stmt = q->stmt.g;
756
757   if (mod)
758     gimple_seq_add_seq (&q->repl_stmt, mod);
759
760   x = gimple_build_goto (finlab);
761   gimple_set_location (x, q->location);
762   gimple_seq_add_stmt (&q->repl_stmt, x);
763 }
764
765 /* Similar, but easier, for GIMPLE_GOTO.  */
766
767 static void
768 do_goto_redirection (struct goto_queue_node *q, tree finlab, gimple_seq mod,
769                      struct leh_tf_state *tf)
770 {
771   gimple x;
772
773   gcc_assert (q->is_label);
774
775   q->cont_stmt = gimple_build_goto (tf->dest_array[q->index]);
776
777   if (mod)
778     gimple_seq_add_seq (&q->repl_stmt, mod);
779
780   x = gimple_build_goto (finlab);
781   gimple_set_location (x, q->location);
782   gimple_seq_add_stmt (&q->repl_stmt, x);
783 }
784
785 /* Emit a standard landing pad sequence into SEQ for REGION.  */
786
787 static void
788 emit_post_landing_pad (gimple_seq *seq, eh_region region)
789 {
790   eh_landing_pad lp = region->landing_pads;
791   gimple x;
792
793   if (lp == NULL)
794     lp = gen_eh_landing_pad (region);
795
796   lp->post_landing_pad = create_artificial_label (UNKNOWN_LOCATION);
797   EH_LANDING_PAD_NR (lp->post_landing_pad) = lp->index;
798
799   x = gimple_build_label (lp->post_landing_pad);
800   gimple_seq_add_stmt (seq, x);
801 }
802
803 /* Emit a RESX statement into SEQ for REGION.  */
804
805 static void
806 emit_resx (gimple_seq *seq, eh_region region)
807 {
808   gimple x = gimple_build_resx (region->index);
809   gimple_seq_add_stmt (seq, x);
810   if (region->outer)
811     record_stmt_eh_region (region->outer, x);
812 }
813
814 /* Emit an EH_DISPATCH statement into SEQ for REGION.  */
815
816 static void
817 emit_eh_dispatch (gimple_seq *seq, eh_region region)
818 {
819   gimple x = gimple_build_eh_dispatch (region->index);
820   gimple_seq_add_stmt (seq, x);
821 }
822
823 /* Note that the current EH region may contain a throw, or a
824    call to a function which itself may contain a throw.  */
825
826 static void
827 note_eh_region_may_contain_throw (eh_region region)
828 {
829   while (bitmap_set_bit (eh_region_may_contain_throw_map, region->index))
830     {
831       if (region->type == ERT_MUST_NOT_THROW)
832         break;
833       region = region->outer;
834       if (region == NULL)
835         break;
836     }
837 }
838
839 /* Check if REGION has been marked as containing a throw.  If REGION is
840    NULL, this predicate is false.  */
841
842 static inline bool
843 eh_region_may_contain_throw (eh_region r)
844 {
845   return r && bitmap_bit_p (eh_region_may_contain_throw_map, r->index);
846 }
847
848 /* We want to transform
849         try { body; } catch { stuff; }
850    to
851         normal_seqence:
852           body;
853           over:
854         eh_seqence:
855           landing_pad:
856           stuff;
857           goto over;
858
859    TP is a GIMPLE_TRY node.  REGION is the region whose post_landing_pad
860    should be placed before the second operand, or NULL.  OVER is
861    an existing label that should be put at the exit, or NULL.  */
862
863 static gimple_seq
864 frob_into_branch_around (gimple tp, eh_region region, tree over)
865 {
866   gimple x;
867   gimple_seq cleanup, result;
868   location_t loc = gimple_location (tp);
869
870   cleanup = gimple_try_cleanup (tp);
871   result = gimple_try_eval (tp);
872
873   if (region)
874     emit_post_landing_pad (&eh_seq, region);
875
876   if (gimple_seq_may_fallthru (cleanup))
877     {
878       if (!over)
879         over = create_artificial_label (loc);
880       x = gimple_build_goto (over);
881       gimple_set_location (x, loc);
882       gimple_seq_add_stmt (&cleanup, x);
883     }
884   gimple_seq_add_seq (&eh_seq, cleanup);
885
886   if (over)
887     {
888       x = gimple_build_label (over);
889       gimple_seq_add_stmt (&result, x);
890     }
891   return result;
892 }
893
894 /* A subroutine of lower_try_finally.  Duplicate the tree rooted at T.
895    Make sure to record all new labels found.  */
896
897 static gimple_seq
898 lower_try_finally_dup_block (gimple_seq seq, struct leh_state *outer_state,
899                              location_t loc)
900 {
901   gimple region = NULL;
902   gimple_seq new_seq;
903   gimple_stmt_iterator gsi;
904
905   new_seq = copy_gimple_seq_and_replace_locals (seq);
906
907   for (gsi = gsi_start (new_seq); !gsi_end_p (gsi); gsi_next (&gsi))
908     {
909       gimple stmt = gsi_stmt (gsi);
910       if (LOCATION_LOCUS (gimple_location (stmt)) == UNKNOWN_LOCATION)
911         {
912           tree block = gimple_block (stmt);
913           gimple_set_location (stmt, loc);
914           gimple_set_block (stmt, block);
915         }
916     }
917
918   if (outer_state->tf)
919     region = outer_state->tf->try_finally_expr;
920   collect_finally_tree_1 (new_seq, region);
921
922   return new_seq;
923 }
924
925 /* A subroutine of lower_try_finally.  Create a fallthru label for
926    the given try_finally state.  The only tricky bit here is that
927    we have to make sure to record the label in our outer context.  */
928
929 static tree
930 lower_try_finally_fallthru_label (struct leh_tf_state *tf)
931 {
932   tree label = tf->fallthru_label;
933   treemple temp;
934
935   if (!label)
936     {
937       label = create_artificial_label (gimple_location (tf->try_finally_expr));
938       tf->fallthru_label = label;
939       if (tf->outer->tf)
940         {
941           temp.t = label;
942           record_in_finally_tree (temp, tf->outer->tf->try_finally_expr);
943         }
944     }
945   return label;
946 }
947
948 /* A subroutine of lower_try_finally.  If FINALLY consits of a
949    GIMPLE_EH_ELSE node, return it.  */
950
951 static inline gimple
952 get_eh_else (gimple_seq finally)
953 {
954   gimple x = gimple_seq_first_stmt (finally);
955   if (gimple_code (x) == GIMPLE_EH_ELSE)
956     {
957       gcc_assert (gimple_seq_singleton_p (finally));
958       return x;
959     }
960   return NULL;
961 }
962
963 /* A subroutine of lower_try_finally.  If the eh_protect_cleanup_actions
964    langhook returns non-null, then the language requires that the exception
965    path out of a try_finally be treated specially.  To wit: the code within
966    the finally block may not itself throw an exception.  We have two choices
967    here. First we can duplicate the finally block and wrap it in a
968    must_not_throw region.  Second, we can generate code like
969
970         try {
971           finally_block;
972         } catch {
973           if (fintmp == eh_edge)
974             protect_cleanup_actions;
975         }
976
977    where "fintmp" is the temporary used in the switch statement generation
978    alternative considered below.  For the nonce, we always choose the first
979    option.
980
981    THIS_STATE may be null if this is a try-cleanup, not a try-finally.  */
982
983 static void
984 honor_protect_cleanup_actions (struct leh_state *outer_state,
985                                struct leh_state *this_state,
986                                struct leh_tf_state *tf)
987 {
988   tree protect_cleanup_actions;
989   gimple_stmt_iterator gsi;
990   bool finally_may_fallthru;
991   gimple_seq finally;
992   gimple x, eh_else;
993
994   /* First check for nothing to do.  */
995   if (lang_hooks.eh_protect_cleanup_actions == NULL)
996     return;
997   protect_cleanup_actions = lang_hooks.eh_protect_cleanup_actions ();
998   if (protect_cleanup_actions == NULL)
999     return;
1000
1001   finally = gimple_try_cleanup (tf->top_p);
1002   eh_else = get_eh_else (finally);
1003
1004   /* Duplicate the FINALLY block.  Only need to do this for try-finally,
1005      and not for cleanups.  If we've got an EH_ELSE, extract it now.  */
1006   if (eh_else)
1007     {
1008       finally = gimple_eh_else_e_body (eh_else);
1009       gimple_try_set_cleanup (tf->top_p, gimple_eh_else_n_body (eh_else));
1010     }
1011   else if (this_state)
1012     finally = lower_try_finally_dup_block (finally, outer_state,
1013         gimple_location (tf->try_finally_expr));
1014   finally_may_fallthru = gimple_seq_may_fallthru (finally);
1015
1016   /* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
1017      set, the handler of the TRY_CATCH_EXPR is another cleanup which ought
1018      to be in an enclosing scope, but needs to be implemented at this level
1019      to avoid a nesting violation (see wrap_temporary_cleanups in
1020      cp/decl.c).  Since it's logically at an outer level, we should call
1021      terminate before we get to it, so strip it away before adding the
1022      MUST_NOT_THROW filter.  */
1023   gsi = gsi_start (finally);
1024   x = gsi_stmt (gsi);
1025   if (gimple_code (x) == GIMPLE_TRY
1026       && gimple_try_kind (x) == GIMPLE_TRY_CATCH
1027       && gimple_try_catch_is_cleanup (x))
1028     {
1029       gsi_insert_seq_before (&gsi, gimple_try_eval (x), GSI_SAME_STMT);
1030       gsi_remove (&gsi, false);
1031     }
1032
1033   /* Wrap the block with protect_cleanup_actions as the action.  */
1034   x = gimple_build_eh_must_not_throw (protect_cleanup_actions);
1035   x = gimple_build_try (finally, gimple_seq_alloc_with_stmt (x),
1036                         GIMPLE_TRY_CATCH);
1037   finally = lower_eh_must_not_throw (outer_state, x);
1038
1039   /* Drop all of this into the exception sequence.  */
1040   emit_post_landing_pad (&eh_seq, tf->region);
1041   gimple_seq_add_seq (&eh_seq, finally);
1042   if (finally_may_fallthru)
1043     emit_resx (&eh_seq, tf->region);
1044
1045   /* Having now been handled, EH isn't to be considered with
1046      the rest of the outgoing edges.  */
1047   tf->may_throw = false;
1048 }
1049
1050 /* A subroutine of lower_try_finally.  We have determined that there is
1051    no fallthru edge out of the finally block.  This means that there is
1052    no outgoing edge corresponding to any incoming edge.  Restructure the
1053    try_finally node for this special case.  */
1054
1055 static void
1056 lower_try_finally_nofallthru (struct leh_state *state,
1057                               struct leh_tf_state *tf)
1058 {
1059   tree lab;
1060   gimple x, eh_else;
1061   gimple_seq finally;
1062   struct goto_queue_node *q, *qe;
1063
1064   lab = create_artificial_label (gimple_location (tf->try_finally_expr));
1065
1066   /* We expect that tf->top_p is a GIMPLE_TRY. */
1067   finally = gimple_try_cleanup (tf->top_p);
1068   tf->top_p_seq = gimple_try_eval (tf->top_p);
1069
1070   x = gimple_build_label (lab);
1071   gimple_seq_add_stmt (&tf->top_p_seq, x);
1072
1073   q = tf->goto_queue;
1074   qe = q + tf->goto_queue_active;
1075   for (; q < qe; ++q)
1076     if (q->index < 0)
1077       do_return_redirection (q, lab, NULL);
1078     else
1079       do_goto_redirection (q, lab, NULL, tf);
1080
1081   replace_goto_queue (tf);
1082
1083   /* Emit the finally block into the stream.  Lower EH_ELSE at this time.  */
1084   eh_else = get_eh_else (finally);
1085   if (eh_else)
1086     {
1087       finally = gimple_eh_else_n_body (eh_else);
1088       lower_eh_constructs_1 (state, &finally);
1089       gimple_seq_add_seq (&tf->top_p_seq, finally);
1090
1091       if (tf->may_throw)
1092         {
1093           finally = gimple_eh_else_e_body (eh_else);
1094           lower_eh_constructs_1 (state, &finally);
1095
1096           emit_post_landing_pad (&eh_seq, tf->region);
1097           gimple_seq_add_seq (&eh_seq, finally);
1098         }
1099     }
1100   else
1101     {
1102       lower_eh_constructs_1 (state, &finally);
1103       gimple_seq_add_seq (&tf->top_p_seq, finally);
1104
1105       if (tf->may_throw)
1106         {
1107           emit_post_landing_pad (&eh_seq, tf->region);
1108
1109           x = gimple_build_goto (lab);
1110           gimple_set_location (x, gimple_location (tf->try_finally_expr));
1111           gimple_seq_add_stmt (&eh_seq, x);
1112         }
1113     }
1114 }
1115
1116 /* A subroutine of lower_try_finally.  We have determined that there is
1117    exactly one destination of the finally block.  Restructure the
1118    try_finally node for this special case.  */
1119
1120 static void
1121 lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
1122 {
1123   struct goto_queue_node *q, *qe;
1124   gimple x;
1125   gimple_seq finally;
1126   gimple_stmt_iterator gsi;
1127   tree finally_label;
1128   location_t loc = gimple_location (tf->try_finally_expr);
1129
1130   finally = gimple_try_cleanup (tf->top_p);
1131   tf->top_p_seq = gimple_try_eval (tf->top_p);
1132
1133   /* Since there's only one destination, and the destination edge can only
1134      either be EH or non-EH, that implies that all of our incoming edges
1135      are of the same type.  Therefore we can lower EH_ELSE immediately.  */
1136   x = get_eh_else (finally);
1137   if (x)
1138     {
1139       if (tf->may_throw)
1140         finally = gimple_eh_else_e_body (x);
1141       else
1142         finally = gimple_eh_else_n_body (x);
1143     }
1144
1145   lower_eh_constructs_1 (state, &finally);
1146
1147   for (gsi = gsi_start (finally); !gsi_end_p (gsi); gsi_next (&gsi))
1148     {
1149       gimple stmt = gsi_stmt (gsi);
1150       if (LOCATION_LOCUS (gimple_location (stmt)) == UNKNOWN_LOCATION)
1151         {
1152           tree block = gimple_block (stmt);
1153           gimple_set_location (stmt, gimple_location (tf->try_finally_expr));
1154           gimple_set_block (stmt, block);
1155         }
1156     }
1157
1158   if (tf->may_throw)
1159     {
1160       /* Only reachable via the exception edge.  Add the given label to
1161          the head of the FINALLY block.  Append a RESX at the end.  */
1162       emit_post_landing_pad (&eh_seq, tf->region);
1163       gimple_seq_add_seq (&eh_seq, finally);
1164       emit_resx (&eh_seq, tf->region);
1165       return;
1166     }
1167
1168   if (tf->may_fallthru)
1169     {
1170       /* Only reachable via the fallthru edge.  Do nothing but let
1171          the two blocks run together; we'll fall out the bottom.  */
1172       gimple_seq_add_seq (&tf->top_p_seq, finally);
1173       return;
1174     }
1175
1176   finally_label = create_artificial_label (loc);
1177   x = gimple_build_label (finally_label);
1178   gimple_seq_add_stmt (&tf->top_p_seq, x);
1179
1180   gimple_seq_add_seq (&tf->top_p_seq, finally);
1181
1182   q = tf->goto_queue;
1183   qe = q + tf->goto_queue_active;
1184
1185   if (tf->may_return)
1186     {
1187       /* Reachable by return expressions only.  Redirect them.  */
1188       for (; q < qe; ++q)
1189         do_return_redirection (q, finally_label, NULL);
1190       replace_goto_queue (tf);
1191     }
1192   else
1193     {
1194       /* Reachable by goto expressions only.  Redirect them.  */
1195       for (; q < qe; ++q)
1196         do_goto_redirection (q, finally_label, NULL, tf);
1197       replace_goto_queue (tf);
1198
1199       if (tf->dest_array[0] == tf->fallthru_label)
1200         {
1201           /* Reachable by goto to fallthru label only.  Redirect it
1202              to the new label (already created, sadly), and do not
1203              emit the final branch out, or the fallthru label.  */
1204           tf->fallthru_label = NULL;
1205           return;
1206         }
1207     }
1208
1209   /* Place the original return/goto to the original destination
1210      immediately after the finally block. */
1211   x = tf->goto_queue[0].cont_stmt;
1212   gimple_seq_add_stmt (&tf->top_p_seq, x);
1213   maybe_record_in_goto_queue (state, x);
1214 }
1215
1216 /* A subroutine of lower_try_finally.  There are multiple edges incoming
1217    and outgoing from the finally block.  Implement this by duplicating the
1218    finally block for every destination.  */
1219
1220 static void
1221 lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
1222 {
1223   gimple_seq finally;
1224   gimple_seq new_stmt;
1225   gimple_seq seq;
1226   gimple x, eh_else;
1227   tree tmp;
1228   location_t tf_loc = gimple_location (tf->try_finally_expr);
1229
1230   finally = gimple_try_cleanup (tf->top_p);
1231
1232   /* Notice EH_ELSE, and simplify some of the remaining code
1233      by considering FINALLY to be the normal return path only.  */
1234   eh_else = get_eh_else (finally);
1235   if (eh_else)
1236     finally = gimple_eh_else_n_body (eh_else);
1237
1238   tf->top_p_seq = gimple_try_eval (tf->top_p);
1239   new_stmt = NULL;
1240
1241   if (tf->may_fallthru)
1242     {
1243       seq = lower_try_finally_dup_block (finally, state, tf_loc);
1244       lower_eh_constructs_1 (state, &seq);
1245       gimple_seq_add_seq (&new_stmt, seq);
1246
1247       tmp = lower_try_finally_fallthru_label (tf);
1248       x = gimple_build_goto (tmp);
1249       gimple_set_location (x, tf_loc);
1250       gimple_seq_add_stmt (&new_stmt, x);
1251     }
1252
1253   if (tf->may_throw)
1254     {
1255       /* We don't need to copy the EH path of EH_ELSE,
1256          since it is only emitted once.  */
1257       if (eh_else)
1258         seq = gimple_eh_else_e_body (eh_else);
1259       else
1260         seq = lower_try_finally_dup_block (finally, state, tf_loc);
1261       lower_eh_constructs_1 (state, &seq);
1262
1263       emit_post_landing_pad (&eh_seq, tf->region);
1264       gimple_seq_add_seq (&eh_seq, seq);
1265       emit_resx (&eh_seq, tf->region);
1266     }
1267
1268   if (tf->goto_queue)
1269     {
1270       struct goto_queue_node *q, *qe;
1271       int return_index, index;
1272       struct labels_s
1273       {
1274         struct goto_queue_node *q;
1275         tree label;
1276       } *labels;
1277
1278       return_index = tf->dest_array.length ();
1279       labels = XCNEWVEC (struct labels_s, return_index + 1);
1280
1281       q = tf->goto_queue;
1282       qe = q + tf->goto_queue_active;
1283       for (; q < qe; q++)
1284         {
1285           index = q->index < 0 ? return_index : q->index;
1286
1287           if (!labels[index].q)
1288             labels[index].q = q;
1289         }
1290
1291       for (index = 0; index < return_index + 1; index++)
1292         {
1293           tree lab;
1294
1295           q = labels[index].q;
1296           if (! q)
1297             continue;
1298
1299           lab = labels[index].label
1300             = create_artificial_label (tf_loc);
1301
1302           if (index == return_index)
1303             do_return_redirection (q, lab, NULL);
1304           else
1305             do_goto_redirection (q, lab, NULL, tf);
1306
1307           x = gimple_build_label (lab);
1308           gimple_seq_add_stmt (&new_stmt, x);
1309
1310           seq = lower_try_finally_dup_block (finally, state, q->location);
1311           lower_eh_constructs_1 (state, &seq);
1312           gimple_seq_add_seq (&new_stmt, seq);
1313
1314           gimple_seq_add_stmt (&new_stmt, q->cont_stmt);
1315           maybe_record_in_goto_queue (state, q->cont_stmt);
1316         }
1317
1318       for (q = tf->goto_queue; q < qe; q++)
1319         {
1320           tree lab;
1321
1322           index = q->index < 0 ? return_index : q->index;
1323
1324           if (labels[index].q == q)
1325             continue;
1326
1327           lab = labels[index].label;
1328
1329           if (index == return_index)
1330             do_return_redirection (q, lab, NULL);
1331           else
1332             do_goto_redirection (q, lab, NULL, tf);
1333         }
1334
1335       replace_goto_queue (tf);
1336       free (labels);
1337     }
1338
1339   /* Need to link new stmts after running replace_goto_queue due
1340      to not wanting to process the same goto stmts twice.  */
1341   gimple_seq_add_seq (&tf->top_p_seq, new_stmt);
1342 }
1343
1344 /* A subroutine of lower_try_finally.  There are multiple edges incoming
1345    and outgoing from the finally block.  Implement this by instrumenting
1346    each incoming edge and creating a switch statement at the end of the
1347    finally block that branches to the appropriate destination.  */
1348
1349 static void
1350 lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
1351 {
1352   struct goto_queue_node *q, *qe;
1353   tree finally_tmp, finally_label;
1354   int return_index, eh_index, fallthru_index;
1355   int nlabels, ndests, j, last_case_index;
1356   tree last_case;
1357   vec<tree> case_label_vec;
1358   gimple_seq switch_body = NULL;
1359   gimple x, eh_else;
1360   tree tmp;
1361   gimple switch_stmt;
1362   gimple_seq finally;
1363   hash_map<tree, gimple> *cont_map = NULL;
1364   /* The location of the TRY_FINALLY stmt.  */
1365   location_t tf_loc = gimple_location (tf->try_finally_expr);
1366   /* The location of the finally block.  */
1367   location_t finally_loc;
1368
1369   finally = gimple_try_cleanup (tf->top_p);
1370   eh_else = get_eh_else (finally);
1371
1372   /* Mash the TRY block to the head of the chain.  */
1373   tf->top_p_seq = gimple_try_eval (tf->top_p);
1374
1375   /* The location of the finally is either the last stmt in the finally
1376      block or the location of the TRY_FINALLY itself.  */
1377   x = gimple_seq_last_stmt (finally);
1378   finally_loc = x ? gimple_location (x) : tf_loc;
1379
1380   /* Prepare for switch statement generation.  */
1381   nlabels = tf->dest_array.length ();
1382   return_index = nlabels;
1383   eh_index = return_index + tf->may_return;
1384   fallthru_index = eh_index + (tf->may_throw && !eh_else);
1385   ndests = fallthru_index + tf->may_fallthru;
1386
1387   finally_tmp = create_tmp_var (integer_type_node, "finally_tmp");
1388   finally_label = create_artificial_label (finally_loc);
1389
1390   /* We use vec::quick_push on case_label_vec throughout this function,
1391      since we know the size in advance and allocate precisely as muce
1392      space as needed.  */
1393   case_label_vec.create (ndests);
1394   last_case = NULL;
1395   last_case_index = 0;
1396
1397   /* Begin inserting code for getting to the finally block.  Things
1398      are done in this order to correspond to the sequence the code is
1399      laid out.  */
1400
1401   if (tf->may_fallthru)
1402     {
1403       x = gimple_build_assign (finally_tmp,
1404                                build_int_cst (integer_type_node,
1405                                               fallthru_index));
1406       gimple_seq_add_stmt (&tf->top_p_seq, x);
1407
1408       tmp = build_int_cst (integer_type_node, fallthru_index);
1409       last_case = build_case_label (tmp, NULL,
1410                                     create_artificial_label (tf_loc));
1411       case_label_vec.quick_push (last_case);
1412       last_case_index++;
1413
1414       x = gimple_build_label (CASE_LABEL (last_case));
1415       gimple_seq_add_stmt (&switch_body, x);
1416
1417       tmp = lower_try_finally_fallthru_label (tf);
1418       x = gimple_build_goto (tmp);
1419       gimple_set_location (x, tf_loc);
1420       gimple_seq_add_stmt (&switch_body, x);
1421     }
1422
1423   /* For EH_ELSE, emit the exception path (plus resx) now, then
1424      subsequently we only need consider the normal path.  */
1425   if (eh_else)
1426     {
1427       if (tf->may_throw)
1428         {
1429           finally = gimple_eh_else_e_body (eh_else);
1430           lower_eh_constructs_1 (state, &finally);
1431
1432           emit_post_landing_pad (&eh_seq, tf->region);
1433           gimple_seq_add_seq (&eh_seq, finally);
1434           emit_resx (&eh_seq, tf->region);
1435         }
1436
1437       finally = gimple_eh_else_n_body (eh_else);
1438     }
1439   else if (tf->may_throw)
1440     {
1441       emit_post_landing_pad (&eh_seq, tf->region);
1442
1443       x = gimple_build_assign (finally_tmp,
1444                                build_int_cst (integer_type_node, eh_index));
1445       gimple_seq_add_stmt (&eh_seq, x);
1446
1447       x = gimple_build_goto (finally_label);
1448       gimple_set_location (x, tf_loc);
1449       gimple_seq_add_stmt (&eh_seq, x);
1450
1451       tmp = build_int_cst (integer_type_node, eh_index);
1452       last_case = build_case_label (tmp, NULL,
1453                                     create_artificial_label (tf_loc));
1454       case_label_vec.quick_push (last_case);
1455       last_case_index++;
1456
1457       x = gimple_build_label (CASE_LABEL (last_case));
1458       gimple_seq_add_stmt (&eh_seq, x);
1459       emit_resx (&eh_seq, tf->region);
1460     }
1461
1462   x = gimple_build_label (finally_label);
1463   gimple_seq_add_stmt (&tf->top_p_seq, x);
1464
1465   lower_eh_constructs_1 (state, &finally);
1466   gimple_seq_add_seq (&tf->top_p_seq, finally);
1467
1468   /* Redirect each incoming goto edge.  */
1469   q = tf->goto_queue;
1470   qe = q + tf->goto_queue_active;
1471   j = last_case_index + tf->may_return;
1472   /* Prepare the assignments to finally_tmp that are executed upon the
1473      entrance through a particular edge. */
1474   for (; q < qe; ++q)
1475     {
1476       gimple_seq mod = NULL;
1477       int switch_id;
1478       unsigned int case_index;
1479
1480       if (q->index < 0)
1481         {
1482           x = gimple_build_assign (finally_tmp,
1483                                    build_int_cst (integer_type_node,
1484                                                   return_index));
1485           gimple_seq_add_stmt (&mod, x);
1486           do_return_redirection (q, finally_label, mod);
1487           switch_id = return_index;
1488         }
1489       else
1490         {
1491           x = gimple_build_assign (finally_tmp,
1492                                    build_int_cst (integer_type_node, q->index));
1493           gimple_seq_add_stmt (&mod, x);
1494           do_goto_redirection (q, finally_label, mod, tf);
1495           switch_id = q->index;
1496         }
1497
1498       case_index = j + q->index;
1499       if (case_label_vec.length () <= case_index || !case_label_vec[case_index])
1500         {
1501           tree case_lab;
1502           tmp = build_int_cst (integer_type_node, switch_id);
1503           case_lab = build_case_label (tmp, NULL,
1504                                        create_artificial_label (tf_loc));
1505           /* We store the cont_stmt in the pointer map, so that we can recover
1506              it in the loop below.  */
1507           if (!cont_map)
1508             cont_map = new hash_map<tree, gimple>;
1509           cont_map->put (case_lab, q->cont_stmt);
1510           case_label_vec.quick_push (case_lab);
1511         }
1512     }
1513   for (j = last_case_index; j < last_case_index + nlabels; j++)
1514     {
1515       gimple cont_stmt;
1516
1517       last_case = case_label_vec[j];
1518
1519       gcc_assert (last_case);
1520       gcc_assert (cont_map);
1521
1522       cont_stmt = *cont_map->get (last_case);
1523
1524       x = gimple_build_label (CASE_LABEL (last_case));
1525       gimple_seq_add_stmt (&switch_body, x);
1526       gimple_seq_add_stmt (&switch_body, cont_stmt);
1527       maybe_record_in_goto_queue (state, cont_stmt);
1528     }
1529   if (cont_map)
1530     delete cont_map;
1531
1532   replace_goto_queue (tf);
1533
1534   /* Make sure that the last case is the default label, as one is required.
1535      Then sort the labels, which is also required in GIMPLE.  */
1536   CASE_LOW (last_case) = NULL;
1537   tree tem = case_label_vec.pop ();
1538   gcc_assert (tem == last_case);
1539   sort_case_labels (case_label_vec);
1540
1541   /* Build the switch statement, setting last_case to be the default
1542      label.  */
1543   switch_stmt = gimple_build_switch (finally_tmp, last_case,
1544                                      case_label_vec);
1545   gimple_set_location (switch_stmt, finally_loc);
1546
1547   /* Need to link SWITCH_STMT after running replace_goto_queue
1548      due to not wanting to process the same goto stmts twice.  */
1549   gimple_seq_add_stmt (&tf->top_p_seq, switch_stmt);
1550   gimple_seq_add_seq (&tf->top_p_seq, switch_body);
1551 }
1552
1553 /* Decide whether or not we are going to duplicate the finally block.
1554    There are several considerations.
1555
1556    First, if this is Java, then the finally block contains code
1557    written by the user.  It has line numbers associated with it,
1558    so duplicating the block means it's difficult to set a breakpoint.
1559    Since controlling code generation via -g is verboten, we simply
1560    never duplicate code without optimization.
1561
1562    Second, we'd like to prevent egregious code growth.  One way to
1563    do this is to estimate the size of the finally block, multiply
1564    that by the number of copies we'd need to make, and compare against
1565    the estimate of the size of the switch machinery we'd have to add.  */
1566
1567 static bool
1568 decide_copy_try_finally (int ndests, bool may_throw, gimple_seq finally)
1569 {
1570   int f_estimate, sw_estimate;
1571   gimple eh_else;
1572
1573   /* If there's an EH_ELSE involved, the exception path is separate
1574      and really doesn't come into play for this computation.  */
1575   eh_else = get_eh_else (finally);
1576   if (eh_else)
1577     {
1578       ndests -= may_throw;
1579       finally = gimple_eh_else_n_body (eh_else);
1580     }
1581
1582   if (!optimize)
1583     {
1584       gimple_stmt_iterator gsi;
1585
1586       if (ndests == 1)
1587         return true;
1588
1589       for (gsi = gsi_start (finally); !gsi_end_p (gsi); gsi_next (&gsi))
1590         {
1591           gimple stmt = gsi_stmt (gsi);
1592           if (!is_gimple_debug (stmt) && !gimple_clobber_p (stmt))
1593             return false;
1594         }
1595       return true;
1596     }
1597
1598   /* Finally estimate N times, plus N gotos.  */
1599   f_estimate = count_insns_seq (finally, &eni_size_weights);
1600   f_estimate = (f_estimate + 1) * ndests;
1601
1602   /* Switch statement (cost 10), N variable assignments, N gotos.  */
1603   sw_estimate = 10 + 2 * ndests;
1604
1605   /* Optimize for size clearly wants our best guess.  */
1606   if (optimize_function_for_size_p (cfun))
1607     return f_estimate < sw_estimate;
1608
1609   /* ??? These numbers are completely made up so far.  */
1610   if (optimize > 1)
1611     return f_estimate < 100 || f_estimate < sw_estimate * 2;
1612   else
1613     return f_estimate < 40 || f_estimate * 2 < sw_estimate * 3;
1614 }
1615
1616 /* REG is the enclosing region for a possible cleanup region, or the region
1617    itself.  Returns TRUE if such a region would be unreachable.
1618
1619    Cleanup regions within a must-not-throw region aren't actually reachable
1620    even if there are throwing stmts within them, because the personality
1621    routine will call terminate before unwinding.  */
1622
1623 static bool
1624 cleanup_is_dead_in (eh_region reg)
1625 {
1626   while (reg && reg->type == ERT_CLEANUP)
1627     reg = reg->outer;
1628   return (reg && reg->type == ERT_MUST_NOT_THROW);
1629 }
1630
1631 /* A subroutine of lower_eh_constructs_1.  Lower a GIMPLE_TRY_FINALLY nodes
1632    to a sequence of labels and blocks, plus the exception region trees
1633    that record all the magic.  This is complicated by the need to
1634    arrange for the FINALLY block to be executed on all exits.  */
1635
1636 static gimple_seq
1637 lower_try_finally (struct leh_state *state, gimple tp)
1638 {
1639   struct leh_tf_state this_tf;
1640   struct leh_state this_state;
1641   int ndests;
1642   gimple_seq old_eh_seq;
1643
1644   /* Process the try block.  */
1645
1646   memset (&this_tf, 0, sizeof (this_tf));
1647   this_tf.try_finally_expr = tp;
1648   this_tf.top_p = tp;
1649   this_tf.outer = state;
1650   if (using_eh_for_cleanups_p () && !cleanup_is_dead_in (state->cur_region))
1651     {
1652       this_tf.region = gen_eh_region_cleanup (state->cur_region);
1653       this_state.cur_region = this_tf.region;
1654     }
1655   else
1656     {
1657       this_tf.region = NULL;
1658       this_state.cur_region = state->cur_region;
1659     }
1660
1661   this_state.ehp_region = state->ehp_region;
1662   this_state.tf = &this_tf;
1663
1664   old_eh_seq = eh_seq;
1665   eh_seq = NULL;
1666
1667   lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
1668
1669   /* Determine if the try block is escaped through the bottom.  */
1670   this_tf.may_fallthru = gimple_seq_may_fallthru (gimple_try_eval (tp));
1671
1672   /* Determine if any exceptions are possible within the try block.  */
1673   if (this_tf.region)
1674     this_tf.may_throw = eh_region_may_contain_throw (this_tf.region);
1675   if (this_tf.may_throw)
1676     honor_protect_cleanup_actions (state, &this_state, &this_tf);
1677
1678   /* Determine how many edges (still) reach the finally block.  Or rather,
1679      how many destinations are reached by the finally block.  Use this to
1680      determine how we process the finally block itself.  */
1681
1682   ndests = this_tf.dest_array.length ();
1683   ndests += this_tf.may_fallthru;
1684   ndests += this_tf.may_return;
1685   ndests += this_tf.may_throw;
1686
1687   /* If the FINALLY block is not reachable, dike it out.  */
1688   if (ndests == 0)
1689     {
1690       gimple_seq_add_seq (&this_tf.top_p_seq, gimple_try_eval (tp));
1691       gimple_try_set_cleanup (tp, NULL);
1692     }
1693   /* If the finally block doesn't fall through, then any destination
1694      we might try to impose there isn't reached either.  There may be
1695      some minor amount of cleanup and redirection still needed.  */
1696   else if (!gimple_seq_may_fallthru (gimple_try_cleanup (tp)))
1697     lower_try_finally_nofallthru (state, &this_tf);
1698
1699   /* We can easily special-case redirection to a single destination.  */
1700   else if (ndests == 1)
1701     lower_try_finally_onedest (state, &this_tf);
1702   else if (decide_copy_try_finally (ndests, this_tf.may_throw,
1703                                     gimple_try_cleanup (tp)))
1704     lower_try_finally_copy (state, &this_tf);
1705   else
1706     lower_try_finally_switch (state, &this_tf);
1707
1708   /* If someone requested we add a label at the end of the transformed
1709      block, do so.  */
1710   if (this_tf.fallthru_label)
1711     {
1712       /* This must be reached only if ndests == 0. */
1713       gimple x = gimple_build_label (this_tf.fallthru_label);
1714       gimple_seq_add_stmt (&this_tf.top_p_seq, x);
1715     }
1716
1717   this_tf.dest_array.release ();
1718   free (this_tf.goto_queue);
1719   if (this_tf.goto_queue_map)
1720     delete this_tf.goto_queue_map;
1721
1722   /* If there was an old (aka outer) eh_seq, append the current eh_seq.
1723      If there was no old eh_seq, then the append is trivially already done.  */
1724   if (old_eh_seq)
1725     {
1726       if (eh_seq == NULL)
1727         eh_seq = old_eh_seq;
1728       else
1729         {
1730           gimple_seq new_eh_seq = eh_seq;
1731           eh_seq = old_eh_seq;
1732           gimple_seq_add_seq (&eh_seq, new_eh_seq);
1733         }
1734     }
1735
1736   return this_tf.top_p_seq;
1737 }
1738
1739 /* A subroutine of lower_eh_constructs_1.  Lower a GIMPLE_TRY_CATCH with a
1740    list of GIMPLE_CATCH to a sequence of labels and blocks, plus the
1741    exception region trees that records all the magic.  */
1742
1743 static gimple_seq
1744 lower_catch (struct leh_state *state, gimple tp)
1745 {
1746   eh_region try_region = NULL;
1747   struct leh_state this_state = *state;
1748   gimple_stmt_iterator gsi;
1749   tree out_label;
1750   gimple_seq new_seq, cleanup;
1751   gimple x;
1752   location_t try_catch_loc = gimple_location (tp);
1753
1754   if (flag_exceptions)
1755     {
1756       try_region = gen_eh_region_try (state->cur_region);
1757       this_state.cur_region = try_region;
1758     }
1759
1760   lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
1761
1762   if (!eh_region_may_contain_throw (try_region))
1763     return gimple_try_eval (tp);
1764
1765   new_seq = NULL;
1766   emit_eh_dispatch (&new_seq, try_region);
1767   emit_resx (&new_seq, try_region);
1768
1769   this_state.cur_region = state->cur_region;
1770   this_state.ehp_region = try_region;
1771
1772   out_label = NULL;
1773   cleanup = gimple_try_cleanup (tp);
1774   for (gsi = gsi_start (cleanup);
1775        !gsi_end_p (gsi);
1776        gsi_next (&gsi))
1777     {
1778       eh_catch c;
1779       gimple gcatch;
1780       gimple_seq handler;
1781
1782       gcatch = gsi_stmt (gsi);
1783       c = gen_eh_region_catch (try_region, gimple_catch_types (gcatch));
1784
1785       handler = gimple_catch_handler (gcatch);
1786       lower_eh_constructs_1 (&this_state, &handler);
1787
1788       c->label = create_artificial_label (UNKNOWN_LOCATION);
1789       x = gimple_build_label (c->label);
1790       gimple_seq_add_stmt (&new_seq, x);
1791
1792       gimple_seq_add_seq (&new_seq, handler);
1793
1794       if (gimple_seq_may_fallthru (new_seq))
1795         {
1796           if (!out_label)
1797             out_label = create_artificial_label (try_catch_loc);
1798
1799           x = gimple_build_goto (out_label);
1800           gimple_seq_add_stmt (&new_seq, x);
1801         }
1802       if (!c->type_list)
1803         break;
1804     }
1805
1806   gimple_try_set_cleanup (tp, new_seq);
1807
1808   return frob_into_branch_around (tp, try_region, out_label);
1809 }
1810
1811 /* A subroutine of lower_eh_constructs_1.  Lower a GIMPLE_TRY with a
1812    GIMPLE_EH_FILTER to a sequence of labels and blocks, plus the exception
1813    region trees that record all the magic.  */
1814
1815 static gimple_seq
1816 lower_eh_filter (struct leh_state *state, gimple tp)
1817 {
1818   struct leh_state this_state = *state;
1819   eh_region this_region = NULL;
1820   gimple inner, x;
1821   gimple_seq new_seq;
1822
1823   inner = gimple_seq_first_stmt (gimple_try_cleanup (tp));
1824
1825   if (flag_exceptions)
1826     {
1827       this_region = gen_eh_region_allowed (state->cur_region,
1828                                            gimple_eh_filter_types (inner));
1829       this_state.cur_region = this_region;
1830     }
1831
1832   lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
1833
1834   if (!eh_region_may_contain_throw (this_region))
1835     return gimple_try_eval (tp);
1836
1837   new_seq = NULL;
1838   this_state.cur_region = state->cur_region;
1839   this_state.ehp_region = this_region;
1840
1841   emit_eh_dispatch (&new_seq, this_region);
1842   emit_resx (&new_seq, this_region);
1843
1844   this_region->u.allowed.label = create_artificial_label (UNKNOWN_LOCATION);
1845   x = gimple_build_label (this_region->u.allowed.label);
1846   gimple_seq_add_stmt (&new_seq, x);
1847
1848   lower_eh_constructs_1 (&this_state, gimple_eh_filter_failure_ptr (inner));
1849   gimple_seq_add_seq (&new_seq, gimple_eh_filter_failure (inner));
1850
1851   gimple_try_set_cleanup (tp, new_seq);
1852
1853   return frob_into_branch_around (tp, this_region, NULL);
1854 }
1855
1856 /* A subroutine of lower_eh_constructs_1.  Lower a GIMPLE_TRY with
1857    an GIMPLE_EH_MUST_NOT_THROW to a sequence of labels and blocks,
1858    plus the exception region trees that record all the magic.  */
1859
1860 static gimple_seq
1861 lower_eh_must_not_throw (struct leh_state *state, gimple tp)
1862 {
1863   struct leh_state this_state = *state;
1864
1865   if (flag_exceptions)
1866     {
1867       gimple inner = gimple_seq_first_stmt (gimple_try_cleanup (tp));
1868       eh_region this_region;
1869
1870       this_region = gen_eh_region_must_not_throw (state->cur_region);
1871       this_region->u.must_not_throw.failure_decl
1872         = gimple_eh_must_not_throw_fndecl (inner);
1873       this_region->u.must_not_throw.failure_loc
1874         = LOCATION_LOCUS (gimple_location (tp));
1875
1876       /* In order to get mangling applied to this decl, we must mark it
1877          used now.  Otherwise, pass_ipa_free_lang_data won't think it
1878          needs to happen.  */
1879       TREE_USED (this_region->u.must_not_throw.failure_decl) = 1;
1880
1881       this_state.cur_region = this_region;
1882     }
1883
1884   lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
1885
1886   return gimple_try_eval (tp);
1887 }
1888
1889 /* Implement a cleanup expression.  This is similar to try-finally,
1890    except that we only execute the cleanup block for exception edges.  */
1891
1892 static gimple_seq
1893 lower_cleanup (struct leh_state *state, gimple tp)
1894 {
1895   struct leh_state this_state = *state;
1896   eh_region this_region = NULL;
1897   struct leh_tf_state fake_tf;
1898   gimple_seq result;
1899   bool cleanup_dead = cleanup_is_dead_in (state->cur_region);
1900
1901   if (flag_exceptions && !cleanup_dead)
1902     {
1903       this_region = gen_eh_region_cleanup (state->cur_region);
1904       this_state.cur_region = this_region;
1905     }
1906
1907   lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
1908
1909   if (cleanup_dead || !eh_region_may_contain_throw (this_region))
1910     return gimple_try_eval (tp);
1911
1912   /* Build enough of a try-finally state so that we can reuse
1913      honor_protect_cleanup_actions.  */
1914   memset (&fake_tf, 0, sizeof (fake_tf));
1915   fake_tf.top_p = fake_tf.try_finally_expr = tp;
1916   fake_tf.outer = state;
1917   fake_tf.region = this_region;
1918   fake_tf.may_fallthru = gimple_seq_may_fallthru (gimple_try_eval (tp));
1919   fake_tf.may_throw = true;
1920
1921   honor_protect_cleanup_actions (state, NULL, &fake_tf);
1922
1923   if (fake_tf.may_throw)
1924     {
1925       /* In this case honor_protect_cleanup_actions had nothing to do,
1926          and we should process this normally.  */
1927       lower_eh_constructs_1 (state, gimple_try_cleanup_ptr (tp));
1928       result = frob_into_branch_around (tp, this_region,
1929                                         fake_tf.fallthru_label);
1930     }
1931   else
1932     {
1933       /* In this case honor_protect_cleanup_actions did nearly all of
1934          the work.  All we have left is to append the fallthru_label.  */
1935
1936       result = gimple_try_eval (tp);
1937       if (fake_tf.fallthru_label)
1938         {
1939           gimple x = gimple_build_label (fake_tf.fallthru_label);
1940           gimple_seq_add_stmt (&result, x);
1941         }
1942     }
1943   return result;
1944 }
1945
1946 /* Main loop for lowering eh constructs. Also moves gsi to the next
1947    statement. */
1948
1949 static void
1950 lower_eh_constructs_2 (struct leh_state *state, gimple_stmt_iterator *gsi)
1951 {
1952   gimple_seq replace;
1953   gimple x;
1954   gimple stmt = gsi_stmt (*gsi);
1955
1956   switch (gimple_code (stmt))
1957     {
1958     case GIMPLE_CALL:
1959       {
1960         tree fndecl = gimple_call_fndecl (stmt);
1961         tree rhs, lhs;
1962
1963         if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
1964           switch (DECL_FUNCTION_CODE (fndecl))
1965             {
1966             case BUILT_IN_EH_POINTER:
1967               /* The front end may have generated a call to
1968                  __builtin_eh_pointer (0) within a catch region.  Replace
1969                  this zero argument with the current catch region number.  */
1970               if (state->ehp_region)
1971                 {
1972                   tree nr = build_int_cst (integer_type_node,
1973                                            state->ehp_region->index);
1974                   gimple_call_set_arg (stmt, 0, nr);
1975                 }
1976               else
1977                 {
1978                   /* The user has dome something silly.  Remove it.  */
1979                   rhs = null_pointer_node;
1980                   goto do_replace;
1981                 }
1982               break;
1983
1984             case BUILT_IN_EH_FILTER:
1985               /* ??? This should never appear, but since it's a builtin it
1986                  is accessible to abuse by users.  Just remove it and
1987                  replace the use with the arbitrary value zero.  */
1988               rhs = build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
1989             do_replace:
1990               lhs = gimple_call_lhs (stmt);
1991               x = gimple_build_assign (lhs, rhs);
1992               gsi_insert_before (gsi, x, GSI_SAME_STMT);
1993               /* FALLTHRU */
1994
1995             case BUILT_IN_EH_COPY_VALUES:
1996               /* Likewise this should not appear.  Remove it.  */
1997               gsi_remove (gsi, true);
1998               return;
1999
2000             default:
2001               break;
2002             }
2003       }
2004       /* FALLTHRU */
2005
2006     case GIMPLE_ASSIGN:
2007       /* If the stmt can throw use a new temporary for the assignment
2008          to a LHS.  This makes sure the old value of the LHS is
2009          available on the EH edge.  Only do so for statements that
2010          potentially fall through (no noreturn calls e.g.), otherwise
2011          this new assignment might create fake fallthru regions.  */
2012       if (stmt_could_throw_p (stmt)
2013           && gimple_has_lhs (stmt)
2014           && gimple_stmt_may_fallthru (stmt)
2015           && !tree_could_throw_p (gimple_get_lhs (stmt))
2016           && is_gimple_reg_type (TREE_TYPE (gimple_get_lhs (stmt))))
2017         {
2018           tree lhs = gimple_get_lhs (stmt);
2019           tree tmp = create_tmp_var (TREE_TYPE (lhs), NULL);
2020           gimple s = gimple_build_assign (lhs, tmp);
2021           gimple_set_location (s, gimple_location (stmt));
2022           gimple_set_block (s, gimple_block (stmt));
2023           gimple_set_lhs (stmt, tmp);
2024           if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE
2025               || TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE)
2026             DECL_GIMPLE_REG_P (tmp) = 1;
2027           gsi_insert_after (gsi, s, GSI_SAME_STMT);
2028         }
2029       /* Look for things that can throw exceptions, and record them.  */
2030       if (state->cur_region && stmt_could_throw_p (stmt))
2031         {
2032           record_stmt_eh_region (state->cur_region, stmt);
2033           note_eh_region_may_contain_throw (state->cur_region);
2034         }
2035       break;
2036
2037     case GIMPLE_COND:
2038     case GIMPLE_GOTO:
2039     case GIMPLE_RETURN:
2040       maybe_record_in_goto_queue (state, stmt);
2041       break;
2042
2043     case GIMPLE_SWITCH:
2044       verify_norecord_switch_expr (state, stmt);
2045       break;
2046
2047     case GIMPLE_TRY:
2048       if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
2049         replace = lower_try_finally (state, stmt);
2050       else
2051         {
2052           x = gimple_seq_first_stmt (gimple_try_cleanup (stmt));
2053           if (!x)
2054             {
2055               replace = gimple_try_eval (stmt);
2056               lower_eh_constructs_1 (state, &replace);
2057             }
2058           else
2059             switch (gimple_code (x))
2060               {
2061                 case GIMPLE_CATCH:
2062                     replace = lower_catch (state, stmt);
2063                     break;
2064                 case GIMPLE_EH_FILTER:
2065                     replace = lower_eh_filter (state, stmt);
2066                     break;
2067                 case GIMPLE_EH_MUST_NOT_THROW:
2068                     replace = lower_eh_must_not_throw (state, stmt);
2069                     break;
2070                 case GIMPLE_EH_ELSE:
2071                     /* This code is only valid with GIMPLE_TRY_FINALLY.  */
2072                     gcc_unreachable ();
2073                 default:
2074                     replace = lower_cleanup (state, stmt);
2075                     break;
2076               }
2077         }
2078
2079       /* Remove the old stmt and insert the transformed sequence
2080          instead. */
2081       gsi_insert_seq_before (gsi, replace, GSI_SAME_STMT);
2082       gsi_remove (gsi, true);
2083
2084       /* Return since we don't want gsi_next () */
2085       return;
2086
2087     case GIMPLE_EH_ELSE:
2088       /* We should be eliminating this in lower_try_finally et al.  */
2089       gcc_unreachable ();
2090
2091     default:
2092       /* A type, a decl, or some kind of statement that we're not
2093          interested in.  Don't walk them.  */
2094       break;
2095     }
2096
2097   gsi_next (gsi);
2098 }
2099
2100 /* A helper to unwrap a gimple_seq and feed stmts to lower_eh_constructs_2. */
2101
2102 static void
2103 lower_eh_constructs_1 (struct leh_state *state, gimple_seq *pseq)
2104 {
2105   gimple_stmt_iterator gsi;
2106   for (gsi = gsi_start (*pseq); !gsi_end_p (gsi);)
2107     lower_eh_constructs_2 (state, &gsi);
2108 }
2109
2110 namespace {
2111
2112 const pass_data pass_data_lower_eh =
2113 {
2114   GIMPLE_PASS, /* type */
2115   "eh", /* name */
2116   OPTGROUP_NONE, /* optinfo_flags */
2117   TV_TREE_EH, /* tv_id */
2118   PROP_gimple_lcf, /* properties_required */
2119   PROP_gimple_leh, /* properties_provided */
2120   0, /* properties_destroyed */
2121   0, /* todo_flags_start */
2122   0, /* todo_flags_finish */
2123 };
2124
2125 class pass_lower_eh : public gimple_opt_pass
2126 {
2127 public:
2128   pass_lower_eh (gcc::context *ctxt)
2129     : gimple_opt_pass (pass_data_lower_eh, ctxt)
2130   {}
2131
2132   /* opt_pass methods: */
2133   virtual unsigned int execute (function *);
2134
2135 }; // class pass_lower_eh
2136
2137 unsigned int
2138 pass_lower_eh::execute (function *fun)
2139 {
2140   struct leh_state null_state;
2141   gimple_seq bodyp;
2142
2143   bodyp = gimple_body (current_function_decl);
2144   if (bodyp == NULL)
2145     return 0;
2146
2147   finally_tree = new hash_table<finally_tree_hasher> (31);
2148   eh_region_may_contain_throw_map = BITMAP_ALLOC (NULL);
2149   memset (&null_state, 0, sizeof (null_state));
2150
2151   collect_finally_tree_1 (bodyp, NULL);
2152   lower_eh_constructs_1 (&null_state, &bodyp);
2153   gimple_set_body (current_function_decl, bodyp);
2154
2155   /* We assume there's a return statement, or something, at the end of
2156      the function, and thus ploping the EH sequence afterward won't
2157      change anything.  */
2158   gcc_assert (!gimple_seq_may_fallthru (bodyp));
2159   gimple_seq_add_seq (&bodyp, eh_seq);
2160
2161   /* We assume that since BODYP already existed, adding EH_SEQ to it
2162      didn't change its value, and we don't have to re-set the function.  */
2163   gcc_assert (bodyp == gimple_body (current_function_decl));
2164
2165   delete finally_tree;
2166   finally_tree = NULL;
2167   BITMAP_FREE (eh_region_may_contain_throw_map);
2168   eh_seq = NULL;
2169
2170   /* If this function needs a language specific EH personality routine
2171      and the frontend didn't already set one do so now.  */
2172   if (function_needs_eh_personality (fun) == eh_personality_lang
2173       && !DECL_FUNCTION_PERSONALITY (current_function_decl))
2174     DECL_FUNCTION_PERSONALITY (current_function_decl)
2175       = lang_hooks.eh_personality ();
2176
2177   return 0;
2178 }
2179
2180 } // anon namespace
2181
2182 gimple_opt_pass *
2183 make_pass_lower_eh (gcc::context *ctxt)
2184 {
2185   return new pass_lower_eh (ctxt);
2186 }
2187 \f
2188 /* Create the multiple edges from an EH_DISPATCH statement to all of
2189    the possible handlers for its EH region.  Return true if there's
2190    no fallthru edge; false if there is.  */
2191
2192 bool
2193 make_eh_dispatch_edges (gimple stmt)
2194 {
2195   eh_region r;
2196   eh_catch c;
2197   basic_block src, dst;
2198
2199   r = get_eh_region_from_number (gimple_eh_dispatch_region (stmt));
2200   src = gimple_bb (stmt);
2201
2202   switch (r->type)
2203     {
2204     case ERT_TRY:
2205       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
2206         {
2207           dst = label_to_block (c->label);
2208           make_edge (src, dst, 0);
2209
2210           /* A catch-all handler doesn't have a fallthru.  */
2211           if (c->type_list == NULL)
2212             return false;
2213         }
2214       break;
2215
2216     case ERT_ALLOWED_EXCEPTIONS:
2217       dst = label_to_block (r->u.allowed.label);
2218       make_edge (src, dst, 0);
2219       break;
2220
2221     default:
2222       gcc_unreachable ();
2223     }
2224
2225   return true;
2226 }
2227
2228 /* Create the single EH edge from STMT to its nearest landing pad,
2229    if there is such a landing pad within the current function.  */
2230
2231 void
2232 make_eh_edges (gimple stmt)
2233 {
2234   basic_block src, dst;
2235   eh_landing_pad lp;
2236   int lp_nr;
2237
2238   lp_nr = lookup_stmt_eh_lp (stmt);
2239   if (lp_nr <= 0)
2240     return;
2241
2242   lp = get_eh_landing_pad_from_number (lp_nr);
2243   gcc_assert (lp != NULL);
2244
2245   src = gimple_bb (stmt);
2246   dst = label_to_block (lp->post_landing_pad);
2247   make_edge (src, dst, EDGE_EH);
2248 }
2249
2250 /* Do the work in redirecting EDGE_IN to NEW_BB within the EH region tree;
2251    do not actually perform the final edge redirection.
2252
2253    CHANGE_REGION is true when we're being called from cleanup_empty_eh and
2254    we intend to change the destination EH region as well; this means
2255    EH_LANDING_PAD_NR must already be set on the destination block label.
2256    If false, we're being called from generic cfg manipulation code and we
2257    should preserve our place within the region tree.  */
2258
2259 static void
2260 redirect_eh_edge_1 (edge edge_in, basic_block new_bb, bool change_region)
2261 {
2262   eh_landing_pad old_lp, new_lp;
2263   basic_block old_bb;
2264   gimple throw_stmt;
2265   int old_lp_nr, new_lp_nr;
2266   tree old_label, new_label;
2267   edge_iterator ei;
2268   edge e;
2269
2270   old_bb = edge_in->dest;
2271   old_label = gimple_block_label (old_bb);
2272   old_lp_nr = EH_LANDING_PAD_NR (old_label);
2273   gcc_assert (old_lp_nr > 0);
2274   old_lp = get_eh_landing_pad_from_number (old_lp_nr);
2275
2276   throw_stmt = last_stmt (edge_in->src);
2277   gcc_assert (lookup_stmt_eh_lp (throw_stmt) == old_lp_nr);
2278
2279   new_label = gimple_block_label (new_bb);
2280
2281   /* Look for an existing region that might be using NEW_BB already.  */
2282   new_lp_nr = EH_LANDING_PAD_NR (new_label);
2283   if (new_lp_nr)
2284     {
2285       new_lp = get_eh_landing_pad_from_number (new_lp_nr);
2286       gcc_assert (new_lp);
2287
2288       /* Unless CHANGE_REGION is true, the new and old landing pad
2289          had better be associated with the same EH region.  */
2290       gcc_assert (change_region || new_lp->region == old_lp->region);
2291     }
2292   else
2293     {
2294       new_lp = NULL;
2295       gcc_assert (!change_region);
2296     }
2297
2298   /* Notice when we redirect the last EH edge away from OLD_BB.  */
2299   FOR_EACH_EDGE (e, ei, old_bb->preds)
2300     if (e != edge_in && (e->flags & EDGE_EH))
2301       break;
2302
2303   if (new_lp)
2304     {
2305       /* NEW_LP already exists.  If there are still edges into OLD_LP,
2306          there's nothing to do with the EH tree.  If there are no more
2307          edges into OLD_LP, then we want to remove OLD_LP as it is unused.
2308          If CHANGE_REGION is true, then our caller is expecting to remove
2309          the landing pad.  */
2310       if (e == NULL && !change_region)
2311         remove_eh_landing_pad (old_lp);
2312     }
2313   else
2314     {
2315       /* No correct landing pad exists.  If there are no more edges
2316          into OLD_LP, then we can simply re-use the existing landing pad.
2317          Otherwise, we have to create a new landing pad.  */
2318       if (e == NULL)
2319         {
2320           EH_LANDING_PAD_NR (old_lp->post_landing_pad) = 0;
2321           new_lp = old_lp;
2322         }
2323       else
2324         new_lp = gen_eh_landing_pad (old_lp->region);
2325       new_lp->post_landing_pad = new_label;
2326       EH_LANDING_PAD_NR (new_label) = new_lp->index;
2327     }
2328
2329   /* Maybe move the throwing statement to the new region.  */
2330   if (old_lp != new_lp)
2331     {
2332       remove_stmt_from_eh_lp (throw_stmt);
2333       add_stmt_to_eh_lp (throw_stmt, new_lp->index);
2334     }
2335 }
2336
2337 /* Redirect EH edge E to NEW_BB.  */
2338
2339 edge
2340 redirect_eh_edge (edge edge_in, basic_block new_bb)
2341 {
2342   redirect_eh_edge_1 (edge_in, new_bb, false);
2343   return ssa_redirect_edge (edge_in, new_bb);
2344 }
2345
2346 /* This is a subroutine of gimple_redirect_edge_and_branch.  Update the
2347    labels for redirecting a non-fallthru EH_DISPATCH edge E to NEW_BB.
2348    The actual edge update will happen in the caller.  */
2349
2350 void
2351 redirect_eh_dispatch_edge (gimple stmt, edge e, basic_block new_bb)
2352 {
2353   tree new_lab = gimple_block_label (new_bb);
2354   bool any_changed = false;
2355   basic_block old_bb;
2356   eh_region r;
2357   eh_catch c;
2358
2359   r = get_eh_region_from_number (gimple_eh_dispatch_region (stmt));
2360   switch (r->type)
2361     {
2362     case ERT_TRY:
2363       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
2364         {
2365           old_bb = label_to_block (c->label);
2366           if (old_bb == e->dest)
2367             {
2368               c->label = new_lab;
2369               any_changed = true;
2370             }
2371         }
2372       break;
2373
2374     case ERT_ALLOWED_EXCEPTIONS:
2375       old_bb = label_to_block (r->u.allowed.label);
2376       gcc_assert (old_bb == e->dest);
2377       r->u.allowed.label = new_lab;
2378       any_changed = true;
2379       break;
2380
2381     default:
2382       gcc_unreachable ();
2383     }
2384
2385   gcc_assert (any_changed);
2386 }
2387 \f
2388 /* Helper function for operation_could_trap_p and stmt_could_throw_p.  */
2389
2390 bool
2391 operation_could_trap_helper_p (enum tree_code op,
2392                                bool fp_operation,
2393                                bool honor_trapv,
2394                                bool honor_nans,
2395                                bool honor_snans,
2396                                tree divisor,
2397                                bool *handled)
2398 {
2399   *handled = true;
2400   switch (op)
2401     {
2402     case TRUNC_DIV_EXPR:
2403     case CEIL_DIV_EXPR:
2404     case FLOOR_DIV_EXPR:
2405     case ROUND_DIV_EXPR:
2406     case EXACT_DIV_EXPR:
2407     case CEIL_MOD_EXPR:
2408     case FLOOR_MOD_EXPR:
2409     case ROUND_MOD_EXPR:
2410     case TRUNC_MOD_EXPR:
2411     case RDIV_EXPR:
2412       if (honor_snans || honor_trapv)
2413         return true;
2414       if (fp_operation)
2415         return flag_trapping_math;
2416       if (!TREE_CONSTANT (divisor) || integer_zerop (divisor))
2417         return true;
2418       return false;
2419
2420     case LT_EXPR:
2421     case LE_EXPR:
2422     case GT_EXPR:
2423     case GE_EXPR:
2424     case LTGT_EXPR:
2425       /* Some floating point comparisons may trap.  */
2426       return honor_nans;
2427
2428     case EQ_EXPR:
2429     case NE_EXPR:
2430     case UNORDERED_EXPR:
2431     case ORDERED_EXPR:
2432     case UNLT_EXPR:
2433     case UNLE_EXPR:
2434     case UNGT_EXPR:
2435     case UNGE_EXPR:
2436     case UNEQ_EXPR:
2437       return honor_snans;
2438
2439     case NEGATE_EXPR:
2440     case ABS_EXPR:
2441     case CONJ_EXPR:
2442       /* These operations don't trap with floating point.  */
2443       if (honor_trapv)
2444         return true;
2445       return false;
2446
2447     case PLUS_EXPR:
2448     case MINUS_EXPR:
2449     case MULT_EXPR:
2450       /* Any floating arithmetic may trap.  */
2451       if (fp_operation && flag_trapping_math)
2452         return true;
2453       if (honor_trapv)
2454         return true;
2455       return false;
2456
2457     case COMPLEX_EXPR:
2458     case CONSTRUCTOR:
2459       /* Constructing an object cannot trap.  */
2460       return false;
2461
2462     default:
2463       /* Any floating arithmetic may trap.  */
2464       if (fp_operation && flag_trapping_math)
2465         return true;
2466
2467       *handled = false;
2468       return false;
2469     }
2470 }
2471
2472 /* Return true if operation OP may trap.  FP_OPERATION is true if OP is applied
2473    on floating-point values.  HONOR_TRAPV is true if OP is applied on integer
2474    type operands that may trap.  If OP is a division operator, DIVISOR contains
2475    the value of the divisor.  */
2476
2477 bool
2478 operation_could_trap_p (enum tree_code op, bool fp_operation, bool honor_trapv,
2479                         tree divisor)
2480 {
2481   bool honor_nans = (fp_operation && flag_trapping_math
2482                      && !flag_finite_math_only);
2483   bool honor_snans = fp_operation && flag_signaling_nans != 0;
2484   bool handled;
2485
2486   if (TREE_CODE_CLASS (op) != tcc_comparison
2487       && TREE_CODE_CLASS (op) != tcc_unary
2488       && TREE_CODE_CLASS (op) != tcc_binary)
2489     return false;
2490
2491   return operation_could_trap_helper_p (op, fp_operation, honor_trapv,
2492                                         honor_nans, honor_snans, divisor,
2493                                         &handled);
2494 }
2495
2496
2497 /* Returns true if it is possible to prove that the index of
2498    an array access REF (an ARRAY_REF expression) falls into the
2499    array bounds.  */
2500
2501 static bool
2502 in_array_bounds_p (tree ref)
2503 {
2504   tree idx = TREE_OPERAND (ref, 1);
2505   tree min, max;
2506
2507   if (TREE_CODE (idx) != INTEGER_CST)
2508     return false;
2509
2510   min = array_ref_low_bound (ref);
2511   max = array_ref_up_bound (ref);
2512   if (!min
2513       || !max
2514       || TREE_CODE (min) != INTEGER_CST
2515       || TREE_CODE (max) != INTEGER_CST)
2516     return false;
2517
2518   if (tree_int_cst_lt (idx, min)
2519       || tree_int_cst_lt (max, idx))
2520     return false;
2521
2522   return true;
2523 }
2524
2525 /* Returns true if it is possible to prove that the range of
2526    an array access REF (an ARRAY_RANGE_REF expression) falls
2527    into the array bounds.  */
2528
2529 static bool
2530 range_in_array_bounds_p (tree ref)
2531 {
2532   tree domain_type = TYPE_DOMAIN (TREE_TYPE (ref));
2533   tree range_min, range_max, min, max;
2534
2535   range_min = TYPE_MIN_VALUE (domain_type);
2536   range_max = TYPE_MAX_VALUE (domain_type);
2537   if (!range_min
2538       || !range_max
2539       || TREE_CODE (range_min) != INTEGER_CST
2540       || TREE_CODE (range_max) != INTEGER_CST)
2541     return false;
2542
2543   min = array_ref_low_bound (ref);
2544   max = array_ref_up_bound (ref);
2545   if (!min
2546       || !max
2547       || TREE_CODE (min) != INTEGER_CST
2548       || TREE_CODE (max) != INTEGER_CST)
2549     return false;
2550
2551   if (tree_int_cst_lt (range_min, min)
2552       || tree_int_cst_lt (max, range_max))
2553     return false;
2554
2555   return true;
2556 }
2557
2558 /* Return true if EXPR can trap, as in dereferencing an invalid pointer
2559    location or floating point arithmetic.  C.f. the rtl version, may_trap_p.
2560    This routine expects only GIMPLE lhs or rhs input.  */
2561
2562 bool
2563 tree_could_trap_p (tree expr)
2564 {
2565   enum tree_code code;
2566   bool fp_operation = false;
2567   bool honor_trapv = false;
2568   tree t, base, div = NULL_TREE;
2569
2570   if (!expr)
2571     return false;
2572
2573   code = TREE_CODE (expr);
2574   t = TREE_TYPE (expr);
2575
2576   if (t)
2577     {
2578       if (COMPARISON_CLASS_P (expr))
2579         fp_operation = FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)));
2580       else
2581         fp_operation = FLOAT_TYPE_P (t);
2582       honor_trapv = INTEGRAL_TYPE_P (t) && TYPE_OVERFLOW_TRAPS (t);
2583     }
2584
2585   if (TREE_CODE_CLASS (code) == tcc_binary)
2586     div = TREE_OPERAND (expr, 1);
2587   if (operation_could_trap_p (code, fp_operation, honor_trapv, div))
2588     return true;
2589
2590  restart:
2591   switch (code)
2592     {
2593     case COMPONENT_REF:
2594     case REALPART_EXPR:
2595     case IMAGPART_EXPR:
2596     case BIT_FIELD_REF:
2597     case VIEW_CONVERT_EXPR:
2598     case WITH_SIZE_EXPR:
2599       expr = TREE_OPERAND (expr, 0);
2600       code = TREE_CODE (expr);
2601       goto restart;
2602
2603     case ARRAY_RANGE_REF:
2604       base = TREE_OPERAND (expr, 0);
2605       if (tree_could_trap_p (base))
2606         return true;
2607       if (TREE_THIS_NOTRAP (expr))
2608         return false;
2609       return !range_in_array_bounds_p (expr);
2610
2611     case ARRAY_REF:
2612       base = TREE_OPERAND (expr, 0);
2613       if (tree_could_trap_p (base))
2614         return true;
2615       if (TREE_THIS_NOTRAP (expr))
2616         return false;
2617       return !in_array_bounds_p (expr);
2618
2619     case TARGET_MEM_REF:
2620     case MEM_REF:
2621       if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR
2622           && tree_could_trap_p (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)))
2623         return true;
2624       if (TREE_THIS_NOTRAP (expr))
2625         return false;
2626       /* We cannot prove that the access is in-bounds when we have
2627          variable-index TARGET_MEM_REFs.  */
2628       if (code == TARGET_MEM_REF
2629           && (TMR_INDEX (expr) || TMR_INDEX2 (expr)))
2630         return true;
2631       if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
2632         {
2633           tree base = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
2634           offset_int off = mem_ref_offset (expr);
2635           if (wi::neg_p (off, SIGNED))
2636             return true;
2637           if (TREE_CODE (base) == STRING_CST)
2638             return wi::leu_p (TREE_STRING_LENGTH (base), off);
2639           else if (DECL_SIZE_UNIT (base) == NULL_TREE
2640                    || TREE_CODE (DECL_SIZE_UNIT (base)) != INTEGER_CST
2641                    || wi::leu_p (wi::to_offset (DECL_SIZE_UNIT (base)), off))
2642             return true;
2643           /* Now we are sure the first byte of the access is inside
2644              the object.  */
2645           return false;
2646         }
2647       return true;
2648
2649     case INDIRECT_REF:
2650       return !TREE_THIS_NOTRAP (expr);
2651
2652     case ASM_EXPR:
2653       return TREE_THIS_VOLATILE (expr);
2654
2655     case CALL_EXPR:
2656       t = get_callee_fndecl (expr);
2657       /* Assume that calls to weak functions may trap.  */
2658       if (!t || !DECL_P (t))
2659         return true;
2660       if (DECL_WEAK (t))
2661         return tree_could_trap_p (t);
2662       return false;
2663
2664     case FUNCTION_DECL:
2665       /* Assume that accesses to weak functions may trap, unless we know
2666          they are certainly defined in current TU or in some other
2667          LTO partition.  */
2668       if (DECL_WEAK (expr) && !DECL_COMDAT (expr) && DECL_EXTERNAL (expr))
2669         {
2670           cgraph_node *node = cgraph_node::get (expr);
2671           if (node)
2672             node = node->function_symbol ();
2673           return !(node && node->in_other_partition);
2674         }
2675       return false;
2676
2677     case VAR_DECL:
2678       /* Assume that accesses to weak vars may trap, unless we know
2679          they are certainly defined in current TU or in some other
2680          LTO partition.  */
2681       if (DECL_WEAK (expr) && !DECL_COMDAT (expr) && DECL_EXTERNAL (expr))
2682         {
2683           varpool_node *node = varpool_node::get (expr);
2684           if (node)
2685             node = node->ultimate_alias_target ();
2686           return !(node && node->in_other_partition);
2687         }
2688       return false;
2689
2690     default:
2691       return false;
2692     }
2693 }
2694
2695
2696 /* Helper for stmt_could_throw_p.  Return true if STMT (assumed to be a
2697    an assignment or a conditional) may throw.  */
2698
2699 static bool
2700 stmt_could_throw_1_p (gimple stmt)
2701 {
2702   enum tree_code code = gimple_expr_code (stmt);
2703   bool honor_nans = false;
2704   bool honor_snans = false;
2705   bool fp_operation = false;
2706   bool honor_trapv = false;
2707   tree t;
2708   size_t i;
2709   bool handled, ret;
2710
2711   if (TREE_CODE_CLASS (code) == tcc_comparison
2712       || TREE_CODE_CLASS (code) == tcc_unary
2713       || TREE_CODE_CLASS (code) == tcc_binary)
2714     {
2715       if (is_gimple_assign (stmt)
2716           && TREE_CODE_CLASS (code) == tcc_comparison)
2717         t = TREE_TYPE (gimple_assign_rhs1 (stmt));
2718       else if (gimple_code (stmt) == GIMPLE_COND)
2719         t = TREE_TYPE (gimple_cond_lhs (stmt));
2720       else
2721         t = gimple_expr_type (stmt);
2722       fp_operation = FLOAT_TYPE_P (t);
2723       if (fp_operation)
2724         {
2725           honor_nans = flag_trapping_math && !flag_finite_math_only;
2726           honor_snans = flag_signaling_nans != 0;
2727         }
2728       else if (INTEGRAL_TYPE_P (t) && TYPE_OVERFLOW_TRAPS (t))
2729         honor_trapv = true;
2730     }
2731
2732   /* Check if the main expression may trap.  */
2733   t = is_gimple_assign (stmt) ? gimple_assign_rhs2 (stmt) : NULL;
2734   ret = operation_could_trap_helper_p (code, fp_operation, honor_trapv,
2735                                        honor_nans, honor_snans, t,
2736                                        &handled);
2737   if (handled)
2738     return ret;
2739
2740   /* If the expression does not trap, see if any of the individual operands may
2741      trap.  */
2742   for (i = 0; i < gimple_num_ops (stmt); i++)
2743     if (tree_could_trap_p (gimple_op (stmt, i)))
2744       return true;
2745
2746   return false;
2747 }
2748
2749
2750 /* Return true if statement STMT could throw an exception.  */
2751
2752 bool
2753 stmt_could_throw_p (gimple stmt)
2754 {
2755   if (!flag_exceptions)
2756     return false;
2757
2758   /* The only statements that can throw an exception are assignments,
2759      conditionals, calls, resx, and asms.  */
2760   switch (gimple_code (stmt))
2761     {
2762     case GIMPLE_RESX:
2763       return true;
2764
2765     case GIMPLE_CALL:
2766       return !gimple_call_nothrow_p (stmt);
2767
2768     case GIMPLE_ASSIGN:
2769     case GIMPLE_COND:
2770       if (!cfun->can_throw_non_call_exceptions)
2771         return false;
2772       return stmt_could_throw_1_p (stmt);
2773
2774     case GIMPLE_ASM:
2775       if (!cfun->can_throw_non_call_exceptions)
2776         return false;
2777       return gimple_asm_volatile_p (stmt);
2778
2779     default:
2780       return false;
2781     }
2782 }
2783
2784
2785 /* Return true if expression T could throw an exception.  */
2786
2787 bool
2788 tree_could_throw_p (tree t)
2789 {
2790   if (!flag_exceptions)
2791     return false;
2792   if (TREE_CODE (t) == MODIFY_EXPR)
2793     {
2794       if (cfun->can_throw_non_call_exceptions
2795           && tree_could_trap_p (TREE_OPERAND (t, 0)))
2796         return true;
2797       t = TREE_OPERAND (t, 1);
2798     }
2799
2800   if (TREE_CODE (t) == WITH_SIZE_EXPR)
2801     t = TREE_OPERAND (t, 0);
2802   if (TREE_CODE (t) == CALL_EXPR)
2803     return (call_expr_flags (t) & ECF_NOTHROW) == 0;
2804   if (cfun->can_throw_non_call_exceptions)
2805     return tree_could_trap_p (t);
2806   return false;
2807 }
2808
2809 /* Return true if STMT can throw an exception that is not caught within
2810    the current function (CFUN).  */
2811
2812 bool
2813 stmt_can_throw_external (gimple stmt)
2814 {
2815   int lp_nr;
2816
2817   if (!stmt_could_throw_p (stmt))
2818     return false;
2819
2820   lp_nr = lookup_stmt_eh_lp (stmt);
2821   return lp_nr == 0;
2822 }
2823
2824 /* Return true if STMT can throw an exception that is caught within
2825    the current function (CFUN).  */
2826
2827 bool
2828 stmt_can_throw_internal (gimple stmt)
2829 {
2830   int lp_nr;
2831
2832   if (!stmt_could_throw_p (stmt))
2833     return false;
2834
2835   lp_nr = lookup_stmt_eh_lp (stmt);
2836   return lp_nr > 0;
2837 }
2838
2839 /* Given a statement STMT in IFUN, if STMT can no longer throw, then
2840    remove any entry it might have from the EH table.  Return true if
2841    any change was made.  */
2842
2843 bool
2844 maybe_clean_eh_stmt_fn (struct function *ifun, gimple stmt)
2845 {
2846   if (stmt_could_throw_p (stmt))
2847     return false;
2848   return remove_stmt_from_eh_lp_fn (ifun, stmt);
2849 }
2850
2851 /* Likewise, but always use the current function.  */
2852
2853 bool
2854 maybe_clean_eh_stmt (gimple stmt)
2855 {
2856   return maybe_clean_eh_stmt_fn (cfun, stmt);
2857 }
2858
2859 /* Given a statement OLD_STMT and a new statement NEW_STMT that has replaced
2860    OLD_STMT in the function, remove OLD_STMT from the EH table and put NEW_STMT
2861    in the table if it should be in there.  Return TRUE if a replacement was
2862    done that my require an EH edge purge.  */
2863
2864 bool
2865 maybe_clean_or_replace_eh_stmt (gimple old_stmt, gimple new_stmt)
2866 {
2867   int lp_nr = lookup_stmt_eh_lp (old_stmt);
2868
2869   if (lp_nr != 0)
2870     {
2871       bool new_stmt_could_throw = stmt_could_throw_p (new_stmt);
2872
2873       if (new_stmt == old_stmt && new_stmt_could_throw)
2874         return false;
2875
2876       remove_stmt_from_eh_lp (old_stmt);
2877       if (new_stmt_could_throw)
2878         {
2879           add_stmt_to_eh_lp (new_stmt, lp_nr);
2880           return false;
2881         }
2882       else
2883         return true;
2884     }
2885
2886   return false;
2887 }
2888
2889 /* Given a statement OLD_STMT in OLD_FUN and a duplicate statement NEW_STMT
2890    in NEW_FUN, copy the EH table data from OLD_STMT to NEW_STMT.  The MAP
2891    operand is the return value of duplicate_eh_regions.  */
2892
2893 bool
2894 maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
2895                             struct function *old_fun, gimple old_stmt,
2896                             hash_map<void *, void *> *map,
2897                             int default_lp_nr)
2898 {
2899   int old_lp_nr, new_lp_nr;
2900
2901   if (!stmt_could_throw_p (new_stmt))
2902     return false;
2903
2904   old_lp_nr = lookup_stmt_eh_lp_fn (old_fun, old_stmt);
2905   if (old_lp_nr == 0)
2906     {
2907       if (default_lp_nr == 0)
2908         return false;
2909       new_lp_nr = default_lp_nr;
2910     }
2911   else if (old_lp_nr > 0)
2912     {
2913       eh_landing_pad old_lp, new_lp;
2914
2915       old_lp = (*old_fun->eh->lp_array)[old_lp_nr];
2916       new_lp = static_cast<eh_landing_pad> (*map->get (old_lp));
2917       new_lp_nr = new_lp->index;
2918     }
2919   else
2920     {
2921       eh_region old_r, new_r;
2922
2923       old_r = (*old_fun->eh->region_array)[-old_lp_nr];
2924       new_r = static_cast<eh_region> (*map->get (old_r));
2925       new_lp_nr = -new_r->index;
2926     }
2927
2928   add_stmt_to_eh_lp_fn (new_fun, new_stmt, new_lp_nr);
2929   return true;
2930 }
2931
2932 /* Similar, but both OLD_STMT and NEW_STMT are within the current function,
2933    and thus no remapping is required.  */
2934
2935 bool
2936 maybe_duplicate_eh_stmt (gimple new_stmt, gimple old_stmt)
2937 {
2938   int lp_nr;
2939
2940   if (!stmt_could_throw_p (new_stmt))
2941     return false;
2942
2943   lp_nr = lookup_stmt_eh_lp (old_stmt);
2944   if (lp_nr == 0)
2945     return false;
2946
2947   add_stmt_to_eh_lp (new_stmt, lp_nr);
2948   return true;
2949 }
2950 \f
2951 /* Returns TRUE if oneh and twoh are exception handlers (gimple_try_cleanup of
2952    GIMPLE_TRY) that are similar enough to be considered the same.  Currently
2953    this only handles handlers consisting of a single call, as that's the
2954    important case for C++: a destructor call for a particular object showing
2955    up in multiple handlers.  */
2956
2957 static bool
2958 same_handler_p (gimple_seq oneh, gimple_seq twoh)
2959 {
2960   gimple_stmt_iterator gsi;
2961   gimple ones, twos;
2962   unsigned int ai;
2963
2964   gsi = gsi_start (oneh);
2965   if (!gsi_one_before_end_p (gsi))
2966     return false;
2967   ones = gsi_stmt (gsi);
2968
2969   gsi = gsi_start (twoh);
2970   if (!gsi_one_before_end_p (gsi))
2971     return false;
2972   twos = gsi_stmt (gsi);
2973
2974   if (!is_gimple_call (ones)
2975       || !is_gimple_call (twos)
2976       || gimple_call_lhs (ones)
2977       || gimple_call_lhs (twos)
2978       || gimple_call_chain (ones)
2979       || gimple_call_chain (twos)
2980       || !gimple_call_same_target_p (ones, twos)
2981       || gimple_call_num_args (ones) != gimple_call_num_args (twos))
2982     return false;
2983
2984   for (ai = 0; ai < gimple_call_num_args (ones); ++ai)
2985     if (!operand_equal_p (gimple_call_arg (ones, ai),
2986                           gimple_call_arg (twos, ai), 0))
2987       return false;
2988
2989   return true;
2990 }
2991
2992 /* Optimize
2993     try { A() } finally { try { ~B() } catch { ~A() } }
2994     try { ... } finally { ~A() }
2995    into
2996     try { A() } catch { ~B() }
2997     try { ~B() ... } finally { ~A() }
2998
2999    This occurs frequently in C++, where A is a local variable and B is a
3000    temporary used in the initializer for A.  */
3001
3002 static void
3003 optimize_double_finally (gimple one, gimple two)
3004 {
3005   gimple oneh;
3006   gimple_stmt_iterator gsi;
3007   gimple_seq cleanup;
3008
3009   cleanup = gimple_try_cleanup (one);
3010   gsi = gsi_start (cleanup);
3011   if (!gsi_one_before_end_p (gsi))
3012     return;
3013
3014   oneh = gsi_stmt (gsi);
3015   if (gimple_code (oneh) != GIMPLE_TRY
3016       || gimple_try_kind (oneh) != GIMPLE_TRY_CATCH)
3017     return;
3018
3019   if (same_handler_p (gimple_try_cleanup (oneh), gimple_try_cleanup (two)))
3020     {
3021       gimple_seq seq = gimple_try_eval (oneh);
3022
3023       gimple_try_set_cleanup (one, seq);
3024       gimple_try_set_kind (one, GIMPLE_TRY_CATCH);
3025       seq = copy_gimple_seq_and_replace_locals (seq);
3026       gimple_seq_add_seq (&seq, gimple_try_eval (two));
3027       gimple_try_set_eval (two, seq);
3028     }
3029 }
3030
3031 /* Perform EH refactoring optimizations that are simpler to do when code
3032    flow has been lowered but EH structures haven't.  */
3033
3034 static void
3035 refactor_eh_r (gimple_seq seq)
3036 {
3037   gimple_stmt_iterator gsi;
3038   gimple one, two;
3039
3040   one = NULL;
3041   two = NULL;
3042   gsi = gsi_start (seq);
3043   while (1)
3044     {
3045       one = two;
3046       if (gsi_end_p (gsi))
3047         two = NULL;
3048       else
3049         two = gsi_stmt (gsi);
3050       if (one
3051           && two
3052           && gimple_code (one) == GIMPLE_TRY
3053           && gimple_code (two) == GIMPLE_TRY
3054           && gimple_try_kind (one) == GIMPLE_TRY_FINALLY
3055           && gimple_try_kind (two) == GIMPLE_TRY_FINALLY)
3056         optimize_double_finally (one, two);
3057       if (one)
3058         switch (gimple_code (one))
3059           {
3060           case GIMPLE_TRY:
3061             refactor_eh_r (gimple_try_eval (one));
3062             refactor_eh_r (gimple_try_cleanup (one));
3063             break;
3064           case GIMPLE_CATCH:
3065             refactor_eh_r (gimple_catch_handler (one));
3066             break;
3067           case GIMPLE_EH_FILTER:
3068             refactor_eh_r (gimple_eh_filter_failure (one));
3069             break;
3070           case GIMPLE_EH_ELSE:
3071             refactor_eh_r (gimple_eh_else_n_body (one));
3072             refactor_eh_r (gimple_eh_else_e_body (one));
3073             break;
3074           default:
3075             break;
3076           }
3077       if (two)
3078         gsi_next (&gsi);
3079       else
3080         break;
3081     }
3082 }
3083
3084 namespace {
3085
3086 const pass_data pass_data_refactor_eh =
3087 {
3088   GIMPLE_PASS, /* type */
3089   "ehopt", /* name */
3090   OPTGROUP_NONE, /* optinfo_flags */
3091   TV_TREE_EH, /* tv_id */
3092   PROP_gimple_lcf, /* properties_required */
3093   0, /* properties_provided */
3094   0, /* properties_destroyed */
3095   0, /* todo_flags_start */
3096   0, /* todo_flags_finish */
3097 };
3098
3099 class pass_refactor_eh : public gimple_opt_pass
3100 {
3101 public:
3102   pass_refactor_eh (gcc::context *ctxt)
3103     : gimple_opt_pass (pass_data_refactor_eh, ctxt)
3104   {}
3105
3106   /* opt_pass methods: */
3107   virtual bool gate (function *) { return flag_exceptions != 0; }
3108   virtual unsigned int execute (function *)
3109     {
3110       refactor_eh_r (gimple_body (current_function_decl));
3111       return 0;
3112     }
3113
3114 }; // class pass_refactor_eh
3115
3116 } // anon namespace
3117
3118 gimple_opt_pass *
3119 make_pass_refactor_eh (gcc::context *ctxt)
3120 {
3121   return new pass_refactor_eh (ctxt);
3122 }
3123 \f
3124 /* At the end of gimple optimization, we can lower RESX.  */
3125
3126 static bool
3127 lower_resx (basic_block bb, gimple stmt, hash_map<eh_region, tree> *mnt_map)
3128 {
3129   int lp_nr;
3130   eh_region src_r, dst_r;
3131   gimple_stmt_iterator gsi;
3132   gimple x;
3133   tree fn, src_nr;
3134   bool ret = false;
3135
3136   lp_nr = lookup_stmt_eh_lp (stmt);
3137   if (lp_nr != 0)
3138     dst_r = get_eh_region_from_lp_number (lp_nr);
3139   else
3140     dst_r = NULL;
3141
3142   src_r = get_eh_region_from_number (gimple_resx_region (stmt));
3143   gsi = gsi_last_bb (bb);
3144
3145   if (src_r == NULL)
3146     {
3147       /* We can wind up with no source region when pass_cleanup_eh shows
3148          that there are no entries into an eh region and deletes it, but
3149          then the block that contains the resx isn't removed.  This can
3150          happen without optimization when the switch statement created by
3151          lower_try_finally_switch isn't simplified to remove the eh case.
3152
3153          Resolve this by expanding the resx node to an abort.  */
3154
3155       fn = builtin_decl_implicit (BUILT_IN_TRAP);
3156       x = gimple_build_call (fn, 0);
3157       gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3158
3159       while (EDGE_COUNT (bb->succs) > 0)
3160         remove_edge (EDGE_SUCC (bb, 0));
3161     }
3162   else if (dst_r)
3163     {
3164       /* When we have a destination region, we resolve this by copying
3165          the excptr and filter values into place, and changing the edge
3166          to immediately after the landing pad.  */
3167       edge e;
3168
3169       if (lp_nr < 0)
3170         {
3171           basic_block new_bb;
3172           tree lab;
3173
3174           /* We are resuming into a MUST_NOT_CALL region.  Expand a call to
3175              the failure decl into a new block, if needed.  */
3176           gcc_assert (dst_r->type == ERT_MUST_NOT_THROW);
3177
3178           tree *slot = mnt_map->get (dst_r);
3179           if (slot == NULL)
3180             {
3181               gimple_stmt_iterator gsi2;
3182
3183               new_bb = create_empty_bb (bb);
3184               add_bb_to_loop (new_bb, bb->loop_father);
3185               lab = gimple_block_label (new_bb);
3186               gsi2 = gsi_start_bb (new_bb);
3187
3188               fn = dst_r->u.must_not_throw.failure_decl;
3189               x = gimple_build_call (fn, 0);
3190               gimple_set_location (x, dst_r->u.must_not_throw.failure_loc);
3191               gsi_insert_after (&gsi2, x, GSI_CONTINUE_LINKING);
3192
3193               mnt_map->put (dst_r, lab);
3194             }
3195           else
3196             {
3197               lab = *slot;
3198               new_bb = label_to_block (lab);
3199             }
3200
3201           gcc_assert (EDGE_COUNT (bb->succs) == 0);
3202           e = make_edge (bb, new_bb, EDGE_FALLTHRU);
3203           e->count = bb->count;
3204           e->probability = REG_BR_PROB_BASE;
3205         }
3206       else
3207         {
3208           edge_iterator ei;
3209           tree dst_nr = build_int_cst (integer_type_node, dst_r->index);
3210
3211           fn = builtin_decl_implicit (BUILT_IN_EH_COPY_VALUES);
3212           src_nr = build_int_cst (integer_type_node, src_r->index);
3213           x = gimple_build_call (fn, 2, dst_nr, src_nr);
3214           gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3215
3216           /* Update the flags for the outgoing edge.  */
3217           e = single_succ_edge (bb);
3218           gcc_assert (e->flags & EDGE_EH);
3219           e->flags = (e->flags & ~EDGE_EH) | EDGE_FALLTHRU;
3220
3221           /* If there are no more EH users of the landing pad, delete it.  */
3222           FOR_EACH_EDGE (e, ei, e->dest->preds)
3223             if (e->flags & EDGE_EH)
3224               break;
3225           if (e == NULL)
3226             {
3227               eh_landing_pad lp = get_eh_landing_pad_from_number (lp_nr);
3228               remove_eh_landing_pad (lp);
3229             }
3230         }
3231
3232       ret = true;
3233     }
3234   else
3235     {
3236       tree var;
3237
3238       /* When we don't have a destination region, this exception escapes
3239          up the call chain.  We resolve this by generating a call to the
3240          _Unwind_Resume library function.  */
3241
3242       /* The ARM EABI redefines _Unwind_Resume as __cxa_end_cleanup
3243          with no arguments for C++ and Java.  Check for that.  */
3244       if (src_r->use_cxa_end_cleanup)
3245         {
3246           fn = builtin_decl_implicit (BUILT_IN_CXA_END_CLEANUP);
3247           x = gimple_build_call (fn, 0);
3248           gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3249         }
3250       else
3251         {
3252           fn = builtin_decl_implicit (BUILT_IN_EH_POINTER);
3253           src_nr = build_int_cst (integer_type_node, src_r->index);
3254           x = gimple_build_call (fn, 1, src_nr);
3255           var = create_tmp_var (ptr_type_node, NULL);
3256           var = make_ssa_name (var, x);
3257           gimple_call_set_lhs (x, var);
3258           gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3259
3260           fn = builtin_decl_implicit (BUILT_IN_UNWIND_RESUME);
3261           x = gimple_build_call (fn, 1, var);
3262           gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3263         }
3264
3265       gcc_assert (EDGE_COUNT (bb->succs) == 0);
3266     }
3267
3268   gsi_remove (&gsi, true);
3269
3270   return ret;
3271 }
3272
3273 namespace {
3274
3275 const pass_data pass_data_lower_resx =
3276 {
3277   GIMPLE_PASS, /* type */
3278   "resx", /* name */
3279   OPTGROUP_NONE, /* optinfo_flags */
3280   TV_TREE_EH, /* tv_id */
3281   PROP_gimple_lcf, /* properties_required */
3282   0, /* properties_provided */
3283   0, /* properties_destroyed */
3284   0, /* todo_flags_start */
3285   0, /* todo_flags_finish */
3286 };
3287
3288 class pass_lower_resx : public gimple_opt_pass
3289 {
3290 public:
3291   pass_lower_resx (gcc::context *ctxt)
3292     : gimple_opt_pass (pass_data_lower_resx, ctxt)
3293   {}
3294
3295   /* opt_pass methods: */
3296   virtual bool gate (function *) { return flag_exceptions != 0; }
3297   virtual unsigned int execute (function *);
3298
3299 }; // class pass_lower_resx
3300
3301 unsigned
3302 pass_lower_resx::execute (function *fun)
3303 {
3304   basic_block bb;
3305   bool dominance_invalidated = false;
3306   bool any_rewritten = false;
3307
3308   hash_map<eh_region, tree> mnt_map;
3309
3310   FOR_EACH_BB_FN (bb, fun)
3311     {
3312       gimple last = last_stmt (bb);
3313       if (last && is_gimple_resx (last))
3314         {
3315           dominance_invalidated |= lower_resx (bb, last, &mnt_map);
3316           any_rewritten = true;
3317         }
3318     }
3319
3320   if (dominance_invalidated)
3321     {
3322       free_dominance_info (CDI_DOMINATORS);
3323       free_dominance_info (CDI_POST_DOMINATORS);
3324     }
3325
3326   return any_rewritten ? TODO_update_ssa_only_virtuals : 0;
3327 }
3328
3329 } // anon namespace
3330
3331 gimple_opt_pass *
3332 make_pass_lower_resx (gcc::context *ctxt)
3333 {
3334   return new pass_lower_resx (ctxt);
3335 }
3336
3337 /* Try to optimize var = {v} {CLOBBER} stmts followed just by
3338    external throw.  */
3339
3340 static void
3341 optimize_clobbers (basic_block bb)
3342 {
3343   gimple_stmt_iterator gsi = gsi_last_bb (bb);
3344   bool any_clobbers = false;
3345   bool seen_stack_restore = false;
3346   edge_iterator ei;
3347   edge e;
3348
3349   /* Only optimize anything if the bb contains at least one clobber,
3350      ends with resx (checked by caller), optionally contains some
3351      debug stmts or labels, or at most one __builtin_stack_restore
3352      call, and has an incoming EH edge.  */
3353   for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
3354     {
3355       gimple stmt = gsi_stmt (gsi);
3356       if (is_gimple_debug (stmt))
3357         continue;
3358       if (gimple_clobber_p (stmt))
3359         {
3360           any_clobbers = true;
3361           continue;
3362         }
3363       if (!seen_stack_restore
3364           && gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE))
3365         {
3366           seen_stack_restore = true;
3367           continue;
3368         }
3369       if (gimple_code (stmt) == GIMPLE_LABEL)
3370         break;
3371       return;
3372     }
3373   if (!any_clobbers)
3374     return;
3375   FOR_EACH_EDGE (e, ei, bb->preds)
3376     if (e->flags & EDGE_EH)
3377       break;
3378   if (e == NULL)
3379     return;
3380   gsi = gsi_last_bb (bb);
3381   for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
3382     {
3383       gimple stmt = gsi_stmt (gsi);
3384       if (!gimple_clobber_p (stmt))
3385         continue;
3386       unlink_stmt_vdef (stmt);
3387       gsi_remove (&gsi, true);
3388       release_defs (stmt);
3389     }
3390 }
3391
3392 /* Try to sink var = {v} {CLOBBER} stmts followed just by
3393    internal throw to successor BB.  */
3394
3395 static int
3396 sink_clobbers (basic_block bb)
3397 {
3398   edge e;
3399   edge_iterator ei;
3400   gimple_stmt_iterator gsi, dgsi;
3401   basic_block succbb;
3402   bool any_clobbers = false;
3403   unsigned todo = 0;
3404
3405   /* Only optimize if BB has a single EH successor and
3406      all predecessor edges are EH too.  */
3407   if (!single_succ_p (bb)
3408       || (single_succ_edge (bb)->flags & EDGE_EH) == 0)
3409     return 0;
3410
3411   FOR_EACH_EDGE (e, ei, bb->preds)
3412     {
3413       if ((e->flags & EDGE_EH) == 0)
3414         return 0;
3415     }
3416
3417   /* And BB contains only CLOBBER stmts before the final
3418      RESX.  */
3419   gsi = gsi_last_bb (bb);
3420   for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
3421     {
3422       gimple stmt = gsi_stmt (gsi);
3423       if (is_gimple_debug (stmt))
3424         continue;
3425       if (gimple_code (stmt) == GIMPLE_LABEL)
3426         break;
3427       if (!gimple_clobber_p (stmt))
3428         return 0;
3429       any_clobbers = true;
3430     }
3431   if (!any_clobbers)
3432     return 0;
3433
3434   edge succe = single_succ_edge (bb);
3435   succbb = succe->dest;
3436
3437   /* See if there is a virtual PHI node to take an updated virtual
3438      operand from.  */
3439   gimple vphi = NULL;
3440   tree vuse = NULL_TREE;
3441   for (gsi = gsi_start_phis (succbb); !gsi_end_p (gsi); gsi_next (&gsi))
3442     {
3443       tree res = gimple_phi_result (gsi_stmt (gsi));
3444       if (virtual_operand_p (res))
3445         {
3446           vphi = gsi_stmt (gsi);
3447           vuse = res;
3448           break;
3449         }
3450     }
3451
3452   dgsi = gsi_after_labels (succbb);
3453   gsi = gsi_last_bb (bb);
3454   for (gsi_prev (&gsi); !gsi_end_p (gsi); gsi_prev (&gsi))
3455     {
3456       gimple stmt = gsi_stmt (gsi);
3457       tree lhs;
3458       if (is_gimple_debug (stmt))
3459         continue;
3460       if (gimple_code (stmt) == GIMPLE_LABEL)
3461         break;
3462       lhs = gimple_assign_lhs (stmt);
3463       /* Unfortunately we don't have dominance info updated at this
3464          point, so checking if
3465          dominated_by_p (CDI_DOMINATORS, succbb,
3466                          gimple_bb (SSA_NAME_DEF_STMT (TREE_OPERAND (lhs, 0)))
3467          would be too costly.  Thus, avoid sinking any clobbers that
3468          refer to non-(D) SSA_NAMEs.  */
3469       if (TREE_CODE (lhs) == MEM_REF
3470           && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME
3471           && !SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (lhs, 0)))
3472         {
3473           unlink_stmt_vdef (stmt);
3474           gsi_remove (&gsi, true);
3475           release_defs (stmt);
3476           continue;
3477         }
3478
3479       /* As we do not change stmt order when sinking across a
3480          forwarder edge we can keep virtual operands in place.  */
3481       gsi_remove (&gsi, false);
3482       gsi_insert_before (&dgsi, stmt, GSI_NEW_STMT);
3483
3484       /* But adjust virtual operands if we sunk across a PHI node.  */
3485       if (vuse)
3486         {
3487           gimple use_stmt;
3488           imm_use_iterator iter;
3489           use_operand_p use_p;
3490           FOR_EACH_IMM_USE_STMT (use_stmt, iter, vuse)
3491             FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
3492               SET_USE (use_p, gimple_vdef (stmt));
3493           if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse))
3494             {
3495               SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_vdef (stmt)) = 1;
3496               SSA_NAME_OCCURS_IN_ABNORMAL_PHI (vuse) = 0;
3497             }
3498           /* Adjust the incoming virtual operand.  */
3499           SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (vphi, succe), gimple_vuse (stmt));
3500           SET_USE (gimple_vuse_op (stmt), vuse);
3501         }
3502       /* If there isn't a single predecessor but no virtual PHI node
3503          arrange for virtual operands to be renamed.  */
3504       else if (gimple_vuse_op (stmt) != NULL_USE_OPERAND_P
3505                && !single_pred_p (succbb))
3506         {
3507           /* In this case there will be no use of the VDEF of this stmt. 
3508              ???  Unless this is a secondary opportunity and we have not
3509              removed unreachable blocks yet, so we cannot assert this.  
3510              Which also means we will end up renaming too many times.  */
3511           SET_USE (gimple_vuse_op (stmt), gimple_vop (cfun));
3512           mark_virtual_operands_for_renaming (cfun);
3513           todo |= TODO_update_ssa_only_virtuals;
3514         }
3515     }
3516
3517   return todo;
3518 }
3519
3520 /* At the end of inlining, we can lower EH_DISPATCH.  Return true when 
3521    we have found some duplicate labels and removed some edges.  */
3522
3523 static bool
3524 lower_eh_dispatch (basic_block src, gimple stmt)
3525 {
3526   gimple_stmt_iterator gsi;
3527   int region_nr;
3528   eh_region r;
3529   tree filter, fn;
3530   gimple x;
3531   bool redirected = false;
3532
3533   region_nr = gimple_eh_dispatch_region (stmt);
3534   r = get_eh_region_from_number (region_nr);
3535
3536   gsi = gsi_last_bb (src);
3537
3538   switch (r->type)
3539     {
3540     case ERT_TRY:
3541       {
3542         auto_vec<tree> labels;
3543         tree default_label = NULL;
3544         eh_catch c;
3545         edge_iterator ei;
3546         edge e;
3547         hash_set<tree> seen_values;
3548
3549         /* Collect the labels for a switch.  Zero the post_landing_pad
3550            field becase we'll no longer have anything keeping these labels
3551            in existence and the optimizer will be free to merge these
3552            blocks at will.  */
3553         for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
3554           {
3555             tree tp_node, flt_node, lab = c->label;
3556             bool have_label = false;
3557
3558             c->label = NULL;
3559             tp_node = c->type_list;
3560             flt_node = c->filter_list;
3561
3562             if (tp_node == NULL)
3563               {
3564                 default_label = lab;
3565                 break;
3566               }
3567             do
3568               {
3569                 /* Filter out duplicate labels that arise when this handler 
3570                    is shadowed by an earlier one.  When no labels are 
3571                    attached to the handler anymore, we remove 
3572                    the corresponding edge and then we delete unreachable 
3573                    blocks at the end of this pass.  */
3574                 if (! seen_values.contains (TREE_VALUE (flt_node)))
3575                   {
3576                     tree t = build_case_label (TREE_VALUE (flt_node),
3577                                                NULL, lab);
3578                     labels.safe_push (t);
3579                     seen_values.add (TREE_VALUE (flt_node));
3580                     have_label = true;
3581                   }
3582
3583                 tp_node = TREE_CHAIN (tp_node);
3584                 flt_node = TREE_CHAIN (flt_node);
3585               }
3586             while (tp_node);
3587             if (! have_label)
3588               {
3589                 remove_edge (find_edge (src, label_to_block (lab)));
3590                 redirected = true;
3591               }
3592           }
3593
3594         /* Clean up the edge flags.  */
3595         FOR_EACH_EDGE (e, ei, src->succs)
3596           {
3597             if (e->flags & EDGE_FALLTHRU)
3598               {
3599                 /* If there was no catch-all, use the fallthru edge.  */
3600                 if (default_label == NULL)
3601                   default_label = gimple_block_label (e->dest);
3602                 e->flags &= ~EDGE_FALLTHRU;
3603               }
3604           }
3605         gcc_assert (default_label != NULL);
3606
3607         /* Don't generate a switch if there's only a default case.
3608            This is common in the form of try { A; } catch (...) { B; }.  */
3609         if (!labels.exists ())
3610           {
3611             e = single_succ_edge (src);
3612             e->flags |= EDGE_FALLTHRU;
3613           }
3614         else
3615           {
3616             fn = builtin_decl_implicit (BUILT_IN_EH_FILTER);
3617             x = gimple_build_call (fn, 1, build_int_cst (integer_type_node,
3618                                                          region_nr));
3619             filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL);
3620             filter = make_ssa_name (filter, x);
3621             gimple_call_set_lhs (x, filter);
3622             gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3623
3624             /* Turn the default label into a default case.  */
3625             default_label = build_case_label (NULL, NULL, default_label);
3626             sort_case_labels (labels);
3627
3628             x = gimple_build_switch (filter, default_label, labels);
3629             gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3630           }
3631       }
3632       break;
3633
3634     case ERT_ALLOWED_EXCEPTIONS:
3635       {
3636         edge b_e = BRANCH_EDGE (src);
3637         edge f_e = FALLTHRU_EDGE (src);
3638
3639         fn = builtin_decl_implicit (BUILT_IN_EH_FILTER);
3640         x = gimple_build_call (fn, 1, build_int_cst (integer_type_node,
3641                                                      region_nr));
3642         filter = create_tmp_var (TREE_TYPE (TREE_TYPE (fn)), NULL);
3643         filter = make_ssa_name (filter, x);
3644         gimple_call_set_lhs (x, filter);
3645         gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3646
3647         r->u.allowed.label = NULL;
3648         x = gimple_build_cond (EQ_EXPR, filter,
3649                                build_int_cst (TREE_TYPE (filter),
3650                                               r->u.allowed.filter),
3651                                NULL_TREE, NULL_TREE);
3652         gsi_insert_before (&gsi, x, GSI_SAME_STMT);
3653
3654         b_e->flags = b_e->flags | EDGE_TRUE_VALUE;
3655         f_e->flags = (f_e->flags & ~EDGE_FALLTHRU) | EDGE_FALSE_VALUE;
3656       }
3657       break;
3658
3659     default:
3660       gcc_unreachable ();
3661     }
3662
3663   /* Replace the EH_DISPATCH with the SWITCH or COND generated above.  */
3664   gsi_remove (&gsi, true);
3665   return redirected;
3666 }
3667
3668 namespace {
3669
3670 const pass_data pass_data_lower_eh_dispatch =
3671 {
3672   GIMPLE_PASS, /* type */
3673   "ehdisp", /* name */
3674   OPTGROUP_NONE, /* optinfo_flags */
3675   TV_TREE_EH, /* tv_id */
3676   PROP_gimple_lcf, /* properties_required */
3677   0, /* properties_provided */
3678   0, /* properties_destroyed */
3679   0, /* todo_flags_start */
3680   0, /* todo_flags_finish */
3681 };
3682
3683 class pass_lower_eh_dispatch : public gimple_opt_pass
3684 {
3685 public:
3686   pass_lower_eh_dispatch (gcc::context *ctxt)
3687     : gimple_opt_pass (pass_data_lower_eh_dispatch, ctxt)
3688   {}
3689
3690   /* opt_pass methods: */
3691   virtual bool gate (function *fun) { return fun->eh->region_tree != NULL; }
3692   virtual unsigned int execute (function *);
3693
3694 }; // class pass_lower_eh_dispatch
3695
3696 unsigned
3697 pass_lower_eh_dispatch::execute (function *fun)
3698 {
3699   basic_block bb;
3700   int flags = 0;
3701   bool redirected = false;
3702
3703   assign_filter_values ();
3704
3705   FOR_EACH_BB_FN (bb, fun)
3706     {
3707       gimple last = last_stmt (bb);
3708       if (last == NULL)
3709         continue;
3710       if (gimple_code (last) == GIMPLE_EH_DISPATCH)
3711         {
3712           redirected |= lower_eh_dispatch (bb, last);
3713           flags |= TODO_update_ssa_only_virtuals;
3714         }
3715       else if (gimple_code (last) == GIMPLE_RESX)
3716         {
3717           if (stmt_can_throw_external (last))
3718             optimize_clobbers (bb);
3719           else
3720             flags |= sink_clobbers (bb);
3721         }
3722     }
3723
3724   if (redirected)
3725     delete_unreachable_blocks ();
3726   return flags;
3727 }
3728
3729 } // anon namespace
3730
3731 gimple_opt_pass *
3732 make_pass_lower_eh_dispatch (gcc::context *ctxt)
3733 {
3734   return new pass_lower_eh_dispatch (ctxt);
3735 }
3736 \f
3737 /* Walk statements, see what regions and, optionally, landing pads
3738    are really referenced.
3739    
3740    Returns in R_REACHABLEP an sbitmap with bits set for reachable regions,
3741    and in LP_REACHABLE an sbitmap with bits set for reachable landing pads.
3742
3743    Passing NULL for LP_REACHABLE is valid, in this case only reachable
3744    regions are marked.
3745
3746    The caller is responsible for freeing the returned sbitmaps.  */
3747
3748 static void
3749 mark_reachable_handlers (sbitmap *r_reachablep, sbitmap *lp_reachablep)
3750 {
3751   sbitmap r_reachable, lp_reachable;
3752   basic_block bb;
3753   bool mark_landing_pads = (lp_reachablep != NULL);
3754   gcc_checking_assert (r_reachablep != NULL);
3755
3756   r_reachable = sbitmap_alloc (cfun->eh->region_array->length ());
3757   bitmap_clear (r_reachable);
3758   *r_reachablep = r_reachable;
3759
3760   if (mark_landing_pads)
3761     {
3762       lp_reachable = sbitmap_alloc (cfun->eh->lp_array->length ());
3763       bitmap_clear (lp_reachable);
3764       *lp_reachablep = lp_reachable;
3765     }
3766   else
3767     lp_reachable = NULL;
3768
3769   FOR_EACH_BB_FN (bb, cfun)
3770     {
3771       gimple_stmt_iterator gsi;
3772
3773       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3774         {
3775           gimple stmt = gsi_stmt (gsi);
3776
3777           if (mark_landing_pads)
3778             {
3779               int lp_nr = lookup_stmt_eh_lp (stmt);
3780
3781               /* Negative LP numbers are MUST_NOT_THROW regions which
3782                  are not considered BB enders.  */
3783               if (lp_nr < 0)
3784                 bitmap_set_bit (r_reachable, -lp_nr);
3785
3786               /* Positive LP numbers are real landing pads, and BB enders.  */
3787               else if (lp_nr > 0)
3788                 {
3789                   gcc_assert (gsi_one_before_end_p (gsi));
3790                   eh_region region = get_eh_region_from_lp_number (lp_nr);
3791                   bitmap_set_bit (r_reachable, region->index);
3792                   bitmap_set_bit (lp_reachable, lp_nr);
3793                 }
3794             }
3795
3796           /* Avoid removing regions referenced from RESX/EH_DISPATCH.  */
3797           switch (gimple_code (stmt))
3798             {
3799             case GIMPLE_RESX:
3800               bitmap_set_bit (r_reachable, gimple_resx_region (stmt));
3801               break;
3802             case GIMPLE_EH_DISPATCH:
3803               bitmap_set_bit (r_reachable, gimple_eh_dispatch_region (stmt));
3804               break;
3805             default:
3806               break;
3807             }
3808         }
3809     }
3810 }
3811
3812 /* Remove unreachable handlers and unreachable landing pads.  */
3813
3814 static void
3815 remove_unreachable_handlers (void)
3816 {
3817   sbitmap r_reachable, lp_reachable;
3818   eh_region region;
3819   eh_landing_pad lp;
3820   unsigned i;
3821
3822   mark_reachable_handlers (&r_reachable, &lp_reachable);
3823
3824   if (dump_file)
3825     {
3826       fprintf (dump_file, "Before removal of unreachable regions:\n");
3827       dump_eh_tree (dump_file, cfun);
3828       fprintf (dump_file, "Reachable regions: ");
3829       dump_bitmap_file (dump_file, r_reachable);
3830       fprintf (dump_file, "Reachable landing pads: ");
3831       dump_bitmap_file (dump_file, lp_reachable);
3832     }
3833
3834   if (dump_file)
3835     {
3836       FOR_EACH_VEC_SAFE_ELT (cfun->eh->region_array, i, region)
3837         if (region && !bitmap_bit_p (r_reachable, region->index))
3838           fprintf (dump_file,
3839                    "Removing unreachable region %d\n",
3840                    region->index);
3841     }
3842
3843   remove_unreachable_eh_regions (r_reachable);
3844
3845   FOR_EACH_VEC_SAFE_ELT (cfun->eh->lp_array, i, lp)
3846     if (lp && !bitmap_bit_p (lp_reachable, lp->index))
3847       {
3848         if (dump_file)
3849           fprintf (dump_file,
3850                    "Removing unreachable landing pad %d\n",
3851                    lp->index);
3852         remove_eh_landing_pad (lp);
3853       }
3854
3855   if (dump_file)
3856     {
3857       fprintf (dump_file, "\n\nAfter removal of unreachable regions:\n");
3858       dump_eh_tree (dump_file, cfun);
3859       fprintf (dump_file, "\n\n");
3860     }
3861
3862   sbitmap_free (r_reachable);
3863   sbitmap_free (lp_reachable);
3864
3865 #ifdef ENABLE_CHECKING
3866   verify_eh_tree (cfun);
3867 #endif
3868 }
3869
3870 /* Remove unreachable handlers if any landing pads have been removed after
3871    last ehcleanup pass (due to gimple_purge_dead_eh_edges).  */
3872
3873 void
3874 maybe_remove_unreachable_handlers (void)
3875 {
3876   eh_landing_pad lp;
3877   unsigned i;
3878
3879   if (cfun->eh == NULL)
3880     return;
3881            
3882   FOR_EACH_VEC_SAFE_ELT (cfun->eh->lp_array, i, lp)
3883     if (lp && lp->post_landing_pad)
3884       {
3885         if (label_to_block (lp->post_landing_pad) == NULL)
3886           {
3887             remove_unreachable_handlers ();
3888             return;
3889           }
3890       }
3891 }
3892
3893 /* Remove regions that do not have landing pads.  This assumes
3894    that remove_unreachable_handlers has already been run, and
3895    that we've just manipulated the landing pads since then.
3896
3897    Preserve regions with landing pads and regions that prevent
3898    exceptions from propagating further, even if these regions
3899    are not reachable.  */
3900
3901 static void
3902 remove_unreachable_handlers_no_lp (void)
3903 {
3904   eh_region region;
3905   sbitmap r_reachable;
3906   unsigned i;
3907
3908   mark_reachable_handlers (&r_reachable, /*lp_reachablep=*/NULL);
3909
3910   FOR_EACH_VEC_SAFE_ELT (cfun->eh->region_array, i, region)
3911     {
3912       if (! region)
3913         continue;
3914
3915       if (region->landing_pads != NULL
3916           || region->type == ERT_MUST_NOT_THROW)
3917         bitmap_set_bit (r_reachable, region->index);
3918
3919       if (dump_file
3920           && !bitmap_bit_p (r_reachable, region->index))
3921         fprintf (dump_file,
3922                  "Removing unreachable region %d\n",
3923                  region->index);
3924     }
3925
3926   remove_unreachable_eh_regions (r_reachable);
3927
3928   sbitmap_free (r_reachable);
3929 }
3930
3931 /* Undo critical edge splitting on an EH landing pad.  Earlier, we
3932    optimisticaly split all sorts of edges, including EH edges.  The
3933    optimization passes in between may not have needed them; if not,
3934    we should undo the split.
3935
3936    Recognize this case by having one EH edge incoming to the BB and
3937    one normal edge outgoing; BB should be empty apart from the
3938    post_landing_pad label.
3939
3940    Note that this is slightly different from the empty handler case
3941    handled by cleanup_empty_eh, in that the actual handler may yet
3942    have actual code but the landing pad has been separated from the
3943    handler.  As such, cleanup_empty_eh relies on this transformation
3944    having been done first.  */
3945
3946 static bool
3947 unsplit_eh (eh_landing_pad lp)
3948 {
3949   basic_block bb = label_to_block (lp->post_landing_pad);
3950   gimple_stmt_iterator gsi;
3951   edge e_in, e_out;
3952
3953   /* Quickly check the edge counts on BB for singularity.  */
3954   if (!single_pred_p (bb) || !single_succ_p (bb))
3955     return false;
3956   e_in = single_pred_edge (bb);
3957   e_out = single_succ_edge (bb);
3958
3959   /* Input edge must be EH and output edge must be normal.  */
3960   if ((e_in->flags & EDGE_EH) == 0 || (e_out->flags & EDGE_EH) != 0)
3961     return false;
3962
3963   /* The block must be empty except for the labels and debug insns.  */
3964   gsi = gsi_after_labels (bb);
3965   if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
3966     gsi_next_nondebug (&gsi);
3967   if (!gsi_end_p (gsi))
3968     return false;
3969
3970   /* The destination block must not already have a landing pad
3971      for a different region.  */
3972   for (gsi = gsi_start_bb (e_out->dest); !gsi_end_p (gsi); gsi_next (&gsi))
3973     {
3974       gimple stmt = gsi_stmt (gsi);
3975       tree lab;
3976       int lp_nr;
3977
3978       if (gimple_code (stmt) != GIMPLE_LABEL)
3979         break;
3980       lab = gimple_label_label (stmt);
3981       lp_nr = EH_LANDING_PAD_NR (lab);
3982       if (lp_nr && get_eh_region_from_lp_number (lp_nr) != lp->region)
3983         return false;
3984     }
3985
3986   /* The new destination block must not already be a destination of
3987      the source block, lest we merge fallthru and eh edges and get
3988      all sorts of confused.  */
3989   if (find_edge (e_in->src, e_out->dest))
3990     return false;
3991
3992   /* ??? We can get degenerate phis due to cfg cleanups.  I would have
3993      thought this should have been cleaned up by a phicprop pass, but
3994      that doesn't appear to handle virtuals.  Propagate by hand.  */
3995   if (!gimple_seq_empty_p (phi_nodes (bb)))
3996     {
3997       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); )
3998         {
3999           gimple use_stmt, phi = gsi_stmt (gsi);
4000           tree lhs = gimple_phi_result (phi);
4001           tree rhs = gimple_phi_arg_def (phi, 0);
4002           use_operand_p use_p;
4003           imm_use_iterator iter;
4004
4005           FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
4006             {
4007               FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
4008                 SET_USE (use_p, rhs);
4009             }
4010
4011           if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
4012             SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs) = 1;
4013
4014           remove_phi_node (&gsi, true);
4015         }
4016     }
4017
4018   if (dump_file && (dump_flags & TDF_DETAILS))
4019     fprintf (dump_file, "Unsplit EH landing pad %d to block %i.\n",
4020              lp->index, e_out->dest->index);
4021
4022   /* Redirect the edge.  Since redirect_eh_edge_1 expects to be moving
4023      a successor edge, humor it.  But do the real CFG change with the
4024      predecessor of E_OUT in order to preserve the ordering of arguments
4025      to the PHI nodes in E_OUT->DEST.  */
4026   redirect_eh_edge_1 (e_in, e_out->dest, false);
4027   redirect_edge_pred (e_out, e_in->src);
4028   e_out->flags = e_in->flags;
4029   e_out->probability = e_in->probability;
4030   e_out->count = e_in->count;
4031   remove_edge (e_in);
4032
4033   return true;
4034 }
4035
4036 /* Examine each landing pad block and see if it matches unsplit_eh.  */
4037
4038 static bool
4039 unsplit_all_eh (void)
4040 {
4041   bool changed = false;
4042   eh_landing_pad lp;
4043   int i;
4044
4045   for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
4046     if (lp)
4047       changed |= unsplit_eh (lp);
4048
4049   return changed;
4050 }
4051
4052 /* A subroutine of cleanup_empty_eh.  Redirect all EH edges incoming
4053    to OLD_BB to NEW_BB; return true on success, false on failure.
4054
4055    OLD_BB_OUT is the edge into NEW_BB from OLD_BB, so if we miss any
4056    PHI variables from OLD_BB we can pick them up from OLD_BB_OUT.
4057    Virtual PHIs may be deleted and marked for renaming.  */
4058
4059 static bool
4060 cleanup_empty_eh_merge_phis (basic_block new_bb, basic_block old_bb,
4061                              edge old_bb_out, bool change_region)
4062 {
4063   gimple_stmt_iterator ngsi, ogsi;
4064   edge_iterator ei;
4065   edge e;
4066   bitmap ophi_handled;
4067
4068   /* The destination block must not be a regular successor for any
4069      of the preds of the landing pad.  Thus, avoid turning
4070         <..>
4071          |  \ EH
4072          |  <..>
4073          |  /
4074         <..>
4075      into
4076         <..>
4077         |  | EH
4078         <..>
4079      which CFG verification would choke on.  See PR45172 and PR51089.  */
4080   FOR_EACH_EDGE (e, ei, old_bb->preds)
4081     if (find_edge (e->src, new_bb))
4082       return false;
4083
4084   FOR_EACH_EDGE (e, ei, old_bb->preds)
4085     redirect_edge_var_map_clear (e);
4086
4087   ophi_handled = BITMAP_ALLOC (NULL);
4088
4089   /* First, iterate through the PHIs on NEW_BB and set up the edge_var_map
4090      for the edges we're going to move.  */
4091   for (ngsi = gsi_start_phis (new_bb); !gsi_end_p (ngsi); gsi_next (&ngsi))
4092     {
4093       gimple ophi, nphi = gsi_stmt (ngsi);
4094       tree nresult, nop;
4095
4096       nresult = gimple_phi_result (nphi);
4097       nop = gimple_phi_arg_def (nphi, old_bb_out->dest_idx);
4098
4099       /* Find the corresponding PHI in OLD_BB so we can forward-propagate
4100          the source ssa_name.  */
4101       ophi = NULL;
4102       for (ogsi = gsi_start_phis (old_bb); !gsi_end_p (ogsi); gsi_next (&ogsi))
4103         {
4104           ophi = gsi_stmt (ogsi);
4105           if (gimple_phi_result (ophi) == nop)
4106             break;
4107           ophi = NULL;
4108         }
4109
4110       /* If we did find the corresponding PHI, copy those inputs.  */
4111       if (ophi)
4112         {
4113           /* If NOP is used somewhere else beyond phis in new_bb, give up.  */
4114           if (!has_single_use (nop))
4115             {
4116               imm_use_iterator imm_iter;
4117               use_operand_p use_p;
4118
4119               FOR_EACH_IMM_USE_FAST (use_p, imm_iter, nop)
4120                 {
4121                   if (!gimple_debug_bind_p (USE_STMT (use_p))
4122                       && (gimple_code (USE_STMT (use_p)) != GIMPLE_PHI
4123                           || gimple_bb (USE_STMT (use_p)) != new_bb))
4124                     goto fail;
4125                 }
4126             }
4127           bitmap_set_bit (ophi_handled, SSA_NAME_VERSION (nop));
4128           FOR_EACH_EDGE (e, ei, old_bb->preds)
4129             {
4130               location_t oloc;
4131               tree oop;
4132
4133               if ((e->flags & EDGE_EH) == 0)
4134                 continue;
4135               oop = gimple_phi_arg_def (ophi, e->dest_idx);
4136               oloc = gimple_phi_arg_location (ophi, e->dest_idx);
4137               redirect_edge_var_map_add (e, nresult, oop, oloc);
4138             }
4139         }
4140       /* If we didn't find the PHI, if it's a real variable or a VOP, we know
4141          from the fact that OLD_BB is tree_empty_eh_handler_p that the
4142          variable is unchanged from input to the block and we can simply
4143          re-use the input to NEW_BB from the OLD_BB_OUT edge.  */
4144       else
4145         {
4146           location_t nloc
4147             = gimple_phi_arg_location (nphi, old_bb_out->dest_idx);
4148           FOR_EACH_EDGE (e, ei, old_bb->preds)
4149             redirect_edge_var_map_add (e, nresult, nop, nloc);
4150         }
4151     }
4152
4153   /* Second, verify that all PHIs from OLD_BB have been handled.  If not,
4154      we don't know what values from the other edges into NEW_BB to use.  */
4155   for (ogsi = gsi_start_phis (old_bb); !gsi_end_p (ogsi); gsi_next (&ogsi))
4156     {
4157       gimple ophi = gsi_stmt (ogsi);
4158       tree oresult = gimple_phi_result (ophi);
4159       if (!bitmap_bit_p (ophi_handled, SSA_NAME_VERSION (oresult)))
4160         goto fail;
4161     }
4162
4163   /* Finally, move the edges and update the PHIs.  */
4164   for (ei = ei_start (old_bb->preds); (e = ei_safe_edge (ei)); )
4165     if (e->flags & EDGE_EH)
4166       {
4167         /* ???  CFG manipluation routines do not try to update loop
4168            form on edge redirection.  Do so manually here for now.  */
4169         /* If we redirect a loop entry or latch edge that will either create
4170            a multiple entry loop or rotate the loop.  If the loops merge
4171            we may have created a loop with multiple latches.
4172            All of this isn't easily fixed thus cancel the affected loop
4173            and mark the other loop as possibly having multiple latches.  */
4174         if (e->dest == e->dest->loop_father->header)
4175           {
4176             mark_loop_for_removal (e->dest->loop_father);
4177             new_bb->loop_father->latch = NULL;
4178             loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
4179           }
4180         redirect_eh_edge_1 (e, new_bb, change_region);
4181         redirect_edge_succ (e, new_bb);
4182         flush_pending_stmts (e);
4183       }
4184     else
4185       ei_next (&ei);
4186
4187   BITMAP_FREE (ophi_handled);
4188   return true;
4189
4190  fail:
4191   FOR_EACH_EDGE (e, ei, old_bb->preds)
4192     redirect_edge_var_map_clear (e);
4193   BITMAP_FREE (ophi_handled);
4194   return false;
4195 }
4196
4197 /* A subroutine of cleanup_empty_eh.  Move a landing pad LP from its
4198    old region to NEW_REGION at BB.  */
4199
4200 static void
4201 cleanup_empty_eh_move_lp (basic_block bb, edge e_out,
4202                           eh_landing_pad lp, eh_region new_region)
4203 {
4204   gimple_stmt_iterator gsi;
4205   eh_landing_pad *pp;
4206
4207   for (pp = &lp->region->landing_pads; *pp != lp; pp = &(*pp)->next_lp)
4208     continue;
4209   *pp = lp->next_lp;
4210
4211   lp->region = new_region;
4212   lp->next_lp = new_region->landing_pads;
4213   new_region->landing_pads = lp;
4214
4215   /* Delete the RESX that was matched within the empty handler block.  */
4216   gsi = gsi_last_bb (bb);
4217   unlink_stmt_vdef (gsi_stmt (gsi));
4218   gsi_remove (&gsi, true);
4219
4220   /* Clean up E_OUT for the fallthru.  */
4221   e_out->flags = (e_out->flags & ~EDGE_EH) | EDGE_FALLTHRU;
4222   e_out->probability = REG_BR_PROB_BASE;
4223 }
4224
4225 /* A subroutine of cleanup_empty_eh.  Handle more complex cases of
4226    unsplitting than unsplit_eh was prepared to handle, e.g. when
4227    multiple incoming edges and phis are involved.  */
4228
4229 static bool
4230 cleanup_empty_eh_unsplit (basic_block bb, edge e_out, eh_landing_pad lp)
4231 {
4232   gimple_stmt_iterator gsi;
4233   tree lab;
4234
4235   /* We really ought not have totally lost everything following
4236      a landing pad label.  Given that BB is empty, there had better
4237      be a successor.  */
4238   gcc_assert (e_out != NULL);
4239
4240   /* The destination block must not already have a landing pad
4241      for a different region.  */
4242   lab = NULL;
4243   for (gsi = gsi_start_bb (e_out->dest); !gsi_end_p (gsi); gsi_next (&gsi))
4244     {
4245       gimple stmt = gsi_stmt (gsi);
4246       int lp_nr;
4247
4248       if (gimple_code (stmt) != GIMPLE_LABEL)
4249         break;
4250       lab = gimple_label_label (stmt);
4251       lp_nr = EH_LANDING_PAD_NR (lab);
4252       if (lp_nr && get_eh_region_from_lp_number (lp_nr) != lp->region)
4253         return false;
4254     }
4255
4256   /* Attempt to move the PHIs into the successor block.  */
4257   if (cleanup_empty_eh_merge_phis (e_out->dest, bb, e_out, false))
4258     {
4259       if (dump_file && (dump_flags & TDF_DETAILS))
4260         fprintf (dump_file,
4261                  "Unsplit EH landing pad %d to block %i "
4262                  "(via cleanup_empty_eh).\n",
4263                  lp->index, e_out->dest->index);
4264       return true;
4265     }
4266
4267   return false;
4268 }
4269
4270 /* Return true if edge E_FIRST is part of an empty infinite loop
4271    or leads to such a loop through a series of single successor
4272    empty bbs.  */
4273
4274 static bool
4275 infinite_empty_loop_p (edge e_first)
4276 {
4277   bool inf_loop = false;
4278   edge e;
4279
4280   if (e_first->dest == e_first->src)
4281     return true;
4282
4283   e_first->src->aux = (void *) 1;
4284   for (e = e_first; single_succ_p (e->dest); e = single_succ_edge (e->dest))
4285     {
4286       gimple_stmt_iterator gsi;
4287       if (e->dest->aux)
4288         {
4289           inf_loop = true;
4290           break;
4291         }
4292       e->dest->aux = (void *) 1;
4293       gsi = gsi_after_labels (e->dest);
4294       if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
4295         gsi_next_nondebug (&gsi);
4296       if (!gsi_end_p (gsi))
4297         break;
4298     }
4299   e_first->src->aux = NULL;
4300   for (e = e_first; e->dest->aux; e = single_succ_edge (e->dest))
4301     e->dest->aux = NULL;
4302
4303   return inf_loop;
4304 }
4305
4306 /* Examine the block associated with LP to determine if it's an empty
4307    handler for its EH region.  If so, attempt to redirect EH edges to
4308    an outer region.  Return true the CFG was updated in any way.  This
4309    is similar to jump forwarding, just across EH edges.  */
4310
4311 static bool
4312 cleanup_empty_eh (eh_landing_pad lp)
4313 {
4314   basic_block bb = label_to_block (lp->post_landing_pad);
4315   gimple_stmt_iterator gsi;
4316   gimple resx;
4317   eh_region new_region;
4318   edge_iterator ei;
4319   edge e, e_out;
4320   bool has_non_eh_pred;
4321   bool ret = false;
4322   int new_lp_nr;
4323
4324   /* There can be zero or one edges out of BB.  This is the quickest test.  */
4325   switch (EDGE_COUNT (bb->succs))
4326     {
4327     case 0:
4328       e_out = NULL;
4329       break;
4330     case 1:
4331       e_out = single_succ_edge (bb);
4332       break;
4333     default:
4334       return false;
4335     }
4336
4337   resx = last_stmt (bb);
4338   if (resx && is_gimple_resx (resx))
4339     {
4340       if (stmt_can_throw_external (resx))
4341         optimize_clobbers (bb);
4342       else if (sink_clobbers (bb))
4343         ret = true;
4344     }
4345
4346   gsi = gsi_after_labels (bb);
4347
4348   /* Make sure to skip debug statements.  */
4349   if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
4350     gsi_next_nondebug (&gsi);
4351
4352   /* If the block is totally empty, look for more unsplitting cases.  */
4353   if (gsi_end_p (gsi))
4354     {
4355       /* For the degenerate case of an infinite loop bail out.
4356          If bb has no successors and is totally empty, which can happen e.g.
4357          because of incorrect noreturn attribute, bail out too.  */
4358       if (e_out == NULL
4359           || infinite_empty_loop_p (e_out))
4360         return ret;
4361
4362       return ret | cleanup_empty_eh_unsplit (bb, e_out, lp);
4363     }
4364
4365   /* The block should consist only of a single RESX statement, modulo a
4366      preceding call to __builtin_stack_restore if there is no outgoing
4367      edge, since the call can be eliminated in this case.  */
4368   resx = gsi_stmt (gsi);
4369   if (!e_out && gimple_call_builtin_p (resx, BUILT_IN_STACK_RESTORE))
4370     {
4371       gsi_next (&gsi);
4372       resx = gsi_stmt (gsi);
4373     }
4374   if (!is_gimple_resx (resx))
4375     return ret;
4376   gcc_assert (gsi_one_before_end_p (gsi));
4377
4378   /* Determine if there are non-EH edges, or resx edges into the handler.  */
4379   has_non_eh_pred = false;
4380   FOR_EACH_EDGE (e, ei, bb->preds)
4381     if (!(e->flags & EDGE_EH))
4382       has_non_eh_pred = true;
4383
4384   /* Find the handler that's outer of the empty handler by looking at
4385      where the RESX instruction was vectored.  */
4386   new_lp_nr = lookup_stmt_eh_lp (resx);
4387   new_region = get_eh_region_from_lp_number (new_lp_nr);
4388
4389   /* If there's no destination region within the current function,
4390      redirection is trivial via removing the throwing statements from
4391      the EH region, removing the EH edges, and allowing the block
4392      to go unreachable.  */
4393   if (new_region == NULL)
4394     {
4395       gcc_assert (e_out == NULL);
4396       for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
4397         if (e->flags & EDGE_EH)
4398           {
4399             gimple stmt = last_stmt (e->src);
4400             remove_stmt_from_eh_lp (stmt);
4401             remove_edge (e);
4402           }
4403         else
4404           ei_next (&ei);
4405       goto succeed;
4406     }
4407
4408   /* If the destination region is a MUST_NOT_THROW, allow the runtime
4409      to handle the abort and allow the blocks to go unreachable.  */
4410   if (new_region->type == ERT_MUST_NOT_THROW)
4411     {
4412       for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
4413         if (e->flags & EDGE_EH)
4414           {
4415             gimple stmt = last_stmt (e->src);
4416             remove_stmt_from_eh_lp (stmt);
4417             add_stmt_to_eh_lp (stmt, new_lp_nr);
4418             remove_edge (e);
4419           }
4420         else
4421           ei_next (&ei);
4422       goto succeed;
4423     }
4424
4425   /* Try to redirect the EH edges and merge the PHIs into the destination
4426      landing pad block.  If the merge succeeds, we'll already have redirected
4427      all the EH edges.  The handler itself will go unreachable if there were
4428      no normal edges.  */
4429   if (cleanup_empty_eh_merge_phis (e_out->dest, bb, e_out, true))
4430     goto succeed;
4431
4432   /* Finally, if all input edges are EH edges, then we can (potentially)
4433      reduce the number of transfers from the runtime by moving the landing
4434      pad from the original region to the new region.  This is a win when
4435      we remove the last CLEANUP region along a particular exception
4436      propagation path.  Since nothing changes except for the region with
4437      which the landing pad is associated, the PHI nodes do not need to be
4438      adjusted at all.  */
4439   if (!has_non_eh_pred)
4440     {
4441       cleanup_empty_eh_move_lp (bb, e_out, lp, new_region);
4442       if (dump_file && (dump_flags & TDF_DETAILS))
4443         fprintf (dump_file, "Empty EH handler %i moved to EH region %i.\n",
4444                  lp->index, new_region->index);
4445
4446       /* ??? The CFG didn't change, but we may have rendered the
4447          old EH region unreachable.  Trigger a cleanup there.  */
4448       return true;
4449     }
4450
4451   return ret;
4452
4453  succeed:
4454   if (dump_file && (dump_flags & TDF_DETAILS))
4455     fprintf (dump_file, "Empty EH handler %i removed.\n", lp->index);
4456   remove_eh_landing_pad (lp);
4457   return true;
4458 }
4459
4460 /* Do a post-order traversal of the EH region tree.  Examine each
4461    post_landing_pad block and see if we can eliminate it as empty.  */
4462
4463 static bool
4464 cleanup_all_empty_eh (void)
4465 {
4466   bool changed = false;
4467   eh_landing_pad lp;
4468   int i;
4469
4470   for (i = 1; vec_safe_iterate (cfun->eh->lp_array, i, &lp); ++i)
4471     if (lp)
4472       changed |= cleanup_empty_eh (lp);
4473
4474   return changed;
4475 }
4476
4477 /* Perform cleanups and lowering of exception handling
4478     1) cleanups regions with handlers doing nothing are optimized out
4479     2) MUST_NOT_THROW regions that became dead because of 1) are optimized out
4480     3) Info about regions that are containing instructions, and regions
4481        reachable via local EH edges is collected
4482     4) Eh tree is pruned for regions no longer necessary.
4483
4484    TODO: Push MUST_NOT_THROW regions to the root of the EH tree.
4485          Unify those that have the same failure decl and locus.
4486 */
4487
4488 static unsigned int
4489 execute_cleanup_eh_1 (void)
4490 {
4491   /* Do this first: unsplit_all_eh and cleanup_all_empty_eh can die
4492      looking up unreachable landing pads.  */
4493   remove_unreachable_handlers ();
4494
4495   /* Watch out for the region tree vanishing due to all unreachable.  */
4496   if (cfun->eh->region_tree)
4497     {
4498       bool changed = false;
4499
4500       if (optimize)
4501         changed |= unsplit_all_eh ();
4502       changed |= cleanup_all_empty_eh ();
4503
4504       if (changed)
4505         {
4506           free_dominance_info (CDI_DOMINATORS);
4507           free_dominance_info (CDI_POST_DOMINATORS);
4508
4509           /* We delayed all basic block deletion, as we may have performed
4510              cleanups on EH edges while non-EH edges were still present.  */
4511           delete_unreachable_blocks ();
4512
4513           /* We manipulated the landing pads.  Remove any region that no
4514              longer has a landing pad.  */
4515           remove_unreachable_handlers_no_lp ();
4516
4517           return TODO_cleanup_cfg | TODO_update_ssa_only_virtuals;
4518         }
4519     }
4520
4521   return 0;
4522 }
4523
4524 namespace {
4525
4526 const pass_data pass_data_cleanup_eh =
4527 {
4528   GIMPLE_PASS, /* type */
4529   "ehcleanup", /* name */
4530   OPTGROUP_NONE, /* optinfo_flags */
4531   TV_TREE_EH, /* tv_id */
4532   PROP_gimple_lcf, /* properties_required */
4533   0, /* properties_provided */
4534   0, /* properties_destroyed */
4535   0, /* todo_flags_start */
4536   0, /* todo_flags_finish */
4537 };
4538
4539 class pass_cleanup_eh : public gimple_opt_pass
4540 {
4541 public:
4542   pass_cleanup_eh (gcc::context *ctxt)
4543     : gimple_opt_pass (pass_data_cleanup_eh, ctxt)
4544   {}
4545
4546   /* opt_pass methods: */
4547   opt_pass * clone () { return new pass_cleanup_eh (m_ctxt); }
4548   virtual bool gate (function *fun)
4549     {
4550       return fun->eh != NULL && fun->eh->region_tree != NULL;
4551     }
4552
4553   virtual unsigned int execute (function *);
4554
4555 }; // class pass_cleanup_eh
4556
4557 unsigned int
4558 pass_cleanup_eh::execute (function *fun)
4559 {
4560   int ret = execute_cleanup_eh_1 ();
4561
4562   /* If the function no longer needs an EH personality routine
4563      clear it.  This exposes cross-language inlining opportunities
4564      and avoids references to a never defined personality routine.  */
4565   if (DECL_FUNCTION_PERSONALITY (current_function_decl)
4566       && function_needs_eh_personality (fun) != eh_personality_lang)
4567     DECL_FUNCTION_PERSONALITY (current_function_decl) = NULL_TREE;
4568
4569   return ret;
4570 }
4571
4572 } // anon namespace
4573
4574 gimple_opt_pass *
4575 make_pass_cleanup_eh (gcc::context *ctxt)
4576 {
4577   return new pass_cleanup_eh (ctxt);
4578 }
4579 \f
4580 /* Verify that BB containing STMT as the last statement, has precisely the
4581    edge that make_eh_edges would create.  */
4582
4583 DEBUG_FUNCTION bool
4584 verify_eh_edges (gimple stmt)
4585 {
4586   basic_block bb = gimple_bb (stmt);
4587   eh_landing_pad lp = NULL;
4588   int lp_nr;
4589   edge_iterator ei;
4590   edge e, eh_edge;
4591
4592   lp_nr = lookup_stmt_eh_lp (stmt);
4593   if (lp_nr > 0)
4594     lp = get_eh_landing_pad_from_number (lp_nr);
4595
4596   eh_edge = NULL;
4597   FOR_EACH_EDGE (e, ei, bb->succs)
4598     {
4599       if (e->flags & EDGE_EH)
4600         {
4601           if (eh_edge)
4602             {
4603               error ("BB %i has multiple EH edges", bb->index);
4604               return true;
4605             }
4606           else
4607             eh_edge = e;
4608         }
4609     }
4610
4611   if (lp == NULL)
4612     {
4613       if (eh_edge)
4614         {
4615           error ("BB %i can not throw but has an EH edge", bb->index);
4616           return true;
4617         }
4618       return false;
4619     }
4620
4621   if (!stmt_could_throw_p (stmt))
4622     {
4623       error ("BB %i last statement has incorrectly set lp", bb->index);
4624       return true;
4625     }
4626
4627   if (eh_edge == NULL)
4628     {
4629       error ("BB %i is missing an EH edge", bb->index);
4630       return true;
4631     }
4632
4633   if (eh_edge->dest != label_to_block (lp->post_landing_pad))
4634     {
4635       error ("Incorrect EH edge %i->%i", bb->index, eh_edge->dest->index);
4636       return true;
4637     }
4638
4639   return false;
4640 }
4641
4642 /* Similarly, but handle GIMPLE_EH_DISPATCH specifically.  */
4643
4644 DEBUG_FUNCTION bool
4645 verify_eh_dispatch_edge (gimple stmt)
4646 {
4647   eh_region r;
4648   eh_catch c;
4649   basic_block src, dst;
4650   bool want_fallthru = true;
4651   edge_iterator ei;
4652   edge e, fall_edge;
4653
4654   r = get_eh_region_from_number (gimple_eh_dispatch_region (stmt));
4655   src = gimple_bb (stmt);
4656
4657   FOR_EACH_EDGE (e, ei, src->succs)
4658     gcc_assert (e->aux == NULL);
4659
4660   switch (r->type)
4661     {
4662     case ERT_TRY:
4663       for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
4664         {
4665           dst = label_to_block (c->label);
4666           e = find_edge (src, dst);
4667           if (e == NULL)
4668             {
4669               error ("BB %i is missing an edge", src->index);
4670               return true;
4671             }
4672           e->aux = (void *)e;
4673
4674           /* A catch-all handler doesn't have a fallthru.  */
4675           if (c->type_list == NULL)
4676             {
4677               want_fallthru = false;
4678               break;
4679             }
4680         }
4681       break;
4682
4683     case ERT_ALLOWED_EXCEPTIONS:
4684       dst = label_to_block (r->u.allowed.label);
4685       e = find_edge (src, dst);
4686       if (e == NULL)
4687         {
4688           error ("BB %i is missing an edge", src->index);
4689           return true;
4690         }
4691       e->aux = (void *)e;
4692       break;
4693
4694     default:
4695       gcc_unreachable ();
4696     }
4697
4698   fall_edge = NULL;
4699   FOR_EACH_EDGE (e, ei, src->succs)
4700     {
4701       if (e->flags & EDGE_FALLTHRU)
4702         {
4703           if (fall_edge != NULL)
4704             {
4705               error ("BB %i too many fallthru edges", src->index);
4706               return true;
4707             }
4708           fall_edge = e;
4709         }
4710       else if (e->aux)
4711         e->aux = NULL;
4712       else
4713         {
4714           error ("BB %i has incorrect edge", src->index);
4715           return true;
4716         }
4717     }
4718   if ((fall_edge != NULL) ^ want_fallthru)
4719     {
4720       error ("BB %i has incorrect fallthru edge", src->index);
4721       return true;
4722     }
4723
4724   return false;
4725 }