xref: /dragonfly/contrib/gcc-4.7/gcc/cfgcleanup.c (revision 95d28233)
1e4b17023SJohn Marino /* Control flow optimization code for GNU compiler.
2e4b17023SJohn Marino    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3e4b17023SJohn Marino    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
4e4b17023SJohn Marino    Free Software Foundation, Inc.
5e4b17023SJohn Marino 
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino 
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11e4b17023SJohn Marino version.
12e4b17023SJohn Marino 
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16e4b17023SJohn Marino for more details.
17e4b17023SJohn Marino 
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21e4b17023SJohn Marino 
22e4b17023SJohn Marino /* This file contains optimizer of the control flow.  The main entry point is
23e4b17023SJohn Marino    cleanup_cfg.  Following optimizations are performed:
24e4b17023SJohn Marino 
25e4b17023SJohn Marino    - Unreachable blocks removal
26e4b17023SJohn Marino    - Edge forwarding (edge to the forwarder block is forwarded to its
27e4b17023SJohn Marino      successor.  Simplification of the branch instruction is performed by
28e4b17023SJohn Marino      underlying infrastructure so branch can be converted to simplejump or
29e4b17023SJohn Marino      eliminated).
30e4b17023SJohn Marino    - Cross jumping (tail merging)
31e4b17023SJohn Marino    - Conditional jump-around-simplejump simplification
32e4b17023SJohn Marino    - Basic block merging.  */
33e4b17023SJohn Marino 
34e4b17023SJohn Marino #include "config.h"
35e4b17023SJohn Marino #include "system.h"
36e4b17023SJohn Marino #include "coretypes.h"
37e4b17023SJohn Marino #include "tm.h"
38e4b17023SJohn Marino #include "rtl.h"
39e4b17023SJohn Marino #include "hard-reg-set.h"
40e4b17023SJohn Marino #include "regs.h"
41e4b17023SJohn Marino #include "timevar.h"
42e4b17023SJohn Marino #include "output.h"
43e4b17023SJohn Marino #include "insn-config.h"
44e4b17023SJohn Marino #include "flags.h"
45e4b17023SJohn Marino #include "recog.h"
46e4b17023SJohn Marino #include "diagnostic-core.h"
47e4b17023SJohn Marino #include "cselib.h"
48e4b17023SJohn Marino #include "params.h"
49e4b17023SJohn Marino #include "tm_p.h"
50e4b17023SJohn Marino #include "target.h"
51e4b17023SJohn Marino #include "cfglayout.h"
52e4b17023SJohn Marino #include "emit-rtl.h"
53e4b17023SJohn Marino #include "tree-pass.h"
54e4b17023SJohn Marino #include "cfgloop.h"
55e4b17023SJohn Marino #include "expr.h"
56e4b17023SJohn Marino #include "df.h"
57e4b17023SJohn Marino #include "dce.h"
58e4b17023SJohn Marino #include "dbgcnt.h"
59e4b17023SJohn Marino 
60e4b17023SJohn Marino #define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK)
61e4b17023SJohn Marino 
62e4b17023SJohn Marino /* Set to true when we are running first pass of try_optimize_cfg loop.  */
63e4b17023SJohn Marino static bool first_pass;
64e4b17023SJohn Marino 
65e4b17023SJohn Marino /* Set to true if crossjumps occured in the latest run of try_optimize_cfg.  */
66e4b17023SJohn Marino static bool crossjumps_occured;
67e4b17023SJohn Marino 
68e4b17023SJohn Marino /* Set to true if we couldn't run an optimization due to stale liveness
69e4b17023SJohn Marino    information; we should run df_analyze to enable more opportunities.  */
70e4b17023SJohn Marino static bool block_was_dirty;
71e4b17023SJohn Marino 
72e4b17023SJohn Marino static bool try_crossjump_to_edge (int, edge, edge, enum replace_direction);
73e4b17023SJohn Marino static bool try_crossjump_bb (int, basic_block);
74e4b17023SJohn Marino static bool outgoing_edges_match (int, basic_block, basic_block);
75e4b17023SJohn Marino static enum replace_direction old_insns_match_p (int, rtx, rtx);
76e4b17023SJohn Marino 
77e4b17023SJohn Marino static void merge_blocks_move_predecessor_nojumps (basic_block, basic_block);
78e4b17023SJohn Marino static void merge_blocks_move_successor_nojumps (basic_block, basic_block);
79e4b17023SJohn Marino static bool try_optimize_cfg (int);
80e4b17023SJohn Marino static bool try_simplify_condjump (basic_block);
81e4b17023SJohn Marino static bool try_forward_edges (int, basic_block);
82e4b17023SJohn Marino static edge thread_jump (edge, basic_block);
83e4b17023SJohn Marino static bool mark_effect (rtx, bitmap);
84e4b17023SJohn Marino static void notice_new_block (basic_block);
85e4b17023SJohn Marino static void update_forwarder_flag (basic_block);
86e4b17023SJohn Marino static int mentions_nonequal_regs (rtx *, void *);
87e4b17023SJohn Marino static void merge_memattrs (rtx, rtx);
88e4b17023SJohn Marino 
89e4b17023SJohn Marino /* Set flags for newly created block.  */
90e4b17023SJohn Marino 
91e4b17023SJohn Marino static void
notice_new_block(basic_block bb)92e4b17023SJohn Marino notice_new_block (basic_block bb)
93e4b17023SJohn Marino {
94e4b17023SJohn Marino   if (!bb)
95e4b17023SJohn Marino     return;
96e4b17023SJohn Marino 
97e4b17023SJohn Marino   if (forwarder_block_p (bb))
98e4b17023SJohn Marino     bb->flags |= BB_FORWARDER_BLOCK;
99e4b17023SJohn Marino }
100e4b17023SJohn Marino 
101e4b17023SJohn Marino /* Recompute forwarder flag after block has been modified.  */
102e4b17023SJohn Marino 
103e4b17023SJohn Marino static void
update_forwarder_flag(basic_block bb)104e4b17023SJohn Marino update_forwarder_flag (basic_block bb)
105e4b17023SJohn Marino {
106e4b17023SJohn Marino   if (forwarder_block_p (bb))
107e4b17023SJohn Marino     bb->flags |= BB_FORWARDER_BLOCK;
108e4b17023SJohn Marino   else
109e4b17023SJohn Marino     bb->flags &= ~BB_FORWARDER_BLOCK;
110e4b17023SJohn Marino }
111e4b17023SJohn Marino 
112e4b17023SJohn Marino /* Simplify a conditional jump around an unconditional jump.
113e4b17023SJohn Marino    Return true if something changed.  */
114e4b17023SJohn Marino 
115e4b17023SJohn Marino static bool
try_simplify_condjump(basic_block cbranch_block)116e4b17023SJohn Marino try_simplify_condjump (basic_block cbranch_block)
117e4b17023SJohn Marino {
118e4b17023SJohn Marino   basic_block jump_block, jump_dest_block, cbranch_dest_block;
119e4b17023SJohn Marino   edge cbranch_jump_edge, cbranch_fallthru_edge;
120e4b17023SJohn Marino   rtx cbranch_insn;
121e4b17023SJohn Marino 
122e4b17023SJohn Marino   /* Verify that there are exactly two successors.  */
123e4b17023SJohn Marino   if (EDGE_COUNT (cbranch_block->succs) != 2)
124e4b17023SJohn Marino     return false;
125e4b17023SJohn Marino 
126e4b17023SJohn Marino   /* Verify that we've got a normal conditional branch at the end
127e4b17023SJohn Marino      of the block.  */
128e4b17023SJohn Marino   cbranch_insn = BB_END (cbranch_block);
129e4b17023SJohn Marino   if (!any_condjump_p (cbranch_insn))
130e4b17023SJohn Marino     return false;
131e4b17023SJohn Marino 
132e4b17023SJohn Marino   cbranch_fallthru_edge = FALLTHRU_EDGE (cbranch_block);
133e4b17023SJohn Marino   cbranch_jump_edge = BRANCH_EDGE (cbranch_block);
134e4b17023SJohn Marino 
135e4b17023SJohn Marino   /* The next block must not have multiple predecessors, must not
136e4b17023SJohn Marino      be the last block in the function, and must contain just the
137e4b17023SJohn Marino      unconditional jump.  */
138e4b17023SJohn Marino   jump_block = cbranch_fallthru_edge->dest;
139e4b17023SJohn Marino   if (!single_pred_p (jump_block)
140e4b17023SJohn Marino       || jump_block->next_bb == EXIT_BLOCK_PTR
141e4b17023SJohn Marino       || !FORWARDER_BLOCK_P (jump_block))
142e4b17023SJohn Marino     return false;
143e4b17023SJohn Marino   jump_dest_block = single_succ (jump_block);
144e4b17023SJohn Marino 
145e4b17023SJohn Marino   /* If we are partitioning hot/cold basic blocks, we don't want to
146e4b17023SJohn Marino      mess up unconditional or indirect jumps that cross between hot
147e4b17023SJohn Marino      and cold sections.
148e4b17023SJohn Marino 
149e4b17023SJohn Marino      Basic block partitioning may result in some jumps that appear to
150e4b17023SJohn Marino      be optimizable (or blocks that appear to be mergeable), but which really
151e4b17023SJohn Marino      must be left untouched (they are required to make it safely across
152e4b17023SJohn Marino      partition boundaries).  See the comments at the top of
153e4b17023SJohn Marino      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
154e4b17023SJohn Marino 
155e4b17023SJohn Marino   if (BB_PARTITION (jump_block) != BB_PARTITION (jump_dest_block)
156e4b17023SJohn Marino       || (cbranch_jump_edge->flags & EDGE_CROSSING))
157e4b17023SJohn Marino     return false;
158e4b17023SJohn Marino 
159e4b17023SJohn Marino   /* The conditional branch must target the block after the
160e4b17023SJohn Marino      unconditional branch.  */
161e4b17023SJohn Marino   cbranch_dest_block = cbranch_jump_edge->dest;
162e4b17023SJohn Marino 
163e4b17023SJohn Marino   if (cbranch_dest_block == EXIT_BLOCK_PTR
164e4b17023SJohn Marino       || !can_fallthru (jump_block, cbranch_dest_block))
165e4b17023SJohn Marino     return false;
166e4b17023SJohn Marino 
167e4b17023SJohn Marino   /* Invert the conditional branch.  */
168e4b17023SJohn Marino   if (!invert_jump (cbranch_insn, block_label (jump_dest_block), 0))
169e4b17023SJohn Marino     return false;
170e4b17023SJohn Marino 
171e4b17023SJohn Marino   if (dump_file)
172e4b17023SJohn Marino     fprintf (dump_file, "Simplifying condjump %i around jump %i\n",
173e4b17023SJohn Marino 	     INSN_UID (cbranch_insn), INSN_UID (BB_END (jump_block)));
174e4b17023SJohn Marino 
175e4b17023SJohn Marino   /* Success.  Update the CFG to match.  Note that after this point
176e4b17023SJohn Marino      the edge variable names appear backwards; the redirection is done
177e4b17023SJohn Marino      this way to preserve edge profile data.  */
178e4b17023SJohn Marino   cbranch_jump_edge = redirect_edge_succ_nodup (cbranch_jump_edge,
179e4b17023SJohn Marino 						cbranch_dest_block);
180e4b17023SJohn Marino   cbranch_fallthru_edge = redirect_edge_succ_nodup (cbranch_fallthru_edge,
181e4b17023SJohn Marino 						    jump_dest_block);
182e4b17023SJohn Marino   cbranch_jump_edge->flags |= EDGE_FALLTHRU;
183e4b17023SJohn Marino   cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
184e4b17023SJohn Marino   update_br_prob_note (cbranch_block);
185e4b17023SJohn Marino 
186e4b17023SJohn Marino   /* Delete the block with the unconditional jump, and clean up the mess.  */
187e4b17023SJohn Marino   delete_basic_block (jump_block);
188e4b17023SJohn Marino   tidy_fallthru_edge (cbranch_jump_edge);
189e4b17023SJohn Marino   update_forwarder_flag (cbranch_block);
190e4b17023SJohn Marino 
191e4b17023SJohn Marino   return true;
192e4b17023SJohn Marino }
193e4b17023SJohn Marino 
194e4b17023SJohn Marino /* Attempt to prove that operation is NOOP using CSElib or mark the effect
195e4b17023SJohn Marino    on register.  Used by jump threading.  */
196e4b17023SJohn Marino 
197e4b17023SJohn Marino static bool
mark_effect(rtx exp,regset nonequal)198e4b17023SJohn Marino mark_effect (rtx exp, regset nonequal)
199e4b17023SJohn Marino {
200e4b17023SJohn Marino   int regno;
201e4b17023SJohn Marino   rtx dest;
202e4b17023SJohn Marino   switch (GET_CODE (exp))
203e4b17023SJohn Marino     {
204e4b17023SJohn Marino       /* In case we do clobber the register, mark it as equal, as we know the
205e4b17023SJohn Marino 	 value is dead so it don't have to match.  */
206e4b17023SJohn Marino     case CLOBBER:
207e4b17023SJohn Marino       if (REG_P (XEXP (exp, 0)))
208e4b17023SJohn Marino 	{
209e4b17023SJohn Marino 	  dest = XEXP (exp, 0);
210e4b17023SJohn Marino 	  regno = REGNO (dest);
211e4b17023SJohn Marino 	  if (HARD_REGISTER_NUM_P (regno))
212e4b17023SJohn Marino 	    bitmap_clear_range (nonequal, regno,
213e4b17023SJohn Marino 				hard_regno_nregs[regno][GET_MODE (dest)]);
214e4b17023SJohn Marino 	  else
215e4b17023SJohn Marino 	    bitmap_clear_bit (nonequal, regno);
216e4b17023SJohn Marino 	}
217e4b17023SJohn Marino       return false;
218e4b17023SJohn Marino 
219e4b17023SJohn Marino     case SET:
220e4b17023SJohn Marino       if (rtx_equal_for_cselib_p (SET_DEST (exp), SET_SRC (exp)))
221e4b17023SJohn Marino 	return false;
222e4b17023SJohn Marino       dest = SET_DEST (exp);
223e4b17023SJohn Marino       if (dest == pc_rtx)
224e4b17023SJohn Marino 	return false;
225e4b17023SJohn Marino       if (!REG_P (dest))
226e4b17023SJohn Marino 	return true;
227e4b17023SJohn Marino       regno = REGNO (dest);
228e4b17023SJohn Marino       if (HARD_REGISTER_NUM_P (regno))
229e4b17023SJohn Marino 	bitmap_set_range (nonequal, regno,
230e4b17023SJohn Marino 			  hard_regno_nregs[regno][GET_MODE (dest)]);
231e4b17023SJohn Marino       else
232e4b17023SJohn Marino 	bitmap_set_bit (nonequal, regno);
233e4b17023SJohn Marino       return false;
234e4b17023SJohn Marino 
235e4b17023SJohn Marino     default:
236e4b17023SJohn Marino       return false;
237e4b17023SJohn Marino     }
238e4b17023SJohn Marino }
239e4b17023SJohn Marino 
240e4b17023SJohn Marino /* Return nonzero if X is a register set in regset DATA.
241e4b17023SJohn Marino    Called via for_each_rtx.  */
242e4b17023SJohn Marino static int
mentions_nonequal_regs(rtx * x,void * data)243e4b17023SJohn Marino mentions_nonequal_regs (rtx *x, void *data)
244e4b17023SJohn Marino {
245e4b17023SJohn Marino   regset nonequal = (regset) data;
246e4b17023SJohn Marino   if (REG_P (*x))
247e4b17023SJohn Marino     {
248e4b17023SJohn Marino       int regno;
249e4b17023SJohn Marino 
250e4b17023SJohn Marino       regno = REGNO (*x);
251e4b17023SJohn Marino       if (REGNO_REG_SET_P (nonequal, regno))
252e4b17023SJohn Marino 	return 1;
253e4b17023SJohn Marino       if (regno < FIRST_PSEUDO_REGISTER)
254e4b17023SJohn Marino 	{
255e4b17023SJohn Marino 	  int n = hard_regno_nregs[regno][GET_MODE (*x)];
256e4b17023SJohn Marino 	  while (--n > 0)
257e4b17023SJohn Marino 	    if (REGNO_REG_SET_P (nonequal, regno + n))
258e4b17023SJohn Marino 	      return 1;
259e4b17023SJohn Marino 	}
260e4b17023SJohn Marino     }
261e4b17023SJohn Marino   return 0;
262e4b17023SJohn Marino }
263e4b17023SJohn Marino /* Attempt to prove that the basic block B will have no side effects and
264e4b17023SJohn Marino    always continues in the same edge if reached via E.  Return the edge
265e4b17023SJohn Marino    if exist, NULL otherwise.  */
266e4b17023SJohn Marino 
267e4b17023SJohn Marino static edge
thread_jump(edge e,basic_block b)268e4b17023SJohn Marino thread_jump (edge e, basic_block b)
269e4b17023SJohn Marino {
270e4b17023SJohn Marino   rtx set1, set2, cond1, cond2, insn;
271e4b17023SJohn Marino   enum rtx_code code1, code2, reversed_code2;
272e4b17023SJohn Marino   bool reverse1 = false;
273e4b17023SJohn Marino   unsigned i;
274e4b17023SJohn Marino   regset nonequal;
275e4b17023SJohn Marino   bool failed = false;
276e4b17023SJohn Marino   reg_set_iterator rsi;
277e4b17023SJohn Marino 
278e4b17023SJohn Marino   if (b->flags & BB_NONTHREADABLE_BLOCK)
279e4b17023SJohn Marino     return NULL;
280e4b17023SJohn Marino 
281e4b17023SJohn Marino   /* At the moment, we do handle only conditional jumps, but later we may
282e4b17023SJohn Marino      want to extend this code to tablejumps and others.  */
283e4b17023SJohn Marino   if (EDGE_COUNT (e->src->succs) != 2)
284e4b17023SJohn Marino     return NULL;
285e4b17023SJohn Marino   if (EDGE_COUNT (b->succs) != 2)
286e4b17023SJohn Marino     {
287e4b17023SJohn Marino       b->flags |= BB_NONTHREADABLE_BLOCK;
288e4b17023SJohn Marino       return NULL;
289e4b17023SJohn Marino     }
290e4b17023SJohn Marino 
291e4b17023SJohn Marino   /* Second branch must end with onlyjump, as we will eliminate the jump.  */
292e4b17023SJohn Marino   if (!any_condjump_p (BB_END (e->src)))
293e4b17023SJohn Marino     return NULL;
294e4b17023SJohn Marino 
295e4b17023SJohn Marino   if (!any_condjump_p (BB_END (b)) || !onlyjump_p (BB_END (b)))
296e4b17023SJohn Marino     {
297e4b17023SJohn Marino       b->flags |= BB_NONTHREADABLE_BLOCK;
298e4b17023SJohn Marino       return NULL;
299e4b17023SJohn Marino     }
300e4b17023SJohn Marino 
301e4b17023SJohn Marino   set1 = pc_set (BB_END (e->src));
302e4b17023SJohn Marino   set2 = pc_set (BB_END (b));
303e4b17023SJohn Marino   if (((e->flags & EDGE_FALLTHRU) != 0)
304e4b17023SJohn Marino       != (XEXP (SET_SRC (set1), 1) == pc_rtx))
305e4b17023SJohn Marino     reverse1 = true;
306e4b17023SJohn Marino 
307e4b17023SJohn Marino   cond1 = XEXP (SET_SRC (set1), 0);
308e4b17023SJohn Marino   cond2 = XEXP (SET_SRC (set2), 0);
309e4b17023SJohn Marino   if (reverse1)
310e4b17023SJohn Marino     code1 = reversed_comparison_code (cond1, BB_END (e->src));
311e4b17023SJohn Marino   else
312e4b17023SJohn Marino     code1 = GET_CODE (cond1);
313e4b17023SJohn Marino 
314e4b17023SJohn Marino   code2 = GET_CODE (cond2);
315e4b17023SJohn Marino   reversed_code2 = reversed_comparison_code (cond2, BB_END (b));
316e4b17023SJohn Marino 
317e4b17023SJohn Marino   if (!comparison_dominates_p (code1, code2)
318e4b17023SJohn Marino       && !comparison_dominates_p (code1, reversed_code2))
319e4b17023SJohn Marino     return NULL;
320e4b17023SJohn Marino 
321e4b17023SJohn Marino   /* Ensure that the comparison operators are equivalent.
322e4b17023SJohn Marino      ??? This is far too pessimistic.  We should allow swapped operands,
323e4b17023SJohn Marino      different CCmodes, or for example comparisons for interval, that
324e4b17023SJohn Marino      dominate even when operands are not equivalent.  */
325e4b17023SJohn Marino   if (!rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
326e4b17023SJohn Marino       || !rtx_equal_p (XEXP (cond1, 1), XEXP (cond2, 1)))
327e4b17023SJohn Marino     return NULL;
328e4b17023SJohn Marino 
329e4b17023SJohn Marino   /* Short circuit cases where block B contains some side effects, as we can't
330e4b17023SJohn Marino      safely bypass it.  */
331e4b17023SJohn Marino   for (insn = NEXT_INSN (BB_HEAD (b)); insn != NEXT_INSN (BB_END (b));
332e4b17023SJohn Marino        insn = NEXT_INSN (insn))
333e4b17023SJohn Marino     if (INSN_P (insn) && side_effects_p (PATTERN (insn)))
334e4b17023SJohn Marino       {
335e4b17023SJohn Marino 	b->flags |= BB_NONTHREADABLE_BLOCK;
336e4b17023SJohn Marino 	return NULL;
337e4b17023SJohn Marino       }
338e4b17023SJohn Marino 
339e4b17023SJohn Marino   cselib_init (0);
340e4b17023SJohn Marino 
341e4b17023SJohn Marino   /* First process all values computed in the source basic block.  */
342e4b17023SJohn Marino   for (insn = NEXT_INSN (BB_HEAD (e->src));
343e4b17023SJohn Marino        insn != NEXT_INSN (BB_END (e->src));
344e4b17023SJohn Marino        insn = NEXT_INSN (insn))
345e4b17023SJohn Marino     if (INSN_P (insn))
346e4b17023SJohn Marino       cselib_process_insn (insn);
347e4b17023SJohn Marino 
348e4b17023SJohn Marino   nonequal = BITMAP_ALLOC (NULL);
349e4b17023SJohn Marino   CLEAR_REG_SET (nonequal);
350e4b17023SJohn Marino 
351e4b17023SJohn Marino   /* Now assume that we've continued by the edge E to B and continue
352e4b17023SJohn Marino      processing as if it were same basic block.
353e4b17023SJohn Marino      Our goal is to prove that whole block is an NOOP.  */
354e4b17023SJohn Marino 
355e4b17023SJohn Marino   for (insn = NEXT_INSN (BB_HEAD (b));
356e4b17023SJohn Marino        insn != NEXT_INSN (BB_END (b)) && !failed;
357e4b17023SJohn Marino        insn = NEXT_INSN (insn))
358e4b17023SJohn Marino     {
359e4b17023SJohn Marino       if (INSN_P (insn))
360e4b17023SJohn Marino 	{
361e4b17023SJohn Marino 	  rtx pat = PATTERN (insn);
362e4b17023SJohn Marino 
363e4b17023SJohn Marino 	  if (GET_CODE (pat) == PARALLEL)
364e4b17023SJohn Marino 	    {
365e4b17023SJohn Marino 	      for (i = 0; i < (unsigned)XVECLEN (pat, 0); i++)
366e4b17023SJohn Marino 		failed |= mark_effect (XVECEXP (pat, 0, i), nonequal);
367e4b17023SJohn Marino 	    }
368e4b17023SJohn Marino 	  else
369e4b17023SJohn Marino 	    failed |= mark_effect (pat, nonequal);
370e4b17023SJohn Marino 	}
371e4b17023SJohn Marino 
372e4b17023SJohn Marino       cselib_process_insn (insn);
373e4b17023SJohn Marino     }
374e4b17023SJohn Marino 
375e4b17023SJohn Marino   /* Later we should clear nonequal of dead registers.  So far we don't
376e4b17023SJohn Marino      have life information in cfg_cleanup.  */
377e4b17023SJohn Marino   if (failed)
378e4b17023SJohn Marino     {
379e4b17023SJohn Marino       b->flags |= BB_NONTHREADABLE_BLOCK;
380e4b17023SJohn Marino       goto failed_exit;
381e4b17023SJohn Marino     }
382e4b17023SJohn Marino 
383e4b17023SJohn Marino   /* cond2 must not mention any register that is not equal to the
384e4b17023SJohn Marino      former block.  */
385e4b17023SJohn Marino   if (for_each_rtx (&cond2, mentions_nonequal_regs, nonequal))
386e4b17023SJohn Marino     goto failed_exit;
387e4b17023SJohn Marino 
388e4b17023SJohn Marino   EXECUTE_IF_SET_IN_REG_SET (nonequal, 0, i, rsi)
389e4b17023SJohn Marino     goto failed_exit;
390e4b17023SJohn Marino 
391e4b17023SJohn Marino   BITMAP_FREE (nonequal);
392e4b17023SJohn Marino   cselib_finish ();
393e4b17023SJohn Marino   if ((comparison_dominates_p (code1, code2) != 0)
394e4b17023SJohn Marino       != (XEXP (SET_SRC (set2), 1) == pc_rtx))
395e4b17023SJohn Marino     return BRANCH_EDGE (b);
396e4b17023SJohn Marino   else
397e4b17023SJohn Marino     return FALLTHRU_EDGE (b);
398e4b17023SJohn Marino 
399e4b17023SJohn Marino failed_exit:
400e4b17023SJohn Marino   BITMAP_FREE (nonequal);
401e4b17023SJohn Marino   cselib_finish ();
402e4b17023SJohn Marino   return NULL;
403e4b17023SJohn Marino }
404e4b17023SJohn Marino 
405e4b17023SJohn Marino /* Attempt to forward edges leaving basic block B.
406e4b17023SJohn Marino    Return true if successful.  */
407e4b17023SJohn Marino 
408e4b17023SJohn Marino static bool
try_forward_edges(int mode,basic_block b)409e4b17023SJohn Marino try_forward_edges (int mode, basic_block b)
410e4b17023SJohn Marino {
411e4b17023SJohn Marino   bool changed = false;
412e4b17023SJohn Marino   edge_iterator ei;
413e4b17023SJohn Marino   edge e, *threaded_edges = NULL;
414e4b17023SJohn Marino 
415e4b17023SJohn Marino   /* If we are partitioning hot/cold basic blocks, we don't want to
416e4b17023SJohn Marino      mess up unconditional or indirect jumps that cross between hot
417e4b17023SJohn Marino      and cold sections.
418e4b17023SJohn Marino 
419e4b17023SJohn Marino      Basic block partitioning may result in some jumps that appear to
420e4b17023SJohn Marino      be optimizable (or blocks that appear to be mergeable), but which really
421e4b17023SJohn Marino      must be left untouched (they are required to make it safely across
422e4b17023SJohn Marino      partition boundaries).  See the comments at the top of
423e4b17023SJohn Marino      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
424e4b17023SJohn Marino 
425e4b17023SJohn Marino   if (find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX))
426e4b17023SJohn Marino     return false;
427e4b17023SJohn Marino 
428e4b17023SJohn Marino   for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); )
429e4b17023SJohn Marino     {
430e4b17023SJohn Marino       basic_block target, first;
431e4b17023SJohn Marino       int counter, goto_locus;
432e4b17023SJohn Marino       bool threaded = false;
433e4b17023SJohn Marino       int nthreaded_edges = 0;
434e4b17023SJohn Marino       bool may_thread = first_pass || (b->flags & BB_MODIFIED) != 0;
435e4b17023SJohn Marino 
436e4b17023SJohn Marino       /* Skip complex edges because we don't know how to update them.
437e4b17023SJohn Marino 
438e4b17023SJohn Marino 	 Still handle fallthru edges, as we can succeed to forward fallthru
439e4b17023SJohn Marino 	 edge to the same place as the branch edge of conditional branch
440e4b17023SJohn Marino 	 and turn conditional branch to an unconditional branch.  */
441e4b17023SJohn Marino       if (e->flags & EDGE_COMPLEX)
442e4b17023SJohn Marino 	{
443e4b17023SJohn Marino 	  ei_next (&ei);
444e4b17023SJohn Marino 	  continue;
445e4b17023SJohn Marino 	}
446e4b17023SJohn Marino 
447e4b17023SJohn Marino       target = first = e->dest;
448e4b17023SJohn Marino       counter = NUM_FIXED_BLOCKS;
449e4b17023SJohn Marino       goto_locus = e->goto_locus;
450e4b17023SJohn Marino 
451e4b17023SJohn Marino       /* If we are partitioning hot/cold basic_blocks, we don't want to mess
452e4b17023SJohn Marino 	 up jumps that cross between hot/cold sections.
453e4b17023SJohn Marino 
454e4b17023SJohn Marino 	 Basic block partitioning may result in some jumps that appear
455e4b17023SJohn Marino 	 to be optimizable (or blocks that appear to be mergeable), but which
456e4b17023SJohn Marino 	 really must be left untouched (they are required to make it safely
457e4b17023SJohn Marino 	 across partition boundaries).  See the comments at the top of
458e4b17023SJohn Marino 	 bb-reorder.c:partition_hot_cold_basic_blocks for complete
459e4b17023SJohn Marino 	 details.  */
460e4b17023SJohn Marino 
461e4b17023SJohn Marino       if (first != EXIT_BLOCK_PTR
462e4b17023SJohn Marino 	  && find_reg_note (BB_END (first), REG_CROSSING_JUMP, NULL_RTX))
463e4b17023SJohn Marino 	return false;
464e4b17023SJohn Marino 
465e4b17023SJohn Marino       while (counter < n_basic_blocks)
466e4b17023SJohn Marino 	{
467e4b17023SJohn Marino 	  basic_block new_target = NULL;
468e4b17023SJohn Marino 	  bool new_target_threaded = false;
469e4b17023SJohn Marino 	  may_thread |= (target->flags & BB_MODIFIED) != 0;
470e4b17023SJohn Marino 
471e4b17023SJohn Marino 	  if (FORWARDER_BLOCK_P (target)
472e4b17023SJohn Marino 	      && !(single_succ_edge (target)->flags & EDGE_CROSSING)
473e4b17023SJohn Marino 	      && single_succ (target) != EXIT_BLOCK_PTR)
474e4b17023SJohn Marino 	    {
475e4b17023SJohn Marino 	      /* Bypass trivial infinite loops.  */
476e4b17023SJohn Marino 	      new_target = single_succ (target);
477e4b17023SJohn Marino 	      if (target == new_target)
478e4b17023SJohn Marino 		counter = n_basic_blocks;
479e4b17023SJohn Marino 	      else if (!optimize)
480e4b17023SJohn Marino 		{
481e4b17023SJohn Marino 		  /* When not optimizing, ensure that edges or forwarder
482e4b17023SJohn Marino 		     blocks with different locus are not optimized out.  */
483e4b17023SJohn Marino 		  int new_locus = single_succ_edge (target)->goto_locus;
484e4b17023SJohn Marino 		  int locus = goto_locus;
485e4b17023SJohn Marino 
486e4b17023SJohn Marino 		  if (new_locus && locus && !locator_eq (new_locus, locus))
487e4b17023SJohn Marino 		    new_target = NULL;
488e4b17023SJohn Marino 		  else
489e4b17023SJohn Marino 		    {
490e4b17023SJohn Marino 		      rtx last;
491e4b17023SJohn Marino 
492e4b17023SJohn Marino 		      if (new_locus)
493e4b17023SJohn Marino 			locus = new_locus;
494e4b17023SJohn Marino 
495e4b17023SJohn Marino 		      last = BB_END (target);
496e4b17023SJohn Marino 		      if (DEBUG_INSN_P (last))
497e4b17023SJohn Marino 			last = prev_nondebug_insn (last);
498e4b17023SJohn Marino 
499e4b17023SJohn Marino 		      new_locus = last && INSN_P (last)
500e4b17023SJohn Marino 				  ? INSN_LOCATOR (last) : 0;
501e4b17023SJohn Marino 
502e4b17023SJohn Marino 		      if (new_locus && locus && !locator_eq (new_locus, locus))
503e4b17023SJohn Marino 			new_target = NULL;
504e4b17023SJohn Marino 		      else
505e4b17023SJohn Marino 			{
506e4b17023SJohn Marino 			  if (new_locus)
507e4b17023SJohn Marino 			    locus = new_locus;
508e4b17023SJohn Marino 
509e4b17023SJohn Marino 			  goto_locus = locus;
510e4b17023SJohn Marino 			}
511e4b17023SJohn Marino 		    }
512e4b17023SJohn Marino 		}
513e4b17023SJohn Marino 	    }
514e4b17023SJohn Marino 
515e4b17023SJohn Marino 	  /* Allow to thread only over one edge at time to simplify updating
516e4b17023SJohn Marino 	     of probabilities.  */
517e4b17023SJohn Marino 	  else if ((mode & CLEANUP_THREADING) && may_thread)
518e4b17023SJohn Marino 	    {
519e4b17023SJohn Marino 	      edge t = thread_jump (e, target);
520e4b17023SJohn Marino 	      if (t)
521e4b17023SJohn Marino 		{
522e4b17023SJohn Marino 		  if (!threaded_edges)
523e4b17023SJohn Marino 		    threaded_edges = XNEWVEC (edge, n_basic_blocks);
524e4b17023SJohn Marino 		  else
525e4b17023SJohn Marino 		    {
526e4b17023SJohn Marino 		      int i;
527e4b17023SJohn Marino 
528e4b17023SJohn Marino 		      /* Detect an infinite loop across blocks not
529e4b17023SJohn Marino 			 including the start block.  */
530e4b17023SJohn Marino 		      for (i = 0; i < nthreaded_edges; ++i)
531e4b17023SJohn Marino 			if (threaded_edges[i] == t)
532e4b17023SJohn Marino 			  break;
533e4b17023SJohn Marino 		      if (i < nthreaded_edges)
534e4b17023SJohn Marino 			{
535e4b17023SJohn Marino 			  counter = n_basic_blocks;
536e4b17023SJohn Marino 			  break;
537e4b17023SJohn Marino 			}
538e4b17023SJohn Marino 		    }
539e4b17023SJohn Marino 
540e4b17023SJohn Marino 		  /* Detect an infinite loop across the start block.  */
541e4b17023SJohn Marino 		  if (t->dest == b)
542e4b17023SJohn Marino 		    break;
543e4b17023SJohn Marino 
544e4b17023SJohn Marino 		  gcc_assert (nthreaded_edges < n_basic_blocks - NUM_FIXED_BLOCKS);
545e4b17023SJohn Marino 		  threaded_edges[nthreaded_edges++] = t;
546e4b17023SJohn Marino 
547e4b17023SJohn Marino 		  new_target = t->dest;
548e4b17023SJohn Marino 		  new_target_threaded = true;
549e4b17023SJohn Marino 		}
550e4b17023SJohn Marino 	    }
551e4b17023SJohn Marino 
552e4b17023SJohn Marino 	  if (!new_target)
553e4b17023SJohn Marino 	    break;
554e4b17023SJohn Marino 
555e4b17023SJohn Marino 	  counter++;
556e4b17023SJohn Marino 	  target = new_target;
557e4b17023SJohn Marino 	  threaded |= new_target_threaded;
558e4b17023SJohn Marino 	}
559e4b17023SJohn Marino 
560e4b17023SJohn Marino       if (counter >= n_basic_blocks)
561e4b17023SJohn Marino 	{
562e4b17023SJohn Marino 	  if (dump_file)
563e4b17023SJohn Marino 	    fprintf (dump_file, "Infinite loop in BB %i.\n",
564e4b17023SJohn Marino 		     target->index);
565e4b17023SJohn Marino 	}
566e4b17023SJohn Marino       else if (target == first)
567e4b17023SJohn Marino 	; /* We didn't do anything.  */
568e4b17023SJohn Marino       else
569e4b17023SJohn Marino 	{
570e4b17023SJohn Marino 	  /* Save the values now, as the edge may get removed.  */
571e4b17023SJohn Marino 	  gcov_type edge_count = e->count;
572e4b17023SJohn Marino 	  int edge_probability = e->probability;
573e4b17023SJohn Marino 	  int edge_frequency;
574e4b17023SJohn Marino 	  int n = 0;
575e4b17023SJohn Marino 
576e4b17023SJohn Marino 	  e->goto_locus = goto_locus;
577e4b17023SJohn Marino 
578e4b17023SJohn Marino 	  /* Don't force if target is exit block.  */
579e4b17023SJohn Marino 	  if (threaded && target != EXIT_BLOCK_PTR)
580e4b17023SJohn Marino 	    {
581e4b17023SJohn Marino 	      notice_new_block (redirect_edge_and_branch_force (e, target));
582e4b17023SJohn Marino 	      if (dump_file)
583e4b17023SJohn Marino 		fprintf (dump_file, "Conditionals threaded.\n");
584e4b17023SJohn Marino 	    }
585e4b17023SJohn Marino 	  else if (!redirect_edge_and_branch (e, target))
586e4b17023SJohn Marino 	    {
587e4b17023SJohn Marino 	      if (dump_file)
588e4b17023SJohn Marino 		fprintf (dump_file,
589e4b17023SJohn Marino 			 "Forwarding edge %i->%i to %i failed.\n",
590e4b17023SJohn Marino 			 b->index, e->dest->index, target->index);
591e4b17023SJohn Marino 	      ei_next (&ei);
592e4b17023SJohn Marino 	      continue;
593e4b17023SJohn Marino 	    }
594e4b17023SJohn Marino 
595e4b17023SJohn Marino 	  /* We successfully forwarded the edge.  Now update profile
596e4b17023SJohn Marino 	     data: for each edge we traversed in the chain, remove
597e4b17023SJohn Marino 	     the original edge's execution count.  */
598e4b17023SJohn Marino 	  edge_frequency = ((edge_probability * b->frequency
599e4b17023SJohn Marino 			     + REG_BR_PROB_BASE / 2)
600e4b17023SJohn Marino 			    / REG_BR_PROB_BASE);
601e4b17023SJohn Marino 
602e4b17023SJohn Marino 	  do
603e4b17023SJohn Marino 	    {
604e4b17023SJohn Marino 	      edge t;
605e4b17023SJohn Marino 
606e4b17023SJohn Marino 	      if (!single_succ_p (first))
607e4b17023SJohn Marino 		{
608e4b17023SJohn Marino 		  gcc_assert (n < nthreaded_edges);
609e4b17023SJohn Marino 		  t = threaded_edges [n++];
610e4b17023SJohn Marino 		  gcc_assert (t->src == first);
611e4b17023SJohn Marino 		  update_bb_profile_for_threading (first, edge_frequency,
612e4b17023SJohn Marino 						   edge_count, t);
613e4b17023SJohn Marino 		  update_br_prob_note (first);
614e4b17023SJohn Marino 		}
615e4b17023SJohn Marino 	      else
616e4b17023SJohn Marino 		{
617e4b17023SJohn Marino 		  first->count -= edge_count;
618e4b17023SJohn Marino 		  if (first->count < 0)
619e4b17023SJohn Marino 		    first->count = 0;
620e4b17023SJohn Marino 		  first->frequency -= edge_frequency;
621e4b17023SJohn Marino 		  if (first->frequency < 0)
622e4b17023SJohn Marino 		    first->frequency = 0;
623e4b17023SJohn Marino 		  /* It is possible that as the result of
624e4b17023SJohn Marino 		     threading we've removed edge as it is
625e4b17023SJohn Marino 		     threaded to the fallthru edge.  Avoid
626e4b17023SJohn Marino 		     getting out of sync.  */
627e4b17023SJohn Marino 		  if (n < nthreaded_edges
628e4b17023SJohn Marino 		      && first == threaded_edges [n]->src)
629e4b17023SJohn Marino 		    n++;
630e4b17023SJohn Marino 		  t = single_succ_edge (first);
631e4b17023SJohn Marino 		}
632e4b17023SJohn Marino 
633e4b17023SJohn Marino 	      t->count -= edge_count;
634e4b17023SJohn Marino 	      if (t->count < 0)
635e4b17023SJohn Marino 		t->count = 0;
636e4b17023SJohn Marino 	      first = t->dest;
637e4b17023SJohn Marino 	    }
638e4b17023SJohn Marino 	  while (first != target);
639e4b17023SJohn Marino 
640e4b17023SJohn Marino 	  changed = true;
641e4b17023SJohn Marino 	  continue;
642e4b17023SJohn Marino 	}
643e4b17023SJohn Marino       ei_next (&ei);
644e4b17023SJohn Marino     }
645e4b17023SJohn Marino 
646e4b17023SJohn Marino   free (threaded_edges);
647e4b17023SJohn Marino   return changed;
648e4b17023SJohn Marino }
649e4b17023SJohn Marino 
650e4b17023SJohn Marino 
651e4b17023SJohn Marino /* Blocks A and B are to be merged into a single block.  A has no incoming
652e4b17023SJohn Marino    fallthru edge, so it can be moved before B without adding or modifying
653e4b17023SJohn Marino    any jumps (aside from the jump from A to B).  */
654e4b17023SJohn Marino 
655e4b17023SJohn Marino static void
merge_blocks_move_predecessor_nojumps(basic_block a,basic_block b)656e4b17023SJohn Marino merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b)
657e4b17023SJohn Marino {
658e4b17023SJohn Marino   rtx barrier;
659e4b17023SJohn Marino 
660e4b17023SJohn Marino   /* If we are partitioning hot/cold basic blocks, we don't want to
661e4b17023SJohn Marino      mess up unconditional or indirect jumps that cross between hot
662e4b17023SJohn Marino      and cold sections.
663e4b17023SJohn Marino 
664e4b17023SJohn Marino      Basic block partitioning may result in some jumps that appear to
665e4b17023SJohn Marino      be optimizable (or blocks that appear to be mergeable), but which really
666e4b17023SJohn Marino      must be left untouched (they are required to make it safely across
667e4b17023SJohn Marino      partition boundaries).  See the comments at the top of
668e4b17023SJohn Marino      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
669e4b17023SJohn Marino 
670e4b17023SJohn Marino   if (BB_PARTITION (a) != BB_PARTITION (b))
671e4b17023SJohn Marino     return;
672e4b17023SJohn Marino 
673e4b17023SJohn Marino   barrier = next_nonnote_insn (BB_END (a));
674e4b17023SJohn Marino   gcc_assert (BARRIER_P (barrier));
675e4b17023SJohn Marino   delete_insn (barrier);
676e4b17023SJohn Marino 
677e4b17023SJohn Marino   /* Scramble the insn chain.  */
678e4b17023SJohn Marino   if (BB_END (a) != PREV_INSN (BB_HEAD (b)))
679e4b17023SJohn Marino     reorder_insns_nobb (BB_HEAD (a), BB_END (a), PREV_INSN (BB_HEAD (b)));
680e4b17023SJohn Marino   df_set_bb_dirty (a);
681e4b17023SJohn Marino 
682e4b17023SJohn Marino   if (dump_file)
683e4b17023SJohn Marino     fprintf (dump_file, "Moved block %d before %d and merged.\n",
684e4b17023SJohn Marino 	     a->index, b->index);
685e4b17023SJohn Marino 
686e4b17023SJohn Marino   /* Swap the records for the two blocks around.  */
687e4b17023SJohn Marino 
688e4b17023SJohn Marino   unlink_block (a);
689e4b17023SJohn Marino   link_block (a, b->prev_bb);
690e4b17023SJohn Marino 
691e4b17023SJohn Marino   /* Now blocks A and B are contiguous.  Merge them.  */
692e4b17023SJohn Marino   merge_blocks (a, b);
693e4b17023SJohn Marino }
694e4b17023SJohn Marino 
695e4b17023SJohn Marino /* Blocks A and B are to be merged into a single block.  B has no outgoing
696e4b17023SJohn Marino    fallthru edge, so it can be moved after A without adding or modifying
697e4b17023SJohn Marino    any jumps (aside from the jump from A to B).  */
698e4b17023SJohn Marino 
699e4b17023SJohn Marino static void
merge_blocks_move_successor_nojumps(basic_block a,basic_block b)700e4b17023SJohn Marino merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
701e4b17023SJohn Marino {
702e4b17023SJohn Marino   rtx barrier, real_b_end;
703e4b17023SJohn Marino   rtx label, table;
704e4b17023SJohn Marino 
705e4b17023SJohn Marino   /* If we are partitioning hot/cold basic blocks, we don't want to
706e4b17023SJohn Marino      mess up unconditional or indirect jumps that cross between hot
707e4b17023SJohn Marino      and cold sections.
708e4b17023SJohn Marino 
709e4b17023SJohn Marino      Basic block partitioning may result in some jumps that appear to
710e4b17023SJohn Marino      be optimizable (or blocks that appear to be mergeable), but which really
711e4b17023SJohn Marino      must be left untouched (they are required to make it safely across
712e4b17023SJohn Marino      partition boundaries).  See the comments at the top of
713e4b17023SJohn Marino      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
714e4b17023SJohn Marino 
715e4b17023SJohn Marino   if (BB_PARTITION (a) != BB_PARTITION (b))
716e4b17023SJohn Marino     return;
717e4b17023SJohn Marino 
718e4b17023SJohn Marino   real_b_end = BB_END (b);
719e4b17023SJohn Marino 
720e4b17023SJohn Marino   /* If there is a jump table following block B temporarily add the jump table
721e4b17023SJohn Marino      to block B so that it will also be moved to the correct location.  */
722e4b17023SJohn Marino   if (tablejump_p (BB_END (b), &label, &table)
723e4b17023SJohn Marino       && prev_active_insn (label) == BB_END (b))
724e4b17023SJohn Marino     {
725e4b17023SJohn Marino       BB_END (b) = table;
726e4b17023SJohn Marino     }
727e4b17023SJohn Marino 
728e4b17023SJohn Marino   /* There had better have been a barrier there.  Delete it.  */
729e4b17023SJohn Marino   barrier = NEXT_INSN (BB_END (b));
730e4b17023SJohn Marino   if (barrier && BARRIER_P (barrier))
731e4b17023SJohn Marino     delete_insn (barrier);
732e4b17023SJohn Marino 
733e4b17023SJohn Marino 
734e4b17023SJohn Marino   /* Scramble the insn chain.  */
735e4b17023SJohn Marino   reorder_insns_nobb (BB_HEAD (b), BB_END (b), BB_END (a));
736e4b17023SJohn Marino 
737e4b17023SJohn Marino   /* Restore the real end of b.  */
738e4b17023SJohn Marino   BB_END (b) = real_b_end;
739e4b17023SJohn Marino 
740e4b17023SJohn Marino   if (dump_file)
741e4b17023SJohn Marino     fprintf (dump_file, "Moved block %d after %d and merged.\n",
742e4b17023SJohn Marino 	     b->index, a->index);
743e4b17023SJohn Marino 
744e4b17023SJohn Marino   /* Now blocks A and B are contiguous.  Merge them.  */
745e4b17023SJohn Marino   merge_blocks (a, b);
746e4b17023SJohn Marino }
747e4b17023SJohn Marino 
748e4b17023SJohn Marino /* Attempt to merge basic blocks that are potentially non-adjacent.
749e4b17023SJohn Marino    Return NULL iff the attempt failed, otherwise return basic block
750e4b17023SJohn Marino    where cleanup_cfg should continue.  Because the merging commonly
751e4b17023SJohn Marino    moves basic block away or introduces another optimization
752e4b17023SJohn Marino    possibility, return basic block just before B so cleanup_cfg don't
753e4b17023SJohn Marino    need to iterate.
754e4b17023SJohn Marino 
755e4b17023SJohn Marino    It may be good idea to return basic block before C in the case
756e4b17023SJohn Marino    C has been moved after B and originally appeared earlier in the
757e4b17023SJohn Marino    insn sequence, but we have no information available about the
758e4b17023SJohn Marino    relative ordering of these two.  Hopefully it is not too common.  */
759e4b17023SJohn Marino 
760e4b17023SJohn Marino static basic_block
merge_blocks_move(edge e,basic_block b,basic_block c,int mode)761e4b17023SJohn Marino merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
762e4b17023SJohn Marino {
763e4b17023SJohn Marino   basic_block next;
764e4b17023SJohn Marino 
765e4b17023SJohn Marino   /* If we are partitioning hot/cold basic blocks, we don't want to
766e4b17023SJohn Marino      mess up unconditional or indirect jumps that cross between hot
767e4b17023SJohn Marino      and cold sections.
768e4b17023SJohn Marino 
769e4b17023SJohn Marino      Basic block partitioning may result in some jumps that appear to
770e4b17023SJohn Marino      be optimizable (or blocks that appear to be mergeable), but which really
771e4b17023SJohn Marino      must be left untouched (they are required to make it safely across
772e4b17023SJohn Marino      partition boundaries).  See the comments at the top of
773e4b17023SJohn Marino      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
774e4b17023SJohn Marino 
775e4b17023SJohn Marino   if (BB_PARTITION (b) != BB_PARTITION (c))
776e4b17023SJohn Marino     return NULL;
777e4b17023SJohn Marino 
778e4b17023SJohn Marino   /* If B has a fallthru edge to C, no need to move anything.  */
779e4b17023SJohn Marino   if (e->flags & EDGE_FALLTHRU)
780e4b17023SJohn Marino     {
781e4b17023SJohn Marino       int b_index = b->index, c_index = c->index;
782e4b17023SJohn Marino       merge_blocks (b, c);
783e4b17023SJohn Marino       update_forwarder_flag (b);
784e4b17023SJohn Marino 
785e4b17023SJohn Marino       if (dump_file)
786e4b17023SJohn Marino 	fprintf (dump_file, "Merged %d and %d without moving.\n",
787e4b17023SJohn Marino 		 b_index, c_index);
788e4b17023SJohn Marino 
789e4b17023SJohn Marino       return b->prev_bb == ENTRY_BLOCK_PTR ? b : b->prev_bb;
790e4b17023SJohn Marino     }
791e4b17023SJohn Marino 
792e4b17023SJohn Marino   /* Otherwise we will need to move code around.  Do that only if expensive
793e4b17023SJohn Marino      transformations are allowed.  */
794e4b17023SJohn Marino   else if (mode & CLEANUP_EXPENSIVE)
795e4b17023SJohn Marino     {
796e4b17023SJohn Marino       edge tmp_edge, b_fallthru_edge;
797e4b17023SJohn Marino       bool c_has_outgoing_fallthru;
798e4b17023SJohn Marino       bool b_has_incoming_fallthru;
799e4b17023SJohn Marino 
800e4b17023SJohn Marino       /* Avoid overactive code motion, as the forwarder blocks should be
801e4b17023SJohn Marino 	 eliminated by edge redirection instead.  One exception might have
802e4b17023SJohn Marino 	 been if B is a forwarder block and C has no fallthru edge, but
803e4b17023SJohn Marino 	 that should be cleaned up by bb-reorder instead.  */
804e4b17023SJohn Marino       if (FORWARDER_BLOCK_P (b) || FORWARDER_BLOCK_P (c))
805e4b17023SJohn Marino 	return NULL;
806e4b17023SJohn Marino 
807e4b17023SJohn Marino       /* We must make sure to not munge nesting of lexical blocks,
808e4b17023SJohn Marino 	 and loop notes.  This is done by squeezing out all the notes
809e4b17023SJohn Marino 	 and leaving them there to lie.  Not ideal, but functional.  */
810e4b17023SJohn Marino 
811e4b17023SJohn Marino       tmp_edge = find_fallthru_edge (c->succs);
812e4b17023SJohn Marino       c_has_outgoing_fallthru = (tmp_edge != NULL);
813e4b17023SJohn Marino 
814e4b17023SJohn Marino       tmp_edge = find_fallthru_edge (b->preds);
815e4b17023SJohn Marino       b_has_incoming_fallthru = (tmp_edge != NULL);
816e4b17023SJohn Marino       b_fallthru_edge = tmp_edge;
817e4b17023SJohn Marino       next = b->prev_bb;
818e4b17023SJohn Marino       if (next == c)
819e4b17023SJohn Marino 	next = next->prev_bb;
820e4b17023SJohn Marino 
821e4b17023SJohn Marino       /* Otherwise, we're going to try to move C after B.  If C does
822e4b17023SJohn Marino 	 not have an outgoing fallthru, then it can be moved
823e4b17023SJohn Marino 	 immediately after B without introducing or modifying jumps.  */
824e4b17023SJohn Marino       if (! c_has_outgoing_fallthru)
825e4b17023SJohn Marino 	{
826e4b17023SJohn Marino 	  merge_blocks_move_successor_nojumps (b, c);
827e4b17023SJohn Marino 	  return next == ENTRY_BLOCK_PTR ? next->next_bb : next;
828e4b17023SJohn Marino 	}
829e4b17023SJohn Marino 
830e4b17023SJohn Marino       /* If B does not have an incoming fallthru, then it can be moved
831e4b17023SJohn Marino 	 immediately before C without introducing or modifying jumps.
832e4b17023SJohn Marino 	 C cannot be the first block, so we do not have to worry about
833e4b17023SJohn Marino 	 accessing a non-existent block.  */
834e4b17023SJohn Marino 
835e4b17023SJohn Marino       if (b_has_incoming_fallthru)
836e4b17023SJohn Marino 	{
837e4b17023SJohn Marino 	  basic_block bb;
838e4b17023SJohn Marino 
839e4b17023SJohn Marino 	  if (b_fallthru_edge->src == ENTRY_BLOCK_PTR)
840e4b17023SJohn Marino 	    return NULL;
841e4b17023SJohn Marino 	  bb = force_nonfallthru (b_fallthru_edge);
842e4b17023SJohn Marino 	  if (bb)
843e4b17023SJohn Marino 	    notice_new_block (bb);
844e4b17023SJohn Marino 	}
845e4b17023SJohn Marino 
846e4b17023SJohn Marino       merge_blocks_move_predecessor_nojumps (b, c);
847e4b17023SJohn Marino       return next == ENTRY_BLOCK_PTR ? next->next_bb : next;
848e4b17023SJohn Marino     }
849e4b17023SJohn Marino 
850e4b17023SJohn Marino   return NULL;
851e4b17023SJohn Marino }
852e4b17023SJohn Marino 
853e4b17023SJohn Marino 
854e4b17023SJohn Marino /* Removes the memory attributes of MEM expression
855e4b17023SJohn Marino    if they are not equal.  */
856e4b17023SJohn Marino 
857e4b17023SJohn Marino void
merge_memattrs(rtx x,rtx y)858e4b17023SJohn Marino merge_memattrs (rtx x, rtx y)
859e4b17023SJohn Marino {
860e4b17023SJohn Marino   int i;
861e4b17023SJohn Marino   int j;
862e4b17023SJohn Marino   enum rtx_code code;
863e4b17023SJohn Marino   const char *fmt;
864e4b17023SJohn Marino 
865e4b17023SJohn Marino   if (x == y)
866e4b17023SJohn Marino     return;
867e4b17023SJohn Marino   if (x == 0 || y == 0)
868e4b17023SJohn Marino     return;
869e4b17023SJohn Marino 
870e4b17023SJohn Marino   code = GET_CODE (x);
871e4b17023SJohn Marino 
872e4b17023SJohn Marino   if (code != GET_CODE (y))
873e4b17023SJohn Marino     return;
874e4b17023SJohn Marino 
875e4b17023SJohn Marino   if (GET_MODE (x) != GET_MODE (y))
876e4b17023SJohn Marino     return;
877e4b17023SJohn Marino 
878e4b17023SJohn Marino   if (code == MEM && MEM_ATTRS (x) != MEM_ATTRS (y))
879e4b17023SJohn Marino     {
880e4b17023SJohn Marino       if (! MEM_ATTRS (x))
881e4b17023SJohn Marino 	MEM_ATTRS (y) = 0;
882e4b17023SJohn Marino       else if (! MEM_ATTRS (y))
883e4b17023SJohn Marino 	MEM_ATTRS (x) = 0;
884e4b17023SJohn Marino       else
885e4b17023SJohn Marino 	{
886e4b17023SJohn Marino 	  HOST_WIDE_INT mem_size;
887e4b17023SJohn Marino 
888e4b17023SJohn Marino 	  if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
889e4b17023SJohn Marino 	    {
890e4b17023SJohn Marino 	      set_mem_alias_set (x, 0);
891e4b17023SJohn Marino 	      set_mem_alias_set (y, 0);
892e4b17023SJohn Marino 	    }
893e4b17023SJohn Marino 
894e4b17023SJohn Marino 	  if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y)))
895e4b17023SJohn Marino 	    {
896e4b17023SJohn Marino 	      set_mem_expr (x, 0);
897e4b17023SJohn Marino 	      set_mem_expr (y, 0);
898e4b17023SJohn Marino 	      clear_mem_offset (x);
899e4b17023SJohn Marino 	      clear_mem_offset (y);
900e4b17023SJohn Marino 	    }
901e4b17023SJohn Marino 	  else if (MEM_OFFSET_KNOWN_P (x) != MEM_OFFSET_KNOWN_P (y)
902e4b17023SJohn Marino 		   || (MEM_OFFSET_KNOWN_P (x)
903e4b17023SJohn Marino 		       && MEM_OFFSET (x) != MEM_OFFSET (y)))
904e4b17023SJohn Marino 	    {
905e4b17023SJohn Marino 	      clear_mem_offset (x);
906e4b17023SJohn Marino 	      clear_mem_offset (y);
907e4b17023SJohn Marino 	    }
908e4b17023SJohn Marino 
909e4b17023SJohn Marino 	  if (MEM_SIZE_KNOWN_P (x) && MEM_SIZE_KNOWN_P (y))
910e4b17023SJohn Marino 	    {
911e4b17023SJohn Marino 	      mem_size = MAX (MEM_SIZE (x), MEM_SIZE (y));
912e4b17023SJohn Marino 	      set_mem_size (x, mem_size);
913e4b17023SJohn Marino 	      set_mem_size (y, mem_size);
914e4b17023SJohn Marino 	    }
915e4b17023SJohn Marino 	  else
916e4b17023SJohn Marino 	    {
917e4b17023SJohn Marino 	      clear_mem_size (x);
918e4b17023SJohn Marino 	      clear_mem_size (y);
919e4b17023SJohn Marino 	    }
920e4b17023SJohn Marino 
921e4b17023SJohn Marino 	  set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y)));
922e4b17023SJohn Marino 	  set_mem_align (y, MEM_ALIGN (x));
923e4b17023SJohn Marino 	}
924e4b17023SJohn Marino     }
925*95d28233SJohn Marino   if (code == MEM)
926*95d28233SJohn Marino     {
927*95d28233SJohn Marino       if (MEM_READONLY_P (x) != MEM_READONLY_P (y))
928*95d28233SJohn Marino 	{
929*95d28233SJohn Marino 	  MEM_READONLY_P (x) = 0;
930*95d28233SJohn Marino 	  MEM_READONLY_P (y) = 0;
931*95d28233SJohn Marino 	}
932*95d28233SJohn Marino       if (MEM_NOTRAP_P (x) != MEM_NOTRAP_P (y))
933*95d28233SJohn Marino 	{
934*95d28233SJohn Marino 	  MEM_NOTRAP_P (x) = 0;
935*95d28233SJohn Marino 	  MEM_NOTRAP_P (y) = 0;
936*95d28233SJohn Marino 	}
937*95d28233SJohn Marino       if (MEM_VOLATILE_P (x) != MEM_VOLATILE_P (y))
938*95d28233SJohn Marino 	{
939*95d28233SJohn Marino 	  MEM_VOLATILE_P (x) = 1;
940*95d28233SJohn Marino 	  MEM_VOLATILE_P (y) = 1;
941*95d28233SJohn Marino 	}
942*95d28233SJohn Marino     }
943e4b17023SJohn Marino 
944e4b17023SJohn Marino   fmt = GET_RTX_FORMAT (code);
945e4b17023SJohn Marino   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
946e4b17023SJohn Marino     {
947e4b17023SJohn Marino       switch (fmt[i])
948e4b17023SJohn Marino 	{
949e4b17023SJohn Marino 	case 'E':
950e4b17023SJohn Marino 	  /* Two vectors must have the same length.  */
951e4b17023SJohn Marino 	  if (XVECLEN (x, i) != XVECLEN (y, i))
952e4b17023SJohn Marino 	    return;
953e4b17023SJohn Marino 
954e4b17023SJohn Marino 	  for (j = 0; j < XVECLEN (x, i); j++)
955e4b17023SJohn Marino 	    merge_memattrs (XVECEXP (x, i, j), XVECEXP (y, i, j));
956e4b17023SJohn Marino 
957e4b17023SJohn Marino 	  break;
958e4b17023SJohn Marino 
959e4b17023SJohn Marino 	case 'e':
960e4b17023SJohn Marino 	  merge_memattrs (XEXP (x, i), XEXP (y, i));
961e4b17023SJohn Marino 	}
962e4b17023SJohn Marino     }
963e4b17023SJohn Marino   return;
964e4b17023SJohn Marino }
965e4b17023SJohn Marino 
966e4b17023SJohn Marino 
967e4b17023SJohn Marino  /* Checks if patterns P1 and P2 are equivalent, apart from the possibly
968e4b17023SJohn Marino     different single sets S1 and S2.  */
969e4b17023SJohn Marino 
970e4b17023SJohn Marino static bool
equal_different_set_p(rtx p1,rtx s1,rtx p2,rtx s2)971e4b17023SJohn Marino equal_different_set_p (rtx p1, rtx s1, rtx p2, rtx s2)
972e4b17023SJohn Marino {
973e4b17023SJohn Marino   int i;
974e4b17023SJohn Marino   rtx e1, e2;
975e4b17023SJohn Marino 
976e4b17023SJohn Marino   if (p1 == s1 && p2 == s2)
977e4b17023SJohn Marino     return true;
978e4b17023SJohn Marino 
979e4b17023SJohn Marino   if (GET_CODE (p1) != PARALLEL || GET_CODE (p2) != PARALLEL)
980e4b17023SJohn Marino     return false;
981e4b17023SJohn Marino 
982e4b17023SJohn Marino   if (XVECLEN (p1, 0) != XVECLEN (p2, 0))
983e4b17023SJohn Marino     return false;
984e4b17023SJohn Marino 
985e4b17023SJohn Marino   for (i = 0; i < XVECLEN (p1, 0); i++)
986e4b17023SJohn Marino     {
987e4b17023SJohn Marino       e1 = XVECEXP (p1, 0, i);
988e4b17023SJohn Marino       e2 = XVECEXP (p2, 0, i);
989e4b17023SJohn Marino       if (e1 == s1 && e2 == s2)
990e4b17023SJohn Marino         continue;
991e4b17023SJohn Marino       if (reload_completed
992e4b17023SJohn Marino           ? rtx_renumbered_equal_p (e1, e2) : rtx_equal_p (e1, e2))
993e4b17023SJohn Marino         continue;
994e4b17023SJohn Marino 
995e4b17023SJohn Marino         return false;
996e4b17023SJohn Marino     }
997e4b17023SJohn Marino 
998e4b17023SJohn Marino   return true;
999e4b17023SJohn Marino }
1000e4b17023SJohn Marino 
1001e4b17023SJohn Marino /* Examine register notes on I1 and I2 and return:
1002e4b17023SJohn Marino    - dir_forward if I1 can be replaced by I2, or
1003e4b17023SJohn Marino    - dir_backward if I2 can be replaced by I1, or
1004e4b17023SJohn Marino    - dir_both if both are the case.  */
1005e4b17023SJohn Marino 
1006e4b17023SJohn Marino static enum replace_direction
can_replace_by(rtx i1,rtx i2)1007e4b17023SJohn Marino can_replace_by (rtx i1, rtx i2)
1008e4b17023SJohn Marino {
1009e4b17023SJohn Marino   rtx s1, s2, d1, d2, src1, src2, note1, note2;
1010e4b17023SJohn Marino   bool c1, c2;
1011e4b17023SJohn Marino 
1012e4b17023SJohn Marino   /* Check for 2 sets.  */
1013e4b17023SJohn Marino   s1 = single_set (i1);
1014e4b17023SJohn Marino   s2 = single_set (i2);
1015e4b17023SJohn Marino   if (s1 == NULL_RTX || s2 == NULL_RTX)
1016e4b17023SJohn Marino     return dir_none;
1017e4b17023SJohn Marino 
1018e4b17023SJohn Marino   /* Check that the 2 sets set the same dest.  */
1019e4b17023SJohn Marino   d1 = SET_DEST (s1);
1020e4b17023SJohn Marino   d2 = SET_DEST (s2);
1021e4b17023SJohn Marino   if (!(reload_completed
1022e4b17023SJohn Marino         ? rtx_renumbered_equal_p (d1, d2) : rtx_equal_p (d1, d2)))
1023e4b17023SJohn Marino     return dir_none;
1024e4b17023SJohn Marino 
1025e4b17023SJohn Marino   /* Find identical req_equiv or reg_equal note, which implies that the 2 sets
1026e4b17023SJohn Marino      set dest to the same value.  */
1027e4b17023SJohn Marino   note1 = find_reg_equal_equiv_note (i1);
1028e4b17023SJohn Marino   note2 = find_reg_equal_equiv_note (i2);
1029e4b17023SJohn Marino   if (!note1 || !note2 || !rtx_equal_p (XEXP (note1, 0), XEXP (note2, 0))
1030e4b17023SJohn Marino       || !CONST_INT_P (XEXP (note1, 0)))
1031e4b17023SJohn Marino     return dir_none;
1032e4b17023SJohn Marino 
1033e4b17023SJohn Marino   if (!equal_different_set_p (PATTERN (i1), s1, PATTERN (i2), s2))
1034e4b17023SJohn Marino     return dir_none;
1035e4b17023SJohn Marino 
1036e4b17023SJohn Marino   /* Although the 2 sets set dest to the same value, we cannot replace
1037e4b17023SJohn Marino        (set (dest) (const_int))
1038e4b17023SJohn Marino      by
1039e4b17023SJohn Marino        (set (dest) (reg))
1040e4b17023SJohn Marino      because we don't know if the reg is live and has the same value at the
1041e4b17023SJohn Marino      location of replacement.  */
1042e4b17023SJohn Marino   src1 = SET_SRC (s1);
1043e4b17023SJohn Marino   src2 = SET_SRC (s2);
1044e4b17023SJohn Marino   c1 = CONST_INT_P (src1);
1045e4b17023SJohn Marino   c2 = CONST_INT_P (src2);
1046e4b17023SJohn Marino   if (c1 && c2)
1047e4b17023SJohn Marino     return dir_both;
1048e4b17023SJohn Marino   else if (c2)
1049e4b17023SJohn Marino     return dir_forward;
1050e4b17023SJohn Marino   else if (c1)
1051e4b17023SJohn Marino     return dir_backward;
1052e4b17023SJohn Marino 
1053e4b17023SJohn Marino   return dir_none;
1054e4b17023SJohn Marino }
1055e4b17023SJohn Marino 
1056e4b17023SJohn Marino /* Merges directions A and B.  */
1057e4b17023SJohn Marino 
1058e4b17023SJohn Marino static enum replace_direction
merge_dir(enum replace_direction a,enum replace_direction b)1059e4b17023SJohn Marino merge_dir (enum replace_direction a, enum replace_direction b)
1060e4b17023SJohn Marino {
1061e4b17023SJohn Marino   /* Implements the following table:
1062e4b17023SJohn Marino         |bo fw bw no
1063e4b17023SJohn Marino      ---+-----------
1064e4b17023SJohn Marino      bo |bo fw bw no
1065e4b17023SJohn Marino      fw |-- fw no no
1066e4b17023SJohn Marino      bw |-- -- bw no
1067e4b17023SJohn Marino      no |-- -- -- no.  */
1068e4b17023SJohn Marino 
1069e4b17023SJohn Marino   if (a == b)
1070e4b17023SJohn Marino     return a;
1071e4b17023SJohn Marino 
1072e4b17023SJohn Marino   if (a == dir_both)
1073e4b17023SJohn Marino     return b;
1074e4b17023SJohn Marino   if (b == dir_both)
1075e4b17023SJohn Marino     return a;
1076e4b17023SJohn Marino 
1077e4b17023SJohn Marino   return dir_none;
1078e4b17023SJohn Marino }
1079e4b17023SJohn Marino 
1080e4b17023SJohn Marino /* Examine I1 and I2 and return:
1081e4b17023SJohn Marino    - dir_forward if I1 can be replaced by I2, or
1082e4b17023SJohn Marino    - dir_backward if I2 can be replaced by I1, or
1083e4b17023SJohn Marino    - dir_both if both are the case.  */
1084e4b17023SJohn Marino 
1085e4b17023SJohn Marino static enum replace_direction
old_insns_match_p(int mode ATTRIBUTE_UNUSED,rtx i1,rtx i2)1086e4b17023SJohn Marino old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
1087e4b17023SJohn Marino {
1088e4b17023SJohn Marino   rtx p1, p2;
1089e4b17023SJohn Marino 
1090e4b17023SJohn Marino   /* Verify that I1 and I2 are equivalent.  */
1091e4b17023SJohn Marino   if (GET_CODE (i1) != GET_CODE (i2))
1092e4b17023SJohn Marino     return dir_none;
1093e4b17023SJohn Marino 
1094e4b17023SJohn Marino   /* __builtin_unreachable() may lead to empty blocks (ending with
1095e4b17023SJohn Marino      NOTE_INSN_BASIC_BLOCK).  They may be crossjumped. */
1096e4b17023SJohn Marino   if (NOTE_INSN_BASIC_BLOCK_P (i1) && NOTE_INSN_BASIC_BLOCK_P (i2))
1097e4b17023SJohn Marino     return dir_both;
1098e4b17023SJohn Marino 
1099e4b17023SJohn Marino   /* ??? Do not allow cross-jumping between different stack levels.  */
1100e4b17023SJohn Marino   p1 = find_reg_note (i1, REG_ARGS_SIZE, NULL);
1101e4b17023SJohn Marino   p2 = find_reg_note (i2, REG_ARGS_SIZE, NULL);
1102e4b17023SJohn Marino   if (p1 && p2)
1103e4b17023SJohn Marino     {
1104e4b17023SJohn Marino       p1 = XEXP (p1, 0);
1105e4b17023SJohn Marino       p2 = XEXP (p2, 0);
1106e4b17023SJohn Marino       if (!rtx_equal_p (p1, p2))
1107e4b17023SJohn Marino         return dir_none;
1108e4b17023SJohn Marino 
1109e4b17023SJohn Marino       /* ??? Worse, this adjustment had better be constant lest we
1110e4b17023SJohn Marino          have differing incoming stack levels.  */
1111e4b17023SJohn Marino       if (!frame_pointer_needed
1112e4b17023SJohn Marino           && find_args_size_adjust (i1) == HOST_WIDE_INT_MIN)
1113e4b17023SJohn Marino 	return dir_none;
1114e4b17023SJohn Marino     }
1115e4b17023SJohn Marino   else if (p1 || p2)
1116e4b17023SJohn Marino     return dir_none;
1117e4b17023SJohn Marino 
1118e4b17023SJohn Marino   p1 = PATTERN (i1);
1119e4b17023SJohn Marino   p2 = PATTERN (i2);
1120e4b17023SJohn Marino 
1121e4b17023SJohn Marino   if (GET_CODE (p1) != GET_CODE (p2))
1122e4b17023SJohn Marino     return dir_none;
1123e4b17023SJohn Marino 
1124e4b17023SJohn Marino   /* If this is a CALL_INSN, compare register usage information.
1125e4b17023SJohn Marino      If we don't check this on stack register machines, the two
1126e4b17023SJohn Marino      CALL_INSNs might be merged leaving reg-stack.c with mismatching
1127e4b17023SJohn Marino      numbers of stack registers in the same basic block.
1128e4b17023SJohn Marino      If we don't check this on machines with delay slots, a delay slot may
1129e4b17023SJohn Marino      be filled that clobbers a parameter expected by the subroutine.
1130e4b17023SJohn Marino 
1131e4b17023SJohn Marino      ??? We take the simple route for now and assume that if they're
1132e4b17023SJohn Marino      equal, they were constructed identically.
1133e4b17023SJohn Marino 
1134e4b17023SJohn Marino      Also check for identical exception regions.  */
1135e4b17023SJohn Marino 
1136e4b17023SJohn Marino   if (CALL_P (i1))
1137e4b17023SJohn Marino     {
1138e4b17023SJohn Marino       /* Ensure the same EH region.  */
1139e4b17023SJohn Marino       rtx n1 = find_reg_note (i1, REG_EH_REGION, 0);
1140e4b17023SJohn Marino       rtx n2 = find_reg_note (i2, REG_EH_REGION, 0);
1141e4b17023SJohn Marino 
1142e4b17023SJohn Marino       if (!n1 && n2)
1143e4b17023SJohn Marino 	return dir_none;
1144e4b17023SJohn Marino 
1145e4b17023SJohn Marino       if (n1 && (!n2 || XEXP (n1, 0) != XEXP (n2, 0)))
1146e4b17023SJohn Marino 	return dir_none;
1147e4b17023SJohn Marino 
1148e4b17023SJohn Marino       if (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
1149e4b17023SJohn Marino 			CALL_INSN_FUNCTION_USAGE (i2))
1150e4b17023SJohn Marino 	  || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2))
1151e4b17023SJohn Marino 	return dir_none;
1152e4b17023SJohn Marino     }
1153e4b17023SJohn Marino 
1154e4b17023SJohn Marino #ifdef STACK_REGS
1155e4b17023SJohn Marino   /* If cross_jump_death_matters is not 0, the insn's mode
1156e4b17023SJohn Marino      indicates whether or not the insn contains any stack-like
1157e4b17023SJohn Marino      regs.  */
1158e4b17023SJohn Marino 
1159e4b17023SJohn Marino   if ((mode & CLEANUP_POST_REGSTACK) && stack_regs_mentioned (i1))
1160e4b17023SJohn Marino     {
1161e4b17023SJohn Marino       /* If register stack conversion has already been done, then
1162e4b17023SJohn Marino 	 death notes must also be compared before it is certain that
1163e4b17023SJohn Marino 	 the two instruction streams match.  */
1164e4b17023SJohn Marino 
1165e4b17023SJohn Marino       rtx note;
1166e4b17023SJohn Marino       HARD_REG_SET i1_regset, i2_regset;
1167e4b17023SJohn Marino 
1168e4b17023SJohn Marino       CLEAR_HARD_REG_SET (i1_regset);
1169e4b17023SJohn Marino       CLEAR_HARD_REG_SET (i2_regset);
1170e4b17023SJohn Marino 
1171e4b17023SJohn Marino       for (note = REG_NOTES (i1); note; note = XEXP (note, 1))
1172e4b17023SJohn Marino 	if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0)))
1173e4b17023SJohn Marino 	  SET_HARD_REG_BIT (i1_regset, REGNO (XEXP (note, 0)));
1174e4b17023SJohn Marino 
1175e4b17023SJohn Marino       for (note = REG_NOTES (i2); note; note = XEXP (note, 1))
1176e4b17023SJohn Marino 	if (REG_NOTE_KIND (note) == REG_DEAD && STACK_REG_P (XEXP (note, 0)))
1177e4b17023SJohn Marino 	  SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0)));
1178e4b17023SJohn Marino 
1179e4b17023SJohn Marino       if (!hard_reg_set_equal_p (i1_regset, i2_regset))
1180e4b17023SJohn Marino 	return dir_none;
1181e4b17023SJohn Marino     }
1182e4b17023SJohn Marino #endif
1183e4b17023SJohn Marino 
1184e4b17023SJohn Marino   if (reload_completed
1185e4b17023SJohn Marino       ? rtx_renumbered_equal_p (p1, p2) : rtx_equal_p (p1, p2))
1186e4b17023SJohn Marino     return dir_both;
1187e4b17023SJohn Marino 
1188e4b17023SJohn Marino   return can_replace_by (i1, i2);
1189e4b17023SJohn Marino }
1190e4b17023SJohn Marino 
1191e4b17023SJohn Marino /* When comparing insns I1 and I2 in flow_find_cross_jump or
1192e4b17023SJohn Marino    flow_find_head_matching_sequence, ensure the notes match.  */
1193e4b17023SJohn Marino 
1194e4b17023SJohn Marino static void
merge_notes(rtx i1,rtx i2)1195e4b17023SJohn Marino merge_notes (rtx i1, rtx i2)
1196e4b17023SJohn Marino {
1197e4b17023SJohn Marino   /* If the merged insns have different REG_EQUAL notes, then
1198e4b17023SJohn Marino      remove them.  */
1199e4b17023SJohn Marino   rtx equiv1 = find_reg_equal_equiv_note (i1);
1200e4b17023SJohn Marino   rtx equiv2 = find_reg_equal_equiv_note (i2);
1201e4b17023SJohn Marino 
1202e4b17023SJohn Marino   if (equiv1 && !equiv2)
1203e4b17023SJohn Marino     remove_note (i1, equiv1);
1204e4b17023SJohn Marino   else if (!equiv1 && equiv2)
1205e4b17023SJohn Marino     remove_note (i2, equiv2);
1206e4b17023SJohn Marino   else if (equiv1 && equiv2
1207e4b17023SJohn Marino 	   && !rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0)))
1208e4b17023SJohn Marino     {
1209e4b17023SJohn Marino       remove_note (i1, equiv1);
1210e4b17023SJohn Marino       remove_note (i2, equiv2);
1211e4b17023SJohn Marino     }
1212e4b17023SJohn Marino }
1213e4b17023SJohn Marino 
1214e4b17023SJohn Marino  /* Walks from I1 in BB1 backward till the next non-debug insn, and returns the
1215e4b17023SJohn Marino     resulting insn in I1, and the corresponding bb in BB1.  At the head of a
1216e4b17023SJohn Marino     bb, if there is a predecessor bb that reaches this bb via fallthru, and
1217e4b17023SJohn Marino     FOLLOW_FALLTHRU, walks further in the predecessor bb and registers this in
1218e4b17023SJohn Marino     DID_FALLTHRU.  Otherwise, stops at the head of the bb.  */
1219e4b17023SJohn Marino 
1220e4b17023SJohn Marino static void
walk_to_nondebug_insn(rtx * i1,basic_block * bb1,bool follow_fallthru,bool * did_fallthru)1221e4b17023SJohn Marino walk_to_nondebug_insn (rtx *i1, basic_block *bb1, bool follow_fallthru,
1222e4b17023SJohn Marino                        bool *did_fallthru)
1223e4b17023SJohn Marino {
1224e4b17023SJohn Marino   edge fallthru;
1225e4b17023SJohn Marino 
1226e4b17023SJohn Marino   *did_fallthru = false;
1227e4b17023SJohn Marino 
1228e4b17023SJohn Marino   /* Ignore notes.  */
1229e4b17023SJohn Marino   while (!NONDEBUG_INSN_P (*i1))
1230e4b17023SJohn Marino     {
1231e4b17023SJohn Marino       if (*i1 != BB_HEAD (*bb1))
1232e4b17023SJohn Marino         {
1233e4b17023SJohn Marino           *i1 = PREV_INSN (*i1);
1234e4b17023SJohn Marino           continue;
1235e4b17023SJohn Marino         }
1236e4b17023SJohn Marino 
1237e4b17023SJohn Marino       if (!follow_fallthru)
1238e4b17023SJohn Marino         return;
1239e4b17023SJohn Marino 
1240e4b17023SJohn Marino       fallthru = find_fallthru_edge ((*bb1)->preds);
1241e4b17023SJohn Marino       if (!fallthru || fallthru->src == ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun)
1242e4b17023SJohn Marino           || !single_succ_p (fallthru->src))
1243e4b17023SJohn Marino         return;
1244e4b17023SJohn Marino 
1245e4b17023SJohn Marino       *bb1 = fallthru->src;
1246e4b17023SJohn Marino       *i1 = BB_END (*bb1);
1247e4b17023SJohn Marino       *did_fallthru = true;
1248e4b17023SJohn Marino      }
1249e4b17023SJohn Marino }
1250e4b17023SJohn Marino 
1251e4b17023SJohn Marino /* Look through the insns at the end of BB1 and BB2 and find the longest
1252e4b17023SJohn Marino    sequence that are either equivalent, or allow forward or backward
1253e4b17023SJohn Marino    replacement.  Store the first insns for that sequence in *F1 and *F2 and
1254e4b17023SJohn Marino    return the sequence length.
1255e4b17023SJohn Marino 
1256e4b17023SJohn Marino    DIR_P indicates the allowed replacement direction on function entry, and
1257e4b17023SJohn Marino    the actual replacement direction on function exit.  If NULL, only equivalent
1258e4b17023SJohn Marino    sequences are allowed.
1259e4b17023SJohn Marino 
1260e4b17023SJohn Marino    To simplify callers of this function, if the blocks match exactly,
1261e4b17023SJohn Marino    store the head of the blocks in *F1 and *F2.  */
1262e4b17023SJohn Marino 
1263e4b17023SJohn Marino int
flow_find_cross_jump(basic_block bb1,basic_block bb2,rtx * f1,rtx * f2,enum replace_direction * dir_p)1264e4b17023SJohn Marino flow_find_cross_jump (basic_block bb1, basic_block bb2, rtx *f1, rtx *f2,
1265e4b17023SJohn Marino                       enum replace_direction *dir_p)
1266e4b17023SJohn Marino {
1267e4b17023SJohn Marino   rtx i1, i2, last1, last2, afterlast1, afterlast2;
1268e4b17023SJohn Marino   int ninsns = 0;
1269e4b17023SJohn Marino   rtx p1;
1270e4b17023SJohn Marino   enum replace_direction dir, last_dir, afterlast_dir;
1271e4b17023SJohn Marino   bool follow_fallthru, did_fallthru;
1272e4b17023SJohn Marino 
1273e4b17023SJohn Marino   if (dir_p)
1274e4b17023SJohn Marino     dir = *dir_p;
1275e4b17023SJohn Marino   else
1276e4b17023SJohn Marino     dir = dir_both;
1277e4b17023SJohn Marino   afterlast_dir = dir;
1278e4b17023SJohn Marino   last_dir = afterlast_dir;
1279e4b17023SJohn Marino 
1280e4b17023SJohn Marino   /* Skip simple jumps at the end of the blocks.  Complex jumps still
1281e4b17023SJohn Marino      need to be compared for equivalence, which we'll do below.  */
1282e4b17023SJohn Marino 
1283e4b17023SJohn Marino   i1 = BB_END (bb1);
1284e4b17023SJohn Marino   last1 = afterlast1 = last2 = afterlast2 = NULL_RTX;
1285e4b17023SJohn Marino   if (onlyjump_p (i1)
1286e4b17023SJohn Marino       || (returnjump_p (i1) && !side_effects_p (PATTERN (i1))))
1287e4b17023SJohn Marino     {
1288e4b17023SJohn Marino       last1 = i1;
1289e4b17023SJohn Marino       i1 = PREV_INSN (i1);
1290e4b17023SJohn Marino     }
1291e4b17023SJohn Marino 
1292e4b17023SJohn Marino   i2 = BB_END (bb2);
1293e4b17023SJohn Marino   if (onlyjump_p (i2)
1294e4b17023SJohn Marino       || (returnjump_p (i2) && !side_effects_p (PATTERN (i2))))
1295e4b17023SJohn Marino     {
1296e4b17023SJohn Marino       last2 = i2;
1297e4b17023SJohn Marino       /* Count everything except for unconditional jump as insn.  */
1298e4b17023SJohn Marino       if (!simplejump_p (i2) && !returnjump_p (i2) && last1)
1299e4b17023SJohn Marino 	ninsns++;
1300e4b17023SJohn Marino       i2 = PREV_INSN (i2);
1301e4b17023SJohn Marino     }
1302e4b17023SJohn Marino 
1303e4b17023SJohn Marino   while (true)
1304e4b17023SJohn Marino     {
1305e4b17023SJohn Marino       /* In the following example, we can replace all jumps to C by jumps to A.
1306e4b17023SJohn Marino 
1307e4b17023SJohn Marino          This removes 4 duplicate insns.
1308e4b17023SJohn Marino          [bb A] insn1            [bb C] insn1
1309e4b17023SJohn Marino                 insn2                   insn2
1310e4b17023SJohn Marino          [bb B] insn3                   insn3
1311e4b17023SJohn Marino                 insn4                   insn4
1312e4b17023SJohn Marino                 jump_insn               jump_insn
1313e4b17023SJohn Marino 
1314e4b17023SJohn Marino          We could also replace all jumps to A by jumps to C, but that leaves B
1315e4b17023SJohn Marino          alive, and removes only 2 duplicate insns.  In a subsequent crossjump
1316e4b17023SJohn Marino          step, all jumps to B would be replaced with jumps to the middle of C,
1317e4b17023SJohn Marino          achieving the same result with more effort.
1318e4b17023SJohn Marino          So we allow only the first possibility, which means that we don't allow
1319e4b17023SJohn Marino          fallthru in the block that's being replaced.  */
1320e4b17023SJohn Marino 
1321e4b17023SJohn Marino       follow_fallthru = dir_p && dir != dir_forward;
1322e4b17023SJohn Marino       walk_to_nondebug_insn (&i1, &bb1, follow_fallthru, &did_fallthru);
1323e4b17023SJohn Marino       if (did_fallthru)
1324e4b17023SJohn Marino         dir = dir_backward;
1325e4b17023SJohn Marino 
1326e4b17023SJohn Marino       follow_fallthru = dir_p && dir != dir_backward;
1327e4b17023SJohn Marino       walk_to_nondebug_insn (&i2, &bb2, follow_fallthru, &did_fallthru);
1328e4b17023SJohn Marino       if (did_fallthru)
1329e4b17023SJohn Marino         dir = dir_forward;
1330e4b17023SJohn Marino 
1331e4b17023SJohn Marino       if (i1 == BB_HEAD (bb1) || i2 == BB_HEAD (bb2))
1332e4b17023SJohn Marino 	break;
1333e4b17023SJohn Marino 
1334e4b17023SJohn Marino       dir = merge_dir (dir, old_insns_match_p (0, i1, i2));
1335e4b17023SJohn Marino       if (dir == dir_none || (!dir_p && dir != dir_both))
1336e4b17023SJohn Marino 	break;
1337e4b17023SJohn Marino 
1338e4b17023SJohn Marino       merge_memattrs (i1, i2);
1339e4b17023SJohn Marino 
1340e4b17023SJohn Marino       /* Don't begin a cross-jump with a NOTE insn.  */
1341e4b17023SJohn Marino       if (INSN_P (i1))
1342e4b17023SJohn Marino 	{
1343e4b17023SJohn Marino 	  merge_notes (i1, i2);
1344e4b17023SJohn Marino 
1345e4b17023SJohn Marino 	  afterlast1 = last1, afterlast2 = last2;
1346e4b17023SJohn Marino 	  last1 = i1, last2 = i2;
1347e4b17023SJohn Marino 	  afterlast_dir = last_dir;
1348e4b17023SJohn Marino 	  last_dir = dir;
1349e4b17023SJohn Marino 	  p1 = PATTERN (i1);
1350e4b17023SJohn Marino 	  if (!(GET_CODE (p1) == USE || GET_CODE (p1) == CLOBBER))
1351e4b17023SJohn Marino 	    ninsns++;
1352e4b17023SJohn Marino 	}
1353e4b17023SJohn Marino 
1354e4b17023SJohn Marino       i1 = PREV_INSN (i1);
1355e4b17023SJohn Marino       i2 = PREV_INSN (i2);
1356e4b17023SJohn Marino     }
1357e4b17023SJohn Marino 
1358e4b17023SJohn Marino #ifdef HAVE_cc0
1359e4b17023SJohn Marino   /* Don't allow the insn after a compare to be shared by
1360e4b17023SJohn Marino      cross-jumping unless the compare is also shared.  */
1361e4b17023SJohn Marino   if (ninsns && reg_mentioned_p (cc0_rtx, last1) && ! sets_cc0_p (last1))
1362e4b17023SJohn Marino     last1 = afterlast1, last2 = afterlast2, last_dir = afterlast_dir, ninsns--;
1363e4b17023SJohn Marino #endif
1364e4b17023SJohn Marino 
1365e4b17023SJohn Marino   /* Include preceding notes and labels in the cross-jump.  One,
1366e4b17023SJohn Marino      this may bring us to the head of the blocks as requested above.
1367e4b17023SJohn Marino      Two, it keeps line number notes as matched as may be.  */
1368e4b17023SJohn Marino   if (ninsns)
1369e4b17023SJohn Marino     {
1370e4b17023SJohn Marino       bb1 = BLOCK_FOR_INSN (last1);
1371e4b17023SJohn Marino       while (last1 != BB_HEAD (bb1) && !NONDEBUG_INSN_P (PREV_INSN (last1)))
1372e4b17023SJohn Marino 	last1 = PREV_INSN (last1);
1373e4b17023SJohn Marino 
1374e4b17023SJohn Marino       if (last1 != BB_HEAD (bb1) && LABEL_P (PREV_INSN (last1)))
1375e4b17023SJohn Marino 	last1 = PREV_INSN (last1);
1376e4b17023SJohn Marino 
1377e4b17023SJohn Marino       bb2 = BLOCK_FOR_INSN (last2);
1378e4b17023SJohn Marino       while (last2 != BB_HEAD (bb2) && !NONDEBUG_INSN_P (PREV_INSN (last2)))
1379e4b17023SJohn Marino 	last2 = PREV_INSN (last2);
1380e4b17023SJohn Marino 
1381e4b17023SJohn Marino       if (last2 != BB_HEAD (bb2) && LABEL_P (PREV_INSN (last2)))
1382e4b17023SJohn Marino 	last2 = PREV_INSN (last2);
1383e4b17023SJohn Marino 
1384e4b17023SJohn Marino       *f1 = last1;
1385e4b17023SJohn Marino       *f2 = last2;
1386e4b17023SJohn Marino     }
1387e4b17023SJohn Marino 
1388e4b17023SJohn Marino   if (dir_p)
1389e4b17023SJohn Marino     *dir_p = last_dir;
1390e4b17023SJohn Marino   return ninsns;
1391e4b17023SJohn Marino }
1392e4b17023SJohn Marino 
1393e4b17023SJohn Marino /* Like flow_find_cross_jump, except start looking for a matching sequence from
1394e4b17023SJohn Marino    the head of the two blocks.  Do not include jumps at the end.
1395e4b17023SJohn Marino    If STOP_AFTER is nonzero, stop after finding that many matching
1396e4b17023SJohn Marino    instructions.  */
1397e4b17023SJohn Marino 
1398e4b17023SJohn Marino int
flow_find_head_matching_sequence(basic_block bb1,basic_block bb2,rtx * f1,rtx * f2,int stop_after)1399e4b17023SJohn Marino flow_find_head_matching_sequence (basic_block bb1, basic_block bb2, rtx *f1,
1400e4b17023SJohn Marino 				  rtx *f2, int stop_after)
1401e4b17023SJohn Marino {
1402e4b17023SJohn Marino   rtx i1, i2, last1, last2, beforelast1, beforelast2;
1403e4b17023SJohn Marino   int ninsns = 0;
1404e4b17023SJohn Marino   edge e;
1405e4b17023SJohn Marino   edge_iterator ei;
1406e4b17023SJohn Marino   int nehedges1 = 0, nehedges2 = 0;
1407e4b17023SJohn Marino 
1408e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, bb1->succs)
1409e4b17023SJohn Marino     if (e->flags & EDGE_EH)
1410e4b17023SJohn Marino       nehedges1++;
1411e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, bb2->succs)
1412e4b17023SJohn Marino     if (e->flags & EDGE_EH)
1413e4b17023SJohn Marino       nehedges2++;
1414e4b17023SJohn Marino 
1415e4b17023SJohn Marino   i1 = BB_HEAD (bb1);
1416e4b17023SJohn Marino   i2 = BB_HEAD (bb2);
1417e4b17023SJohn Marino   last1 = beforelast1 = last2 = beforelast2 = NULL_RTX;
1418e4b17023SJohn Marino 
1419e4b17023SJohn Marino   while (true)
1420e4b17023SJohn Marino     {
1421e4b17023SJohn Marino       /* Ignore notes, except NOTE_INSN_EPILOGUE_BEG.  */
1422e4b17023SJohn Marino       while (!NONDEBUG_INSN_P (i1) && i1 != BB_END (bb1))
1423e4b17023SJohn Marino 	{
1424e4b17023SJohn Marino 	  if (NOTE_P (i1) && NOTE_KIND (i1) == NOTE_INSN_EPILOGUE_BEG)
1425e4b17023SJohn Marino 	    break;
1426e4b17023SJohn Marino 	  i1 = NEXT_INSN (i1);
1427e4b17023SJohn Marino 	}
1428e4b17023SJohn Marino 
1429e4b17023SJohn Marino       while (!NONDEBUG_INSN_P (i2) && i2 != BB_END (bb2))
1430e4b17023SJohn Marino 	{
1431e4b17023SJohn Marino 	  if (NOTE_P (i2) && NOTE_KIND (i2) == NOTE_INSN_EPILOGUE_BEG)
1432e4b17023SJohn Marino 	    break;
1433e4b17023SJohn Marino 	  i2 = NEXT_INSN (i2);
1434e4b17023SJohn Marino 	}
1435e4b17023SJohn Marino 
1436e4b17023SJohn Marino       if ((i1 == BB_END (bb1) && !NONDEBUG_INSN_P (i1))
1437e4b17023SJohn Marino 	  || (i2 == BB_END (bb2) && !NONDEBUG_INSN_P (i2)))
1438e4b17023SJohn Marino 	break;
1439e4b17023SJohn Marino 
1440e4b17023SJohn Marino       if (NOTE_P (i1) || NOTE_P (i2)
1441e4b17023SJohn Marino 	  || JUMP_P (i1) || JUMP_P (i2))
1442e4b17023SJohn Marino 	break;
1443e4b17023SJohn Marino 
1444e4b17023SJohn Marino       /* A sanity check to make sure we're not merging insns with different
1445e4b17023SJohn Marino 	 effects on EH.  If only one of them ends a basic block, it shouldn't
1446e4b17023SJohn Marino 	 have an EH edge; if both end a basic block, there should be the same
1447e4b17023SJohn Marino 	 number of EH edges.  */
1448e4b17023SJohn Marino       if ((i1 == BB_END (bb1) && i2 != BB_END (bb2)
1449e4b17023SJohn Marino 	   && nehedges1 > 0)
1450e4b17023SJohn Marino 	  || (i2 == BB_END (bb2) && i1 != BB_END (bb1)
1451e4b17023SJohn Marino 	      && nehedges2 > 0)
1452e4b17023SJohn Marino 	  || (i1 == BB_END (bb1) && i2 == BB_END (bb2)
1453e4b17023SJohn Marino 	      && nehedges1 != nehedges2))
1454e4b17023SJohn Marino 	break;
1455e4b17023SJohn Marino 
1456e4b17023SJohn Marino       if (old_insns_match_p (0, i1, i2) != dir_both)
1457e4b17023SJohn Marino 	break;
1458e4b17023SJohn Marino 
1459e4b17023SJohn Marino       merge_memattrs (i1, i2);
1460e4b17023SJohn Marino 
1461e4b17023SJohn Marino       /* Don't begin a cross-jump with a NOTE insn.  */
1462e4b17023SJohn Marino       if (INSN_P (i1))
1463e4b17023SJohn Marino 	{
1464e4b17023SJohn Marino 	  merge_notes (i1, i2);
1465e4b17023SJohn Marino 
1466e4b17023SJohn Marino 	  beforelast1 = last1, beforelast2 = last2;
1467e4b17023SJohn Marino 	  last1 = i1, last2 = i2;
1468e4b17023SJohn Marino 	  ninsns++;
1469e4b17023SJohn Marino 	}
1470e4b17023SJohn Marino 
1471e4b17023SJohn Marino       if (i1 == BB_END (bb1) || i2 == BB_END (bb2)
1472e4b17023SJohn Marino 	  || (stop_after > 0 && ninsns == stop_after))
1473e4b17023SJohn Marino 	break;
1474e4b17023SJohn Marino 
1475e4b17023SJohn Marino       i1 = NEXT_INSN (i1);
1476e4b17023SJohn Marino       i2 = NEXT_INSN (i2);
1477e4b17023SJohn Marino     }
1478e4b17023SJohn Marino 
1479e4b17023SJohn Marino #ifdef HAVE_cc0
1480e4b17023SJohn Marino   /* Don't allow a compare to be shared by cross-jumping unless the insn
1481e4b17023SJohn Marino      after the compare is also shared.  */
1482e4b17023SJohn Marino   if (ninsns && reg_mentioned_p (cc0_rtx, last1) && sets_cc0_p (last1))
1483e4b17023SJohn Marino     last1 = beforelast1, last2 = beforelast2, ninsns--;
1484e4b17023SJohn Marino #endif
1485e4b17023SJohn Marino 
1486e4b17023SJohn Marino   if (ninsns)
1487e4b17023SJohn Marino     {
1488e4b17023SJohn Marino       *f1 = last1;
1489e4b17023SJohn Marino       *f2 = last2;
1490e4b17023SJohn Marino     }
1491e4b17023SJohn Marino 
1492e4b17023SJohn Marino   return ninsns;
1493e4b17023SJohn Marino }
1494e4b17023SJohn Marino 
1495e4b17023SJohn Marino /* Return true iff outgoing edges of BB1 and BB2 match, together with
1496e4b17023SJohn Marino    the branch instruction.  This means that if we commonize the control
1497e4b17023SJohn Marino    flow before end of the basic block, the semantic remains unchanged.
1498e4b17023SJohn Marino 
1499e4b17023SJohn Marino    We may assume that there exists one edge with a common destination.  */
1500e4b17023SJohn Marino 
1501e4b17023SJohn Marino static bool
outgoing_edges_match(int mode,basic_block bb1,basic_block bb2)1502e4b17023SJohn Marino outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
1503e4b17023SJohn Marino {
1504e4b17023SJohn Marino   int nehedges1 = 0, nehedges2 = 0;
1505e4b17023SJohn Marino   edge fallthru1 = 0, fallthru2 = 0;
1506e4b17023SJohn Marino   edge e1, e2;
1507e4b17023SJohn Marino   edge_iterator ei;
15085ce9237cSJohn Marino   rtx last1, last2;
15095ce9237cSJohn Marino   bool nonfakeedges;
1510e4b17023SJohn Marino 
1511e4b17023SJohn Marino   /* If we performed shrink-wrapping, edges to the EXIT_BLOCK_PTR can
1512e4b17023SJohn Marino      only be distinguished for JUMP_INSNs.  The two paths may differ in
1513e4b17023SJohn Marino      whether they went through the prologue.  Sibcalls are fine, we know
1514e4b17023SJohn Marino      that we either didn't need or inserted an epilogue before them.  */
1515e4b17023SJohn Marino   if (crtl->shrink_wrapped
1516e4b17023SJohn Marino       && single_succ_p (bb1) && single_succ (bb1) == EXIT_BLOCK_PTR
1517e4b17023SJohn Marino       && !JUMP_P (BB_END (bb1))
1518e4b17023SJohn Marino       && !(CALL_P (BB_END (bb1)) && SIBLING_CALL_P (BB_END (bb1))))
1519e4b17023SJohn Marino     return false;
1520e4b17023SJohn Marino 
1521e4b17023SJohn Marino   /* If BB1 has only one successor, we may be looking at either an
1522e4b17023SJohn Marino      unconditional jump, or a fake edge to exit.  */
1523e4b17023SJohn Marino   if (single_succ_p (bb1)
1524e4b17023SJohn Marino       && (single_succ_edge (bb1)->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
1525e4b17023SJohn Marino       && (!JUMP_P (BB_END (bb1)) || simplejump_p (BB_END (bb1))))
1526e4b17023SJohn Marino     return (single_succ_p (bb2)
1527e4b17023SJohn Marino 	    && (single_succ_edge (bb2)->flags
1528e4b17023SJohn Marino 		& (EDGE_COMPLEX | EDGE_FAKE)) == 0
1529e4b17023SJohn Marino 	    && (!JUMP_P (BB_END (bb2)) || simplejump_p (BB_END (bb2))));
1530e4b17023SJohn Marino 
1531e4b17023SJohn Marino   /* Match conditional jumps - this may get tricky when fallthru and branch
1532e4b17023SJohn Marino      edges are crossed.  */
1533e4b17023SJohn Marino   if (EDGE_COUNT (bb1->succs) == 2
1534e4b17023SJohn Marino       && any_condjump_p (BB_END (bb1))
1535e4b17023SJohn Marino       && onlyjump_p (BB_END (bb1)))
1536e4b17023SJohn Marino     {
1537e4b17023SJohn Marino       edge b1, f1, b2, f2;
1538e4b17023SJohn Marino       bool reverse, match;
1539e4b17023SJohn Marino       rtx set1, set2, cond1, cond2;
1540e4b17023SJohn Marino       enum rtx_code code1, code2;
1541e4b17023SJohn Marino 
1542e4b17023SJohn Marino       if (EDGE_COUNT (bb2->succs) != 2
1543e4b17023SJohn Marino 	  || !any_condjump_p (BB_END (bb2))
1544e4b17023SJohn Marino 	  || !onlyjump_p (BB_END (bb2)))
1545e4b17023SJohn Marino 	return false;
1546e4b17023SJohn Marino 
1547e4b17023SJohn Marino       b1 = BRANCH_EDGE (bb1);
1548e4b17023SJohn Marino       b2 = BRANCH_EDGE (bb2);
1549e4b17023SJohn Marino       f1 = FALLTHRU_EDGE (bb1);
1550e4b17023SJohn Marino       f2 = FALLTHRU_EDGE (bb2);
1551e4b17023SJohn Marino 
1552e4b17023SJohn Marino       /* Get around possible forwarders on fallthru edges.  Other cases
1553e4b17023SJohn Marino 	 should be optimized out already.  */
1554e4b17023SJohn Marino       if (FORWARDER_BLOCK_P (f1->dest))
1555e4b17023SJohn Marino 	f1 = single_succ_edge (f1->dest);
1556e4b17023SJohn Marino 
1557e4b17023SJohn Marino       if (FORWARDER_BLOCK_P (f2->dest))
1558e4b17023SJohn Marino 	f2 = single_succ_edge (f2->dest);
1559e4b17023SJohn Marino 
1560e4b17023SJohn Marino       /* To simplify use of this function, return false if there are
1561e4b17023SJohn Marino 	 unneeded forwarder blocks.  These will get eliminated later
1562e4b17023SJohn Marino 	 during cleanup_cfg.  */
1563e4b17023SJohn Marino       if (FORWARDER_BLOCK_P (f1->dest)
1564e4b17023SJohn Marino 	  || FORWARDER_BLOCK_P (f2->dest)
1565e4b17023SJohn Marino 	  || FORWARDER_BLOCK_P (b1->dest)
1566e4b17023SJohn Marino 	  || FORWARDER_BLOCK_P (b2->dest))
1567e4b17023SJohn Marino 	return false;
1568e4b17023SJohn Marino 
1569e4b17023SJohn Marino       if (f1->dest == f2->dest && b1->dest == b2->dest)
1570e4b17023SJohn Marino 	reverse = false;
1571e4b17023SJohn Marino       else if (f1->dest == b2->dest && b1->dest == f2->dest)
1572e4b17023SJohn Marino 	reverse = true;
1573e4b17023SJohn Marino       else
1574e4b17023SJohn Marino 	return false;
1575e4b17023SJohn Marino 
1576e4b17023SJohn Marino       set1 = pc_set (BB_END (bb1));
1577e4b17023SJohn Marino       set2 = pc_set (BB_END (bb2));
1578e4b17023SJohn Marino       if ((XEXP (SET_SRC (set1), 1) == pc_rtx)
1579e4b17023SJohn Marino 	  != (XEXP (SET_SRC (set2), 1) == pc_rtx))
1580e4b17023SJohn Marino 	reverse = !reverse;
1581e4b17023SJohn Marino 
1582e4b17023SJohn Marino       cond1 = XEXP (SET_SRC (set1), 0);
1583e4b17023SJohn Marino       cond2 = XEXP (SET_SRC (set2), 0);
1584e4b17023SJohn Marino       code1 = GET_CODE (cond1);
1585e4b17023SJohn Marino       if (reverse)
1586e4b17023SJohn Marino 	code2 = reversed_comparison_code (cond2, BB_END (bb2));
1587e4b17023SJohn Marino       else
1588e4b17023SJohn Marino 	code2 = GET_CODE (cond2);
1589e4b17023SJohn Marino 
1590e4b17023SJohn Marino       if (code2 == UNKNOWN)
1591e4b17023SJohn Marino 	return false;
1592e4b17023SJohn Marino 
1593e4b17023SJohn Marino       /* Verify codes and operands match.  */
1594e4b17023SJohn Marino       match = ((code1 == code2
1595e4b17023SJohn Marino 		&& rtx_renumbered_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
1596e4b17023SJohn Marino 		&& rtx_renumbered_equal_p (XEXP (cond1, 1), XEXP (cond2, 1)))
1597e4b17023SJohn Marino 	       || (code1 == swap_condition (code2)
1598e4b17023SJohn Marino 		   && rtx_renumbered_equal_p (XEXP (cond1, 1),
1599e4b17023SJohn Marino 					      XEXP (cond2, 0))
1600e4b17023SJohn Marino 		   && rtx_renumbered_equal_p (XEXP (cond1, 0),
1601e4b17023SJohn Marino 					      XEXP (cond2, 1))));
1602e4b17023SJohn Marino 
1603e4b17023SJohn Marino       /* If we return true, we will join the blocks.  Which means that
1604e4b17023SJohn Marino 	 we will only have one branch prediction bit to work with.  Thus
1605e4b17023SJohn Marino 	 we require the existing branches to have probabilities that are
1606e4b17023SJohn Marino 	 roughly similar.  */
1607e4b17023SJohn Marino       if (match
1608e4b17023SJohn Marino 	  && optimize_bb_for_speed_p (bb1)
1609e4b17023SJohn Marino 	  && optimize_bb_for_speed_p (bb2))
1610e4b17023SJohn Marino 	{
1611e4b17023SJohn Marino 	  int prob2;
1612e4b17023SJohn Marino 
1613e4b17023SJohn Marino 	  if (b1->dest == b2->dest)
1614e4b17023SJohn Marino 	    prob2 = b2->probability;
1615e4b17023SJohn Marino 	  else
1616e4b17023SJohn Marino 	    /* Do not use f2 probability as f2 may be forwarded.  */
1617e4b17023SJohn Marino 	    prob2 = REG_BR_PROB_BASE - b2->probability;
1618e4b17023SJohn Marino 
1619e4b17023SJohn Marino 	  /* Fail if the difference in probabilities is greater than 50%.
1620e4b17023SJohn Marino 	     This rules out two well-predicted branches with opposite
1621e4b17023SJohn Marino 	     outcomes.  */
1622e4b17023SJohn Marino 	  if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 2)
1623e4b17023SJohn Marino 	    {
1624e4b17023SJohn Marino 	      if (dump_file)
1625e4b17023SJohn Marino 		fprintf (dump_file,
1626e4b17023SJohn Marino 			 "Outcomes of branch in bb %i and %i differ too much (%i %i)\n",
1627e4b17023SJohn Marino 			 bb1->index, bb2->index, b1->probability, prob2);
1628e4b17023SJohn Marino 
1629e4b17023SJohn Marino 	      return false;
1630e4b17023SJohn Marino 	    }
1631e4b17023SJohn Marino 	}
1632e4b17023SJohn Marino 
1633e4b17023SJohn Marino       if (dump_file && match)
1634e4b17023SJohn Marino 	fprintf (dump_file, "Conditionals in bb %i and %i match.\n",
1635e4b17023SJohn Marino 		 bb1->index, bb2->index);
1636e4b17023SJohn Marino 
1637e4b17023SJohn Marino       return match;
1638e4b17023SJohn Marino     }
1639e4b17023SJohn Marino 
1640e4b17023SJohn Marino   /* Generic case - we are seeing a computed jump, table jump or trapping
1641e4b17023SJohn Marino      instruction.  */
1642e4b17023SJohn Marino 
1643e4b17023SJohn Marino   /* Check whether there are tablejumps in the end of BB1 and BB2.
1644e4b17023SJohn Marino      Return true if they are identical.  */
1645e4b17023SJohn Marino     {
1646e4b17023SJohn Marino       rtx label1, label2;
1647e4b17023SJohn Marino       rtx table1, table2;
1648e4b17023SJohn Marino 
1649e4b17023SJohn Marino       if (tablejump_p (BB_END (bb1), &label1, &table1)
1650e4b17023SJohn Marino 	  && tablejump_p (BB_END (bb2), &label2, &table2)
1651e4b17023SJohn Marino 	  && GET_CODE (PATTERN (table1)) == GET_CODE (PATTERN (table2)))
1652e4b17023SJohn Marino 	{
1653e4b17023SJohn Marino 	  /* The labels should never be the same rtx.  If they really are same
1654e4b17023SJohn Marino 	     the jump tables are same too. So disable crossjumping of blocks BB1
1655e4b17023SJohn Marino 	     and BB2 because when deleting the common insns in the end of BB1
1656e4b17023SJohn Marino 	     by delete_basic_block () the jump table would be deleted too.  */
1657e4b17023SJohn Marino 	  /* If LABEL2 is referenced in BB1->END do not do anything
1658e4b17023SJohn Marino 	     because we would loose information when replacing
1659e4b17023SJohn Marino 	     LABEL1 by LABEL2 and then LABEL2 by LABEL1 in BB1->END.  */
1660e4b17023SJohn Marino 	  if (label1 != label2 && !rtx_referenced_p (label2, BB_END (bb1)))
1661e4b17023SJohn Marino 	    {
1662e4b17023SJohn Marino 	      /* Set IDENTICAL to true when the tables are identical.  */
1663e4b17023SJohn Marino 	      bool identical = false;
1664e4b17023SJohn Marino 	      rtx p1, p2;
1665e4b17023SJohn Marino 
1666e4b17023SJohn Marino 	      p1 = PATTERN (table1);
1667e4b17023SJohn Marino 	      p2 = PATTERN (table2);
1668e4b17023SJohn Marino 	      if (GET_CODE (p1) == ADDR_VEC && rtx_equal_p (p1, p2))
1669e4b17023SJohn Marino 		{
1670e4b17023SJohn Marino 		  identical = true;
1671e4b17023SJohn Marino 		}
1672e4b17023SJohn Marino 	      else if (GET_CODE (p1) == ADDR_DIFF_VEC
1673e4b17023SJohn Marino 		       && (XVECLEN (p1, 1) == XVECLEN (p2, 1))
1674e4b17023SJohn Marino 		       && rtx_equal_p (XEXP (p1, 2), XEXP (p2, 2))
1675e4b17023SJohn Marino 		       && rtx_equal_p (XEXP (p1, 3), XEXP (p2, 3)))
1676e4b17023SJohn Marino 		{
1677e4b17023SJohn Marino 		  int i;
1678e4b17023SJohn Marino 
1679e4b17023SJohn Marino 		  identical = true;
1680e4b17023SJohn Marino 		  for (i = XVECLEN (p1, 1) - 1; i >= 0 && identical; i--)
1681e4b17023SJohn Marino 		    if (!rtx_equal_p (XVECEXP (p1, 1, i), XVECEXP (p2, 1, i)))
1682e4b17023SJohn Marino 		      identical = false;
1683e4b17023SJohn Marino 		}
1684e4b17023SJohn Marino 
1685e4b17023SJohn Marino 	      if (identical)
1686e4b17023SJohn Marino 		{
1687e4b17023SJohn Marino 		  replace_label_data rr;
1688e4b17023SJohn Marino 		  bool match;
1689e4b17023SJohn Marino 
1690e4b17023SJohn Marino 		  /* Temporarily replace references to LABEL1 with LABEL2
1691e4b17023SJohn Marino 		     in BB1->END so that we could compare the instructions.  */
1692e4b17023SJohn Marino 		  rr.r1 = label1;
1693e4b17023SJohn Marino 		  rr.r2 = label2;
1694e4b17023SJohn Marino 		  rr.update_label_nuses = false;
1695e4b17023SJohn Marino 		  for_each_rtx (&BB_END (bb1), replace_label, &rr);
1696e4b17023SJohn Marino 
1697e4b17023SJohn Marino 		  match = (old_insns_match_p (mode, BB_END (bb1), BB_END (bb2))
1698e4b17023SJohn Marino 			   == dir_both);
1699e4b17023SJohn Marino 		  if (dump_file && match)
1700e4b17023SJohn Marino 		    fprintf (dump_file,
1701e4b17023SJohn Marino 			     "Tablejumps in bb %i and %i match.\n",
1702e4b17023SJohn Marino 			     bb1->index, bb2->index);
1703e4b17023SJohn Marino 
1704e4b17023SJohn Marino 		  /* Set the original label in BB1->END because when deleting
1705e4b17023SJohn Marino 		     a block whose end is a tablejump, the tablejump referenced
1706e4b17023SJohn Marino 		     from the instruction is deleted too.  */
1707e4b17023SJohn Marino 		  rr.r1 = label2;
1708e4b17023SJohn Marino 		  rr.r2 = label1;
1709e4b17023SJohn Marino 		  for_each_rtx (&BB_END (bb1), replace_label, &rr);
1710e4b17023SJohn Marino 
1711e4b17023SJohn Marino 		  return match;
1712e4b17023SJohn Marino 		}
1713e4b17023SJohn Marino 	    }
1714e4b17023SJohn Marino 	  return false;
1715e4b17023SJohn Marino 	}
1716e4b17023SJohn Marino     }
1717e4b17023SJohn Marino 
17185ce9237cSJohn Marino   last1 = BB_END (bb1);
17195ce9237cSJohn Marino   last2 = BB_END (bb2);
17205ce9237cSJohn Marino   if (DEBUG_INSN_P (last1))
17215ce9237cSJohn Marino     last1 = prev_nondebug_insn (last1);
17225ce9237cSJohn Marino   if (DEBUG_INSN_P (last2))
17235ce9237cSJohn Marino     last2 = prev_nondebug_insn (last2);
1724e4b17023SJohn Marino   /* First ensure that the instructions match.  There may be many outgoing
1725e4b17023SJohn Marino      edges so this test is generally cheaper.  */
17265ce9237cSJohn Marino   if (old_insns_match_p (mode, last1, last2) != dir_both)
1727e4b17023SJohn Marino     return false;
1728e4b17023SJohn Marino 
1729e4b17023SJohn Marino   /* Search the outgoing edges, ensure that the counts do match, find possible
1730e4b17023SJohn Marino      fallthru and exception handling edges since these needs more
1731e4b17023SJohn Marino      validation.  */
1732e4b17023SJohn Marino   if (EDGE_COUNT (bb1->succs) != EDGE_COUNT (bb2->succs))
1733e4b17023SJohn Marino     return false;
1734e4b17023SJohn Marino 
17355ce9237cSJohn Marino   nonfakeedges = false;
1736e4b17023SJohn Marino   FOR_EACH_EDGE (e1, ei, bb1->succs)
1737e4b17023SJohn Marino     {
1738e4b17023SJohn Marino       e2 = EDGE_SUCC (bb2, ei.index);
1739e4b17023SJohn Marino 
17405ce9237cSJohn Marino       if ((e1->flags & EDGE_FAKE) == 0)
17415ce9237cSJohn Marino 	nonfakeedges = true;
17425ce9237cSJohn Marino 
1743e4b17023SJohn Marino       if (e1->flags & EDGE_EH)
1744e4b17023SJohn Marino 	nehedges1++;
1745e4b17023SJohn Marino 
1746e4b17023SJohn Marino       if (e2->flags & EDGE_EH)
1747e4b17023SJohn Marino 	nehedges2++;
1748e4b17023SJohn Marino 
1749e4b17023SJohn Marino       if (e1->flags & EDGE_FALLTHRU)
1750e4b17023SJohn Marino 	fallthru1 = e1;
1751e4b17023SJohn Marino       if (e2->flags & EDGE_FALLTHRU)
1752e4b17023SJohn Marino 	fallthru2 = e2;
1753e4b17023SJohn Marino     }
1754e4b17023SJohn Marino 
1755e4b17023SJohn Marino   /* If number of edges of various types does not match, fail.  */
1756e4b17023SJohn Marino   if (nehedges1 != nehedges2
1757e4b17023SJohn Marino       || (fallthru1 != 0) != (fallthru2 != 0))
1758e4b17023SJohn Marino     return false;
1759e4b17023SJohn Marino 
17605ce9237cSJohn Marino   /* If !ACCUMULATE_OUTGOING_ARGS, bb1 (and bb2) have no successors
17615ce9237cSJohn Marino      and the last real insn doesn't have REG_ARGS_SIZE note, don't
17625ce9237cSJohn Marino      attempt to optimize, as the two basic blocks might have different
17635ce9237cSJohn Marino      REG_ARGS_SIZE depths.  For noreturn calls and unconditional
17645ce9237cSJohn Marino      traps there should be REG_ARG_SIZE notes, they could be missing
17655ce9237cSJohn Marino      for __builtin_unreachable () uses though.  */
17665ce9237cSJohn Marino   if (!nonfakeedges
17675ce9237cSJohn Marino       && !ACCUMULATE_OUTGOING_ARGS
17685ce9237cSJohn Marino       && (!INSN_P (last1)
17695ce9237cSJohn Marino           || !find_reg_note (last1, REG_ARGS_SIZE, NULL)))
17705ce9237cSJohn Marino     return false;
17715ce9237cSJohn Marino 
1772e4b17023SJohn Marino   /* fallthru edges must be forwarded to the same destination.  */
1773e4b17023SJohn Marino   if (fallthru1)
1774e4b17023SJohn Marino     {
1775e4b17023SJohn Marino       basic_block d1 = (forwarder_block_p (fallthru1->dest)
1776e4b17023SJohn Marino 			? single_succ (fallthru1->dest): fallthru1->dest);
1777e4b17023SJohn Marino       basic_block d2 = (forwarder_block_p (fallthru2->dest)
1778e4b17023SJohn Marino 			? single_succ (fallthru2->dest): fallthru2->dest);
1779e4b17023SJohn Marino 
1780e4b17023SJohn Marino       if (d1 != d2)
1781e4b17023SJohn Marino 	return false;
1782e4b17023SJohn Marino     }
1783e4b17023SJohn Marino 
1784e4b17023SJohn Marino   /* Ensure the same EH region.  */
1785e4b17023SJohn Marino   {
1786e4b17023SJohn Marino     rtx n1 = find_reg_note (BB_END (bb1), REG_EH_REGION, 0);
1787e4b17023SJohn Marino     rtx n2 = find_reg_note (BB_END (bb2), REG_EH_REGION, 0);
1788e4b17023SJohn Marino 
1789e4b17023SJohn Marino     if (!n1 && n2)
1790e4b17023SJohn Marino       return false;
1791e4b17023SJohn Marino 
1792e4b17023SJohn Marino     if (n1 && (!n2 || XEXP (n1, 0) != XEXP (n2, 0)))
1793e4b17023SJohn Marino       return false;
1794e4b17023SJohn Marino   }
1795e4b17023SJohn Marino 
1796e4b17023SJohn Marino   /* The same checks as in try_crossjump_to_edge. It is required for RTL
1797e4b17023SJohn Marino      version of sequence abstraction.  */
1798e4b17023SJohn Marino   FOR_EACH_EDGE (e1, ei, bb2->succs)
1799e4b17023SJohn Marino     {
1800e4b17023SJohn Marino       edge e2;
1801e4b17023SJohn Marino       edge_iterator ei;
1802e4b17023SJohn Marino       basic_block d1 = e1->dest;
1803e4b17023SJohn Marino 
1804e4b17023SJohn Marino       if (FORWARDER_BLOCK_P (d1))
1805e4b17023SJohn Marino         d1 = EDGE_SUCC (d1, 0)->dest;
1806e4b17023SJohn Marino 
1807e4b17023SJohn Marino       FOR_EACH_EDGE (e2, ei, bb1->succs)
1808e4b17023SJohn Marino         {
1809e4b17023SJohn Marino           basic_block d2 = e2->dest;
1810e4b17023SJohn Marino           if (FORWARDER_BLOCK_P (d2))
1811e4b17023SJohn Marino             d2 = EDGE_SUCC (d2, 0)->dest;
1812e4b17023SJohn Marino           if (d1 == d2)
1813e4b17023SJohn Marino             break;
1814e4b17023SJohn Marino         }
1815e4b17023SJohn Marino 
1816e4b17023SJohn Marino       if (!e2)
1817e4b17023SJohn Marino         return false;
1818e4b17023SJohn Marino     }
1819e4b17023SJohn Marino 
1820e4b17023SJohn Marino   return true;
1821e4b17023SJohn Marino }
1822e4b17023SJohn Marino 
1823e4b17023SJohn Marino /* Returns true if BB basic block has a preserve label.  */
1824e4b17023SJohn Marino 
1825e4b17023SJohn Marino static bool
block_has_preserve_label(basic_block bb)1826e4b17023SJohn Marino block_has_preserve_label (basic_block bb)
1827e4b17023SJohn Marino {
1828e4b17023SJohn Marino   return (bb
1829e4b17023SJohn Marino           && block_label (bb)
1830e4b17023SJohn Marino           && LABEL_PRESERVE_P (block_label (bb)));
1831e4b17023SJohn Marino }
1832e4b17023SJohn Marino 
1833e4b17023SJohn Marino /* E1 and E2 are edges with the same destination block.  Search their
1834e4b17023SJohn Marino    predecessors for common code.  If found, redirect control flow from
1835e4b17023SJohn Marino    (maybe the middle of) E1->SRC to (maybe the middle of) E2->SRC (dir_forward),
1836e4b17023SJohn Marino    or the other way around (dir_backward).  DIR specifies the allowed
1837e4b17023SJohn Marino    replacement direction.  */
1838e4b17023SJohn Marino 
1839e4b17023SJohn Marino static bool
try_crossjump_to_edge(int mode,edge e1,edge e2,enum replace_direction dir)1840e4b17023SJohn Marino try_crossjump_to_edge (int mode, edge e1, edge e2,
1841e4b17023SJohn Marino                        enum replace_direction dir)
1842e4b17023SJohn Marino {
1843e4b17023SJohn Marino   int nmatch;
1844e4b17023SJohn Marino   basic_block src1 = e1->src, src2 = e2->src;
1845e4b17023SJohn Marino   basic_block redirect_to, redirect_from, to_remove;
1846e4b17023SJohn Marino   basic_block osrc1, osrc2, redirect_edges_to, tmp;
1847e4b17023SJohn Marino   rtx newpos1, newpos2;
1848e4b17023SJohn Marino   edge s;
1849e4b17023SJohn Marino   edge_iterator ei;
1850e4b17023SJohn Marino 
1851e4b17023SJohn Marino   newpos1 = newpos2 = NULL_RTX;
1852e4b17023SJohn Marino 
1853e4b17023SJohn Marino   /* If we have partitioned hot/cold basic blocks, it is a bad idea
1854e4b17023SJohn Marino      to try this optimization.
1855e4b17023SJohn Marino 
1856e4b17023SJohn Marino      Basic block partitioning may result in some jumps that appear to
1857e4b17023SJohn Marino      be optimizable (or blocks that appear to be mergeable), but which really
1858e4b17023SJohn Marino      must be left untouched (they are required to make it safely across
1859e4b17023SJohn Marino      partition boundaries).  See the comments at the top of
1860e4b17023SJohn Marino      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
1861e4b17023SJohn Marino 
1862e4b17023SJohn Marino   if (flag_reorder_blocks_and_partition && reload_completed)
1863e4b17023SJohn Marino     return false;
1864e4b17023SJohn Marino 
1865e4b17023SJohn Marino   /* Search backward through forwarder blocks.  We don't need to worry
1866e4b17023SJohn Marino      about multiple entry or chained forwarders, as they will be optimized
1867e4b17023SJohn Marino      away.  We do this to look past the unconditional jump following a
1868e4b17023SJohn Marino      conditional jump that is required due to the current CFG shape.  */
1869e4b17023SJohn Marino   if (single_pred_p (src1)
1870e4b17023SJohn Marino       && FORWARDER_BLOCK_P (src1))
1871e4b17023SJohn Marino     e1 = single_pred_edge (src1), src1 = e1->src;
1872e4b17023SJohn Marino 
1873e4b17023SJohn Marino   if (single_pred_p (src2)
1874e4b17023SJohn Marino       && FORWARDER_BLOCK_P (src2))
1875e4b17023SJohn Marino     e2 = single_pred_edge (src2), src2 = e2->src;
1876e4b17023SJohn Marino 
1877e4b17023SJohn Marino   /* Nothing to do if we reach ENTRY, or a common source block.  */
1878e4b17023SJohn Marino   if (src1 == ENTRY_BLOCK_PTR || src2 == ENTRY_BLOCK_PTR)
1879e4b17023SJohn Marino     return false;
1880e4b17023SJohn Marino   if (src1 == src2)
1881e4b17023SJohn Marino     return false;
1882e4b17023SJohn Marino 
1883e4b17023SJohn Marino   /* Seeing more than 1 forwarder blocks would confuse us later...  */
1884e4b17023SJohn Marino   if (FORWARDER_BLOCK_P (e1->dest)
1885e4b17023SJohn Marino       && FORWARDER_BLOCK_P (single_succ (e1->dest)))
1886e4b17023SJohn Marino     return false;
1887e4b17023SJohn Marino 
1888e4b17023SJohn Marino   if (FORWARDER_BLOCK_P (e2->dest)
1889e4b17023SJohn Marino       && FORWARDER_BLOCK_P (single_succ (e2->dest)))
1890e4b17023SJohn Marino     return false;
1891e4b17023SJohn Marino 
1892e4b17023SJohn Marino   /* Likewise with dead code (possibly newly created by the other optimizations
1893e4b17023SJohn Marino      of cfg_cleanup).  */
1894e4b17023SJohn Marino   if (EDGE_COUNT (src1->preds) == 0 || EDGE_COUNT (src2->preds) == 0)
1895e4b17023SJohn Marino     return false;
1896e4b17023SJohn Marino 
1897e4b17023SJohn Marino   /* Look for the common insn sequence, part the first ...  */
1898e4b17023SJohn Marino   if (!outgoing_edges_match (mode, src1, src2))
1899e4b17023SJohn Marino     return false;
1900e4b17023SJohn Marino 
1901e4b17023SJohn Marino   /* ... and part the second.  */
1902e4b17023SJohn Marino   nmatch = flow_find_cross_jump (src1, src2, &newpos1, &newpos2, &dir);
1903e4b17023SJohn Marino 
1904e4b17023SJohn Marino   osrc1 = src1;
1905e4b17023SJohn Marino   osrc2 = src2;
1906e4b17023SJohn Marino   if (newpos1 != NULL_RTX)
1907e4b17023SJohn Marino     src1 = BLOCK_FOR_INSN (newpos1);
1908e4b17023SJohn Marino   if (newpos2 != NULL_RTX)
1909e4b17023SJohn Marino     src2 = BLOCK_FOR_INSN (newpos2);
1910e4b17023SJohn Marino 
1911e4b17023SJohn Marino   if (dir == dir_backward)
1912e4b17023SJohn Marino     {
1913e4b17023SJohn Marino #define SWAP(T, X, Y) do { T tmp = (X); (X) = (Y); (Y) = tmp; } while (0)
1914e4b17023SJohn Marino       SWAP (basic_block, osrc1, osrc2);
1915e4b17023SJohn Marino       SWAP (basic_block, src1, src2);
1916e4b17023SJohn Marino       SWAP (edge, e1, e2);
1917e4b17023SJohn Marino       SWAP (rtx, newpos1, newpos2);
1918e4b17023SJohn Marino #undef SWAP
1919e4b17023SJohn Marino     }
1920e4b17023SJohn Marino 
1921e4b17023SJohn Marino   /* Don't proceed with the crossjump unless we found a sufficient number
1922e4b17023SJohn Marino      of matching instructions or the 'from' block was totally matched
1923e4b17023SJohn Marino      (such that its predecessors will hopefully be redirected and the
1924e4b17023SJohn Marino      block removed).  */
1925e4b17023SJohn Marino   if ((nmatch < PARAM_VALUE (PARAM_MIN_CROSSJUMP_INSNS))
1926e4b17023SJohn Marino       && (newpos1 != BB_HEAD (src1)))
1927e4b17023SJohn Marino     return false;
1928e4b17023SJohn Marino 
1929e4b17023SJohn Marino   /* Avoid deleting preserve label when redirecting ABNORMAL edges.  */
1930e4b17023SJohn Marino   if (block_has_preserve_label (e1->dest)
1931e4b17023SJohn Marino       && (e1->flags & EDGE_ABNORMAL))
1932e4b17023SJohn Marino     return false;
1933e4b17023SJohn Marino 
1934e4b17023SJohn Marino   /* Here we know that the insns in the end of SRC1 which are common with SRC2
1935e4b17023SJohn Marino      will be deleted.
1936e4b17023SJohn Marino      If we have tablejumps in the end of SRC1 and SRC2
1937e4b17023SJohn Marino      they have been already compared for equivalence in outgoing_edges_match ()
1938e4b17023SJohn Marino      so replace the references to TABLE1 by references to TABLE2.  */
1939e4b17023SJohn Marino     {
1940e4b17023SJohn Marino       rtx label1, label2;
1941e4b17023SJohn Marino       rtx table1, table2;
1942e4b17023SJohn Marino 
1943e4b17023SJohn Marino       if (tablejump_p (BB_END (osrc1), &label1, &table1)
1944e4b17023SJohn Marino 	  && tablejump_p (BB_END (osrc2), &label2, &table2)
1945e4b17023SJohn Marino 	  && label1 != label2)
1946e4b17023SJohn Marino 	{
1947e4b17023SJohn Marino 	  replace_label_data rr;
1948e4b17023SJohn Marino 	  rtx insn;
1949e4b17023SJohn Marino 
1950e4b17023SJohn Marino 	  /* Replace references to LABEL1 with LABEL2.  */
1951e4b17023SJohn Marino 	  rr.r1 = label1;
1952e4b17023SJohn Marino 	  rr.r2 = label2;
1953e4b17023SJohn Marino 	  rr.update_label_nuses = true;
1954e4b17023SJohn Marino 	  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
1955e4b17023SJohn Marino 	    {
1956e4b17023SJohn Marino 	      /* Do not replace the label in SRC1->END because when deleting
1957e4b17023SJohn Marino 		 a block whose end is a tablejump, the tablejump referenced
1958e4b17023SJohn Marino 		 from the instruction is deleted too.  */
1959e4b17023SJohn Marino 	      if (insn != BB_END (osrc1))
1960e4b17023SJohn Marino 		for_each_rtx (&insn, replace_label, &rr);
1961e4b17023SJohn Marino 	    }
1962e4b17023SJohn Marino 	}
1963e4b17023SJohn Marino     }
1964e4b17023SJohn Marino 
1965e4b17023SJohn Marino   /* Avoid splitting if possible.  We must always split when SRC2 has
1966e4b17023SJohn Marino      EH predecessor edges, or we may end up with basic blocks with both
1967e4b17023SJohn Marino      normal and EH predecessor edges.  */
1968e4b17023SJohn Marino   if (newpos2 == BB_HEAD (src2)
1969e4b17023SJohn Marino       && !(EDGE_PRED (src2, 0)->flags & EDGE_EH))
1970e4b17023SJohn Marino     redirect_to = src2;
1971e4b17023SJohn Marino   else
1972e4b17023SJohn Marino     {
1973e4b17023SJohn Marino       if (newpos2 == BB_HEAD (src2))
1974e4b17023SJohn Marino 	{
1975e4b17023SJohn Marino 	  /* Skip possible basic block header.  */
1976e4b17023SJohn Marino 	  if (LABEL_P (newpos2))
1977e4b17023SJohn Marino 	    newpos2 = NEXT_INSN (newpos2);
1978e4b17023SJohn Marino 	  while (DEBUG_INSN_P (newpos2))
1979e4b17023SJohn Marino 	    newpos2 = NEXT_INSN (newpos2);
1980e4b17023SJohn Marino 	  if (NOTE_P (newpos2))
1981e4b17023SJohn Marino 	    newpos2 = NEXT_INSN (newpos2);
1982e4b17023SJohn Marino 	  while (DEBUG_INSN_P (newpos2))
1983e4b17023SJohn Marino 	    newpos2 = NEXT_INSN (newpos2);
1984e4b17023SJohn Marino 	}
1985e4b17023SJohn Marino 
1986e4b17023SJohn Marino       if (dump_file)
1987e4b17023SJohn Marino 	fprintf (dump_file, "Splitting bb %i before %i insns\n",
1988e4b17023SJohn Marino 		 src2->index, nmatch);
1989e4b17023SJohn Marino       redirect_to = split_block (src2, PREV_INSN (newpos2))->dest;
1990e4b17023SJohn Marino     }
1991e4b17023SJohn Marino 
1992e4b17023SJohn Marino   if (dump_file)
1993e4b17023SJohn Marino     fprintf (dump_file,
1994e4b17023SJohn Marino 	     "Cross jumping from bb %i to bb %i; %i common insns\n",
1995e4b17023SJohn Marino 	     src1->index, src2->index, nmatch);
1996e4b17023SJohn Marino 
1997e4b17023SJohn Marino   /* We may have some registers visible through the block.  */
1998e4b17023SJohn Marino   df_set_bb_dirty (redirect_to);
1999e4b17023SJohn Marino 
2000e4b17023SJohn Marino   if (osrc2 == src2)
2001e4b17023SJohn Marino     redirect_edges_to = redirect_to;
2002e4b17023SJohn Marino   else
2003e4b17023SJohn Marino     redirect_edges_to = osrc2;
2004e4b17023SJohn Marino 
2005e4b17023SJohn Marino   /* Recompute the frequencies and counts of outgoing edges.  */
2006e4b17023SJohn Marino   FOR_EACH_EDGE (s, ei, redirect_edges_to->succs)
2007e4b17023SJohn Marino     {
2008e4b17023SJohn Marino       edge s2;
2009e4b17023SJohn Marino       edge_iterator ei;
2010e4b17023SJohn Marino       basic_block d = s->dest;
2011e4b17023SJohn Marino 
2012e4b17023SJohn Marino       if (FORWARDER_BLOCK_P (d))
2013e4b17023SJohn Marino 	d = single_succ (d);
2014e4b17023SJohn Marino 
2015e4b17023SJohn Marino       FOR_EACH_EDGE (s2, ei, src1->succs)
2016e4b17023SJohn Marino 	{
2017e4b17023SJohn Marino 	  basic_block d2 = s2->dest;
2018e4b17023SJohn Marino 	  if (FORWARDER_BLOCK_P (d2))
2019e4b17023SJohn Marino 	    d2 = single_succ (d2);
2020e4b17023SJohn Marino 	  if (d == d2)
2021e4b17023SJohn Marino 	    break;
2022e4b17023SJohn Marino 	}
2023e4b17023SJohn Marino 
2024e4b17023SJohn Marino       s->count += s2->count;
2025e4b17023SJohn Marino 
2026e4b17023SJohn Marino       /* Take care to update possible forwarder blocks.  We verified
2027e4b17023SJohn Marino 	 that there is no more than one in the chain, so we can't run
2028e4b17023SJohn Marino 	 into infinite loop.  */
2029e4b17023SJohn Marino       if (FORWARDER_BLOCK_P (s->dest))
2030e4b17023SJohn Marino 	{
2031e4b17023SJohn Marino 	  single_succ_edge (s->dest)->count += s2->count;
2032e4b17023SJohn Marino 	  s->dest->count += s2->count;
2033e4b17023SJohn Marino 	  s->dest->frequency += EDGE_FREQUENCY (s);
2034e4b17023SJohn Marino 	}
2035e4b17023SJohn Marino 
2036e4b17023SJohn Marino       if (FORWARDER_BLOCK_P (s2->dest))
2037e4b17023SJohn Marino 	{
2038e4b17023SJohn Marino 	  single_succ_edge (s2->dest)->count -= s2->count;
2039e4b17023SJohn Marino 	  if (single_succ_edge (s2->dest)->count < 0)
2040e4b17023SJohn Marino 	    single_succ_edge (s2->dest)->count = 0;
2041e4b17023SJohn Marino 	  s2->dest->count -= s2->count;
2042e4b17023SJohn Marino 	  s2->dest->frequency -= EDGE_FREQUENCY (s);
2043e4b17023SJohn Marino 	  if (s2->dest->frequency < 0)
2044e4b17023SJohn Marino 	    s2->dest->frequency = 0;
2045e4b17023SJohn Marino 	  if (s2->dest->count < 0)
2046e4b17023SJohn Marino 	    s2->dest->count = 0;
2047e4b17023SJohn Marino 	}
2048e4b17023SJohn Marino 
2049e4b17023SJohn Marino       if (!redirect_edges_to->frequency && !src1->frequency)
2050e4b17023SJohn Marino 	s->probability = (s->probability + s2->probability) / 2;
2051e4b17023SJohn Marino       else
2052e4b17023SJohn Marino 	s->probability
2053e4b17023SJohn Marino 	  = ((s->probability * redirect_edges_to->frequency +
2054e4b17023SJohn Marino 	      s2->probability * src1->frequency)
2055e4b17023SJohn Marino 	     / (redirect_edges_to->frequency + src1->frequency));
2056e4b17023SJohn Marino     }
2057e4b17023SJohn Marino 
2058e4b17023SJohn Marino   /* Adjust count and frequency for the block.  An earlier jump
2059e4b17023SJohn Marino      threading pass may have left the profile in an inconsistent
2060e4b17023SJohn Marino      state (see update_bb_profile_for_threading) so we must be
2061e4b17023SJohn Marino      prepared for overflows.  */
2062e4b17023SJohn Marino   tmp = redirect_to;
2063e4b17023SJohn Marino   do
2064e4b17023SJohn Marino     {
2065e4b17023SJohn Marino       tmp->count += src1->count;
2066e4b17023SJohn Marino       tmp->frequency += src1->frequency;
2067e4b17023SJohn Marino       if (tmp->frequency > BB_FREQ_MAX)
2068e4b17023SJohn Marino         tmp->frequency = BB_FREQ_MAX;
2069e4b17023SJohn Marino       if (tmp == redirect_edges_to)
2070e4b17023SJohn Marino         break;
2071e4b17023SJohn Marino       tmp = find_fallthru_edge (tmp->succs)->dest;
2072e4b17023SJohn Marino     }
2073e4b17023SJohn Marino   while (true);
2074e4b17023SJohn Marino   update_br_prob_note (redirect_edges_to);
2075e4b17023SJohn Marino 
2076e4b17023SJohn Marino   /* Edit SRC1 to go to REDIRECT_TO at NEWPOS1.  */
2077e4b17023SJohn Marino 
2078e4b17023SJohn Marino   /* Skip possible basic block header.  */
2079e4b17023SJohn Marino   if (LABEL_P (newpos1))
2080e4b17023SJohn Marino     newpos1 = NEXT_INSN (newpos1);
2081e4b17023SJohn Marino 
2082e4b17023SJohn Marino   while (DEBUG_INSN_P (newpos1))
2083e4b17023SJohn Marino     newpos1 = NEXT_INSN (newpos1);
2084e4b17023SJohn Marino 
2085e4b17023SJohn Marino   if (NOTE_INSN_BASIC_BLOCK_P (newpos1))
2086e4b17023SJohn Marino     newpos1 = NEXT_INSN (newpos1);
2087e4b17023SJohn Marino 
2088e4b17023SJohn Marino   while (DEBUG_INSN_P (newpos1))
2089e4b17023SJohn Marino     newpos1 = NEXT_INSN (newpos1);
2090e4b17023SJohn Marino 
2091e4b17023SJohn Marino   redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
2092e4b17023SJohn Marino   to_remove = single_succ (redirect_from);
2093e4b17023SJohn Marino 
2094e4b17023SJohn Marino   redirect_edge_and_branch_force (single_succ_edge (redirect_from), redirect_to);
2095e4b17023SJohn Marino   delete_basic_block (to_remove);
2096e4b17023SJohn Marino 
2097e4b17023SJohn Marino   update_forwarder_flag (redirect_from);
2098e4b17023SJohn Marino   if (redirect_to != src2)
2099e4b17023SJohn Marino     update_forwarder_flag (src2);
2100e4b17023SJohn Marino 
2101e4b17023SJohn Marino   return true;
2102e4b17023SJohn Marino }
2103e4b17023SJohn Marino 
2104e4b17023SJohn Marino /* Search the predecessors of BB for common insn sequences.  When found,
2105e4b17023SJohn Marino    share code between them by redirecting control flow.  Return true if
2106e4b17023SJohn Marino    any changes made.  */
2107e4b17023SJohn Marino 
2108e4b17023SJohn Marino static bool
try_crossjump_bb(int mode,basic_block bb)2109e4b17023SJohn Marino try_crossjump_bb (int mode, basic_block bb)
2110e4b17023SJohn Marino {
2111e4b17023SJohn Marino   edge e, e2, fallthru;
2112e4b17023SJohn Marino   bool changed;
2113e4b17023SJohn Marino   unsigned max, ix, ix2;
2114e4b17023SJohn Marino 
2115e4b17023SJohn Marino   /* Nothing to do if there is not at least two incoming edges.  */
2116e4b17023SJohn Marino   if (EDGE_COUNT (bb->preds) < 2)
2117e4b17023SJohn Marino     return false;
2118e4b17023SJohn Marino 
2119e4b17023SJohn Marino   /* Don't crossjump if this block ends in a computed jump,
2120e4b17023SJohn Marino      unless we are optimizing for size.  */
2121e4b17023SJohn Marino   if (optimize_bb_for_size_p (bb)
2122e4b17023SJohn Marino       && bb != EXIT_BLOCK_PTR
2123e4b17023SJohn Marino       && computed_jump_p (BB_END (bb)))
2124e4b17023SJohn Marino     return false;
2125e4b17023SJohn Marino 
2126e4b17023SJohn Marino   /* If we are partitioning hot/cold basic blocks, we don't want to
2127e4b17023SJohn Marino      mess up unconditional or indirect jumps that cross between hot
2128e4b17023SJohn Marino      and cold sections.
2129e4b17023SJohn Marino 
2130e4b17023SJohn Marino      Basic block partitioning may result in some jumps that appear to
2131e4b17023SJohn Marino      be optimizable (or blocks that appear to be mergeable), but which really
2132e4b17023SJohn Marino      must be left untouched (they are required to make it safely across
2133e4b17023SJohn Marino      partition boundaries).  See the comments at the top of
2134e4b17023SJohn Marino      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
2135e4b17023SJohn Marino 
2136e4b17023SJohn Marino   if (BB_PARTITION (EDGE_PRED (bb, 0)->src) !=
2137e4b17023SJohn Marino 					BB_PARTITION (EDGE_PRED (bb, 1)->src)
2138e4b17023SJohn Marino       || (EDGE_PRED (bb, 0)->flags & EDGE_CROSSING))
2139e4b17023SJohn Marino     return false;
2140e4b17023SJohn Marino 
2141e4b17023SJohn Marino   /* It is always cheapest to redirect a block that ends in a branch to
2142e4b17023SJohn Marino      a block that falls through into BB, as that adds no branches to the
2143e4b17023SJohn Marino      program.  We'll try that combination first.  */
2144e4b17023SJohn Marino   fallthru = NULL;
2145e4b17023SJohn Marino   max = PARAM_VALUE (PARAM_MAX_CROSSJUMP_EDGES);
2146e4b17023SJohn Marino 
2147e4b17023SJohn Marino   if (EDGE_COUNT (bb->preds) > max)
2148e4b17023SJohn Marino     return false;
2149e4b17023SJohn Marino 
2150e4b17023SJohn Marino   fallthru = find_fallthru_edge (bb->preds);
2151e4b17023SJohn Marino 
2152e4b17023SJohn Marino   changed = false;
2153e4b17023SJohn Marino   for (ix = 0; ix < EDGE_COUNT (bb->preds);)
2154e4b17023SJohn Marino     {
2155e4b17023SJohn Marino       e = EDGE_PRED (bb, ix);
2156e4b17023SJohn Marino       ix++;
2157e4b17023SJohn Marino 
2158e4b17023SJohn Marino       /* As noted above, first try with the fallthru predecessor (or, a
2159e4b17023SJohn Marino 	 fallthru predecessor if we are in cfglayout mode).  */
2160e4b17023SJohn Marino       if (fallthru)
2161e4b17023SJohn Marino 	{
2162e4b17023SJohn Marino 	  /* Don't combine the fallthru edge into anything else.
2163e4b17023SJohn Marino 	     If there is a match, we'll do it the other way around.  */
2164e4b17023SJohn Marino 	  if (e == fallthru)
2165e4b17023SJohn Marino 	    continue;
2166e4b17023SJohn Marino 	  /* If nothing changed since the last attempt, there is nothing
2167e4b17023SJohn Marino 	     we can do.  */
2168e4b17023SJohn Marino 	  if (!first_pass
2169e4b17023SJohn Marino 	      && !((e->src->flags & BB_MODIFIED)
2170e4b17023SJohn Marino 		   || (fallthru->src->flags & BB_MODIFIED)))
2171e4b17023SJohn Marino 	    continue;
2172e4b17023SJohn Marino 
2173e4b17023SJohn Marino 	  if (try_crossjump_to_edge (mode, e, fallthru, dir_forward))
2174e4b17023SJohn Marino 	    {
2175e4b17023SJohn Marino 	      changed = true;
2176e4b17023SJohn Marino 	      ix = 0;
2177e4b17023SJohn Marino 	      continue;
2178e4b17023SJohn Marino 	    }
2179e4b17023SJohn Marino 	}
2180e4b17023SJohn Marino 
2181e4b17023SJohn Marino       /* Non-obvious work limiting check: Recognize that we're going
2182e4b17023SJohn Marino 	 to call try_crossjump_bb on every basic block.  So if we have
2183e4b17023SJohn Marino 	 two blocks with lots of outgoing edges (a switch) and they
2184e4b17023SJohn Marino 	 share lots of common destinations, then we would do the
2185e4b17023SJohn Marino 	 cross-jump check once for each common destination.
2186e4b17023SJohn Marino 
2187e4b17023SJohn Marino 	 Now, if the blocks actually are cross-jump candidates, then
2188e4b17023SJohn Marino 	 all of their destinations will be shared.  Which means that
2189e4b17023SJohn Marino 	 we only need check them for cross-jump candidacy once.  We
2190e4b17023SJohn Marino 	 can eliminate redundant checks of crossjump(A,B) by arbitrarily
2191e4b17023SJohn Marino 	 choosing to do the check from the block for which the edge
2192e4b17023SJohn Marino 	 in question is the first successor of A.  */
2193e4b17023SJohn Marino       if (EDGE_SUCC (e->src, 0) != e)
2194e4b17023SJohn Marino 	continue;
2195e4b17023SJohn Marino 
2196e4b17023SJohn Marino       for (ix2 = 0; ix2 < EDGE_COUNT (bb->preds); ix2++)
2197e4b17023SJohn Marino 	{
2198e4b17023SJohn Marino 	  e2 = EDGE_PRED (bb, ix2);
2199e4b17023SJohn Marino 
2200e4b17023SJohn Marino 	  if (e2 == e)
2201e4b17023SJohn Marino 	    continue;
2202e4b17023SJohn Marino 
2203e4b17023SJohn Marino 	  /* We've already checked the fallthru edge above.  */
2204e4b17023SJohn Marino 	  if (e2 == fallthru)
2205e4b17023SJohn Marino 	    continue;
2206e4b17023SJohn Marino 
2207e4b17023SJohn Marino 	  /* The "first successor" check above only prevents multiple
2208e4b17023SJohn Marino 	     checks of crossjump(A,B).  In order to prevent redundant
2209e4b17023SJohn Marino 	     checks of crossjump(B,A), require that A be the block
2210e4b17023SJohn Marino 	     with the lowest index.  */
2211e4b17023SJohn Marino 	  if (e->src->index > e2->src->index)
2212e4b17023SJohn Marino 	    continue;
2213e4b17023SJohn Marino 
2214e4b17023SJohn Marino 	  /* If nothing changed since the last attempt, there is nothing
2215e4b17023SJohn Marino 	     we can do.  */
2216e4b17023SJohn Marino 	  if (!first_pass
2217e4b17023SJohn Marino 	      && !((e->src->flags & BB_MODIFIED)
2218e4b17023SJohn Marino 		   || (e2->src->flags & BB_MODIFIED)))
2219e4b17023SJohn Marino 	    continue;
2220e4b17023SJohn Marino 
2221e4b17023SJohn Marino 	  /* Both e and e2 are not fallthru edges, so we can crossjump in either
2222e4b17023SJohn Marino 	     direction.  */
2223e4b17023SJohn Marino 	  if (try_crossjump_to_edge (mode, e, e2, dir_both))
2224e4b17023SJohn Marino 	    {
2225e4b17023SJohn Marino 	      changed = true;
2226e4b17023SJohn Marino 	      ix = 0;
2227e4b17023SJohn Marino 	      break;
2228e4b17023SJohn Marino 	    }
2229e4b17023SJohn Marino 	}
2230e4b17023SJohn Marino     }
2231e4b17023SJohn Marino 
2232e4b17023SJohn Marino   if (changed)
2233e4b17023SJohn Marino     crossjumps_occured = true;
2234e4b17023SJohn Marino 
2235e4b17023SJohn Marino   return changed;
2236e4b17023SJohn Marino }
2237e4b17023SJohn Marino 
2238e4b17023SJohn Marino /* Search the successors of BB for common insn sequences.  When found,
2239e4b17023SJohn Marino    share code between them by moving it across the basic block
2240e4b17023SJohn Marino    boundary.  Return true if any changes made.  */
2241e4b17023SJohn Marino 
2242e4b17023SJohn Marino static bool
try_head_merge_bb(basic_block bb)2243e4b17023SJohn Marino try_head_merge_bb (basic_block bb)
2244e4b17023SJohn Marino {
2245e4b17023SJohn Marino   basic_block final_dest_bb = NULL;
2246e4b17023SJohn Marino   int max_match = INT_MAX;
2247e4b17023SJohn Marino   edge e0;
2248e4b17023SJohn Marino   rtx *headptr, *currptr, *nextptr;
2249e4b17023SJohn Marino   bool changed, moveall;
2250e4b17023SJohn Marino   unsigned ix;
2251e4b17023SJohn Marino   rtx e0_last_head, cond, move_before;
2252e4b17023SJohn Marino   unsigned nedges = EDGE_COUNT (bb->succs);
2253e4b17023SJohn Marino   rtx jump = BB_END (bb);
2254e4b17023SJohn Marino   regset live, live_union;
2255e4b17023SJohn Marino 
2256e4b17023SJohn Marino   /* Nothing to do if there is not at least two outgoing edges.  */
2257e4b17023SJohn Marino   if (nedges < 2)
2258e4b17023SJohn Marino     return false;
2259e4b17023SJohn Marino 
2260e4b17023SJohn Marino   /* Don't crossjump if this block ends in a computed jump,
2261e4b17023SJohn Marino      unless we are optimizing for size.  */
2262e4b17023SJohn Marino   if (optimize_bb_for_size_p (bb)
2263e4b17023SJohn Marino       && bb != EXIT_BLOCK_PTR
2264e4b17023SJohn Marino       && computed_jump_p (BB_END (bb)))
2265e4b17023SJohn Marino     return false;
2266e4b17023SJohn Marino 
2267e4b17023SJohn Marino   cond = get_condition (jump, &move_before, true, false);
2268e4b17023SJohn Marino   if (cond == NULL_RTX)
2269e4b17023SJohn Marino     {
2270e4b17023SJohn Marino #ifdef HAVE_cc0
2271e4b17023SJohn Marino       if (reg_mentioned_p (cc0_rtx, jump))
2272e4b17023SJohn Marino 	move_before = prev_nonnote_nondebug_insn (jump);
2273e4b17023SJohn Marino       else
2274e4b17023SJohn Marino #endif
2275e4b17023SJohn Marino 	move_before = jump;
2276e4b17023SJohn Marino     }
2277e4b17023SJohn Marino 
2278e4b17023SJohn Marino   for (ix = 0; ix < nedges; ix++)
2279e4b17023SJohn Marino     if (EDGE_SUCC (bb, ix)->dest == EXIT_BLOCK_PTR)
2280e4b17023SJohn Marino       return false;
2281e4b17023SJohn Marino 
2282e4b17023SJohn Marino   for (ix = 0; ix < nedges; ix++)
2283e4b17023SJohn Marino     {
2284e4b17023SJohn Marino       edge e = EDGE_SUCC (bb, ix);
2285e4b17023SJohn Marino       basic_block other_bb = e->dest;
2286e4b17023SJohn Marino 
2287e4b17023SJohn Marino       if (df_get_bb_dirty (other_bb))
2288e4b17023SJohn Marino 	{
2289e4b17023SJohn Marino 	  block_was_dirty = true;
2290e4b17023SJohn Marino 	  return false;
2291e4b17023SJohn Marino 	}
2292e4b17023SJohn Marino 
2293e4b17023SJohn Marino       if (e->flags & EDGE_ABNORMAL)
2294e4b17023SJohn Marino 	return false;
2295e4b17023SJohn Marino 
2296e4b17023SJohn Marino       /* Normally, all destination blocks must only be reachable from this
2297e4b17023SJohn Marino 	 block, i.e. they must have one incoming edge.
2298e4b17023SJohn Marino 
2299e4b17023SJohn Marino 	 There is one special case we can handle, that of multiple consecutive
2300e4b17023SJohn Marino 	 jumps where the first jumps to one of the targets of the second jump.
2301e4b17023SJohn Marino 	 This happens frequently in switch statements for default labels.
2302e4b17023SJohn Marino 	 The structure is as follows:
2303e4b17023SJohn Marino 	 FINAL_DEST_BB
2304e4b17023SJohn Marino 	 ....
2305e4b17023SJohn Marino 	 if (cond) jump A;
2306e4b17023SJohn Marino 	 fall through
2307e4b17023SJohn Marino 	 BB
2308e4b17023SJohn Marino 	 jump with targets A, B, C, D...
2309e4b17023SJohn Marino 	 A
2310e4b17023SJohn Marino 	 has two incoming edges, from FINAL_DEST_BB and BB
2311e4b17023SJohn Marino 
2312e4b17023SJohn Marino 	 In this case, we can try to move the insns through BB and into
2313e4b17023SJohn Marino 	 FINAL_DEST_BB.  */
2314e4b17023SJohn Marino       if (EDGE_COUNT (other_bb->preds) != 1)
2315e4b17023SJohn Marino 	{
2316e4b17023SJohn Marino 	  edge incoming_edge, incoming_bb_other_edge;
2317e4b17023SJohn Marino 	  edge_iterator ei;
2318e4b17023SJohn Marino 
2319e4b17023SJohn Marino 	  if (final_dest_bb != NULL
2320e4b17023SJohn Marino 	      || EDGE_COUNT (other_bb->preds) != 2)
2321e4b17023SJohn Marino 	    return false;
2322e4b17023SJohn Marino 
2323e4b17023SJohn Marino 	  /* We must be able to move the insns across the whole block.  */
2324e4b17023SJohn Marino 	  move_before = BB_HEAD (bb);
2325e4b17023SJohn Marino 	  while (!NONDEBUG_INSN_P (move_before))
2326e4b17023SJohn Marino 	    move_before = NEXT_INSN (move_before);
2327e4b17023SJohn Marino 
2328e4b17023SJohn Marino 	  if (EDGE_COUNT (bb->preds) != 1)
2329e4b17023SJohn Marino 	    return false;
2330e4b17023SJohn Marino 	  incoming_edge = EDGE_PRED (bb, 0);
2331e4b17023SJohn Marino 	  final_dest_bb = incoming_edge->src;
2332e4b17023SJohn Marino 	  if (EDGE_COUNT (final_dest_bb->succs) != 2)
2333e4b17023SJohn Marino 	    return false;
2334e4b17023SJohn Marino 	  FOR_EACH_EDGE (incoming_bb_other_edge, ei, final_dest_bb->succs)
2335e4b17023SJohn Marino 	    if (incoming_bb_other_edge != incoming_edge)
2336e4b17023SJohn Marino 	      break;
2337e4b17023SJohn Marino 	  if (incoming_bb_other_edge->dest != other_bb)
2338e4b17023SJohn Marino 	    return false;
2339e4b17023SJohn Marino 	}
2340e4b17023SJohn Marino     }
2341e4b17023SJohn Marino 
2342e4b17023SJohn Marino   e0 = EDGE_SUCC (bb, 0);
2343e4b17023SJohn Marino   e0_last_head = NULL_RTX;
2344e4b17023SJohn Marino   changed = false;
2345e4b17023SJohn Marino 
2346e4b17023SJohn Marino   for (ix = 1; ix < nedges; ix++)
2347e4b17023SJohn Marino     {
2348e4b17023SJohn Marino       edge e = EDGE_SUCC (bb, ix);
2349e4b17023SJohn Marino       rtx e0_last, e_last;
2350e4b17023SJohn Marino       int nmatch;
2351e4b17023SJohn Marino 
2352e4b17023SJohn Marino       nmatch = flow_find_head_matching_sequence (e0->dest, e->dest,
2353e4b17023SJohn Marino 						 &e0_last, &e_last, 0);
2354e4b17023SJohn Marino       if (nmatch == 0)
2355e4b17023SJohn Marino 	return false;
2356e4b17023SJohn Marino 
2357e4b17023SJohn Marino       if (nmatch < max_match)
2358e4b17023SJohn Marino 	{
2359e4b17023SJohn Marino 	  max_match = nmatch;
2360e4b17023SJohn Marino 	  e0_last_head = e0_last;
2361e4b17023SJohn Marino 	}
2362e4b17023SJohn Marino     }
2363e4b17023SJohn Marino 
2364e4b17023SJohn Marino   /* If we matched an entire block, we probably have to avoid moving the
2365e4b17023SJohn Marino      last insn.  */
2366e4b17023SJohn Marino   if (max_match > 0
2367e4b17023SJohn Marino       && e0_last_head == BB_END (e0->dest)
2368e4b17023SJohn Marino       && (find_reg_note (e0_last_head, REG_EH_REGION, 0)
2369e4b17023SJohn Marino 	  || control_flow_insn_p (e0_last_head)))
2370e4b17023SJohn Marino     {
2371e4b17023SJohn Marino       max_match--;
2372e4b17023SJohn Marino       if (max_match == 0)
2373e4b17023SJohn Marino 	return false;
2374e4b17023SJohn Marino       do
2375e4b17023SJohn Marino 	e0_last_head = prev_real_insn (e0_last_head);
2376e4b17023SJohn Marino       while (DEBUG_INSN_P (e0_last_head));
2377e4b17023SJohn Marino     }
2378e4b17023SJohn Marino 
2379e4b17023SJohn Marino   if (max_match == 0)
2380e4b17023SJohn Marino     return false;
2381e4b17023SJohn Marino 
2382e4b17023SJohn Marino   /* We must find a union of the live registers at each of the end points.  */
2383e4b17023SJohn Marino   live = BITMAP_ALLOC (NULL);
2384e4b17023SJohn Marino   live_union = BITMAP_ALLOC (NULL);
2385e4b17023SJohn Marino 
2386e4b17023SJohn Marino   currptr = XNEWVEC (rtx, nedges);
2387e4b17023SJohn Marino   headptr = XNEWVEC (rtx, nedges);
2388e4b17023SJohn Marino   nextptr = XNEWVEC (rtx, nedges);
2389e4b17023SJohn Marino 
2390e4b17023SJohn Marino   for (ix = 0; ix < nedges; ix++)
2391e4b17023SJohn Marino     {
2392e4b17023SJohn Marino       int j;
2393e4b17023SJohn Marino       basic_block merge_bb = EDGE_SUCC (bb, ix)->dest;
2394e4b17023SJohn Marino       rtx head = BB_HEAD (merge_bb);
2395e4b17023SJohn Marino 
2396e4b17023SJohn Marino       while (!NONDEBUG_INSN_P (head))
2397e4b17023SJohn Marino 	head = NEXT_INSN (head);
2398e4b17023SJohn Marino       headptr[ix] = head;
2399e4b17023SJohn Marino       currptr[ix] = head;
2400e4b17023SJohn Marino 
2401e4b17023SJohn Marino       /* Compute the end point and live information  */
2402e4b17023SJohn Marino       for (j = 1; j < max_match; j++)
2403e4b17023SJohn Marino 	do
2404e4b17023SJohn Marino 	  head = NEXT_INSN (head);
2405e4b17023SJohn Marino 	while (!NONDEBUG_INSN_P (head));
2406e4b17023SJohn Marino       simulate_backwards_to_point (merge_bb, live, head);
2407e4b17023SJohn Marino       IOR_REG_SET (live_union, live);
2408e4b17023SJohn Marino     }
2409e4b17023SJohn Marino 
2410e4b17023SJohn Marino   /* If we're moving across two blocks, verify the validity of the
2411e4b17023SJohn Marino      first move, then adjust the target and let the loop below deal
2412e4b17023SJohn Marino      with the final move.  */
2413e4b17023SJohn Marino   if (final_dest_bb != NULL)
2414e4b17023SJohn Marino     {
2415e4b17023SJohn Marino       rtx move_upto;
2416e4b17023SJohn Marino 
2417e4b17023SJohn Marino       moveall = can_move_insns_across (currptr[0], e0_last_head, move_before,
2418e4b17023SJohn Marino 				       jump, e0->dest, live_union,
2419e4b17023SJohn Marino 				       NULL, &move_upto);
2420e4b17023SJohn Marino       if (!moveall)
2421e4b17023SJohn Marino 	{
2422e4b17023SJohn Marino 	  if (move_upto == NULL_RTX)
2423e4b17023SJohn Marino 	    goto out;
2424e4b17023SJohn Marino 
2425e4b17023SJohn Marino 	  while (e0_last_head != move_upto)
2426e4b17023SJohn Marino 	    {
2427e4b17023SJohn Marino 	      df_simulate_one_insn_backwards (e0->dest, e0_last_head,
2428e4b17023SJohn Marino 					      live_union);
2429e4b17023SJohn Marino 	      e0_last_head = PREV_INSN (e0_last_head);
2430e4b17023SJohn Marino 	    }
2431e4b17023SJohn Marino 	}
2432e4b17023SJohn Marino       if (e0_last_head == NULL_RTX)
2433e4b17023SJohn Marino 	goto out;
2434e4b17023SJohn Marino 
2435e4b17023SJohn Marino       jump = BB_END (final_dest_bb);
2436e4b17023SJohn Marino       cond = get_condition (jump, &move_before, true, false);
2437e4b17023SJohn Marino       if (cond == NULL_RTX)
2438e4b17023SJohn Marino 	{
2439e4b17023SJohn Marino #ifdef HAVE_cc0
2440e4b17023SJohn Marino 	  if (reg_mentioned_p (cc0_rtx, jump))
2441e4b17023SJohn Marino 	    move_before = prev_nonnote_nondebug_insn (jump);
2442e4b17023SJohn Marino 	  else
2443e4b17023SJohn Marino #endif
2444e4b17023SJohn Marino 	    move_before = jump;
2445e4b17023SJohn Marino 	}
2446e4b17023SJohn Marino     }
2447e4b17023SJohn Marino 
2448e4b17023SJohn Marino   do
2449e4b17023SJohn Marino     {
2450e4b17023SJohn Marino       rtx move_upto;
2451e4b17023SJohn Marino       moveall = can_move_insns_across (currptr[0], e0_last_head,
2452e4b17023SJohn Marino 				       move_before, jump, e0->dest, live_union,
2453e4b17023SJohn Marino 				       NULL, &move_upto);
2454e4b17023SJohn Marino       if (!moveall && move_upto == NULL_RTX)
2455e4b17023SJohn Marino 	{
2456e4b17023SJohn Marino 	  if (jump == move_before)
2457e4b17023SJohn Marino 	    break;
2458e4b17023SJohn Marino 
2459e4b17023SJohn Marino 	  /* Try again, using a different insertion point.  */
2460e4b17023SJohn Marino 	  move_before = jump;
2461e4b17023SJohn Marino 
2462e4b17023SJohn Marino #ifdef HAVE_cc0
2463e4b17023SJohn Marino 	  /* Don't try moving before a cc0 user, as that may invalidate
2464e4b17023SJohn Marino 	     the cc0.  */
2465e4b17023SJohn Marino 	  if (reg_mentioned_p (cc0_rtx, jump))
2466e4b17023SJohn Marino 	    break;
2467e4b17023SJohn Marino #endif
2468e4b17023SJohn Marino 
2469e4b17023SJohn Marino 	  continue;
2470e4b17023SJohn Marino 	}
2471e4b17023SJohn Marino 
2472e4b17023SJohn Marino       if (final_dest_bb && !moveall)
2473e4b17023SJohn Marino 	/* We haven't checked whether a partial move would be OK for the first
2474e4b17023SJohn Marino 	   move, so we have to fail this case.  */
2475e4b17023SJohn Marino 	break;
2476e4b17023SJohn Marino 
2477e4b17023SJohn Marino       changed = true;
2478e4b17023SJohn Marino       for (;;)
2479e4b17023SJohn Marino 	{
2480e4b17023SJohn Marino 	  if (currptr[0] == move_upto)
2481e4b17023SJohn Marino 	    break;
2482e4b17023SJohn Marino 	  for (ix = 0; ix < nedges; ix++)
2483e4b17023SJohn Marino 	    {
2484e4b17023SJohn Marino 	      rtx curr = currptr[ix];
2485e4b17023SJohn Marino 	      do
2486e4b17023SJohn Marino 		curr = NEXT_INSN (curr);
2487e4b17023SJohn Marino 	      while (!NONDEBUG_INSN_P (curr));
2488e4b17023SJohn Marino 	      currptr[ix] = curr;
2489e4b17023SJohn Marino 	    }
2490e4b17023SJohn Marino 	}
2491e4b17023SJohn Marino 
2492e4b17023SJohn Marino       /* If we can't currently move all of the identical insns, remember
2493e4b17023SJohn Marino 	 each insn after the range that we'll merge.  */
2494e4b17023SJohn Marino       if (!moveall)
2495e4b17023SJohn Marino 	for (ix = 0; ix < nedges; ix++)
2496e4b17023SJohn Marino 	  {
2497e4b17023SJohn Marino 	    rtx curr = currptr[ix];
2498e4b17023SJohn Marino 	    do
2499e4b17023SJohn Marino 	      curr = NEXT_INSN (curr);
2500e4b17023SJohn Marino 	    while (!NONDEBUG_INSN_P (curr));
2501e4b17023SJohn Marino 	    nextptr[ix] = curr;
2502e4b17023SJohn Marino 	  }
2503e4b17023SJohn Marino 
2504e4b17023SJohn Marino       reorder_insns (headptr[0], currptr[0], PREV_INSN (move_before));
2505e4b17023SJohn Marino       df_set_bb_dirty (EDGE_SUCC (bb, 0)->dest);
2506e4b17023SJohn Marino       if (final_dest_bb != NULL)
2507e4b17023SJohn Marino 	df_set_bb_dirty (final_dest_bb);
2508e4b17023SJohn Marino       df_set_bb_dirty (bb);
2509e4b17023SJohn Marino       for (ix = 1; ix < nedges; ix++)
2510e4b17023SJohn Marino 	{
2511e4b17023SJohn Marino 	  df_set_bb_dirty (EDGE_SUCC (bb, ix)->dest);
2512e4b17023SJohn Marino 	  delete_insn_chain (headptr[ix], currptr[ix], false);
2513e4b17023SJohn Marino 	}
2514e4b17023SJohn Marino       if (!moveall)
2515e4b17023SJohn Marino 	{
2516e4b17023SJohn Marino 	  if (jump == move_before)
2517e4b17023SJohn Marino 	    break;
2518e4b17023SJohn Marino 
2519e4b17023SJohn Marino 	  /* For the unmerged insns, try a different insertion point.  */
2520e4b17023SJohn Marino 	  move_before = jump;
2521e4b17023SJohn Marino 
2522e4b17023SJohn Marino #ifdef HAVE_cc0
2523e4b17023SJohn Marino 	  /* Don't try moving before a cc0 user, as that may invalidate
2524e4b17023SJohn Marino 	     the cc0.  */
2525e4b17023SJohn Marino 	  if (reg_mentioned_p (cc0_rtx, jump))
2526e4b17023SJohn Marino 	    break;
2527e4b17023SJohn Marino #endif
2528e4b17023SJohn Marino 
2529e4b17023SJohn Marino 	  for (ix = 0; ix < nedges; ix++)
2530e4b17023SJohn Marino 	    currptr[ix] = headptr[ix] = nextptr[ix];
2531e4b17023SJohn Marino 	}
2532e4b17023SJohn Marino     }
2533e4b17023SJohn Marino   while (!moveall);
2534e4b17023SJohn Marino 
2535e4b17023SJohn Marino  out:
2536e4b17023SJohn Marino   free (currptr);
2537e4b17023SJohn Marino   free (headptr);
2538e4b17023SJohn Marino   free (nextptr);
2539e4b17023SJohn Marino 
2540e4b17023SJohn Marino   crossjumps_occured |= changed;
2541e4b17023SJohn Marino 
2542e4b17023SJohn Marino   return changed;
2543e4b17023SJohn Marino }
2544e4b17023SJohn Marino 
2545e4b17023SJohn Marino /* Return true if BB contains just bb note, or bb note followed
2546e4b17023SJohn Marino    by only DEBUG_INSNs.  */
2547e4b17023SJohn Marino 
2548e4b17023SJohn Marino static bool
trivially_empty_bb_p(basic_block bb)2549e4b17023SJohn Marino trivially_empty_bb_p (basic_block bb)
2550e4b17023SJohn Marino {
2551e4b17023SJohn Marino   rtx insn = BB_END (bb);
2552e4b17023SJohn Marino 
2553e4b17023SJohn Marino   while (1)
2554e4b17023SJohn Marino     {
2555e4b17023SJohn Marino       if (insn == BB_HEAD (bb))
2556e4b17023SJohn Marino 	return true;
2557e4b17023SJohn Marino       if (!DEBUG_INSN_P (insn))
2558e4b17023SJohn Marino 	return false;
2559e4b17023SJohn Marino       insn = PREV_INSN (insn);
2560e4b17023SJohn Marino     }
2561e4b17023SJohn Marino }
2562e4b17023SJohn Marino 
2563e4b17023SJohn Marino /* Do simple CFG optimizations - basic block merging, simplifying of jump
2564e4b17023SJohn Marino    instructions etc.  Return nonzero if changes were made.  */
2565e4b17023SJohn Marino 
2566e4b17023SJohn Marino static bool
try_optimize_cfg(int mode)2567e4b17023SJohn Marino try_optimize_cfg (int mode)
2568e4b17023SJohn Marino {
2569e4b17023SJohn Marino   bool changed_overall = false;
2570e4b17023SJohn Marino   bool changed;
2571e4b17023SJohn Marino   int iterations = 0;
2572e4b17023SJohn Marino   basic_block bb, b, next;
2573e4b17023SJohn Marino 
2574e4b17023SJohn Marino   if (mode & (CLEANUP_CROSSJUMP | CLEANUP_THREADING))
2575e4b17023SJohn Marino     clear_bb_flags ();
2576e4b17023SJohn Marino 
2577e4b17023SJohn Marino   crossjumps_occured = false;
2578e4b17023SJohn Marino 
2579e4b17023SJohn Marino   FOR_EACH_BB (bb)
2580e4b17023SJohn Marino     update_forwarder_flag (bb);
2581e4b17023SJohn Marino 
2582e4b17023SJohn Marino   if (! targetm.cannot_modify_jumps_p ())
2583e4b17023SJohn Marino     {
2584e4b17023SJohn Marino       first_pass = true;
2585e4b17023SJohn Marino       /* Attempt to merge blocks as made possible by edge removal.  If
2586e4b17023SJohn Marino 	 a block has only one successor, and the successor has only
2587e4b17023SJohn Marino 	 one predecessor, they may be combined.  */
2588e4b17023SJohn Marino       do
2589e4b17023SJohn Marino 	{
2590e4b17023SJohn Marino 	  block_was_dirty = false;
2591e4b17023SJohn Marino 	  changed = false;
2592e4b17023SJohn Marino 	  iterations++;
2593e4b17023SJohn Marino 
2594e4b17023SJohn Marino 	  if (dump_file)
2595e4b17023SJohn Marino 	    fprintf (dump_file,
2596e4b17023SJohn Marino 		     "\n\ntry_optimize_cfg iteration %i\n\n",
2597e4b17023SJohn Marino 		     iterations);
2598e4b17023SJohn Marino 
2599e4b17023SJohn Marino 	  for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR;)
2600e4b17023SJohn Marino 	    {
2601e4b17023SJohn Marino 	      basic_block c;
2602e4b17023SJohn Marino 	      edge s;
2603e4b17023SJohn Marino 	      bool changed_here = false;
2604e4b17023SJohn Marino 
2605e4b17023SJohn Marino 	      /* Delete trivially dead basic blocks.  This is either
2606e4b17023SJohn Marino 		 blocks with no predecessors, or empty blocks with no
2607e4b17023SJohn Marino 		 successors.  However if the empty block with no
2608e4b17023SJohn Marino 		 successors is the successor of the ENTRY_BLOCK, it is
2609e4b17023SJohn Marino 		 kept.  This ensures that the ENTRY_BLOCK will have a
2610e4b17023SJohn Marino 		 successor which is a precondition for many RTL
2611e4b17023SJohn Marino 		 passes.  Empty blocks may result from expanding
2612e4b17023SJohn Marino 		 __builtin_unreachable ().  */
2613e4b17023SJohn Marino 	      if (EDGE_COUNT (b->preds) == 0
2614e4b17023SJohn Marino 		  || (EDGE_COUNT (b->succs) == 0
2615e4b17023SJohn Marino 		      && trivially_empty_bb_p (b)
2616e4b17023SJohn Marino 		      && single_succ_edge (ENTRY_BLOCK_PTR)->dest != b))
2617e4b17023SJohn Marino 		{
2618e4b17023SJohn Marino 		  c = b->prev_bb;
2619e4b17023SJohn Marino 		  if (EDGE_COUNT (b->preds) > 0)
2620e4b17023SJohn Marino 		    {
2621e4b17023SJohn Marino 		      edge e;
2622e4b17023SJohn Marino 		      edge_iterator ei;
2623e4b17023SJohn Marino 
2624e4b17023SJohn Marino 		      if (current_ir_type () == IR_RTL_CFGLAYOUT)
2625e4b17023SJohn Marino 			{
2626e4b17023SJohn Marino 			  if (b->il.rtl->footer
2627e4b17023SJohn Marino 			      && BARRIER_P (b->il.rtl->footer))
2628e4b17023SJohn Marino 			    FOR_EACH_EDGE (e, ei, b->preds)
2629e4b17023SJohn Marino 			      if ((e->flags & EDGE_FALLTHRU)
2630e4b17023SJohn Marino 				  && e->src->il.rtl->footer == NULL)
2631e4b17023SJohn Marino 				{
2632e4b17023SJohn Marino 				  if (b->il.rtl->footer)
2633e4b17023SJohn Marino 				    {
2634e4b17023SJohn Marino 				      e->src->il.rtl->footer = b->il.rtl->footer;
2635e4b17023SJohn Marino 				      b->il.rtl->footer = NULL;
2636e4b17023SJohn Marino 				    }
2637e4b17023SJohn Marino 				  else
2638e4b17023SJohn Marino 				    {
2639e4b17023SJohn Marino 				      start_sequence ();
2640e4b17023SJohn Marino 				      e->src->il.rtl->footer = emit_barrier ();
2641e4b17023SJohn Marino 				      end_sequence ();
2642e4b17023SJohn Marino 				    }
2643e4b17023SJohn Marino 				}
2644e4b17023SJohn Marino 			}
2645e4b17023SJohn Marino 		      else
2646e4b17023SJohn Marino 			{
2647e4b17023SJohn Marino 			  rtx last = get_last_bb_insn (b);
2648e4b17023SJohn Marino 			  if (last && BARRIER_P (last))
2649e4b17023SJohn Marino 			    FOR_EACH_EDGE (e, ei, b->preds)
2650e4b17023SJohn Marino 			      if ((e->flags & EDGE_FALLTHRU))
2651e4b17023SJohn Marino 				emit_barrier_after (BB_END (e->src));
2652e4b17023SJohn Marino 			}
2653e4b17023SJohn Marino 		    }
2654e4b17023SJohn Marino 		  delete_basic_block (b);
2655e4b17023SJohn Marino 		  changed = true;
2656e4b17023SJohn Marino 		  /* Avoid trying to remove ENTRY_BLOCK_PTR.  */
2657e4b17023SJohn Marino 		  b = (c == ENTRY_BLOCK_PTR ? c->next_bb : c);
2658e4b17023SJohn Marino 		  continue;
2659e4b17023SJohn Marino 		}
2660e4b17023SJohn Marino 
2661e4b17023SJohn Marino 	      /* Remove code labels no longer used.  */
2662e4b17023SJohn Marino 	      if (single_pred_p (b)
2663e4b17023SJohn Marino 		  && (single_pred_edge (b)->flags & EDGE_FALLTHRU)
2664e4b17023SJohn Marino 		  && !(single_pred_edge (b)->flags & EDGE_COMPLEX)
2665e4b17023SJohn Marino 		  && LABEL_P (BB_HEAD (b))
2666e4b17023SJohn Marino 		  /* If the previous block ends with a branch to this
2667e4b17023SJohn Marino 		     block, we can't delete the label.  Normally this
2668e4b17023SJohn Marino 		     is a condjump that is yet to be simplified, but
2669e4b17023SJohn Marino 		     if CASE_DROPS_THRU, this can be a tablejump with
2670e4b17023SJohn Marino 		     some element going to the same place as the
2671e4b17023SJohn Marino 		     default (fallthru).  */
2672e4b17023SJohn Marino 		  && (single_pred (b) == ENTRY_BLOCK_PTR
2673e4b17023SJohn Marino 		      || !JUMP_P (BB_END (single_pred (b)))
2674e4b17023SJohn Marino 		      || ! label_is_jump_target_p (BB_HEAD (b),
2675e4b17023SJohn Marino 						   BB_END (single_pred (b)))))
2676e4b17023SJohn Marino 		{
2677e4b17023SJohn Marino 		  rtx label = BB_HEAD (b);
2678e4b17023SJohn Marino 
2679e4b17023SJohn Marino 		  delete_insn_chain (label, label, false);
2680e4b17023SJohn Marino 		  /* If the case label is undeletable, move it after the
2681e4b17023SJohn Marino 		     BASIC_BLOCK note.  */
2682e4b17023SJohn Marino 		  if (NOTE_KIND (BB_HEAD (b)) == NOTE_INSN_DELETED_LABEL)
2683e4b17023SJohn Marino 		    {
2684e4b17023SJohn Marino 		      rtx bb_note = NEXT_INSN (BB_HEAD (b));
2685e4b17023SJohn Marino 
2686e4b17023SJohn Marino 		      reorder_insns_nobb (label, label, bb_note);
2687e4b17023SJohn Marino 		      BB_HEAD (b) = bb_note;
2688e4b17023SJohn Marino 		      if (BB_END (b) == bb_note)
2689e4b17023SJohn Marino 			BB_END (b) = label;
2690e4b17023SJohn Marino 		    }
2691e4b17023SJohn Marino 		  if (dump_file)
2692e4b17023SJohn Marino 		    fprintf (dump_file, "Deleted label in block %i.\n",
2693e4b17023SJohn Marino 			     b->index);
2694e4b17023SJohn Marino 		}
2695e4b17023SJohn Marino 
2696e4b17023SJohn Marino 	      /* If we fall through an empty block, we can remove it.  */
2697e4b17023SJohn Marino 	      if (!(mode & CLEANUP_CFGLAYOUT)
2698e4b17023SJohn Marino 		  && single_pred_p (b)
2699e4b17023SJohn Marino 		  && (single_pred_edge (b)->flags & EDGE_FALLTHRU)
2700e4b17023SJohn Marino 		  && !LABEL_P (BB_HEAD (b))
2701e4b17023SJohn Marino 		  && FORWARDER_BLOCK_P (b)
2702e4b17023SJohn Marino 		  /* Note that forwarder_block_p true ensures that
2703e4b17023SJohn Marino 		     there is a successor for this block.  */
2704e4b17023SJohn Marino 		  && (single_succ_edge (b)->flags & EDGE_FALLTHRU)
2705e4b17023SJohn Marino 		  && n_basic_blocks > NUM_FIXED_BLOCKS + 1)
2706e4b17023SJohn Marino 		{
2707e4b17023SJohn Marino 		  if (dump_file)
2708e4b17023SJohn Marino 		    fprintf (dump_file,
2709e4b17023SJohn Marino 			     "Deleting fallthru block %i.\n",
2710e4b17023SJohn Marino 			     b->index);
2711e4b17023SJohn Marino 
2712e4b17023SJohn Marino 		  c = b->prev_bb == ENTRY_BLOCK_PTR ? b->next_bb : b->prev_bb;
2713e4b17023SJohn Marino 		  redirect_edge_succ_nodup (single_pred_edge (b),
2714e4b17023SJohn Marino 					    single_succ (b));
2715e4b17023SJohn Marino 		  delete_basic_block (b);
2716e4b17023SJohn Marino 		  changed = true;
2717e4b17023SJohn Marino 		  b = c;
2718e4b17023SJohn Marino 		  continue;
2719e4b17023SJohn Marino 		}
2720e4b17023SJohn Marino 
2721e4b17023SJohn Marino 	      /* Merge B with its single successor, if any.  */
2722e4b17023SJohn Marino 	      if (single_succ_p (b)
2723e4b17023SJohn Marino 		  && (s = single_succ_edge (b))
2724e4b17023SJohn Marino 		  && !(s->flags & EDGE_COMPLEX)
2725e4b17023SJohn Marino 		  && (c = s->dest) != EXIT_BLOCK_PTR
2726e4b17023SJohn Marino 		  && single_pred_p (c)
2727e4b17023SJohn Marino 		  && b != c)
2728e4b17023SJohn Marino 		{
2729e4b17023SJohn Marino 		  /* When not in cfg_layout mode use code aware of reordering
2730e4b17023SJohn Marino 		     INSN.  This code possibly creates new basic blocks so it
2731e4b17023SJohn Marino 		     does not fit merge_blocks interface and is kept here in
2732e4b17023SJohn Marino 		     hope that it will become useless once more of compiler
2733e4b17023SJohn Marino 		     is transformed to use cfg_layout mode.  */
2734e4b17023SJohn Marino 
2735e4b17023SJohn Marino 		  if ((mode & CLEANUP_CFGLAYOUT)
2736e4b17023SJohn Marino 		      && can_merge_blocks_p (b, c))
2737e4b17023SJohn Marino 		    {
2738e4b17023SJohn Marino 		      merge_blocks (b, c);
2739e4b17023SJohn Marino 		      update_forwarder_flag (b);
2740e4b17023SJohn Marino 		      changed_here = true;
2741e4b17023SJohn Marino 		    }
2742e4b17023SJohn Marino 		  else if (!(mode & CLEANUP_CFGLAYOUT)
2743e4b17023SJohn Marino 			   /* If the jump insn has side effects,
2744e4b17023SJohn Marino 			      we can't kill the edge.  */
2745e4b17023SJohn Marino 			   && (!JUMP_P (BB_END (b))
2746e4b17023SJohn Marino 			       || (reload_completed
2747e4b17023SJohn Marino 				   ? simplejump_p (BB_END (b))
2748e4b17023SJohn Marino 				   : (onlyjump_p (BB_END (b))
2749e4b17023SJohn Marino 				      && !tablejump_p (BB_END (b),
2750e4b17023SJohn Marino 						       NULL, NULL))))
2751e4b17023SJohn Marino 			   && (next = merge_blocks_move (s, b, c, mode)))
2752e4b17023SJohn Marino 		      {
2753e4b17023SJohn Marino 			b = next;
2754e4b17023SJohn Marino 			changed_here = true;
2755e4b17023SJohn Marino 		      }
2756e4b17023SJohn Marino 		}
2757e4b17023SJohn Marino 
2758e4b17023SJohn Marino 	      /* Simplify branch over branch.  */
2759e4b17023SJohn Marino 	      if ((mode & CLEANUP_EXPENSIVE)
2760e4b17023SJohn Marino 		   && !(mode & CLEANUP_CFGLAYOUT)
2761e4b17023SJohn Marino 		   && try_simplify_condjump (b))
2762e4b17023SJohn Marino 		changed_here = true;
2763e4b17023SJohn Marino 
2764e4b17023SJohn Marino 	      /* If B has a single outgoing edge, but uses a
2765e4b17023SJohn Marino 		 non-trivial jump instruction without side-effects, we
2766e4b17023SJohn Marino 		 can either delete the jump entirely, or replace it
2767e4b17023SJohn Marino 		 with a simple unconditional jump.  */
2768e4b17023SJohn Marino 	      if (single_succ_p (b)
2769e4b17023SJohn Marino 		  && single_succ (b) != EXIT_BLOCK_PTR
2770e4b17023SJohn Marino 		  && onlyjump_p (BB_END (b))
2771e4b17023SJohn Marino 		  && !find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX)
2772e4b17023SJohn Marino 		  && try_redirect_by_replacing_jump (single_succ_edge (b),
2773e4b17023SJohn Marino 						     single_succ (b),
2774e4b17023SJohn Marino 						     (mode & CLEANUP_CFGLAYOUT) != 0))
2775e4b17023SJohn Marino 		{
2776e4b17023SJohn Marino 		  update_forwarder_flag (b);
2777e4b17023SJohn Marino 		  changed_here = true;
2778e4b17023SJohn Marino 		}
2779e4b17023SJohn Marino 
2780e4b17023SJohn Marino 	      /* Simplify branch to branch.  */
2781e4b17023SJohn Marino 	      if (try_forward_edges (mode, b))
2782e4b17023SJohn Marino 		{
2783e4b17023SJohn Marino 		  update_forwarder_flag (b);
2784e4b17023SJohn Marino 		  changed_here = true;
2785e4b17023SJohn Marino 		}
2786e4b17023SJohn Marino 
2787e4b17023SJohn Marino 	      /* Look for shared code between blocks.  */
2788e4b17023SJohn Marino 	      if ((mode & CLEANUP_CROSSJUMP)
2789e4b17023SJohn Marino 		  && try_crossjump_bb (mode, b))
2790e4b17023SJohn Marino 		changed_here = true;
2791e4b17023SJohn Marino 
2792e4b17023SJohn Marino 	      if ((mode & CLEANUP_CROSSJUMP)
2793e4b17023SJohn Marino 		  /* This can lengthen register lifetimes.  Do it only after
2794e4b17023SJohn Marino 		     reload.  */
2795e4b17023SJohn Marino 		  && reload_completed
2796e4b17023SJohn Marino 		  && try_head_merge_bb (b))
2797e4b17023SJohn Marino 		changed_here = true;
2798e4b17023SJohn Marino 
2799e4b17023SJohn Marino 	      /* Don't get confused by the index shift caused by
2800e4b17023SJohn Marino 		 deleting blocks.  */
2801e4b17023SJohn Marino 	      if (!changed_here)
2802e4b17023SJohn Marino 		b = b->next_bb;
2803e4b17023SJohn Marino 	      else
2804e4b17023SJohn Marino 		changed = true;
2805e4b17023SJohn Marino 	    }
2806e4b17023SJohn Marino 
2807e4b17023SJohn Marino 	  if ((mode & CLEANUP_CROSSJUMP)
2808e4b17023SJohn Marino 	      && try_crossjump_bb (mode, EXIT_BLOCK_PTR))
2809e4b17023SJohn Marino 	    changed = true;
2810e4b17023SJohn Marino 
2811e4b17023SJohn Marino 	  if (block_was_dirty)
2812e4b17023SJohn Marino 	    {
2813e4b17023SJohn Marino 	      /* This should only be set by head-merging.  */
2814e4b17023SJohn Marino 	      gcc_assert (mode & CLEANUP_CROSSJUMP);
2815e4b17023SJohn Marino 	      df_analyze ();
2816e4b17023SJohn Marino 	    }
2817e4b17023SJohn Marino 
2818e4b17023SJohn Marino #ifdef ENABLE_CHECKING
2819e4b17023SJohn Marino 	  if (changed)
2820e4b17023SJohn Marino 	    verify_flow_info ();
2821e4b17023SJohn Marino #endif
2822e4b17023SJohn Marino 
2823e4b17023SJohn Marino 	  changed_overall |= changed;
2824e4b17023SJohn Marino 	  first_pass = false;
2825e4b17023SJohn Marino 	}
2826e4b17023SJohn Marino       while (changed);
2827e4b17023SJohn Marino     }
2828e4b17023SJohn Marino 
2829e4b17023SJohn Marino   FOR_ALL_BB (b)
2830e4b17023SJohn Marino     b->flags &= ~(BB_FORWARDER_BLOCK | BB_NONTHREADABLE_BLOCK);
2831e4b17023SJohn Marino 
2832e4b17023SJohn Marino   return changed_overall;
2833e4b17023SJohn Marino }
2834e4b17023SJohn Marino 
2835e4b17023SJohn Marino /* Delete all unreachable basic blocks.  */
2836e4b17023SJohn Marino 
2837e4b17023SJohn Marino bool
delete_unreachable_blocks(void)2838e4b17023SJohn Marino delete_unreachable_blocks (void)
2839e4b17023SJohn Marino {
2840e4b17023SJohn Marino   bool changed = false;
2841e4b17023SJohn Marino   basic_block b, prev_bb;
2842e4b17023SJohn Marino 
2843e4b17023SJohn Marino   find_unreachable_blocks ();
2844e4b17023SJohn Marino 
2845e4b17023SJohn Marino   /* When we're in GIMPLE mode and there may be debug insns, we should
2846e4b17023SJohn Marino      delete blocks in reverse dominator order, so as to get a chance
2847e4b17023SJohn Marino      to substitute all released DEFs into debug stmts.  If we don't
2848e4b17023SJohn Marino      have dominators information, walking blocks backward gets us a
2849e4b17023SJohn Marino      better chance of retaining most debug information than
2850e4b17023SJohn Marino      otherwise.  */
2851e4b17023SJohn Marino   if (MAY_HAVE_DEBUG_STMTS && current_ir_type () == IR_GIMPLE
2852e4b17023SJohn Marino       && dom_info_available_p (CDI_DOMINATORS))
2853e4b17023SJohn Marino     {
2854e4b17023SJohn Marino       for (b = EXIT_BLOCK_PTR->prev_bb; b != ENTRY_BLOCK_PTR; b = prev_bb)
2855e4b17023SJohn Marino 	{
2856e4b17023SJohn Marino 	  prev_bb = b->prev_bb;
2857e4b17023SJohn Marino 
2858e4b17023SJohn Marino 	  if (!(b->flags & BB_REACHABLE))
2859e4b17023SJohn Marino 	    {
2860e4b17023SJohn Marino 	      /* Speed up the removal of blocks that don't dominate
2861e4b17023SJohn Marino 		 others.  Walking backwards, this should be the common
2862e4b17023SJohn Marino 		 case.  */
2863e4b17023SJohn Marino 	      if (!first_dom_son (CDI_DOMINATORS, b))
2864e4b17023SJohn Marino 		delete_basic_block (b);
2865e4b17023SJohn Marino 	      else
2866e4b17023SJohn Marino 		{
2867e4b17023SJohn Marino 		  VEC (basic_block, heap) *h
2868e4b17023SJohn Marino 		    = get_all_dominated_blocks (CDI_DOMINATORS, b);
2869e4b17023SJohn Marino 
2870e4b17023SJohn Marino 		  while (VEC_length (basic_block, h))
2871e4b17023SJohn Marino 		    {
2872e4b17023SJohn Marino 		      b = VEC_pop (basic_block, h);
2873e4b17023SJohn Marino 
2874e4b17023SJohn Marino 		      prev_bb = b->prev_bb;
2875e4b17023SJohn Marino 
2876e4b17023SJohn Marino 		      gcc_assert (!(b->flags & BB_REACHABLE));
2877e4b17023SJohn Marino 
2878e4b17023SJohn Marino 		      delete_basic_block (b);
2879e4b17023SJohn Marino 		    }
2880e4b17023SJohn Marino 
2881e4b17023SJohn Marino 		  VEC_free (basic_block, heap, h);
2882e4b17023SJohn Marino 		}
2883e4b17023SJohn Marino 
2884e4b17023SJohn Marino 	      changed = true;
2885e4b17023SJohn Marino 	    }
2886e4b17023SJohn Marino 	}
2887e4b17023SJohn Marino     }
2888e4b17023SJohn Marino   else
2889e4b17023SJohn Marino     {
2890e4b17023SJohn Marino       for (b = EXIT_BLOCK_PTR->prev_bb; b != ENTRY_BLOCK_PTR; b = prev_bb)
2891e4b17023SJohn Marino 	{
2892e4b17023SJohn Marino 	  prev_bb = b->prev_bb;
2893e4b17023SJohn Marino 
2894e4b17023SJohn Marino 	  if (!(b->flags & BB_REACHABLE))
2895e4b17023SJohn Marino 	    {
2896e4b17023SJohn Marino 	      delete_basic_block (b);
2897e4b17023SJohn Marino 	      changed = true;
2898e4b17023SJohn Marino 	    }
2899e4b17023SJohn Marino 	}
2900e4b17023SJohn Marino     }
2901e4b17023SJohn Marino 
2902e4b17023SJohn Marino   if (changed)
2903e4b17023SJohn Marino     tidy_fallthru_edges ();
2904e4b17023SJohn Marino   return changed;
2905e4b17023SJohn Marino }
2906e4b17023SJohn Marino 
2907e4b17023SJohn Marino /* Delete any jump tables never referenced.  We can't delete them at the
2908e4b17023SJohn Marino    time of removing tablejump insn as they are referenced by the preceding
2909e4b17023SJohn Marino    insns computing the destination, so we delay deleting and garbagecollect
2910e4b17023SJohn Marino    them once life information is computed.  */
2911e4b17023SJohn Marino void
delete_dead_jumptables(void)2912e4b17023SJohn Marino delete_dead_jumptables (void)
2913e4b17023SJohn Marino {
2914e4b17023SJohn Marino   basic_block bb;
2915e4b17023SJohn Marino 
2916e4b17023SJohn Marino   /* A dead jump table does not belong to any basic block.  Scan insns
2917e4b17023SJohn Marino      between two adjacent basic blocks.  */
2918e4b17023SJohn Marino   FOR_EACH_BB (bb)
2919e4b17023SJohn Marino     {
2920e4b17023SJohn Marino       rtx insn, next;
2921e4b17023SJohn Marino 
2922e4b17023SJohn Marino       for (insn = NEXT_INSN (BB_END (bb));
2923e4b17023SJohn Marino 	   insn && !NOTE_INSN_BASIC_BLOCK_P (insn);
2924e4b17023SJohn Marino 	   insn = next)
2925e4b17023SJohn Marino 	{
2926e4b17023SJohn Marino 	  next = NEXT_INSN (insn);
2927e4b17023SJohn Marino 	  if (LABEL_P (insn)
2928e4b17023SJohn Marino 	      && LABEL_NUSES (insn) == LABEL_PRESERVE_P (insn)
2929e4b17023SJohn Marino 	      && JUMP_TABLE_DATA_P (next))
2930e4b17023SJohn Marino 	    {
2931e4b17023SJohn Marino 	      rtx label = insn, jump = next;
2932e4b17023SJohn Marino 
2933e4b17023SJohn Marino 	      if (dump_file)
2934e4b17023SJohn Marino 		fprintf (dump_file, "Dead jumptable %i removed\n",
2935e4b17023SJohn Marino 			 INSN_UID (insn));
2936e4b17023SJohn Marino 
2937e4b17023SJohn Marino 	      next = NEXT_INSN (next);
2938e4b17023SJohn Marino 	      delete_insn (jump);
2939e4b17023SJohn Marino 	      delete_insn (label);
2940e4b17023SJohn Marino 	    }
2941e4b17023SJohn Marino 	}
2942e4b17023SJohn Marino     }
2943e4b17023SJohn Marino }
2944e4b17023SJohn Marino 
2945e4b17023SJohn Marino 
2946e4b17023SJohn Marino /* Tidy the CFG by deleting unreachable code and whatnot.  */
2947e4b17023SJohn Marino 
2948e4b17023SJohn Marino bool
cleanup_cfg(int mode)2949e4b17023SJohn Marino cleanup_cfg (int mode)
2950e4b17023SJohn Marino {
2951e4b17023SJohn Marino   bool changed = false;
2952e4b17023SJohn Marino 
2953e4b17023SJohn Marino   /* Set the cfglayout mode flag here.  We could update all the callers
2954e4b17023SJohn Marino      but that is just inconvenient, especially given that we eventually
2955e4b17023SJohn Marino      want to have cfglayout mode as the default.  */
2956e4b17023SJohn Marino   if (current_ir_type () == IR_RTL_CFGLAYOUT)
2957e4b17023SJohn Marino     mode |= CLEANUP_CFGLAYOUT;
2958e4b17023SJohn Marino 
2959e4b17023SJohn Marino   timevar_push (TV_CLEANUP_CFG);
2960e4b17023SJohn Marino   if (delete_unreachable_blocks ())
2961e4b17023SJohn Marino     {
2962e4b17023SJohn Marino       changed = true;
2963e4b17023SJohn Marino       /* We've possibly created trivially dead code.  Cleanup it right
2964e4b17023SJohn Marino 	 now to introduce more opportunities for try_optimize_cfg.  */
2965e4b17023SJohn Marino       if (!(mode & (CLEANUP_NO_INSN_DEL))
2966e4b17023SJohn Marino 	  && !reload_completed)
2967e4b17023SJohn Marino 	delete_trivially_dead_insns (get_insns (), max_reg_num ());
2968e4b17023SJohn Marino     }
2969e4b17023SJohn Marino 
2970e4b17023SJohn Marino   compact_blocks ();
2971e4b17023SJohn Marino 
2972e4b17023SJohn Marino   /* To tail-merge blocks ending in the same noreturn function (e.g.
2973e4b17023SJohn Marino      a call to abort) we have to insert fake edges to exit.  Do this
2974e4b17023SJohn Marino      here once.  The fake edges do not interfere with any other CFG
2975e4b17023SJohn Marino      cleanups.  */
2976e4b17023SJohn Marino   if (mode & CLEANUP_CROSSJUMP)
2977e4b17023SJohn Marino     add_noreturn_fake_exit_edges ();
2978e4b17023SJohn Marino 
2979e4b17023SJohn Marino   if (!dbg_cnt (cfg_cleanup))
2980e4b17023SJohn Marino     return changed;
2981e4b17023SJohn Marino 
2982e4b17023SJohn Marino   while (try_optimize_cfg (mode))
2983e4b17023SJohn Marino     {
2984e4b17023SJohn Marino       delete_unreachable_blocks (), changed = true;
2985e4b17023SJohn Marino       if (!(mode & CLEANUP_NO_INSN_DEL))
2986e4b17023SJohn Marino 	{
2987e4b17023SJohn Marino 	  /* Try to remove some trivially dead insns when doing an expensive
2988e4b17023SJohn Marino 	     cleanup.  But delete_trivially_dead_insns doesn't work after
2989e4b17023SJohn Marino 	     reload (it only handles pseudos) and run_fast_dce is too costly
2990e4b17023SJohn Marino 	     to run in every iteration.
2991e4b17023SJohn Marino 
2992e4b17023SJohn Marino 	     For effective cross jumping, we really want to run a fast DCE to
2993e4b17023SJohn Marino 	     clean up any dead conditions, or they get in the way of performing
2994e4b17023SJohn Marino 	     useful tail merges.
2995e4b17023SJohn Marino 
2996e4b17023SJohn Marino 	     Other transformations in cleanup_cfg are not so sensitive to dead
2997e4b17023SJohn Marino 	     code, so delete_trivially_dead_insns or even doing nothing at all
2998e4b17023SJohn Marino 	     is good enough.  */
2999e4b17023SJohn Marino 	  if ((mode & CLEANUP_EXPENSIVE) && !reload_completed
3000e4b17023SJohn Marino 	      && !delete_trivially_dead_insns (get_insns (), max_reg_num ()))
3001e4b17023SJohn Marino 	    break;
3002e4b17023SJohn Marino 	  if ((mode & CLEANUP_CROSSJUMP) && crossjumps_occured)
3003e4b17023SJohn Marino 	    run_fast_dce ();
3004e4b17023SJohn Marino 	}
3005e4b17023SJohn Marino       else
3006e4b17023SJohn Marino 	break;
3007e4b17023SJohn Marino     }
3008e4b17023SJohn Marino 
3009e4b17023SJohn Marino   if (mode & CLEANUP_CROSSJUMP)
3010e4b17023SJohn Marino     remove_fake_exit_edges ();
3011e4b17023SJohn Marino 
3012e4b17023SJohn Marino   /* Don't call delete_dead_jumptables in cfglayout mode, because
3013e4b17023SJohn Marino      that function assumes that jump tables are in the insns stream.
3014e4b17023SJohn Marino      But we also don't _have_ to delete dead jumptables in cfglayout
3015e4b17023SJohn Marino      mode because we shouldn't even be looking at things that are
3016e4b17023SJohn Marino      not in a basic block.  Dead jumptables are cleaned up when
3017e4b17023SJohn Marino      going out of cfglayout mode.  */
3018e4b17023SJohn Marino   if (!(mode & CLEANUP_CFGLAYOUT))
3019e4b17023SJohn Marino     delete_dead_jumptables ();
3020e4b17023SJohn Marino 
3021e4b17023SJohn Marino   timevar_pop (TV_CLEANUP_CFG);
3022e4b17023SJohn Marino 
3023e4b17023SJohn Marino   return changed;
3024e4b17023SJohn Marino }
3025e4b17023SJohn Marino 
3026e4b17023SJohn Marino static unsigned int
rest_of_handle_jump(void)3027e4b17023SJohn Marino rest_of_handle_jump (void)
3028e4b17023SJohn Marino {
3029e4b17023SJohn Marino   if (crtl->tail_call_emit)
3030e4b17023SJohn Marino     fixup_tail_calls ();
3031e4b17023SJohn Marino   return 0;
3032e4b17023SJohn Marino }
3033e4b17023SJohn Marino 
3034e4b17023SJohn Marino struct rtl_opt_pass pass_jump =
3035e4b17023SJohn Marino {
3036e4b17023SJohn Marino  {
3037e4b17023SJohn Marino   RTL_PASS,
3038e4b17023SJohn Marino   "sibling",                            /* name */
3039e4b17023SJohn Marino   NULL,                                 /* gate */
3040e4b17023SJohn Marino   rest_of_handle_jump,			/* execute */
3041e4b17023SJohn Marino   NULL,                                 /* sub */
3042e4b17023SJohn Marino   NULL,                                 /* next */
3043e4b17023SJohn Marino   0,                                    /* static_pass_number */
3044e4b17023SJohn Marino   TV_JUMP,                              /* tv_id */
3045e4b17023SJohn Marino   0,                                    /* properties_required */
3046e4b17023SJohn Marino   0,                                    /* properties_provided */
3047e4b17023SJohn Marino   0,                                    /* properties_destroyed */
3048e4b17023SJohn Marino   TODO_ggc_collect,                     /* todo_flags_start */
3049e4b17023SJohn Marino   TODO_verify_flow,                     /* todo_flags_finish */
3050e4b17023SJohn Marino  }
3051e4b17023SJohn Marino };
3052e4b17023SJohn Marino 
3053e4b17023SJohn Marino 
3054e4b17023SJohn Marino static unsigned int
rest_of_handle_jump2(void)3055e4b17023SJohn Marino rest_of_handle_jump2 (void)
3056e4b17023SJohn Marino {
3057e4b17023SJohn Marino   delete_trivially_dead_insns (get_insns (), max_reg_num ());
3058e4b17023SJohn Marino   if (dump_file)
3059e4b17023SJohn Marino     dump_flow_info (dump_file, dump_flags);
3060e4b17023SJohn Marino   cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
3061e4b17023SJohn Marino 	       | (flag_thread_jumps ? CLEANUP_THREADING : 0));
3062e4b17023SJohn Marino   return 0;
3063e4b17023SJohn Marino }
3064e4b17023SJohn Marino 
3065e4b17023SJohn Marino 
3066e4b17023SJohn Marino struct rtl_opt_pass pass_jump2 =
3067e4b17023SJohn Marino {
3068e4b17023SJohn Marino  {
3069e4b17023SJohn Marino   RTL_PASS,
3070e4b17023SJohn Marino   "jump",                               /* name */
3071e4b17023SJohn Marino   NULL,                                 /* gate */
3072e4b17023SJohn Marino   rest_of_handle_jump2,			/* execute */
3073e4b17023SJohn Marino   NULL,                                 /* sub */
3074e4b17023SJohn Marino   NULL,                                 /* next */
3075e4b17023SJohn Marino   0,                                    /* static_pass_number */
3076e4b17023SJohn Marino   TV_JUMP,                              /* tv_id */
3077e4b17023SJohn Marino   0,                                    /* properties_required */
3078e4b17023SJohn Marino   0,                                    /* properties_provided */
3079e4b17023SJohn Marino   0,                                    /* properties_destroyed */
3080e4b17023SJohn Marino   TODO_ggc_collect,                     /* todo_flags_start */
3081e4b17023SJohn Marino   TODO_verify_rtl_sharing,              /* todo_flags_finish */
3082e4b17023SJohn Marino  }
3083e4b17023SJohn Marino };
3084