xref: /dflybsd-src/contrib/gcc-4.7/gcc/cfgrtl.c (revision 81fc95a5293ee307c688a350a3feb4734aaddbb4)
1e4b17023SJohn Marino /* Control flow graph manipulation 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, 2009, 2010,
4e4b17023SJohn Marino    2011, 2012 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 low level functions to manipulate the CFG and analyze it
23e4b17023SJohn Marino    that are aware of the RTL intermediate language.
24e4b17023SJohn Marino 
25e4b17023SJohn Marino    Available functionality:
26e4b17023SJohn Marino      - Basic CFG/RTL manipulation API documented in cfghooks.h
27e4b17023SJohn Marino      - CFG-aware instruction chain manipulation
28e4b17023SJohn Marino 	 delete_insn, delete_insn_chain
29e4b17023SJohn Marino      - Edge splitting and committing to edges
30e4b17023SJohn Marino 	 insert_insn_on_edge, commit_edge_insertions
31e4b17023SJohn Marino      - CFG updating after insn simplification
32e4b17023SJohn Marino 	 purge_dead_edges, purge_all_dead_edges
33e4b17023SJohn Marino      - CFG fixing after coarse manipulation
34e4b17023SJohn Marino 	fixup_abnormal_edges
35e4b17023SJohn Marino 
36e4b17023SJohn Marino    Functions not supposed for generic use:
37e4b17023SJohn Marino      - Infrastructure to determine quickly basic block for insn
38e4b17023SJohn Marino 	 compute_bb_for_insn, update_bb_for_insn, set_block_for_insn,
39e4b17023SJohn Marino      - Edge redirection with updating and optimizing of insn chain
40e4b17023SJohn Marino 	 block_label, tidy_fallthru_edge, force_nonfallthru  */
41e4b17023SJohn Marino 
42e4b17023SJohn Marino #include "config.h"
43e4b17023SJohn Marino #include "system.h"
44e4b17023SJohn Marino #include "coretypes.h"
45e4b17023SJohn Marino #include "tm.h"
46e4b17023SJohn Marino #include "tree.h"
47e4b17023SJohn Marino #include "hard-reg-set.h"
48e4b17023SJohn Marino #include "basic-block.h"
49e4b17023SJohn Marino #include "regs.h"
50e4b17023SJohn Marino #include "flags.h"
51e4b17023SJohn Marino #include "output.h"
52e4b17023SJohn Marino #include "function.h"
53e4b17023SJohn Marino #include "except.h"
54e4b17023SJohn Marino #include "rtl-error.h"
55e4b17023SJohn Marino #include "tm_p.h"
56e4b17023SJohn Marino #include "obstack.h"
57e4b17023SJohn Marino #include "insn-attr.h"
58e4b17023SJohn Marino #include "insn-config.h"
59e4b17023SJohn Marino #include "cfglayout.h"
60e4b17023SJohn Marino #include "expr.h"
61e4b17023SJohn Marino #include "target.h"
62e4b17023SJohn Marino #include "common/common-target.h"
63e4b17023SJohn Marino #include "cfgloop.h"
64e4b17023SJohn Marino #include "ggc.h"
65e4b17023SJohn Marino #include "tree-pass.h"
66e4b17023SJohn Marino #include "df.h"
67e4b17023SJohn Marino 
68e4b17023SJohn Marino static int can_delete_note_p (const_rtx);
69e4b17023SJohn Marino static int can_delete_label_p (const_rtx);
70e4b17023SJohn Marino static basic_block rtl_split_edge (edge);
71e4b17023SJohn Marino static bool rtl_move_block_after (basic_block, basic_block);
72e4b17023SJohn Marino static int rtl_verify_flow_info (void);
73e4b17023SJohn Marino static basic_block cfg_layout_split_block (basic_block, void *);
74e4b17023SJohn Marino static edge cfg_layout_redirect_edge_and_branch (edge, basic_block);
75e4b17023SJohn Marino static basic_block cfg_layout_redirect_edge_and_branch_force (edge, basic_block);
76e4b17023SJohn Marino static void cfg_layout_delete_block (basic_block);
77e4b17023SJohn Marino static void rtl_delete_block (basic_block);
78e4b17023SJohn Marino static basic_block rtl_redirect_edge_and_branch_force (edge, basic_block);
79e4b17023SJohn Marino static edge rtl_redirect_edge_and_branch (edge, basic_block);
80e4b17023SJohn Marino static basic_block rtl_split_block (basic_block, void *);
81e4b17023SJohn Marino static void rtl_dump_bb (basic_block, FILE *, int, int);
82e4b17023SJohn Marino static int rtl_verify_flow_info_1 (void);
83e4b17023SJohn Marino static void rtl_make_forwarder_block (edge);
84e4b17023SJohn Marino 
85e4b17023SJohn Marino /* Return true if NOTE is not one of the ones that must be kept paired,
86e4b17023SJohn Marino    so that we may simply delete it.  */
87e4b17023SJohn Marino 
88e4b17023SJohn Marino static int
can_delete_note_p(const_rtx note)89e4b17023SJohn Marino can_delete_note_p (const_rtx note)
90e4b17023SJohn Marino {
91e4b17023SJohn Marino   switch (NOTE_KIND (note))
92e4b17023SJohn Marino     {
93e4b17023SJohn Marino     case NOTE_INSN_DELETED:
94e4b17023SJohn Marino     case NOTE_INSN_BASIC_BLOCK:
95e4b17023SJohn Marino     case NOTE_INSN_EPILOGUE_BEG:
96e4b17023SJohn Marino       return true;
97e4b17023SJohn Marino 
98e4b17023SJohn Marino     default:
99e4b17023SJohn Marino       return false;
100e4b17023SJohn Marino     }
101e4b17023SJohn Marino }
102e4b17023SJohn Marino 
103e4b17023SJohn Marino /* True if a given label can be deleted.  */
104e4b17023SJohn Marino 
105e4b17023SJohn Marino static int
can_delete_label_p(const_rtx label)106e4b17023SJohn Marino can_delete_label_p (const_rtx label)
107e4b17023SJohn Marino {
108e4b17023SJohn Marino   return (!LABEL_PRESERVE_P (label)
109e4b17023SJohn Marino 	  /* User declared labels must be preserved.  */
110e4b17023SJohn Marino 	  && LABEL_NAME (label) == 0
111e4b17023SJohn Marino 	  && !in_expr_list_p (forced_labels, label));
112e4b17023SJohn Marino }
113e4b17023SJohn Marino 
114e4b17023SJohn Marino /* Delete INSN by patching it out.  Return the next insn.  */
115e4b17023SJohn Marino 
116e4b17023SJohn Marino rtx
delete_insn(rtx insn)117e4b17023SJohn Marino delete_insn (rtx insn)
118e4b17023SJohn Marino {
119e4b17023SJohn Marino   rtx next = NEXT_INSN (insn);
120e4b17023SJohn Marino   rtx note;
121e4b17023SJohn Marino   bool really_delete = true;
122e4b17023SJohn Marino 
123e4b17023SJohn Marino   if (LABEL_P (insn))
124e4b17023SJohn Marino     {
125e4b17023SJohn Marino       /* Some labels can't be directly removed from the INSN chain, as they
126e4b17023SJohn Marino 	 might be references via variables, constant pool etc.
127e4b17023SJohn Marino 	 Convert them to the special NOTE_INSN_DELETED_LABEL note.  */
128e4b17023SJohn Marino       if (! can_delete_label_p (insn))
129e4b17023SJohn Marino 	{
130e4b17023SJohn Marino 	  const char *name = LABEL_NAME (insn);
131e4b17023SJohn Marino 
132e4b17023SJohn Marino 	  really_delete = false;
133e4b17023SJohn Marino 	  PUT_CODE (insn, NOTE);
134e4b17023SJohn Marino 	  NOTE_KIND (insn) = NOTE_INSN_DELETED_LABEL;
135e4b17023SJohn Marino 	  NOTE_DELETED_LABEL_NAME (insn) = name;
136e4b17023SJohn Marino 	}
137e4b17023SJohn Marino 
138e4b17023SJohn Marino       remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels);
139e4b17023SJohn Marino     }
140e4b17023SJohn Marino 
141e4b17023SJohn Marino   if (really_delete)
142e4b17023SJohn Marino     {
143e4b17023SJohn Marino       /* If this insn has already been deleted, something is very wrong.  */
144e4b17023SJohn Marino       gcc_assert (!INSN_DELETED_P (insn));
145e4b17023SJohn Marino       remove_insn (insn);
146e4b17023SJohn Marino       INSN_DELETED_P (insn) = 1;
147e4b17023SJohn Marino     }
148e4b17023SJohn Marino 
149e4b17023SJohn Marino   /* If deleting a jump, decrement the use count of the label.  Deleting
150e4b17023SJohn Marino      the label itself should happen in the normal course of block merging.  */
151e4b17023SJohn Marino   if (JUMP_P (insn))
152e4b17023SJohn Marino     {
153e4b17023SJohn Marino       if (JUMP_LABEL (insn)
154e4b17023SJohn Marino 	  && LABEL_P (JUMP_LABEL (insn)))
155e4b17023SJohn Marino 	LABEL_NUSES (JUMP_LABEL (insn))--;
156e4b17023SJohn Marino 
157e4b17023SJohn Marino       /* If there are more targets, remove them too.  */
158e4b17023SJohn Marino       while ((note
159e4b17023SJohn Marino 	      = find_reg_note (insn, REG_LABEL_TARGET, NULL_RTX)) != NULL_RTX
160e4b17023SJohn Marino 	     && LABEL_P (XEXP (note, 0)))
161e4b17023SJohn Marino 	{
162e4b17023SJohn Marino 	  LABEL_NUSES (XEXP (note, 0))--;
163e4b17023SJohn Marino 	  remove_note (insn, note);
164e4b17023SJohn Marino 	}
165e4b17023SJohn Marino     }
166e4b17023SJohn Marino 
167e4b17023SJohn Marino   /* Also if deleting any insn that references a label as an operand.  */
168e4b17023SJohn Marino   while ((note = find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX)) != NULL_RTX
169e4b17023SJohn Marino 	 && LABEL_P (XEXP (note, 0)))
170e4b17023SJohn Marino     {
171e4b17023SJohn Marino       LABEL_NUSES (XEXP (note, 0))--;
172e4b17023SJohn Marino       remove_note (insn, note);
173e4b17023SJohn Marino     }
174e4b17023SJohn Marino 
175e4b17023SJohn Marino   if (JUMP_TABLE_DATA_P (insn))
176e4b17023SJohn Marino     {
177e4b17023SJohn Marino       rtx pat = PATTERN (insn);
178e4b17023SJohn Marino       int diff_vec_p = GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC;
179e4b17023SJohn Marino       int len = XVECLEN (pat, diff_vec_p);
180e4b17023SJohn Marino       int i;
181e4b17023SJohn Marino 
182e4b17023SJohn Marino       for (i = 0; i < len; i++)
183e4b17023SJohn Marino 	{
184e4b17023SJohn Marino 	  rtx label = XEXP (XVECEXP (pat, diff_vec_p, i), 0);
185e4b17023SJohn Marino 
186e4b17023SJohn Marino 	  /* When deleting code in bulk (e.g. removing many unreachable
187e4b17023SJohn Marino 	     blocks) we can delete a label that's a target of the vector
188e4b17023SJohn Marino 	     before deleting the vector itself.  */
189e4b17023SJohn Marino 	  if (!NOTE_P (label))
190e4b17023SJohn Marino 	    LABEL_NUSES (label)--;
191e4b17023SJohn Marino 	}
192e4b17023SJohn Marino     }
193e4b17023SJohn Marino 
194e4b17023SJohn Marino   return next;
195e4b17023SJohn Marino }
196e4b17023SJohn Marino 
197e4b17023SJohn Marino /* Like delete_insn but also purge dead edges from BB.  */
198e4b17023SJohn Marino 
199e4b17023SJohn Marino rtx
delete_insn_and_edges(rtx insn)200e4b17023SJohn Marino delete_insn_and_edges (rtx insn)
201e4b17023SJohn Marino {
202e4b17023SJohn Marino   rtx x;
203e4b17023SJohn Marino   bool purge = false;
204e4b17023SJohn Marino 
205e4b17023SJohn Marino   if (INSN_P (insn)
206e4b17023SJohn Marino       && BLOCK_FOR_INSN (insn)
207e4b17023SJohn Marino       && BB_END (BLOCK_FOR_INSN (insn)) == insn)
208e4b17023SJohn Marino     purge = true;
209e4b17023SJohn Marino   x = delete_insn (insn);
210e4b17023SJohn Marino   if (purge)
211e4b17023SJohn Marino     purge_dead_edges (BLOCK_FOR_INSN (insn));
212e4b17023SJohn Marino   return x;
213e4b17023SJohn Marino }
214e4b17023SJohn Marino 
215e4b17023SJohn Marino /* Unlink a chain of insns between START and FINISH, leaving notes
216e4b17023SJohn Marino    that must be paired.  If CLEAR_BB is true, we set bb field for
217e4b17023SJohn Marino    insns that cannot be removed to NULL.  */
218e4b17023SJohn Marino 
219e4b17023SJohn Marino void
delete_insn_chain(rtx start,rtx finish,bool clear_bb)220e4b17023SJohn Marino delete_insn_chain (rtx start, rtx finish, bool clear_bb)
221e4b17023SJohn Marino {
222e4b17023SJohn Marino   rtx next;
223e4b17023SJohn Marino 
224e4b17023SJohn Marino   /* Unchain the insns one by one.  It would be quicker to delete all of these
225e4b17023SJohn Marino      with a single unchaining, rather than one at a time, but we need to keep
226e4b17023SJohn Marino      the NOTE's.  */
227e4b17023SJohn Marino   while (1)
228e4b17023SJohn Marino     {
229e4b17023SJohn Marino       next = NEXT_INSN (start);
230e4b17023SJohn Marino       if (NOTE_P (start) && !can_delete_note_p (start))
231e4b17023SJohn Marino 	;
232e4b17023SJohn Marino       else
233e4b17023SJohn Marino 	next = delete_insn (start);
234e4b17023SJohn Marino 
235e4b17023SJohn Marino       if (clear_bb && !INSN_DELETED_P (start))
236e4b17023SJohn Marino 	set_block_for_insn (start, NULL);
237e4b17023SJohn Marino 
238e4b17023SJohn Marino       if (start == finish)
239e4b17023SJohn Marino 	break;
240e4b17023SJohn Marino       start = next;
241e4b17023SJohn Marino     }
242e4b17023SJohn Marino }
243e4b17023SJohn Marino 
244e4b17023SJohn Marino /* Create a new basic block consisting of the instructions between HEAD and END
245e4b17023SJohn Marino    inclusive.  This function is designed to allow fast BB construction - reuses
246e4b17023SJohn Marino    the note and basic block struct in BB_NOTE, if any and do not grow
247e4b17023SJohn Marino    BASIC_BLOCK chain and should be used directly only by CFG construction code.
248e4b17023SJohn Marino    END can be NULL in to create new empty basic block before HEAD.  Both END
249e4b17023SJohn Marino    and HEAD can be NULL to create basic block at the end of INSN chain.
250e4b17023SJohn Marino    AFTER is the basic block we should be put after.  */
251e4b17023SJohn Marino 
252e4b17023SJohn Marino basic_block
create_basic_block_structure(rtx head,rtx end,rtx bb_note,basic_block after)253e4b17023SJohn Marino create_basic_block_structure (rtx head, rtx end, rtx bb_note, basic_block after)
254e4b17023SJohn Marino {
255e4b17023SJohn Marino   basic_block bb;
256e4b17023SJohn Marino 
257e4b17023SJohn Marino   if (bb_note
258e4b17023SJohn Marino       && (bb = NOTE_BASIC_BLOCK (bb_note)) != NULL
259e4b17023SJohn Marino       && bb->aux == NULL)
260e4b17023SJohn Marino     {
261e4b17023SJohn Marino       /* If we found an existing note, thread it back onto the chain.  */
262e4b17023SJohn Marino 
263e4b17023SJohn Marino       rtx after;
264e4b17023SJohn Marino 
265e4b17023SJohn Marino       if (LABEL_P (head))
266e4b17023SJohn Marino 	after = head;
267e4b17023SJohn Marino       else
268e4b17023SJohn Marino 	{
269e4b17023SJohn Marino 	  after = PREV_INSN (head);
270e4b17023SJohn Marino 	  head = bb_note;
271e4b17023SJohn Marino 	}
272e4b17023SJohn Marino 
273e4b17023SJohn Marino       if (after != bb_note && NEXT_INSN (after) != bb_note)
274e4b17023SJohn Marino 	reorder_insns_nobb (bb_note, bb_note, after);
275e4b17023SJohn Marino     }
276e4b17023SJohn Marino   else
277e4b17023SJohn Marino     {
278e4b17023SJohn Marino       /* Otherwise we must create a note and a basic block structure.  */
279e4b17023SJohn Marino 
280e4b17023SJohn Marino       bb = alloc_block ();
281e4b17023SJohn Marino 
282e4b17023SJohn Marino       init_rtl_bb_info (bb);
283e4b17023SJohn Marino       if (!head && !end)
284e4b17023SJohn Marino 	head = end = bb_note
285e4b17023SJohn Marino 	  = emit_note_after (NOTE_INSN_BASIC_BLOCK, get_last_insn ());
286e4b17023SJohn Marino       else if (LABEL_P (head) && end)
287e4b17023SJohn Marino 	{
288e4b17023SJohn Marino 	  bb_note = emit_note_after (NOTE_INSN_BASIC_BLOCK, head);
289e4b17023SJohn Marino 	  if (head == end)
290e4b17023SJohn Marino 	    end = bb_note;
291e4b17023SJohn Marino 	}
292e4b17023SJohn Marino       else
293e4b17023SJohn Marino 	{
294e4b17023SJohn Marino 	  bb_note = emit_note_before (NOTE_INSN_BASIC_BLOCK, head);
295e4b17023SJohn Marino 	  head = bb_note;
296e4b17023SJohn Marino 	  if (!end)
297e4b17023SJohn Marino 	    end = head;
298e4b17023SJohn Marino 	}
299e4b17023SJohn Marino 
300e4b17023SJohn Marino       NOTE_BASIC_BLOCK (bb_note) = bb;
301e4b17023SJohn Marino     }
302e4b17023SJohn Marino 
303e4b17023SJohn Marino   /* Always include the bb note in the block.  */
304e4b17023SJohn Marino   if (NEXT_INSN (end) == bb_note)
305e4b17023SJohn Marino     end = bb_note;
306e4b17023SJohn Marino 
307e4b17023SJohn Marino   BB_HEAD (bb) = head;
308e4b17023SJohn Marino   BB_END (bb) = end;
309e4b17023SJohn Marino   bb->index = last_basic_block++;
310e4b17023SJohn Marino   bb->flags = BB_NEW | BB_RTL;
311e4b17023SJohn Marino   link_block (bb, after);
312e4b17023SJohn Marino   SET_BASIC_BLOCK (bb->index, bb);
313e4b17023SJohn Marino   df_bb_refs_record (bb->index, false);
314e4b17023SJohn Marino   update_bb_for_insn (bb);
315e4b17023SJohn Marino   BB_SET_PARTITION (bb, BB_UNPARTITIONED);
316e4b17023SJohn Marino 
317e4b17023SJohn Marino   /* Tag the block so that we know it has been used when considering
318e4b17023SJohn Marino      other basic block notes.  */
319e4b17023SJohn Marino   bb->aux = bb;
320e4b17023SJohn Marino 
321e4b17023SJohn Marino   return bb;
322e4b17023SJohn Marino }
323e4b17023SJohn Marino 
324e4b17023SJohn Marino /* Create new basic block consisting of instructions in between HEAD and END
325e4b17023SJohn Marino    and place it to the BB chain after block AFTER.  END can be NULL to
326e4b17023SJohn Marino    create a new empty basic block before HEAD.  Both END and HEAD can be
327e4b17023SJohn Marino    NULL to create basic block at the end of INSN chain.  */
328e4b17023SJohn Marino 
329e4b17023SJohn Marino static basic_block
rtl_create_basic_block(void * headp,void * endp,basic_block after)330e4b17023SJohn Marino rtl_create_basic_block (void *headp, void *endp, basic_block after)
331e4b17023SJohn Marino {
332e4b17023SJohn Marino   rtx head = (rtx) headp, end = (rtx) endp;
333e4b17023SJohn Marino   basic_block bb;
334e4b17023SJohn Marino 
335e4b17023SJohn Marino   /* Grow the basic block array if needed.  */
336e4b17023SJohn Marino   if ((size_t) last_basic_block >= VEC_length (basic_block, basic_block_info))
337e4b17023SJohn Marino     {
338e4b17023SJohn Marino       size_t new_size = last_basic_block + (last_basic_block + 3) / 4;
339e4b17023SJohn Marino       VEC_safe_grow_cleared (basic_block, gc, basic_block_info, new_size);
340e4b17023SJohn Marino     }
341e4b17023SJohn Marino 
342e4b17023SJohn Marino   n_basic_blocks++;
343e4b17023SJohn Marino 
344e4b17023SJohn Marino   bb = create_basic_block_structure (head, end, NULL, after);
345e4b17023SJohn Marino   bb->aux = NULL;
346e4b17023SJohn Marino   return bb;
347e4b17023SJohn Marino }
348e4b17023SJohn Marino 
349e4b17023SJohn Marino static basic_block
cfg_layout_create_basic_block(void * head,void * end,basic_block after)350e4b17023SJohn Marino cfg_layout_create_basic_block (void *head, void *end, basic_block after)
351e4b17023SJohn Marino {
352e4b17023SJohn Marino   basic_block newbb = rtl_create_basic_block (head, end, after);
353e4b17023SJohn Marino 
354e4b17023SJohn Marino   return newbb;
355e4b17023SJohn Marino }
356e4b17023SJohn Marino 
357e4b17023SJohn Marino /* Delete the insns in a (non-live) block.  We physically delete every
358e4b17023SJohn Marino    non-deleted-note insn, and update the flow graph appropriately.
359e4b17023SJohn Marino 
360e4b17023SJohn Marino    Return nonzero if we deleted an exception handler.  */
361e4b17023SJohn Marino 
362e4b17023SJohn Marino /* ??? Preserving all such notes strikes me as wrong.  It would be nice
363e4b17023SJohn Marino    to post-process the stream to remove empty blocks, loops, ranges, etc.  */
364e4b17023SJohn Marino 
365e4b17023SJohn Marino static void
rtl_delete_block(basic_block b)366e4b17023SJohn Marino rtl_delete_block (basic_block b)
367e4b17023SJohn Marino {
368e4b17023SJohn Marino   rtx insn, end;
369e4b17023SJohn Marino 
370e4b17023SJohn Marino   /* If the head of this block is a CODE_LABEL, then it might be the
371e4b17023SJohn Marino      label for an exception handler which can't be reached.  We need
372e4b17023SJohn Marino      to remove the label from the exception_handler_label list.  */
373e4b17023SJohn Marino   insn = BB_HEAD (b);
374e4b17023SJohn Marino 
375e4b17023SJohn Marino   end = get_last_bb_insn (b);
376e4b17023SJohn Marino 
377e4b17023SJohn Marino   /* Selectively delete the entire chain.  */
378e4b17023SJohn Marino   BB_HEAD (b) = NULL;
379e4b17023SJohn Marino   delete_insn_chain (insn, end, true);
380e4b17023SJohn Marino 
381e4b17023SJohn Marino 
382e4b17023SJohn Marino   if (dump_file)
383e4b17023SJohn Marino     fprintf (dump_file, "deleting block %d\n", b->index);
384e4b17023SJohn Marino   df_bb_delete (b->index);
385e4b17023SJohn Marino }
386e4b17023SJohn Marino 
387e4b17023SJohn Marino /* Records the basic block struct in BLOCK_FOR_INSN for every insn.  */
388e4b17023SJohn Marino 
389e4b17023SJohn Marino void
compute_bb_for_insn(void)390e4b17023SJohn Marino compute_bb_for_insn (void)
391e4b17023SJohn Marino {
392e4b17023SJohn Marino   basic_block bb;
393e4b17023SJohn Marino 
394e4b17023SJohn Marino   FOR_EACH_BB (bb)
395e4b17023SJohn Marino     {
396e4b17023SJohn Marino       rtx end = BB_END (bb);
397e4b17023SJohn Marino       rtx insn;
398e4b17023SJohn Marino 
399e4b17023SJohn Marino       for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
400e4b17023SJohn Marino 	{
401e4b17023SJohn Marino 	  BLOCK_FOR_INSN (insn) = bb;
402e4b17023SJohn Marino 	  if (insn == end)
403e4b17023SJohn Marino 	    break;
404e4b17023SJohn Marino 	}
405e4b17023SJohn Marino     }
406e4b17023SJohn Marino }
407e4b17023SJohn Marino 
408e4b17023SJohn Marino /* Release the basic_block_for_insn array.  */
409e4b17023SJohn Marino 
410e4b17023SJohn Marino unsigned int
free_bb_for_insn(void)411e4b17023SJohn Marino free_bb_for_insn (void)
412e4b17023SJohn Marino {
413e4b17023SJohn Marino   rtx insn;
414e4b17023SJohn Marino   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
415e4b17023SJohn Marino     if (!BARRIER_P (insn))
416e4b17023SJohn Marino       BLOCK_FOR_INSN (insn) = NULL;
417e4b17023SJohn Marino   return 0;
418e4b17023SJohn Marino }
419e4b17023SJohn Marino 
420e4b17023SJohn Marino static unsigned int
rest_of_pass_free_cfg(void)421e4b17023SJohn Marino rest_of_pass_free_cfg (void)
422e4b17023SJohn Marino {
423e4b17023SJohn Marino #ifdef DELAY_SLOTS
424e4b17023SJohn Marino   /* The resource.c machinery uses DF but the CFG isn't guaranteed to be
425e4b17023SJohn Marino      valid at that point so it would be too late to call df_analyze.  */
426e4b17023SJohn Marino   if (optimize > 0 && flag_delayed_branch)
427e4b17023SJohn Marino     {
428e4b17023SJohn Marino       df_note_add_problem ();
429e4b17023SJohn Marino       df_analyze ();
430e4b17023SJohn Marino     }
431e4b17023SJohn Marino #endif
432e4b17023SJohn Marino 
433e4b17023SJohn Marino   free_bb_for_insn ();
434e4b17023SJohn Marino   return 0;
435e4b17023SJohn Marino }
436e4b17023SJohn Marino 
437e4b17023SJohn Marino struct rtl_opt_pass pass_free_cfg =
438e4b17023SJohn Marino {
439e4b17023SJohn Marino  {
440e4b17023SJohn Marino   RTL_PASS,
441e4b17023SJohn Marino   "*free_cfg",                          /* name */
442e4b17023SJohn Marino   NULL,                                 /* gate */
443e4b17023SJohn Marino   rest_of_pass_free_cfg,                /* execute */
444e4b17023SJohn Marino   NULL,                                 /* sub */
445e4b17023SJohn Marino   NULL,                                 /* next */
446e4b17023SJohn Marino   0,                                    /* static_pass_number */
447e4b17023SJohn Marino   TV_NONE,                              /* tv_id */
448e4b17023SJohn Marino   0,                                    /* properties_required */
449e4b17023SJohn Marino   0,                                    /* properties_provided */
450e4b17023SJohn Marino   PROP_cfg,                             /* properties_destroyed */
451e4b17023SJohn Marino   0,                                    /* todo_flags_start */
452e4b17023SJohn Marino   0,                                    /* todo_flags_finish */
453e4b17023SJohn Marino  }
454e4b17023SJohn Marino };
455e4b17023SJohn Marino 
456e4b17023SJohn Marino /* Return RTX to emit after when we want to emit code on the entry of function.  */
457e4b17023SJohn Marino rtx
entry_of_function(void)458e4b17023SJohn Marino entry_of_function (void)
459e4b17023SJohn Marino {
460e4b17023SJohn Marino   return (n_basic_blocks > NUM_FIXED_BLOCKS ?
461e4b17023SJohn Marino 	  BB_HEAD (ENTRY_BLOCK_PTR->next_bb) : get_insns ());
462e4b17023SJohn Marino }
463e4b17023SJohn Marino 
464e4b17023SJohn Marino /* Emit INSN at the entry point of the function, ensuring that it is only
465e4b17023SJohn Marino    executed once per function.  */
466e4b17023SJohn Marino void
emit_insn_at_entry(rtx insn)467e4b17023SJohn Marino emit_insn_at_entry (rtx insn)
468e4b17023SJohn Marino {
469e4b17023SJohn Marino   edge_iterator ei = ei_start (ENTRY_BLOCK_PTR->succs);
470e4b17023SJohn Marino   edge e = ei_safe_edge (ei);
471e4b17023SJohn Marino   gcc_assert (e->flags & EDGE_FALLTHRU);
472e4b17023SJohn Marino 
473e4b17023SJohn Marino   insert_insn_on_edge (insn, e);
474e4b17023SJohn Marino   commit_edge_insertions ();
475e4b17023SJohn Marino }
476e4b17023SJohn Marino 
477e4b17023SJohn Marino /* Update BLOCK_FOR_INSN of insns between BEGIN and END
478e4b17023SJohn Marino    (or BARRIER if found) and notify df of the bb change.
479e4b17023SJohn Marino    The insn chain range is inclusive
480e4b17023SJohn Marino    (i.e. both BEGIN and END will be updated. */
481e4b17023SJohn Marino 
482e4b17023SJohn Marino static void
update_bb_for_insn_chain(rtx begin,rtx end,basic_block bb)483e4b17023SJohn Marino update_bb_for_insn_chain (rtx begin, rtx end, basic_block bb)
484e4b17023SJohn Marino {
485e4b17023SJohn Marino   rtx insn;
486e4b17023SJohn Marino 
487e4b17023SJohn Marino   end = NEXT_INSN (end);
488e4b17023SJohn Marino   for (insn = begin; insn != end; insn = NEXT_INSN (insn))
489e4b17023SJohn Marino     if (!BARRIER_P (insn))
490e4b17023SJohn Marino       df_insn_change_bb (insn, bb);
491e4b17023SJohn Marino }
492e4b17023SJohn Marino 
493e4b17023SJohn Marino /* Update BLOCK_FOR_INSN of insns in BB to BB,
494e4b17023SJohn Marino    and notify df of the change.  */
495e4b17023SJohn Marino 
496e4b17023SJohn Marino void
update_bb_for_insn(basic_block bb)497e4b17023SJohn Marino update_bb_for_insn (basic_block bb)
498e4b17023SJohn Marino {
499e4b17023SJohn Marino   update_bb_for_insn_chain (BB_HEAD (bb), BB_END (bb), bb);
500e4b17023SJohn Marino }
501e4b17023SJohn Marino 
502e4b17023SJohn Marino 
503e4b17023SJohn Marino /* Return the NOTE_INSN_BASIC_BLOCK of BB.  */
504e4b17023SJohn Marino rtx
bb_note(basic_block bb)505e4b17023SJohn Marino bb_note (basic_block bb)
506e4b17023SJohn Marino {
507e4b17023SJohn Marino   rtx note;
508e4b17023SJohn Marino 
509e4b17023SJohn Marino   note = BB_HEAD (bb);
510e4b17023SJohn Marino   if (LABEL_P (note))
511e4b17023SJohn Marino     note = NEXT_INSN (note);
512e4b17023SJohn Marino 
513e4b17023SJohn Marino   gcc_assert (NOTE_INSN_BASIC_BLOCK_P (note));
514e4b17023SJohn Marino   return note;
515e4b17023SJohn Marino }
516e4b17023SJohn Marino 
517e4b17023SJohn Marino /* Return the INSN immediately following the NOTE_INSN_BASIC_BLOCK
518e4b17023SJohn Marino    note associated with the BLOCK.  */
519e4b17023SJohn Marino 
520e4b17023SJohn Marino static rtx
first_insn_after_basic_block_note(basic_block block)521e4b17023SJohn Marino first_insn_after_basic_block_note (basic_block block)
522e4b17023SJohn Marino {
523e4b17023SJohn Marino   rtx insn;
524e4b17023SJohn Marino 
525e4b17023SJohn Marino   /* Get the first instruction in the block.  */
526e4b17023SJohn Marino   insn = BB_HEAD (block);
527e4b17023SJohn Marino 
528e4b17023SJohn Marino   if (insn == NULL_RTX)
529e4b17023SJohn Marino     return NULL_RTX;
530e4b17023SJohn Marino   if (LABEL_P (insn))
531e4b17023SJohn Marino     insn = NEXT_INSN (insn);
532e4b17023SJohn Marino   gcc_assert (NOTE_INSN_BASIC_BLOCK_P (insn));
533e4b17023SJohn Marino 
534e4b17023SJohn Marino   return NEXT_INSN (insn);
535e4b17023SJohn Marino }
536e4b17023SJohn Marino 
537e4b17023SJohn Marino /* Creates a new basic block just after basic block B by splitting
538e4b17023SJohn Marino    everything after specified instruction I.  */
539e4b17023SJohn Marino 
540e4b17023SJohn Marino static basic_block
rtl_split_block(basic_block bb,void * insnp)541e4b17023SJohn Marino rtl_split_block (basic_block bb, void *insnp)
542e4b17023SJohn Marino {
543e4b17023SJohn Marino   basic_block new_bb;
544e4b17023SJohn Marino   rtx insn = (rtx) insnp;
545e4b17023SJohn Marino   edge e;
546e4b17023SJohn Marino   edge_iterator ei;
547e4b17023SJohn Marino 
548e4b17023SJohn Marino   if (!insn)
549e4b17023SJohn Marino     {
550e4b17023SJohn Marino       insn = first_insn_after_basic_block_note (bb);
551e4b17023SJohn Marino 
552e4b17023SJohn Marino       if (insn)
553e4b17023SJohn Marino 	{
554e4b17023SJohn Marino 	  rtx next = insn;
555e4b17023SJohn Marino 
556e4b17023SJohn Marino 	  insn = PREV_INSN (insn);
557e4b17023SJohn Marino 
558e4b17023SJohn Marino 	  /* If the block contains only debug insns, insn would have
559e4b17023SJohn Marino 	     been NULL in a non-debug compilation, and then we'd end
560e4b17023SJohn Marino 	     up emitting a DELETED note.  For -fcompare-debug
561e4b17023SJohn Marino 	     stability, emit the note too.  */
562e4b17023SJohn Marino 	  if (insn != BB_END (bb)
563e4b17023SJohn Marino 	      && DEBUG_INSN_P (next)
564e4b17023SJohn Marino 	      && DEBUG_INSN_P (BB_END (bb)))
565e4b17023SJohn Marino 	    {
566e4b17023SJohn Marino 	      while (next != BB_END (bb) && DEBUG_INSN_P (next))
567e4b17023SJohn Marino 		next = NEXT_INSN (next);
568e4b17023SJohn Marino 
569e4b17023SJohn Marino 	      if (next == BB_END (bb))
570e4b17023SJohn Marino 		emit_note_after (NOTE_INSN_DELETED, next);
571e4b17023SJohn Marino 	    }
572e4b17023SJohn Marino 	}
573e4b17023SJohn Marino       else
574e4b17023SJohn Marino 	insn = get_last_insn ();
575e4b17023SJohn Marino     }
576e4b17023SJohn Marino 
577e4b17023SJohn Marino   /* We probably should check type of the insn so that we do not create
578e4b17023SJohn Marino      inconsistent cfg.  It is checked in verify_flow_info anyway, so do not
579e4b17023SJohn Marino      bother.  */
580e4b17023SJohn Marino   if (insn == BB_END (bb))
581e4b17023SJohn Marino     emit_note_after (NOTE_INSN_DELETED, insn);
582e4b17023SJohn Marino 
583e4b17023SJohn Marino   /* Create the new basic block.  */
584e4b17023SJohn Marino   new_bb = create_basic_block (NEXT_INSN (insn), BB_END (bb), bb);
585e4b17023SJohn Marino   BB_COPY_PARTITION (new_bb, bb);
586e4b17023SJohn Marino   BB_END (bb) = insn;
587e4b17023SJohn Marino 
588e4b17023SJohn Marino   /* Redirect the outgoing edges.  */
589e4b17023SJohn Marino   new_bb->succs = bb->succs;
590e4b17023SJohn Marino   bb->succs = NULL;
591e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, new_bb->succs)
592e4b17023SJohn Marino     e->src = new_bb;
593e4b17023SJohn Marino 
594e4b17023SJohn Marino   /* The new block starts off being dirty.  */
595e4b17023SJohn Marino   df_set_bb_dirty (bb);
596e4b17023SJohn Marino   return new_bb;
597e4b17023SJohn Marino }
598e4b17023SJohn Marino 
599e4b17023SJohn Marino /* Blocks A and B are to be merged into a single block A.  The insns
600e4b17023SJohn Marino    are already contiguous.  */
601e4b17023SJohn Marino 
602e4b17023SJohn Marino static void
rtl_merge_blocks(basic_block a,basic_block b)603e4b17023SJohn Marino rtl_merge_blocks (basic_block a, basic_block b)
604e4b17023SJohn Marino {
605e4b17023SJohn Marino   rtx b_head = BB_HEAD (b), b_end = BB_END (b), a_end = BB_END (a);
606e4b17023SJohn Marino   rtx del_first = NULL_RTX, del_last = NULL_RTX;
607e4b17023SJohn Marino   rtx b_debug_start = b_end, b_debug_end = b_end;
608e4b17023SJohn Marino   bool forwarder_p = (b->flags & BB_FORWARDER_BLOCK) != 0;
609e4b17023SJohn Marino   int b_empty = 0;
610e4b17023SJohn Marino 
611e4b17023SJohn Marino   if (dump_file)
612e4b17023SJohn Marino     fprintf (dump_file, "Merging block %d into block %d...\n", b->index,
613e4b17023SJohn Marino 	     a->index);
614e4b17023SJohn Marino 
615e4b17023SJohn Marino   while (DEBUG_INSN_P (b_end))
616e4b17023SJohn Marino     b_end = PREV_INSN (b_debug_start = b_end);
617e4b17023SJohn Marino 
618e4b17023SJohn Marino   /* If there was a CODE_LABEL beginning B, delete it.  */
619e4b17023SJohn Marino   if (LABEL_P (b_head))
620e4b17023SJohn Marino     {
621e4b17023SJohn Marino       /* Detect basic blocks with nothing but a label.  This can happen
622e4b17023SJohn Marino 	 in particular at the end of a function.  */
623e4b17023SJohn Marino       if (b_head == b_end)
624e4b17023SJohn Marino 	b_empty = 1;
625e4b17023SJohn Marino 
626e4b17023SJohn Marino       del_first = del_last = b_head;
627e4b17023SJohn Marino       b_head = NEXT_INSN (b_head);
628e4b17023SJohn Marino     }
629e4b17023SJohn Marino 
630e4b17023SJohn Marino   /* Delete the basic block note and handle blocks containing just that
631e4b17023SJohn Marino      note.  */
632e4b17023SJohn Marino   if (NOTE_INSN_BASIC_BLOCK_P (b_head))
633e4b17023SJohn Marino     {
634e4b17023SJohn Marino       if (b_head == b_end)
635e4b17023SJohn Marino 	b_empty = 1;
636e4b17023SJohn Marino       if (! del_last)
637e4b17023SJohn Marino 	del_first = b_head;
638e4b17023SJohn Marino 
639e4b17023SJohn Marino       del_last = b_head;
640e4b17023SJohn Marino       b_head = NEXT_INSN (b_head);
641e4b17023SJohn Marino     }
642e4b17023SJohn Marino 
643e4b17023SJohn Marino   /* If there was a jump out of A, delete it.  */
644e4b17023SJohn Marino   if (JUMP_P (a_end))
645e4b17023SJohn Marino     {
646e4b17023SJohn Marino       rtx prev;
647e4b17023SJohn Marino 
648e4b17023SJohn Marino       for (prev = PREV_INSN (a_end); ; prev = PREV_INSN (prev))
649e4b17023SJohn Marino 	if (!NOTE_P (prev)
650e4b17023SJohn Marino 	    || NOTE_INSN_BASIC_BLOCK_P (prev)
651e4b17023SJohn Marino 	    || prev == BB_HEAD (a))
652e4b17023SJohn Marino 	  break;
653e4b17023SJohn Marino 
654e4b17023SJohn Marino       del_first = a_end;
655e4b17023SJohn Marino 
656e4b17023SJohn Marino #ifdef HAVE_cc0
657e4b17023SJohn Marino       /* If this was a conditional jump, we need to also delete
658e4b17023SJohn Marino 	 the insn that set cc0.  */
659e4b17023SJohn Marino       if (only_sets_cc0_p (prev))
660e4b17023SJohn Marino 	{
661e4b17023SJohn Marino 	  rtx tmp = prev;
662e4b17023SJohn Marino 
663e4b17023SJohn Marino 	  prev = prev_nonnote_insn (prev);
664e4b17023SJohn Marino 	  if (!prev)
665e4b17023SJohn Marino 	    prev = BB_HEAD (a);
666e4b17023SJohn Marino 	  del_first = tmp;
667e4b17023SJohn Marino 	}
668e4b17023SJohn Marino #endif
669e4b17023SJohn Marino 
670e4b17023SJohn Marino       a_end = PREV_INSN (del_first);
671e4b17023SJohn Marino     }
672e4b17023SJohn Marino   else if (BARRIER_P (NEXT_INSN (a_end)))
673e4b17023SJohn Marino     del_first = NEXT_INSN (a_end);
674e4b17023SJohn Marino 
675e4b17023SJohn Marino   /* Delete everything marked above as well as crap that might be
676e4b17023SJohn Marino      hanging out between the two blocks.  */
677e4b17023SJohn Marino   BB_HEAD (b) = NULL;
678e4b17023SJohn Marino   delete_insn_chain (del_first, del_last, true);
679e4b17023SJohn Marino 
680e4b17023SJohn Marino   /* Reassociate the insns of B with A.  */
681e4b17023SJohn Marino   if (!b_empty)
682e4b17023SJohn Marino     {
683e4b17023SJohn Marino       update_bb_for_insn_chain (a_end, b_debug_end, a);
684e4b17023SJohn Marino 
685e4b17023SJohn Marino       a_end = b_debug_end;
686e4b17023SJohn Marino     }
687e4b17023SJohn Marino   else if (b_end != b_debug_end)
688e4b17023SJohn Marino     {
689e4b17023SJohn Marino       /* Move any deleted labels and other notes between the end of A
690e4b17023SJohn Marino 	 and the debug insns that make up B after the debug insns,
691e4b17023SJohn Marino 	 bringing the debug insns into A while keeping the notes after
692e4b17023SJohn Marino 	 the end of A.  */
693e4b17023SJohn Marino       if (NEXT_INSN (a_end) != b_debug_start)
694e4b17023SJohn Marino 	reorder_insns_nobb (NEXT_INSN (a_end), PREV_INSN (b_debug_start),
695e4b17023SJohn Marino 			    b_debug_end);
696e4b17023SJohn Marino       update_bb_for_insn_chain (b_debug_start, b_debug_end, a);
697e4b17023SJohn Marino       a_end = b_debug_end;
698e4b17023SJohn Marino     }
699e4b17023SJohn Marino 
700e4b17023SJohn Marino   df_bb_delete (b->index);
701e4b17023SJohn Marino   BB_END (a) = a_end;
702e4b17023SJohn Marino 
703e4b17023SJohn Marino   /* If B was a forwarder block, propagate the locus on the edge.  */
704e4b17023SJohn Marino   if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
705e4b17023SJohn Marino     EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;
706e4b17023SJohn Marino 
707e4b17023SJohn Marino   if (dump_file)
708e4b17023SJohn Marino     fprintf (dump_file, "Merged blocks %d and %d.\n", a->index, b->index);
709e4b17023SJohn Marino }
710e4b17023SJohn Marino 
711e4b17023SJohn Marino 
712e4b17023SJohn Marino /* Return true when block A and B can be merged.  */
713e4b17023SJohn Marino 
714e4b17023SJohn Marino static bool
rtl_can_merge_blocks(basic_block a,basic_block b)715e4b17023SJohn Marino rtl_can_merge_blocks (basic_block a, basic_block b)
716e4b17023SJohn Marino {
717e4b17023SJohn Marino   /* If we are partitioning hot/cold basic blocks, we don't want to
718e4b17023SJohn Marino      mess up unconditional or indirect jumps that cross between hot
719e4b17023SJohn Marino      and cold sections.
720e4b17023SJohn Marino 
721e4b17023SJohn Marino      Basic block partitioning may result in some jumps that appear to
722e4b17023SJohn Marino      be optimizable (or blocks that appear to be mergeable), but which really
723e4b17023SJohn Marino      must be left untouched (they are required to make it safely across
724e4b17023SJohn Marino      partition boundaries).  See  the comments at the top of
725e4b17023SJohn Marino      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
726e4b17023SJohn Marino 
727e4b17023SJohn Marino   if (BB_PARTITION (a) != BB_PARTITION (b))
728e4b17023SJohn Marino     return false;
729e4b17023SJohn Marino 
730e4b17023SJohn Marino   /* There must be exactly one edge in between the blocks.  */
731e4b17023SJohn Marino   return (single_succ_p (a)
732e4b17023SJohn Marino 	  && single_succ (a) == b
733e4b17023SJohn Marino 	  && single_pred_p (b)
734e4b17023SJohn Marino 	  && a != b
735e4b17023SJohn Marino 	  /* Must be simple edge.  */
736e4b17023SJohn Marino 	  && !(single_succ_edge (a)->flags & EDGE_COMPLEX)
737e4b17023SJohn Marino 	  && a->next_bb == b
738e4b17023SJohn Marino 	  && a != ENTRY_BLOCK_PTR && b != EXIT_BLOCK_PTR
739e4b17023SJohn Marino 	  /* If the jump insn has side effects,
740e4b17023SJohn Marino 	     we can't kill the edge.  */
741e4b17023SJohn Marino 	  && (!JUMP_P (BB_END (a))
742e4b17023SJohn Marino 	      || (reload_completed
743e4b17023SJohn Marino 		  ? simplejump_p (BB_END (a)) : onlyjump_p (BB_END (a)))));
744e4b17023SJohn Marino }
745e4b17023SJohn Marino 
746e4b17023SJohn Marino /* Return the label in the head of basic block BLOCK.  Create one if it doesn't
747e4b17023SJohn Marino    exist.  */
748e4b17023SJohn Marino 
749e4b17023SJohn Marino rtx
block_label(basic_block block)750e4b17023SJohn Marino block_label (basic_block block)
751e4b17023SJohn Marino {
752e4b17023SJohn Marino   if (block == EXIT_BLOCK_PTR)
753e4b17023SJohn Marino     return NULL_RTX;
754e4b17023SJohn Marino 
755e4b17023SJohn Marino   if (!LABEL_P (BB_HEAD (block)))
756e4b17023SJohn Marino     {
757e4b17023SJohn Marino       BB_HEAD (block) = emit_label_before (gen_label_rtx (), BB_HEAD (block));
758e4b17023SJohn Marino     }
759e4b17023SJohn Marino 
760e4b17023SJohn Marino   return BB_HEAD (block);
761e4b17023SJohn Marino }
762e4b17023SJohn Marino 
763e4b17023SJohn Marino /* Attempt to perform edge redirection by replacing possibly complex jump
764e4b17023SJohn Marino    instruction by unconditional jump or removing jump completely.  This can
765e4b17023SJohn Marino    apply only if all edges now point to the same block.  The parameters and
766e4b17023SJohn Marino    return values are equivalent to redirect_edge_and_branch.  */
767e4b17023SJohn Marino 
768e4b17023SJohn Marino edge
try_redirect_by_replacing_jump(edge e,basic_block target,bool in_cfglayout)769e4b17023SJohn Marino try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
770e4b17023SJohn Marino {
771e4b17023SJohn Marino   basic_block src = e->src;
772e4b17023SJohn Marino   rtx insn = BB_END (src), kill_from;
773e4b17023SJohn Marino   rtx set;
774e4b17023SJohn Marino   int fallthru = 0;
775e4b17023SJohn Marino 
776e4b17023SJohn Marino   /* If we are partitioning hot/cold basic blocks, we don't want to
777e4b17023SJohn Marino      mess up unconditional or indirect jumps that cross between hot
778e4b17023SJohn Marino      and cold sections.
779e4b17023SJohn Marino 
780e4b17023SJohn Marino      Basic block partitioning may result in some jumps that appear to
781e4b17023SJohn Marino      be optimizable (or blocks that appear to be mergeable), but which really
782e4b17023SJohn Marino      must be left untouched (they are required to make it safely across
783e4b17023SJohn Marino      partition boundaries).  See  the comments at the top of
784e4b17023SJohn Marino      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
785e4b17023SJohn Marino 
786e4b17023SJohn Marino   if (find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)
787e4b17023SJohn Marino       || BB_PARTITION (src) != BB_PARTITION (target))
788e4b17023SJohn Marino     return NULL;
789e4b17023SJohn Marino 
790e4b17023SJohn Marino   /* We can replace or remove a complex jump only when we have exactly
791e4b17023SJohn Marino      two edges.  Also, if we have exactly one outgoing edge, we can
792e4b17023SJohn Marino      redirect that.  */
793e4b17023SJohn Marino   if (EDGE_COUNT (src->succs) >= 3
794e4b17023SJohn Marino       /* Verify that all targets will be TARGET.  Specifically, the
795e4b17023SJohn Marino 	 edge that is not E must also go to TARGET.  */
796e4b17023SJohn Marino       || (EDGE_COUNT (src->succs) == 2
797e4b17023SJohn Marino 	  && EDGE_SUCC (src, EDGE_SUCC (src, 0) == e)->dest != target))
798e4b17023SJohn Marino     return NULL;
799e4b17023SJohn Marino 
800e4b17023SJohn Marino   if (!onlyjump_p (insn))
801e4b17023SJohn Marino     return NULL;
802e4b17023SJohn Marino   if ((!optimize || reload_completed) && tablejump_p (insn, NULL, NULL))
803e4b17023SJohn Marino     return NULL;
804e4b17023SJohn Marino 
805e4b17023SJohn Marino   /* Avoid removing branch with side effects.  */
806e4b17023SJohn Marino   set = single_set (insn);
807e4b17023SJohn Marino   if (!set || side_effects_p (set))
808e4b17023SJohn Marino     return NULL;
809e4b17023SJohn Marino 
810e4b17023SJohn Marino   /* In case we zap a conditional jump, we'll need to kill
811e4b17023SJohn Marino      the cc0 setter too.  */
812e4b17023SJohn Marino   kill_from = insn;
813e4b17023SJohn Marino #ifdef HAVE_cc0
814e4b17023SJohn Marino   if (reg_mentioned_p (cc0_rtx, PATTERN (insn))
815e4b17023SJohn Marino       && only_sets_cc0_p (PREV_INSN (insn)))
816e4b17023SJohn Marino     kill_from = PREV_INSN (insn);
817e4b17023SJohn Marino #endif
818e4b17023SJohn Marino 
819e4b17023SJohn Marino   /* See if we can create the fallthru edge.  */
820e4b17023SJohn Marino   if (in_cfglayout || can_fallthru (src, target))
821e4b17023SJohn Marino     {
822e4b17023SJohn Marino       if (dump_file)
823e4b17023SJohn Marino 	fprintf (dump_file, "Removing jump %i.\n", INSN_UID (insn));
824e4b17023SJohn Marino       fallthru = 1;
825e4b17023SJohn Marino 
826e4b17023SJohn Marino       /* Selectively unlink whole insn chain.  */
827e4b17023SJohn Marino       if (in_cfglayout)
828e4b17023SJohn Marino 	{
829e4b17023SJohn Marino 	  rtx insn = src->il.rtl->footer;
830e4b17023SJohn Marino 
831e4b17023SJohn Marino 	  delete_insn_chain (kill_from, BB_END (src), false);
832e4b17023SJohn Marino 
833e4b17023SJohn Marino 	  /* Remove barriers but keep jumptables.  */
834e4b17023SJohn Marino 	  while (insn)
835e4b17023SJohn Marino 	    {
836e4b17023SJohn Marino 	      if (BARRIER_P (insn))
837e4b17023SJohn Marino 		{
838e4b17023SJohn Marino 		  if (PREV_INSN (insn))
839e4b17023SJohn Marino 		    NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
840e4b17023SJohn Marino 		  else
841e4b17023SJohn Marino 		    src->il.rtl->footer = NEXT_INSN (insn);
842e4b17023SJohn Marino 		  if (NEXT_INSN (insn))
843e4b17023SJohn Marino 		    PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
844e4b17023SJohn Marino 		}
845e4b17023SJohn Marino 	      if (LABEL_P (insn))
846e4b17023SJohn Marino 		break;
847e4b17023SJohn Marino 	      insn = NEXT_INSN (insn);
848e4b17023SJohn Marino 	    }
849e4b17023SJohn Marino 	}
850e4b17023SJohn Marino       else
851e4b17023SJohn Marino 	delete_insn_chain (kill_from, PREV_INSN (BB_HEAD (target)),
852e4b17023SJohn Marino 			   false);
853e4b17023SJohn Marino     }
854e4b17023SJohn Marino 
855e4b17023SJohn Marino   /* If this already is simplejump, redirect it.  */
856e4b17023SJohn Marino   else if (simplejump_p (insn))
857e4b17023SJohn Marino     {
858e4b17023SJohn Marino       if (e->dest == target)
859e4b17023SJohn Marino 	return NULL;
860e4b17023SJohn Marino       if (dump_file)
861e4b17023SJohn Marino 	fprintf (dump_file, "Redirecting jump %i from %i to %i.\n",
862e4b17023SJohn Marino 		 INSN_UID (insn), e->dest->index, target->index);
863e4b17023SJohn Marino       if (!redirect_jump (insn, block_label (target), 0))
864e4b17023SJohn Marino 	{
865e4b17023SJohn Marino 	  gcc_assert (target == EXIT_BLOCK_PTR);
866e4b17023SJohn Marino 	  return NULL;
867e4b17023SJohn Marino 	}
868e4b17023SJohn Marino     }
869e4b17023SJohn Marino 
870e4b17023SJohn Marino   /* Cannot do anything for target exit block.  */
871e4b17023SJohn Marino   else if (target == EXIT_BLOCK_PTR)
872e4b17023SJohn Marino     return NULL;
873e4b17023SJohn Marino 
874e4b17023SJohn Marino   /* Or replace possibly complicated jump insn by simple jump insn.  */
875e4b17023SJohn Marino   else
876e4b17023SJohn Marino     {
877e4b17023SJohn Marino       rtx target_label = block_label (target);
878e4b17023SJohn Marino       rtx barrier, label, table;
879e4b17023SJohn Marino 
880e4b17023SJohn Marino       emit_jump_insn_after_noloc (gen_jump (target_label), insn);
881e4b17023SJohn Marino       JUMP_LABEL (BB_END (src)) = target_label;
882e4b17023SJohn Marino       LABEL_NUSES (target_label)++;
883e4b17023SJohn Marino       if (dump_file)
884e4b17023SJohn Marino 	fprintf (dump_file, "Replacing insn %i by jump %i\n",
885e4b17023SJohn Marino 		 INSN_UID (insn), INSN_UID (BB_END (src)));
886e4b17023SJohn Marino 
887e4b17023SJohn Marino 
888e4b17023SJohn Marino       delete_insn_chain (kill_from, insn, false);
889e4b17023SJohn Marino 
890e4b17023SJohn Marino       /* Recognize a tablejump that we are converting to a
891e4b17023SJohn Marino 	 simple jump and remove its associated CODE_LABEL
892e4b17023SJohn Marino 	 and ADDR_VEC or ADDR_DIFF_VEC.  */
893e4b17023SJohn Marino       if (tablejump_p (insn, &label, &table))
894e4b17023SJohn Marino 	delete_insn_chain (label, table, false);
895e4b17023SJohn Marino 
896e4b17023SJohn Marino       barrier = next_nonnote_insn (BB_END (src));
897e4b17023SJohn Marino       if (!barrier || !BARRIER_P (barrier))
898e4b17023SJohn Marino 	emit_barrier_after (BB_END (src));
899e4b17023SJohn Marino       else
900e4b17023SJohn Marino 	{
901e4b17023SJohn Marino 	  if (barrier != NEXT_INSN (BB_END (src)))
902e4b17023SJohn Marino 	    {
903e4b17023SJohn Marino 	      /* Move the jump before barrier so that the notes
904e4b17023SJohn Marino 		 which originally were or were created before jump table are
905e4b17023SJohn Marino 		 inside the basic block.  */
906e4b17023SJohn Marino 	      rtx new_insn = BB_END (src);
907e4b17023SJohn Marino 
908e4b17023SJohn Marino 	      update_bb_for_insn_chain (NEXT_INSN (BB_END (src)),
909e4b17023SJohn Marino 				        PREV_INSN (barrier), src);
910e4b17023SJohn Marino 
911e4b17023SJohn Marino 	      NEXT_INSN (PREV_INSN (new_insn)) = NEXT_INSN (new_insn);
912e4b17023SJohn Marino 	      PREV_INSN (NEXT_INSN (new_insn)) = PREV_INSN (new_insn);
913e4b17023SJohn Marino 
914e4b17023SJohn Marino 	      NEXT_INSN (new_insn) = barrier;
915e4b17023SJohn Marino 	      NEXT_INSN (PREV_INSN (barrier)) = new_insn;
916e4b17023SJohn Marino 
917e4b17023SJohn Marino 	      PREV_INSN (new_insn) = PREV_INSN (barrier);
918e4b17023SJohn Marino 	      PREV_INSN (barrier) = new_insn;
919e4b17023SJohn Marino 	    }
920e4b17023SJohn Marino 	}
921e4b17023SJohn Marino     }
922e4b17023SJohn Marino 
923e4b17023SJohn Marino   /* Keep only one edge out and set proper flags.  */
924e4b17023SJohn Marino   if (!single_succ_p (src))
925e4b17023SJohn Marino     remove_edge (e);
926e4b17023SJohn Marino   gcc_assert (single_succ_p (src));
927e4b17023SJohn Marino 
928e4b17023SJohn Marino   e = single_succ_edge (src);
929e4b17023SJohn Marino   if (fallthru)
930e4b17023SJohn Marino     e->flags = EDGE_FALLTHRU;
931e4b17023SJohn Marino   else
932e4b17023SJohn Marino     e->flags = 0;
933e4b17023SJohn Marino 
934e4b17023SJohn Marino   e->probability = REG_BR_PROB_BASE;
935e4b17023SJohn Marino   e->count = src->count;
936e4b17023SJohn Marino 
937e4b17023SJohn Marino   if (e->dest != target)
938e4b17023SJohn Marino     redirect_edge_succ (e, target);
939e4b17023SJohn Marino   return e;
940e4b17023SJohn Marino }
941e4b17023SJohn Marino 
942e4b17023SJohn Marino /* Subroutine of redirect_branch_edge that tries to patch the jump
943e4b17023SJohn Marino    instruction INSN so that it reaches block NEW.  Do this
944e4b17023SJohn Marino    only when it originally reached block OLD.  Return true if this
945e4b17023SJohn Marino    worked or the original target wasn't OLD, return false if redirection
946e4b17023SJohn Marino    doesn't work.  */
947e4b17023SJohn Marino 
948e4b17023SJohn Marino static bool
patch_jump_insn(rtx insn,rtx old_label,basic_block new_bb)949e4b17023SJohn Marino patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb)
950e4b17023SJohn Marino {
951e4b17023SJohn Marino   rtx tmp;
952e4b17023SJohn Marino   /* Recognize a tablejump and adjust all matching cases.  */
953e4b17023SJohn Marino   if (tablejump_p (insn, NULL, &tmp))
954e4b17023SJohn Marino     {
955e4b17023SJohn Marino       rtvec vec;
956e4b17023SJohn Marino       int j;
957e4b17023SJohn Marino       rtx new_label = block_label (new_bb);
958e4b17023SJohn Marino 
959e4b17023SJohn Marino       if (new_bb == EXIT_BLOCK_PTR)
960e4b17023SJohn Marino 	return false;
961e4b17023SJohn Marino       if (GET_CODE (PATTERN (tmp)) == ADDR_VEC)
962e4b17023SJohn Marino 	vec = XVEC (PATTERN (tmp), 0);
963e4b17023SJohn Marino       else
964e4b17023SJohn Marino 	vec = XVEC (PATTERN (tmp), 1);
965e4b17023SJohn Marino 
966e4b17023SJohn Marino       for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
967e4b17023SJohn Marino 	if (XEXP (RTVEC_ELT (vec, j), 0) == old_label)
968e4b17023SJohn Marino 	  {
969e4b17023SJohn Marino 	    RTVEC_ELT (vec, j) = gen_rtx_LABEL_REF (Pmode, new_label);
970e4b17023SJohn Marino 	    --LABEL_NUSES (old_label);
971e4b17023SJohn Marino 	    ++LABEL_NUSES (new_label);
972e4b17023SJohn Marino 	  }
973e4b17023SJohn Marino 
974e4b17023SJohn Marino       /* Handle casesi dispatch insns.  */
975e4b17023SJohn Marino       if ((tmp = single_set (insn)) != NULL
976e4b17023SJohn Marino 	  && SET_DEST (tmp) == pc_rtx
977e4b17023SJohn Marino 	  && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
978e4b17023SJohn Marino 	  && GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF
979e4b17023SJohn Marino 	  && XEXP (XEXP (SET_SRC (tmp), 2), 0) == old_label)
980e4b17023SJohn Marino 	{
981e4b17023SJohn Marino 	  XEXP (SET_SRC (tmp), 2) = gen_rtx_LABEL_REF (Pmode,
982e4b17023SJohn Marino 						       new_label);
983e4b17023SJohn Marino 	  --LABEL_NUSES (old_label);
984e4b17023SJohn Marino 	  ++LABEL_NUSES (new_label);
985e4b17023SJohn Marino 	}
986e4b17023SJohn Marino     }
987e4b17023SJohn Marino   else if ((tmp = extract_asm_operands (PATTERN (insn))) != NULL)
988e4b17023SJohn Marino     {
989e4b17023SJohn Marino       int i, n = ASM_OPERANDS_LABEL_LENGTH (tmp);
990e4b17023SJohn Marino       rtx new_label, note;
991e4b17023SJohn Marino 
992e4b17023SJohn Marino       if (new_bb == EXIT_BLOCK_PTR)
993e4b17023SJohn Marino 	return false;
994e4b17023SJohn Marino       new_label = block_label (new_bb);
995e4b17023SJohn Marino 
996e4b17023SJohn Marino       for (i = 0; i < n; ++i)
997e4b17023SJohn Marino 	{
998e4b17023SJohn Marino 	  rtx old_ref = ASM_OPERANDS_LABEL (tmp, i);
999e4b17023SJohn Marino 	  gcc_assert (GET_CODE (old_ref) == LABEL_REF);
1000e4b17023SJohn Marino 	  if (XEXP (old_ref, 0) == old_label)
1001e4b17023SJohn Marino 	    {
1002e4b17023SJohn Marino 	      ASM_OPERANDS_LABEL (tmp, i)
1003e4b17023SJohn Marino 		= gen_rtx_LABEL_REF (Pmode, new_label);
1004e4b17023SJohn Marino 	      --LABEL_NUSES (old_label);
1005e4b17023SJohn Marino 	      ++LABEL_NUSES (new_label);
1006e4b17023SJohn Marino 	    }
1007e4b17023SJohn Marino 	}
1008e4b17023SJohn Marino 
1009e4b17023SJohn Marino       if (JUMP_LABEL (insn) == old_label)
1010e4b17023SJohn Marino 	{
1011e4b17023SJohn Marino 	  JUMP_LABEL (insn) = new_label;
1012e4b17023SJohn Marino 	  note = find_reg_note (insn, REG_LABEL_TARGET, new_label);
1013e4b17023SJohn Marino 	  if (note)
1014e4b17023SJohn Marino 	    remove_note (insn, note);
1015e4b17023SJohn Marino 	}
1016e4b17023SJohn Marino       else
1017e4b17023SJohn Marino 	{
1018e4b17023SJohn Marino 	  note = find_reg_note (insn, REG_LABEL_TARGET, old_label);
1019e4b17023SJohn Marino 	  if (note)
1020e4b17023SJohn Marino 	    remove_note (insn, note);
1021e4b17023SJohn Marino 	  if (JUMP_LABEL (insn) != new_label
1022e4b17023SJohn Marino 	      && !find_reg_note (insn, REG_LABEL_TARGET, new_label))
1023e4b17023SJohn Marino 	    add_reg_note (insn, REG_LABEL_TARGET, new_label);
1024e4b17023SJohn Marino 	}
1025e4b17023SJohn Marino       while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label))
1026e4b17023SJohn Marino 	     != NULL_RTX)
1027e4b17023SJohn Marino 	XEXP (note, 0) = new_label;
1028e4b17023SJohn Marino     }
1029e4b17023SJohn Marino   else
1030e4b17023SJohn Marino     {
1031e4b17023SJohn Marino       /* ?? We may play the games with moving the named labels from
1032e4b17023SJohn Marino 	 one basic block to the other in case only one computed_jump is
1033e4b17023SJohn Marino 	 available.  */
1034e4b17023SJohn Marino       if (computed_jump_p (insn)
1035e4b17023SJohn Marino 	  /* A return instruction can't be redirected.  */
1036e4b17023SJohn Marino 	  || returnjump_p (insn))
1037e4b17023SJohn Marino 	return false;
1038e4b17023SJohn Marino 
1039e4b17023SJohn Marino       if (!currently_expanding_to_rtl || JUMP_LABEL (insn) == old_label)
1040e4b17023SJohn Marino 	{
1041e4b17023SJohn Marino 	  /* If the insn doesn't go where we think, we're confused.  */
1042e4b17023SJohn Marino 	  gcc_assert (JUMP_LABEL (insn) == old_label);
1043e4b17023SJohn Marino 
1044e4b17023SJohn Marino 	  /* If the substitution doesn't succeed, die.  This can happen
1045e4b17023SJohn Marino 	     if the back end emitted unrecognizable instructions or if
1046e4b17023SJohn Marino 	     target is exit block on some arches.  */
1047e4b17023SJohn Marino 	  if (!redirect_jump (insn, block_label (new_bb), 0))
1048e4b17023SJohn Marino 	    {
1049e4b17023SJohn Marino 	      gcc_assert (new_bb == EXIT_BLOCK_PTR);
1050e4b17023SJohn Marino 	      return false;
1051e4b17023SJohn Marino 	    }
1052e4b17023SJohn Marino 	}
1053e4b17023SJohn Marino     }
1054e4b17023SJohn Marino   return true;
1055e4b17023SJohn Marino }
1056e4b17023SJohn Marino 
1057e4b17023SJohn Marino 
1058e4b17023SJohn Marino /* Redirect edge representing branch of (un)conditional jump or tablejump,
1059e4b17023SJohn Marino    NULL on failure  */
1060e4b17023SJohn Marino static edge
redirect_branch_edge(edge e,basic_block target)1061e4b17023SJohn Marino redirect_branch_edge (edge e, basic_block target)
1062e4b17023SJohn Marino {
1063e4b17023SJohn Marino   rtx old_label = BB_HEAD (e->dest);
1064e4b17023SJohn Marino   basic_block src = e->src;
1065e4b17023SJohn Marino   rtx insn = BB_END (src);
1066e4b17023SJohn Marino 
1067e4b17023SJohn Marino   /* We can only redirect non-fallthru edges of jump insn.  */
1068e4b17023SJohn Marino   if (e->flags & EDGE_FALLTHRU)
1069e4b17023SJohn Marino     return NULL;
1070e4b17023SJohn Marino   else if (!JUMP_P (insn) && !currently_expanding_to_rtl)
1071e4b17023SJohn Marino     return NULL;
1072e4b17023SJohn Marino 
1073e4b17023SJohn Marino   if (!currently_expanding_to_rtl)
1074e4b17023SJohn Marino     {
1075e4b17023SJohn Marino       if (!patch_jump_insn (insn, old_label, target))
1076e4b17023SJohn Marino 	return NULL;
1077e4b17023SJohn Marino     }
1078e4b17023SJohn Marino   else
1079e4b17023SJohn Marino     /* When expanding this BB might actually contain multiple
1080e4b17023SJohn Marino        jumps (i.e. not yet split by find_many_sub_basic_blocks).
1081e4b17023SJohn Marino        Redirect all of those that match our label.  */
1082e4b17023SJohn Marino     FOR_BB_INSNS (src, insn)
1083e4b17023SJohn Marino       if (JUMP_P (insn) && !patch_jump_insn (insn, old_label, target))
1084e4b17023SJohn Marino 	return NULL;
1085e4b17023SJohn Marino 
1086e4b17023SJohn Marino   if (dump_file)
1087e4b17023SJohn Marino     fprintf (dump_file, "Edge %i->%i redirected to %i\n",
1088e4b17023SJohn Marino 	     e->src->index, e->dest->index, target->index);
1089e4b17023SJohn Marino 
1090e4b17023SJohn Marino   if (e->dest != target)
1091e4b17023SJohn Marino     e = redirect_edge_succ_nodup (e, target);
1092e4b17023SJohn Marino 
1093e4b17023SJohn Marino   return e;
1094e4b17023SJohn Marino }
1095e4b17023SJohn Marino 
1096e4b17023SJohn Marino /* Attempt to change code to redirect edge E to TARGET.  Don't do that on
1097e4b17023SJohn Marino    expense of adding new instructions or reordering basic blocks.
1098e4b17023SJohn Marino 
1099e4b17023SJohn Marino    Function can be also called with edge destination equivalent to the TARGET.
1100e4b17023SJohn Marino    Then it should try the simplifications and do nothing if none is possible.
1101e4b17023SJohn Marino 
1102e4b17023SJohn Marino    Return edge representing the branch if transformation succeeded.  Return NULL
1103e4b17023SJohn Marino    on failure.
1104e4b17023SJohn Marino    We still return NULL in case E already destinated TARGET and we didn't
1105e4b17023SJohn Marino    managed to simplify instruction stream.  */
1106e4b17023SJohn Marino 
1107e4b17023SJohn Marino static edge
rtl_redirect_edge_and_branch(edge e,basic_block target)1108e4b17023SJohn Marino rtl_redirect_edge_and_branch (edge e, basic_block target)
1109e4b17023SJohn Marino {
1110e4b17023SJohn Marino   edge ret;
1111e4b17023SJohn Marino   basic_block src = e->src;
1112e4b17023SJohn Marino 
1113e4b17023SJohn Marino   if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
1114e4b17023SJohn Marino     return NULL;
1115e4b17023SJohn Marino 
1116e4b17023SJohn Marino   if (e->dest == target)
1117e4b17023SJohn Marino     return e;
1118e4b17023SJohn Marino 
1119e4b17023SJohn Marino   if ((ret = try_redirect_by_replacing_jump (e, target, false)) != NULL)
1120e4b17023SJohn Marino     {
1121e4b17023SJohn Marino       df_set_bb_dirty (src);
1122e4b17023SJohn Marino       return ret;
1123e4b17023SJohn Marino     }
1124e4b17023SJohn Marino 
1125e4b17023SJohn Marino   ret = redirect_branch_edge (e, target);
1126e4b17023SJohn Marino   if (!ret)
1127e4b17023SJohn Marino     return NULL;
1128e4b17023SJohn Marino 
1129e4b17023SJohn Marino   df_set_bb_dirty (src);
1130e4b17023SJohn Marino   return ret;
1131e4b17023SJohn Marino }
1132e4b17023SJohn Marino 
1133e4b17023SJohn Marino /* Like force_nonfallthru below, but additionally performs redirection
1134e4b17023SJohn Marino    Used by redirect_edge_and_branch_force.  JUMP_LABEL is used only
1135e4b17023SJohn Marino    when redirecting to the EXIT_BLOCK, it is either ret_rtx or
1136e4b17023SJohn Marino    simple_return_rtx, indicating which kind of returnjump to create.
1137e4b17023SJohn Marino    It should be NULL otherwise.  */
1138e4b17023SJohn Marino 
1139e4b17023SJohn Marino basic_block
force_nonfallthru_and_redirect(edge e,basic_block target,rtx jump_label)1140e4b17023SJohn Marino force_nonfallthru_and_redirect (edge e, basic_block target, rtx jump_label)
1141e4b17023SJohn Marino {
1142e4b17023SJohn Marino   basic_block jump_block, new_bb = NULL, src = e->src;
1143e4b17023SJohn Marino   rtx note;
1144e4b17023SJohn Marino   edge new_edge;
1145e4b17023SJohn Marino   int abnormal_edge_flags = 0;
1146e4b17023SJohn Marino   bool asm_goto_edge = false;
1147e4b17023SJohn Marino   int loc;
1148e4b17023SJohn Marino 
1149e4b17023SJohn Marino   /* In the case the last instruction is conditional jump to the next
1150e4b17023SJohn Marino      instruction, first redirect the jump itself and then continue
1151e4b17023SJohn Marino      by creating a basic block afterwards to redirect fallthru edge.  */
1152e4b17023SJohn Marino   if (e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR
1153e4b17023SJohn Marino       && any_condjump_p (BB_END (e->src))
1154e4b17023SJohn Marino       && JUMP_LABEL (BB_END (e->src)) == BB_HEAD (e->dest))
1155e4b17023SJohn Marino     {
1156e4b17023SJohn Marino       rtx note;
1157e4b17023SJohn Marino       edge b = unchecked_make_edge (e->src, target, 0);
1158e4b17023SJohn Marino       bool redirected;
1159e4b17023SJohn Marino 
1160e4b17023SJohn Marino       redirected = redirect_jump (BB_END (e->src), block_label (target), 0);
1161e4b17023SJohn Marino       gcc_assert (redirected);
1162e4b17023SJohn Marino 
1163e4b17023SJohn Marino       note = find_reg_note (BB_END (e->src), REG_BR_PROB, NULL_RTX);
1164e4b17023SJohn Marino       if (note)
1165e4b17023SJohn Marino 	{
1166e4b17023SJohn Marino 	  int prob = INTVAL (XEXP (note, 0));
1167e4b17023SJohn Marino 
1168e4b17023SJohn Marino 	  b->probability = prob;
1169e4b17023SJohn Marino 	  b->count = e->count * prob / REG_BR_PROB_BASE;
1170e4b17023SJohn Marino 	  e->probability -= e->probability;
1171e4b17023SJohn Marino 	  e->count -= b->count;
1172e4b17023SJohn Marino 	  if (e->probability < 0)
1173e4b17023SJohn Marino 	    e->probability = 0;
1174e4b17023SJohn Marino 	  if (e->count < 0)
1175e4b17023SJohn Marino 	    e->count = 0;
1176e4b17023SJohn Marino 	}
1177e4b17023SJohn Marino     }
1178e4b17023SJohn Marino 
1179e4b17023SJohn Marino   if (e->flags & EDGE_ABNORMAL)
1180e4b17023SJohn Marino     {
1181e4b17023SJohn Marino       /* Irritating special case - fallthru edge to the same block as abnormal
1182e4b17023SJohn Marino 	 edge.
1183e4b17023SJohn Marino 	 We can't redirect abnormal edge, but we still can split the fallthru
1184e4b17023SJohn Marino 	 one and create separate abnormal edge to original destination.
1185e4b17023SJohn Marino 	 This allows bb-reorder to make such edge non-fallthru.  */
1186e4b17023SJohn Marino       gcc_assert (e->dest == target);
1187e4b17023SJohn Marino       abnormal_edge_flags = e->flags & ~(EDGE_FALLTHRU | EDGE_CAN_FALLTHRU);
1188e4b17023SJohn Marino       e->flags &= EDGE_FALLTHRU | EDGE_CAN_FALLTHRU;
1189e4b17023SJohn Marino     }
1190e4b17023SJohn Marino   else
1191e4b17023SJohn Marino     {
1192e4b17023SJohn Marino       gcc_assert (e->flags & EDGE_FALLTHRU);
1193e4b17023SJohn Marino       if (e->src == ENTRY_BLOCK_PTR)
1194e4b17023SJohn Marino 	{
1195e4b17023SJohn Marino 	  /* We can't redirect the entry block.  Create an empty block
1196e4b17023SJohn Marino 	     at the start of the function which we use to add the new
1197e4b17023SJohn Marino 	     jump.  */
1198e4b17023SJohn Marino 	  edge tmp;
1199e4b17023SJohn Marino 	  edge_iterator ei;
1200e4b17023SJohn Marino 	  bool found = false;
1201e4b17023SJohn Marino 
1202e4b17023SJohn Marino 	  basic_block bb = create_basic_block (BB_HEAD (e->dest), NULL, ENTRY_BLOCK_PTR);
1203e4b17023SJohn Marino 
1204e4b17023SJohn Marino 	  /* Change the existing edge's source to be the new block, and add
1205e4b17023SJohn Marino 	     a new edge from the entry block to the new block.  */
1206e4b17023SJohn Marino 	  e->src = bb;
1207e4b17023SJohn Marino 	  for (ei = ei_start (ENTRY_BLOCK_PTR->succs); (tmp = ei_safe_edge (ei)); )
1208e4b17023SJohn Marino 	    {
1209e4b17023SJohn Marino 	      if (tmp == e)
1210e4b17023SJohn Marino 		{
1211e4b17023SJohn Marino 		  VEC_unordered_remove (edge, ENTRY_BLOCK_PTR->succs, ei.index);
1212e4b17023SJohn Marino 		  found = true;
1213e4b17023SJohn Marino 		  break;
1214e4b17023SJohn Marino 		}
1215e4b17023SJohn Marino 	      else
1216e4b17023SJohn Marino 		ei_next (&ei);
1217e4b17023SJohn Marino 	    }
1218e4b17023SJohn Marino 
1219e4b17023SJohn Marino 	  gcc_assert (found);
1220e4b17023SJohn Marino 
1221e4b17023SJohn Marino 	  VEC_safe_push (edge, gc, bb->succs, e);
1222e4b17023SJohn Marino 	  make_single_succ_edge (ENTRY_BLOCK_PTR, bb, EDGE_FALLTHRU);
1223e4b17023SJohn Marino 	}
1224e4b17023SJohn Marino     }
1225e4b17023SJohn Marino 
1226e4b17023SJohn Marino   /* If e->src ends with asm goto, see if any of the ASM_OPERANDS_LABELs
1227e4b17023SJohn Marino      don't point to the target or fallthru label.  */
1228e4b17023SJohn Marino   if (JUMP_P (BB_END (e->src))
1229e4b17023SJohn Marino       && target != EXIT_BLOCK_PTR
1230e4b17023SJohn Marino       && (e->flags & EDGE_FALLTHRU)
1231e4b17023SJohn Marino       && (note = extract_asm_operands (PATTERN (BB_END (e->src)))))
1232e4b17023SJohn Marino     {
1233e4b17023SJohn Marino       int i, n = ASM_OPERANDS_LABEL_LENGTH (note);
1234*5ce9237cSJohn Marino       bool adjust_jump_target = false;
1235e4b17023SJohn Marino 
1236e4b17023SJohn Marino       for (i = 0; i < n; ++i)
1237e4b17023SJohn Marino 	{
1238e4b17023SJohn Marino 	  if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (e->dest))
1239*5ce9237cSJohn Marino 	    {
1240*5ce9237cSJohn Marino 	      LABEL_NUSES (XEXP (ASM_OPERANDS_LABEL (note, i), 0))--;
1241e4b17023SJohn Marino 	      XEXP (ASM_OPERANDS_LABEL (note, i), 0) = block_label (target);
1242*5ce9237cSJohn Marino 	      LABEL_NUSES (XEXP (ASM_OPERANDS_LABEL (note, i), 0))++;
1243*5ce9237cSJohn Marino 	      adjust_jump_target = true;
1244*5ce9237cSJohn Marino 	    }
1245e4b17023SJohn Marino 	  if (XEXP (ASM_OPERANDS_LABEL (note, i), 0) == BB_HEAD (target))
1246e4b17023SJohn Marino 	    asm_goto_edge = true;
1247e4b17023SJohn Marino 	}
1248*5ce9237cSJohn Marino       if (adjust_jump_target)
1249*5ce9237cSJohn Marino 	{
1250*5ce9237cSJohn Marino 	  rtx insn = BB_END (e->src), note;
1251*5ce9237cSJohn Marino 	  rtx old_label = BB_HEAD (e->dest);
1252*5ce9237cSJohn Marino 	  rtx new_label = BB_HEAD (target);
1253*5ce9237cSJohn Marino 
1254*5ce9237cSJohn Marino 	  if (JUMP_LABEL (insn) == old_label)
1255*5ce9237cSJohn Marino 	    {
1256*5ce9237cSJohn Marino 	      JUMP_LABEL (insn) = new_label;
1257*5ce9237cSJohn Marino 	      note = find_reg_note (insn, REG_LABEL_TARGET, new_label);
1258*5ce9237cSJohn Marino 	      if (note)
1259*5ce9237cSJohn Marino 		remove_note (insn, note);
1260*5ce9237cSJohn Marino 	    }
1261*5ce9237cSJohn Marino 	  else
1262*5ce9237cSJohn Marino 	    {
1263*5ce9237cSJohn Marino 	      note = find_reg_note (insn, REG_LABEL_TARGET, old_label);
1264*5ce9237cSJohn Marino 	      if (note)
1265*5ce9237cSJohn Marino 		remove_note (insn, note);
1266*5ce9237cSJohn Marino 	      if (JUMP_LABEL (insn) != new_label
1267*5ce9237cSJohn Marino 		  && !find_reg_note (insn, REG_LABEL_TARGET, new_label))
1268*5ce9237cSJohn Marino 		add_reg_note (insn, REG_LABEL_TARGET, new_label);
1269*5ce9237cSJohn Marino 	    }
1270*5ce9237cSJohn Marino 	  while ((note = find_reg_note (insn, REG_LABEL_OPERAND, old_label))
1271*5ce9237cSJohn Marino 		 != NULL_RTX)
1272*5ce9237cSJohn Marino 	    XEXP (note, 0) = new_label;
1273*5ce9237cSJohn Marino 	}
1274e4b17023SJohn Marino     }
1275e4b17023SJohn Marino 
1276e4b17023SJohn Marino   if (EDGE_COUNT (e->src->succs) >= 2 || abnormal_edge_flags || asm_goto_edge)
1277e4b17023SJohn Marino     {
1278e4b17023SJohn Marino       gcov_type count = e->count;
1279e4b17023SJohn Marino       int probability = e->probability;
1280e4b17023SJohn Marino       /* Create the new structures.  */
1281e4b17023SJohn Marino 
1282e4b17023SJohn Marino       /* If the old block ended with a tablejump, skip its table
1283e4b17023SJohn Marino 	 by searching forward from there.  Otherwise start searching
1284e4b17023SJohn Marino 	 forward from the last instruction of the old block.  */
1285e4b17023SJohn Marino       if (!tablejump_p (BB_END (e->src), NULL, &note))
1286e4b17023SJohn Marino 	note = BB_END (e->src);
1287e4b17023SJohn Marino       note = NEXT_INSN (note);
1288e4b17023SJohn Marino 
1289e4b17023SJohn Marino       jump_block = create_basic_block (note, NULL, e->src);
1290e4b17023SJohn Marino       jump_block->count = count;
1291e4b17023SJohn Marino       jump_block->frequency = EDGE_FREQUENCY (e);
1292e4b17023SJohn Marino       jump_block->loop_depth = target->loop_depth;
1293e4b17023SJohn Marino 
1294e4b17023SJohn Marino       /* Make sure new block ends up in correct hot/cold section.  */
1295e4b17023SJohn Marino 
1296e4b17023SJohn Marino       BB_COPY_PARTITION (jump_block, e->src);
1297e4b17023SJohn Marino       if (flag_reorder_blocks_and_partition
1298e4b17023SJohn Marino 	  && targetm_common.have_named_sections
1299e4b17023SJohn Marino 	  && JUMP_P (BB_END (jump_block))
1300e4b17023SJohn Marino 	  && !any_condjump_p (BB_END (jump_block))
1301e4b17023SJohn Marino 	  && (EDGE_SUCC (jump_block, 0)->flags & EDGE_CROSSING))
1302e4b17023SJohn Marino 	add_reg_note (BB_END (jump_block), REG_CROSSING_JUMP, NULL_RTX);
1303e4b17023SJohn Marino 
1304e4b17023SJohn Marino       /* Wire edge in.  */
1305e4b17023SJohn Marino       new_edge = make_edge (e->src, jump_block, EDGE_FALLTHRU);
1306e4b17023SJohn Marino       new_edge->probability = probability;
1307e4b17023SJohn Marino       new_edge->count = count;
1308e4b17023SJohn Marino 
1309e4b17023SJohn Marino       /* Redirect old edge.  */
1310e4b17023SJohn Marino       redirect_edge_pred (e, jump_block);
1311e4b17023SJohn Marino       e->probability = REG_BR_PROB_BASE;
1312e4b17023SJohn Marino 
1313e4b17023SJohn Marino       /* If asm goto has any label refs to target's label,
1314e4b17023SJohn Marino 	 add also edge from asm goto bb to target.  */
1315e4b17023SJohn Marino       if (asm_goto_edge)
1316e4b17023SJohn Marino 	{
1317e4b17023SJohn Marino 	  new_edge->probability /= 2;
1318e4b17023SJohn Marino 	  new_edge->count /= 2;
1319e4b17023SJohn Marino 	  jump_block->count /= 2;
1320e4b17023SJohn Marino 	  jump_block->frequency /= 2;
1321e4b17023SJohn Marino 	  new_edge = make_edge (new_edge->src, target,
1322e4b17023SJohn Marino 				e->flags & ~EDGE_FALLTHRU);
1323e4b17023SJohn Marino 	  new_edge->probability = probability - probability / 2;
1324e4b17023SJohn Marino 	  new_edge->count = count - count / 2;
1325e4b17023SJohn Marino 	}
1326e4b17023SJohn Marino 
1327e4b17023SJohn Marino       new_bb = jump_block;
1328e4b17023SJohn Marino     }
1329e4b17023SJohn Marino   else
1330e4b17023SJohn Marino     jump_block = e->src;
1331e4b17023SJohn Marino 
1332e4b17023SJohn Marino   if (e->goto_locus && e->goto_block == NULL)
1333e4b17023SJohn Marino     loc = e->goto_locus;
1334e4b17023SJohn Marino   else
1335e4b17023SJohn Marino     loc = 0;
1336e4b17023SJohn Marino   e->flags &= ~EDGE_FALLTHRU;
1337e4b17023SJohn Marino   if (target == EXIT_BLOCK_PTR)
1338e4b17023SJohn Marino     {
1339e4b17023SJohn Marino       if (jump_label == ret_rtx)
1340e4b17023SJohn Marino 	{
1341e4b17023SJohn Marino #ifdef HAVE_return
1342e4b17023SJohn Marino 	  emit_jump_insn_after_setloc (gen_return (), BB_END (jump_block), loc);
1343e4b17023SJohn Marino #else
1344e4b17023SJohn Marino 	  gcc_unreachable ();
1345e4b17023SJohn Marino #endif
1346e4b17023SJohn Marino 	}
1347e4b17023SJohn Marino       else
1348e4b17023SJohn Marino 	{
1349e4b17023SJohn Marino 	  gcc_assert (jump_label == simple_return_rtx);
1350e4b17023SJohn Marino #ifdef HAVE_simple_return
1351e4b17023SJohn Marino 	  emit_jump_insn_after_setloc (gen_simple_return (),
1352e4b17023SJohn Marino 				       BB_END (jump_block), loc);
1353e4b17023SJohn Marino #else
1354e4b17023SJohn Marino 	  gcc_unreachable ();
1355e4b17023SJohn Marino #endif
1356e4b17023SJohn Marino 	}
1357e4b17023SJohn Marino       set_return_jump_label (BB_END (jump_block));
1358e4b17023SJohn Marino     }
1359e4b17023SJohn Marino   else
1360e4b17023SJohn Marino     {
1361e4b17023SJohn Marino       rtx label = block_label (target);
1362e4b17023SJohn Marino       emit_jump_insn_after_setloc (gen_jump (label), BB_END (jump_block), loc);
1363e4b17023SJohn Marino       JUMP_LABEL (BB_END (jump_block)) = label;
1364e4b17023SJohn Marino       LABEL_NUSES (label)++;
1365e4b17023SJohn Marino     }
1366e4b17023SJohn Marino 
1367e4b17023SJohn Marino   emit_barrier_after (BB_END (jump_block));
1368e4b17023SJohn Marino   redirect_edge_succ_nodup (e, target);
1369e4b17023SJohn Marino 
1370e4b17023SJohn Marino   if (abnormal_edge_flags)
1371e4b17023SJohn Marino     make_edge (src, target, abnormal_edge_flags);
1372e4b17023SJohn Marino 
1373e4b17023SJohn Marino   df_mark_solutions_dirty ();
1374e4b17023SJohn Marino   return new_bb;
1375e4b17023SJohn Marino }
1376e4b17023SJohn Marino 
1377e4b17023SJohn Marino /* Edge E is assumed to be fallthru edge.  Emit needed jump instruction
1378e4b17023SJohn Marino    (and possibly create new basic block) to make edge non-fallthru.
1379e4b17023SJohn Marino    Return newly created BB or NULL if none.  */
1380e4b17023SJohn Marino 
1381e4b17023SJohn Marino static basic_block
rtl_force_nonfallthru(edge e)1382e4b17023SJohn Marino rtl_force_nonfallthru (edge e)
1383e4b17023SJohn Marino {
1384e4b17023SJohn Marino   return force_nonfallthru_and_redirect (e, e->dest, NULL_RTX);
1385e4b17023SJohn Marino }
1386e4b17023SJohn Marino 
1387e4b17023SJohn Marino /* Redirect edge even at the expense of creating new jump insn or
1388e4b17023SJohn Marino    basic block.  Return new basic block if created, NULL otherwise.
1389e4b17023SJohn Marino    Conversion must be possible.  */
1390e4b17023SJohn Marino 
1391e4b17023SJohn Marino static basic_block
rtl_redirect_edge_and_branch_force(edge e,basic_block target)1392e4b17023SJohn Marino rtl_redirect_edge_and_branch_force (edge e, basic_block target)
1393e4b17023SJohn Marino {
1394e4b17023SJohn Marino   if (redirect_edge_and_branch (e, target)
1395e4b17023SJohn Marino       || e->dest == target)
1396e4b17023SJohn Marino     return NULL;
1397e4b17023SJohn Marino 
1398e4b17023SJohn Marino   /* In case the edge redirection failed, try to force it to be non-fallthru
1399e4b17023SJohn Marino      and redirect newly created simplejump.  */
1400e4b17023SJohn Marino   df_set_bb_dirty (e->src);
1401e4b17023SJohn Marino   return force_nonfallthru_and_redirect (e, target, NULL_RTX);
1402e4b17023SJohn Marino }
1403e4b17023SJohn Marino 
1404e4b17023SJohn Marino /* The given edge should potentially be a fallthru edge.  If that is in
1405e4b17023SJohn Marino    fact true, delete the jump and barriers that are in the way.  */
1406e4b17023SJohn Marino 
1407e4b17023SJohn Marino static void
rtl_tidy_fallthru_edge(edge e)1408e4b17023SJohn Marino rtl_tidy_fallthru_edge (edge e)
1409e4b17023SJohn Marino {
1410e4b17023SJohn Marino   rtx q;
1411e4b17023SJohn Marino   basic_block b = e->src, c = b->next_bb;
1412e4b17023SJohn Marino 
1413e4b17023SJohn Marino   /* ??? In a late-running flow pass, other folks may have deleted basic
1414e4b17023SJohn Marino      blocks by nopping out blocks, leaving multiple BARRIERs between here
1415e4b17023SJohn Marino      and the target label. They ought to be chastised and fixed.
1416e4b17023SJohn Marino 
1417e4b17023SJohn Marino      We can also wind up with a sequence of undeletable labels between
1418e4b17023SJohn Marino      one block and the next.
1419e4b17023SJohn Marino 
1420e4b17023SJohn Marino      So search through a sequence of barriers, labels, and notes for
1421e4b17023SJohn Marino      the head of block C and assert that we really do fall through.  */
1422e4b17023SJohn Marino 
1423e4b17023SJohn Marino   for (q = NEXT_INSN (BB_END (b)); q != BB_HEAD (c); q = NEXT_INSN (q))
1424e4b17023SJohn Marino     if (INSN_P (q))
1425e4b17023SJohn Marino       return;
1426e4b17023SJohn Marino 
1427e4b17023SJohn Marino   /* Remove what will soon cease being the jump insn from the source block.
1428e4b17023SJohn Marino      If block B consisted only of this single jump, turn it into a deleted
1429e4b17023SJohn Marino      note.  */
1430e4b17023SJohn Marino   q = BB_END (b);
1431e4b17023SJohn Marino   if (JUMP_P (q)
1432e4b17023SJohn Marino       && onlyjump_p (q)
1433e4b17023SJohn Marino       && (any_uncondjump_p (q)
1434e4b17023SJohn Marino 	  || single_succ_p (b)))
1435e4b17023SJohn Marino     {
1436e4b17023SJohn Marino #ifdef HAVE_cc0
1437e4b17023SJohn Marino       /* If this was a conditional jump, we need to also delete
1438e4b17023SJohn Marino 	 the insn that set cc0.  */
1439e4b17023SJohn Marino       if (any_condjump_p (q) && only_sets_cc0_p (PREV_INSN (q)))
1440e4b17023SJohn Marino 	q = PREV_INSN (q);
1441e4b17023SJohn Marino #endif
1442e4b17023SJohn Marino 
1443e4b17023SJohn Marino       q = PREV_INSN (q);
1444e4b17023SJohn Marino     }
1445e4b17023SJohn Marino 
1446e4b17023SJohn Marino   /* Selectively unlink the sequence.  */
1447e4b17023SJohn Marino   if (q != PREV_INSN (BB_HEAD (c)))
1448e4b17023SJohn Marino     delete_insn_chain (NEXT_INSN (q), PREV_INSN (BB_HEAD (c)), false);
1449e4b17023SJohn Marino 
1450e4b17023SJohn Marino   e->flags |= EDGE_FALLTHRU;
1451e4b17023SJohn Marino }
1452e4b17023SJohn Marino 
1453e4b17023SJohn Marino /* Should move basic block BB after basic block AFTER.  NIY.  */
1454e4b17023SJohn Marino 
1455e4b17023SJohn Marino static bool
rtl_move_block_after(basic_block bb ATTRIBUTE_UNUSED,basic_block after ATTRIBUTE_UNUSED)1456e4b17023SJohn Marino rtl_move_block_after (basic_block bb ATTRIBUTE_UNUSED,
1457e4b17023SJohn Marino 		      basic_block after ATTRIBUTE_UNUSED)
1458e4b17023SJohn Marino {
1459e4b17023SJohn Marino   return false;
1460e4b17023SJohn Marino }
1461e4b17023SJohn Marino 
1462e4b17023SJohn Marino /* Split a (typically critical) edge.  Return the new block.
1463e4b17023SJohn Marino    The edge must not be abnormal.
1464e4b17023SJohn Marino 
1465e4b17023SJohn Marino    ??? The code generally expects to be called on critical edges.
1466e4b17023SJohn Marino    The case of a block ending in an unconditional jump to a
1467e4b17023SJohn Marino    block with multiple predecessors is not handled optimally.  */
1468e4b17023SJohn Marino 
1469e4b17023SJohn Marino static basic_block
rtl_split_edge(edge edge_in)1470e4b17023SJohn Marino rtl_split_edge (edge edge_in)
1471e4b17023SJohn Marino {
1472e4b17023SJohn Marino   basic_block bb;
1473e4b17023SJohn Marino   rtx before;
1474e4b17023SJohn Marino 
1475e4b17023SJohn Marino   /* Abnormal edges cannot be split.  */
1476e4b17023SJohn Marino   gcc_assert (!(edge_in->flags & EDGE_ABNORMAL));
1477e4b17023SJohn Marino 
1478e4b17023SJohn Marino   /* We are going to place the new block in front of edge destination.
1479e4b17023SJohn Marino      Avoid existence of fallthru predecessors.  */
1480e4b17023SJohn Marino   if ((edge_in->flags & EDGE_FALLTHRU) == 0)
1481e4b17023SJohn Marino     {
1482e4b17023SJohn Marino       edge e = find_fallthru_edge (edge_in->dest->preds);
1483e4b17023SJohn Marino 
1484e4b17023SJohn Marino       if (e)
1485e4b17023SJohn Marino 	force_nonfallthru (e);
1486e4b17023SJohn Marino     }
1487e4b17023SJohn Marino 
1488e4b17023SJohn Marino   /* Create the basic block note.  */
1489e4b17023SJohn Marino   if (edge_in->dest != EXIT_BLOCK_PTR)
1490e4b17023SJohn Marino     before = BB_HEAD (edge_in->dest);
1491e4b17023SJohn Marino   else
1492e4b17023SJohn Marino     before = NULL_RTX;
1493e4b17023SJohn Marino 
1494e4b17023SJohn Marino   /* If this is a fall through edge to the exit block, the blocks might be
1495e4b17023SJohn Marino      not adjacent, and the right place is after the source.  */
1496e4b17023SJohn Marino   if ((edge_in->flags & EDGE_FALLTHRU) && edge_in->dest == EXIT_BLOCK_PTR)
1497e4b17023SJohn Marino     {
1498e4b17023SJohn Marino       before = NEXT_INSN (BB_END (edge_in->src));
1499e4b17023SJohn Marino       bb = create_basic_block (before, NULL, edge_in->src);
1500e4b17023SJohn Marino       BB_COPY_PARTITION (bb, edge_in->src);
1501e4b17023SJohn Marino     }
1502e4b17023SJohn Marino   else
1503e4b17023SJohn Marino     {
1504e4b17023SJohn Marino       bb = create_basic_block (before, NULL, edge_in->dest->prev_bb);
1505e4b17023SJohn Marino       /* ??? Why not edge_in->dest->prev_bb here?  */
1506e4b17023SJohn Marino       BB_COPY_PARTITION (bb, edge_in->dest);
1507e4b17023SJohn Marino     }
1508e4b17023SJohn Marino 
1509e4b17023SJohn Marino   make_single_succ_edge (bb, edge_in->dest, EDGE_FALLTHRU);
1510e4b17023SJohn Marino 
1511e4b17023SJohn Marino   /* For non-fallthru edges, we must adjust the predecessor's
1512e4b17023SJohn Marino      jump instruction to target our new block.  */
1513e4b17023SJohn Marino   if ((edge_in->flags & EDGE_FALLTHRU) == 0)
1514e4b17023SJohn Marino     {
1515e4b17023SJohn Marino       edge redirected = redirect_edge_and_branch (edge_in, bb);
1516e4b17023SJohn Marino       gcc_assert (redirected);
1517e4b17023SJohn Marino     }
1518e4b17023SJohn Marino   else
1519e4b17023SJohn Marino     {
1520e4b17023SJohn Marino       if (edge_in->src != ENTRY_BLOCK_PTR)
1521e4b17023SJohn Marino 	{
1522e4b17023SJohn Marino 	  /* For asm goto even splitting of fallthru edge might
1523e4b17023SJohn Marino 	     need insn patching, as other labels might point to the
1524e4b17023SJohn Marino 	     old label.  */
1525e4b17023SJohn Marino 	  rtx last = BB_END (edge_in->src);
1526e4b17023SJohn Marino 	  if (last
1527e4b17023SJohn Marino 	      && JUMP_P (last)
1528e4b17023SJohn Marino 	      && edge_in->dest != EXIT_BLOCK_PTR
1529e4b17023SJohn Marino 	      && extract_asm_operands (PATTERN (last)) != NULL_RTX
1530e4b17023SJohn Marino 	      && patch_jump_insn (last, before, bb))
1531e4b17023SJohn Marino 	    df_set_bb_dirty (edge_in->src);
1532e4b17023SJohn Marino 	}
1533e4b17023SJohn Marino       redirect_edge_succ (edge_in, bb);
1534e4b17023SJohn Marino     }
1535e4b17023SJohn Marino 
1536e4b17023SJohn Marino   return bb;
1537e4b17023SJohn Marino }
1538e4b17023SJohn Marino 
1539e4b17023SJohn Marino /* Queue instructions for insertion on an edge between two basic blocks.
1540e4b17023SJohn Marino    The new instructions and basic blocks (if any) will not appear in the
1541e4b17023SJohn Marino    CFG until commit_edge_insertions is called.  */
1542e4b17023SJohn Marino 
1543e4b17023SJohn Marino void
insert_insn_on_edge(rtx pattern,edge e)1544e4b17023SJohn Marino insert_insn_on_edge (rtx pattern, edge e)
1545e4b17023SJohn Marino {
1546e4b17023SJohn Marino   /* We cannot insert instructions on an abnormal critical edge.
1547e4b17023SJohn Marino      It will be easier to find the culprit if we die now.  */
1548e4b17023SJohn Marino   gcc_assert (!((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e)));
1549e4b17023SJohn Marino 
1550e4b17023SJohn Marino   if (e->insns.r == NULL_RTX)
1551e4b17023SJohn Marino     start_sequence ();
1552e4b17023SJohn Marino   else
1553e4b17023SJohn Marino     push_to_sequence (e->insns.r);
1554e4b17023SJohn Marino 
1555e4b17023SJohn Marino   emit_insn (pattern);
1556e4b17023SJohn Marino 
1557e4b17023SJohn Marino   e->insns.r = get_insns ();
1558e4b17023SJohn Marino   end_sequence ();
1559e4b17023SJohn Marino }
1560e4b17023SJohn Marino 
1561e4b17023SJohn Marino /* Update the CFG for the instructions queued on edge E.  */
1562e4b17023SJohn Marino 
1563e4b17023SJohn Marino void
commit_one_edge_insertion(edge e)1564e4b17023SJohn Marino commit_one_edge_insertion (edge e)
1565e4b17023SJohn Marino {
1566e4b17023SJohn Marino   rtx before = NULL_RTX, after = NULL_RTX, insns, tmp, last;
1567e4b17023SJohn Marino   basic_block bb;
1568e4b17023SJohn Marino 
1569e4b17023SJohn Marino   /* Pull the insns off the edge now since the edge might go away.  */
1570e4b17023SJohn Marino   insns = e->insns.r;
1571e4b17023SJohn Marino   e->insns.r = NULL_RTX;
1572e4b17023SJohn Marino 
1573e4b17023SJohn Marino   /* Figure out where to put these insns.  If the destination has
1574e4b17023SJohn Marino      one predecessor, insert there.  Except for the exit block.  */
1575e4b17023SJohn Marino   if (single_pred_p (e->dest) && e->dest != EXIT_BLOCK_PTR)
1576e4b17023SJohn Marino     {
1577e4b17023SJohn Marino       bb = e->dest;
1578e4b17023SJohn Marino 
1579e4b17023SJohn Marino       /* Get the location correct wrt a code label, and "nice" wrt
1580e4b17023SJohn Marino 	 a basic block note, and before everything else.  */
1581e4b17023SJohn Marino       tmp = BB_HEAD (bb);
1582e4b17023SJohn Marino       if (LABEL_P (tmp))
1583e4b17023SJohn Marino 	tmp = NEXT_INSN (tmp);
1584e4b17023SJohn Marino       if (NOTE_INSN_BASIC_BLOCK_P (tmp))
1585e4b17023SJohn Marino 	tmp = NEXT_INSN (tmp);
1586e4b17023SJohn Marino       if (tmp == BB_HEAD (bb))
1587e4b17023SJohn Marino 	before = tmp;
1588e4b17023SJohn Marino       else if (tmp)
1589e4b17023SJohn Marino 	after = PREV_INSN (tmp);
1590e4b17023SJohn Marino       else
1591e4b17023SJohn Marino 	after = get_last_insn ();
1592e4b17023SJohn Marino     }
1593e4b17023SJohn Marino 
1594e4b17023SJohn Marino   /* If the source has one successor and the edge is not abnormal,
1595e4b17023SJohn Marino      insert there.  Except for the entry block.  */
1596e4b17023SJohn Marino   else if ((e->flags & EDGE_ABNORMAL) == 0
1597e4b17023SJohn Marino 	   && single_succ_p (e->src)
1598e4b17023SJohn Marino 	   && e->src != ENTRY_BLOCK_PTR)
1599e4b17023SJohn Marino     {
1600e4b17023SJohn Marino       bb = e->src;
1601e4b17023SJohn Marino 
1602e4b17023SJohn Marino       /* It is possible to have a non-simple jump here.  Consider a target
1603e4b17023SJohn Marino 	 where some forms of unconditional jumps clobber a register.  This
1604e4b17023SJohn Marino 	 happens on the fr30 for example.
1605e4b17023SJohn Marino 
1606e4b17023SJohn Marino 	 We know this block has a single successor, so we can just emit
1607e4b17023SJohn Marino 	 the queued insns before the jump.  */
1608e4b17023SJohn Marino       if (JUMP_P (BB_END (bb)))
1609e4b17023SJohn Marino 	before = BB_END (bb);
1610e4b17023SJohn Marino       else
1611e4b17023SJohn Marino 	{
1612e4b17023SJohn Marino 	  /* We'd better be fallthru, or we've lost track of what's what.  */
1613e4b17023SJohn Marino 	  gcc_assert (e->flags & EDGE_FALLTHRU);
1614e4b17023SJohn Marino 
1615e4b17023SJohn Marino 	  after = BB_END (bb);
1616e4b17023SJohn Marino 	}
1617e4b17023SJohn Marino     }
1618e4b17023SJohn Marino 
1619e4b17023SJohn Marino   /* Otherwise we must split the edge.  */
1620e4b17023SJohn Marino   else
1621e4b17023SJohn Marino     {
1622e4b17023SJohn Marino       bb = split_edge (e);
1623e4b17023SJohn Marino       after = BB_END (bb);
1624e4b17023SJohn Marino 
1625e4b17023SJohn Marino       if (flag_reorder_blocks_and_partition
1626e4b17023SJohn Marino 	  && targetm_common.have_named_sections
1627e4b17023SJohn Marino 	  && e->src != ENTRY_BLOCK_PTR
1628e4b17023SJohn Marino 	  && BB_PARTITION (e->src) == BB_COLD_PARTITION
1629e4b17023SJohn Marino 	  && !(e->flags & EDGE_CROSSING)
1630e4b17023SJohn Marino 	  && JUMP_P (after)
1631e4b17023SJohn Marino 	  && !any_condjump_p (after)
1632e4b17023SJohn Marino 	  && (single_succ_edge (bb)->flags & EDGE_CROSSING))
1633e4b17023SJohn Marino 	add_reg_note (after, REG_CROSSING_JUMP, NULL_RTX);
1634e4b17023SJohn Marino     }
1635e4b17023SJohn Marino 
1636e4b17023SJohn Marino   /* Now that we've found the spot, do the insertion.  */
1637e4b17023SJohn Marino   if (before)
1638e4b17023SJohn Marino     {
1639e4b17023SJohn Marino       emit_insn_before_noloc (insns, before, bb);
1640e4b17023SJohn Marino       last = prev_nonnote_insn (before);
1641e4b17023SJohn Marino     }
1642e4b17023SJohn Marino   else
1643e4b17023SJohn Marino     last = emit_insn_after_noloc (insns, after, bb);
1644e4b17023SJohn Marino 
1645e4b17023SJohn Marino   if (returnjump_p (last))
1646e4b17023SJohn Marino     {
1647e4b17023SJohn Marino       /* ??? Remove all outgoing edges from BB and add one for EXIT.
1648e4b17023SJohn Marino 	 This is not currently a problem because this only happens
1649e4b17023SJohn Marino 	 for the (single) epilogue, which already has a fallthru edge
1650e4b17023SJohn Marino 	 to EXIT.  */
1651e4b17023SJohn Marino 
1652e4b17023SJohn Marino       e = single_succ_edge (bb);
1653e4b17023SJohn Marino       gcc_assert (e->dest == EXIT_BLOCK_PTR
1654e4b17023SJohn Marino 		  && single_succ_p (bb) && (e->flags & EDGE_FALLTHRU));
1655e4b17023SJohn Marino 
1656e4b17023SJohn Marino       e->flags &= ~EDGE_FALLTHRU;
1657e4b17023SJohn Marino       emit_barrier_after (last);
1658e4b17023SJohn Marino 
1659e4b17023SJohn Marino       if (before)
1660e4b17023SJohn Marino 	delete_insn (before);
1661e4b17023SJohn Marino     }
1662e4b17023SJohn Marino   else
1663e4b17023SJohn Marino     gcc_assert (!JUMP_P (last));
1664e4b17023SJohn Marino }
1665e4b17023SJohn Marino 
1666e4b17023SJohn Marino /* Update the CFG for all queued instructions.  */
1667e4b17023SJohn Marino 
1668e4b17023SJohn Marino void
commit_edge_insertions(void)1669e4b17023SJohn Marino commit_edge_insertions (void)
1670e4b17023SJohn Marino {
1671e4b17023SJohn Marino   basic_block bb;
1672e4b17023SJohn Marino 
1673e4b17023SJohn Marino #ifdef ENABLE_CHECKING
1674e4b17023SJohn Marino   verify_flow_info ();
1675e4b17023SJohn Marino #endif
1676e4b17023SJohn Marino 
1677e4b17023SJohn Marino   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
1678e4b17023SJohn Marino     {
1679e4b17023SJohn Marino       edge e;
1680e4b17023SJohn Marino       edge_iterator ei;
1681e4b17023SJohn Marino 
1682e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, bb->succs)
1683e4b17023SJohn Marino 	if (e->insns.r)
1684e4b17023SJohn Marino 	  commit_one_edge_insertion (e);
1685e4b17023SJohn Marino     }
1686e4b17023SJohn Marino }
1687e4b17023SJohn Marino 
1688e4b17023SJohn Marino 
1689e4b17023SJohn Marino /* Print out RTL-specific basic block information (live information
1690e4b17023SJohn Marino    at start and end).  */
1691e4b17023SJohn Marino 
1692e4b17023SJohn Marino static void
rtl_dump_bb(basic_block bb,FILE * outf,int indent,int flags ATTRIBUTE_UNUSED)1693e4b17023SJohn Marino rtl_dump_bb (basic_block bb, FILE *outf, int indent, int flags ATTRIBUTE_UNUSED)
1694e4b17023SJohn Marino {
1695e4b17023SJohn Marino   rtx insn;
1696e4b17023SJohn Marino   rtx last;
1697e4b17023SJohn Marino   char *s_indent;
1698e4b17023SJohn Marino 
1699e4b17023SJohn Marino   s_indent = (char *) alloca ((size_t) indent + 1);
1700e4b17023SJohn Marino   memset (s_indent, ' ', (size_t) indent);
1701e4b17023SJohn Marino   s_indent[indent] = '\0';
1702e4b17023SJohn Marino 
1703e4b17023SJohn Marino   if (df)
1704e4b17023SJohn Marino     {
1705e4b17023SJohn Marino       df_dump_top (bb, outf);
1706e4b17023SJohn Marino       putc ('\n', outf);
1707e4b17023SJohn Marino     }
1708e4b17023SJohn Marino 
1709e4b17023SJohn Marino   if (bb->index != ENTRY_BLOCK && bb->index != EXIT_BLOCK)
1710e4b17023SJohn Marino     for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb)); insn != last;
1711e4b17023SJohn Marino 	 insn = NEXT_INSN (insn))
1712e4b17023SJohn Marino       print_rtl_single (outf, insn);
1713e4b17023SJohn Marino 
1714e4b17023SJohn Marino   if (df)
1715e4b17023SJohn Marino     {
1716e4b17023SJohn Marino       df_dump_bottom (bb, outf);
1717e4b17023SJohn Marino       putc ('\n', outf);
1718e4b17023SJohn Marino     }
1719e4b17023SJohn Marino 
1720e4b17023SJohn Marino }
1721e4b17023SJohn Marino 
1722e4b17023SJohn Marino /* Like print_rtl, but also print out live information for the start of each
1723e4b17023SJohn Marino    basic block.  */
1724e4b17023SJohn Marino 
1725e4b17023SJohn Marino void
print_rtl_with_bb(FILE * outf,const_rtx rtx_first)1726e4b17023SJohn Marino print_rtl_with_bb (FILE *outf, const_rtx rtx_first)
1727e4b17023SJohn Marino {
1728e4b17023SJohn Marino   const_rtx tmp_rtx;
1729e4b17023SJohn Marino   if (rtx_first == 0)
1730e4b17023SJohn Marino     fprintf (outf, "(nil)\n");
1731e4b17023SJohn Marino   else
1732e4b17023SJohn Marino     {
1733e4b17023SJohn Marino       enum bb_state { NOT_IN_BB, IN_ONE_BB, IN_MULTIPLE_BB };
1734e4b17023SJohn Marino       int max_uid = get_max_uid ();
1735e4b17023SJohn Marino       basic_block *start = XCNEWVEC (basic_block, max_uid);
1736e4b17023SJohn Marino       basic_block *end = XCNEWVEC (basic_block, max_uid);
1737e4b17023SJohn Marino       enum bb_state *in_bb_p = XCNEWVEC (enum bb_state, max_uid);
1738e4b17023SJohn Marino 
1739e4b17023SJohn Marino       basic_block bb;
1740e4b17023SJohn Marino 
1741e4b17023SJohn Marino       if (df)
1742e4b17023SJohn Marino 	df_dump_start (outf);
1743e4b17023SJohn Marino 
1744e4b17023SJohn Marino       FOR_EACH_BB_REVERSE (bb)
1745e4b17023SJohn Marino 	{
1746e4b17023SJohn Marino 	  rtx x;
1747e4b17023SJohn Marino 
1748e4b17023SJohn Marino 	  start[INSN_UID (BB_HEAD (bb))] = bb;
1749e4b17023SJohn Marino 	  end[INSN_UID (BB_END (bb))] = bb;
1750e4b17023SJohn Marino 	  for (x = BB_HEAD (bb); x != NULL_RTX; x = NEXT_INSN (x))
1751e4b17023SJohn Marino 	    {
1752e4b17023SJohn Marino 	      enum bb_state state = IN_MULTIPLE_BB;
1753e4b17023SJohn Marino 
1754e4b17023SJohn Marino 	      if (in_bb_p[INSN_UID (x)] == NOT_IN_BB)
1755e4b17023SJohn Marino 		state = IN_ONE_BB;
1756e4b17023SJohn Marino 	      in_bb_p[INSN_UID (x)] = state;
1757e4b17023SJohn Marino 
1758e4b17023SJohn Marino 	      if (x == BB_END (bb))
1759e4b17023SJohn Marino 		break;
1760e4b17023SJohn Marino 	    }
1761e4b17023SJohn Marino 	}
1762e4b17023SJohn Marino 
1763e4b17023SJohn Marino       for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx))
1764e4b17023SJohn Marino 	{
1765e4b17023SJohn Marino 	  int did_output;
1766e4b17023SJohn Marino 
1767e4b17023SJohn Marino 	  bb = start[INSN_UID (tmp_rtx)];
1768e4b17023SJohn Marino 	  if (bb != NULL)
1769e4b17023SJohn Marino 	    dump_bb_info (bb, true, false, dump_flags, ";; ", outf);
1770e4b17023SJohn Marino 
1771e4b17023SJohn Marino 	  if (in_bb_p[INSN_UID (tmp_rtx)] == NOT_IN_BB
1772e4b17023SJohn Marino 	      && !NOTE_P (tmp_rtx)
1773e4b17023SJohn Marino 	      && !BARRIER_P (tmp_rtx))
1774e4b17023SJohn Marino 	    fprintf (outf, ";; Insn is not within a basic block\n");
1775e4b17023SJohn Marino 	  else if (in_bb_p[INSN_UID (tmp_rtx)] == IN_MULTIPLE_BB)
1776e4b17023SJohn Marino 	    fprintf (outf, ";; Insn is in multiple basic blocks\n");
1777e4b17023SJohn Marino 
1778e4b17023SJohn Marino 	  did_output = print_rtl_single (outf, tmp_rtx);
1779e4b17023SJohn Marino 
1780e4b17023SJohn Marino 	  bb = end[INSN_UID (tmp_rtx)];
1781e4b17023SJohn Marino 	  if (bb != NULL)
1782e4b17023SJohn Marino 	    dump_bb_info (bb, false, true, dump_flags, ";; ", outf);
1783e4b17023SJohn Marino 	  if (did_output)
1784e4b17023SJohn Marino 	    putc ('\n', outf);
1785e4b17023SJohn Marino 	}
1786e4b17023SJohn Marino 
1787e4b17023SJohn Marino       free (start);
1788e4b17023SJohn Marino       free (end);
1789e4b17023SJohn Marino       free (in_bb_p);
1790e4b17023SJohn Marino     }
1791e4b17023SJohn Marino 
1792e4b17023SJohn Marino   if (crtl->epilogue_delay_list != 0)
1793e4b17023SJohn Marino     {
1794e4b17023SJohn Marino       fprintf (outf, "\n;; Insns in epilogue delay list:\n\n");
1795e4b17023SJohn Marino       for (tmp_rtx = crtl->epilogue_delay_list; tmp_rtx != 0;
1796e4b17023SJohn Marino 	   tmp_rtx = XEXP (tmp_rtx, 1))
1797e4b17023SJohn Marino 	print_rtl_single (outf, XEXP (tmp_rtx, 0));
1798e4b17023SJohn Marino     }
1799e4b17023SJohn Marino }
1800e4b17023SJohn Marino 
1801e4b17023SJohn Marino void
update_br_prob_note(basic_block bb)1802e4b17023SJohn Marino update_br_prob_note (basic_block bb)
1803e4b17023SJohn Marino {
1804e4b17023SJohn Marino   rtx note;
1805e4b17023SJohn Marino   if (!JUMP_P (BB_END (bb)))
1806e4b17023SJohn Marino     return;
1807e4b17023SJohn Marino   note = find_reg_note (BB_END (bb), REG_BR_PROB, NULL_RTX);
1808e4b17023SJohn Marino   if (!note || INTVAL (XEXP (note, 0)) == BRANCH_EDGE (bb)->probability)
1809e4b17023SJohn Marino     return;
1810e4b17023SJohn Marino   XEXP (note, 0) = GEN_INT (BRANCH_EDGE (bb)->probability);
1811e4b17023SJohn Marino }
1812e4b17023SJohn Marino 
1813e4b17023SJohn Marino /* Get the last insn associated with block BB (that includes barriers and
1814e4b17023SJohn Marino    tablejumps after BB).  */
1815e4b17023SJohn Marino rtx
get_last_bb_insn(basic_block bb)1816e4b17023SJohn Marino get_last_bb_insn (basic_block bb)
1817e4b17023SJohn Marino {
1818e4b17023SJohn Marino   rtx tmp;
1819e4b17023SJohn Marino   rtx end = BB_END (bb);
1820e4b17023SJohn Marino 
1821e4b17023SJohn Marino   /* Include any jump table following the basic block.  */
1822e4b17023SJohn Marino   if (tablejump_p (end, NULL, &tmp))
1823e4b17023SJohn Marino     end = tmp;
1824e4b17023SJohn Marino 
1825e4b17023SJohn Marino   /* Include any barriers that may follow the basic block.  */
1826e4b17023SJohn Marino   tmp = next_nonnote_insn_bb (end);
1827e4b17023SJohn Marino   while (tmp && BARRIER_P (tmp))
1828e4b17023SJohn Marino     {
1829e4b17023SJohn Marino       end = tmp;
1830e4b17023SJohn Marino       tmp = next_nonnote_insn_bb (end);
1831e4b17023SJohn Marino     }
1832e4b17023SJohn Marino 
1833e4b17023SJohn Marino   return end;
1834e4b17023SJohn Marino }
1835e4b17023SJohn Marino 
1836e4b17023SJohn Marino /* Verify the CFG and RTL consistency common for both underlying RTL and
1837e4b17023SJohn Marino    cfglayout RTL.
1838e4b17023SJohn Marino 
1839e4b17023SJohn Marino    Currently it does following checks:
1840e4b17023SJohn Marino 
1841e4b17023SJohn Marino    - overlapping of basic blocks
1842e4b17023SJohn Marino    - insns with wrong BLOCK_FOR_INSN pointers
1843e4b17023SJohn Marino    - headers of basic blocks (the NOTE_INSN_BASIC_BLOCK note)
1844e4b17023SJohn Marino    - tails of basic blocks (ensure that boundary is necessary)
1845e4b17023SJohn Marino    - scans body of the basic block for JUMP_INSN, CODE_LABEL
1846e4b17023SJohn Marino      and NOTE_INSN_BASIC_BLOCK
1847e4b17023SJohn Marino    - verify that no fall_thru edge crosses hot/cold partition boundaries
1848e4b17023SJohn Marino    - verify that there are no pending RTL branch predictions
1849e4b17023SJohn Marino 
1850e4b17023SJohn Marino    In future it can be extended check a lot of other stuff as well
1851e4b17023SJohn Marino    (reachability of basic blocks, life information, etc. etc.).  */
1852e4b17023SJohn Marino 
1853e4b17023SJohn Marino static int
rtl_verify_flow_info_1(void)1854e4b17023SJohn Marino rtl_verify_flow_info_1 (void)
1855e4b17023SJohn Marino {
1856e4b17023SJohn Marino   rtx x;
1857e4b17023SJohn Marino   int err = 0;
1858e4b17023SJohn Marino   basic_block bb;
1859e4b17023SJohn Marino 
1860e4b17023SJohn Marino   /* Check the general integrity of the basic blocks.  */
1861e4b17023SJohn Marino   FOR_EACH_BB_REVERSE (bb)
1862e4b17023SJohn Marino     {
1863e4b17023SJohn Marino       rtx insn;
1864e4b17023SJohn Marino 
1865e4b17023SJohn Marino       if (!(bb->flags & BB_RTL))
1866e4b17023SJohn Marino 	{
1867e4b17023SJohn Marino 	  error ("BB_RTL flag not set for block %d", bb->index);
1868e4b17023SJohn Marino 	  err = 1;
1869e4b17023SJohn Marino 	}
1870e4b17023SJohn Marino 
1871e4b17023SJohn Marino       FOR_BB_INSNS (bb, insn)
1872e4b17023SJohn Marino 	if (BLOCK_FOR_INSN (insn) != bb)
1873e4b17023SJohn Marino 	  {
1874e4b17023SJohn Marino 	    error ("insn %d basic block pointer is %d, should be %d",
1875e4b17023SJohn Marino 		   INSN_UID (insn),
1876e4b17023SJohn Marino 		   BLOCK_FOR_INSN (insn) ? BLOCK_FOR_INSN (insn)->index : 0,
1877e4b17023SJohn Marino 		   bb->index);
1878e4b17023SJohn Marino 	    err = 1;
1879e4b17023SJohn Marino 	  }
1880e4b17023SJohn Marino 
1881e4b17023SJohn Marino       for (insn = bb->il.rtl->header; insn; insn = NEXT_INSN (insn))
1882e4b17023SJohn Marino 	if (!BARRIER_P (insn)
1883e4b17023SJohn Marino 	    && BLOCK_FOR_INSN (insn) != NULL)
1884e4b17023SJohn Marino 	  {
1885e4b17023SJohn Marino 	    error ("insn %d in header of bb %d has non-NULL basic block",
1886e4b17023SJohn Marino 		   INSN_UID (insn), bb->index);
1887e4b17023SJohn Marino 	    err = 1;
1888e4b17023SJohn Marino 	  }
1889e4b17023SJohn Marino       for (insn = bb->il.rtl->footer; insn; insn = NEXT_INSN (insn))
1890e4b17023SJohn Marino 	if (!BARRIER_P (insn)
1891e4b17023SJohn Marino 	    && BLOCK_FOR_INSN (insn) != NULL)
1892e4b17023SJohn Marino 	  {
1893e4b17023SJohn Marino 	    error ("insn %d in footer of bb %d has non-NULL basic block",
1894e4b17023SJohn Marino 		   INSN_UID (insn), bb->index);
1895e4b17023SJohn Marino 	    err = 1;
1896e4b17023SJohn Marino 	  }
1897e4b17023SJohn Marino     }
1898e4b17023SJohn Marino 
1899e4b17023SJohn Marino   /* Now check the basic blocks (boundaries etc.) */
1900e4b17023SJohn Marino   FOR_EACH_BB_REVERSE (bb)
1901e4b17023SJohn Marino     {
1902e4b17023SJohn Marino       int n_fallthru = 0, n_eh = 0, n_call = 0, n_abnormal = 0, n_branch = 0;
1903e4b17023SJohn Marino       edge e, fallthru = NULL;
1904e4b17023SJohn Marino       rtx note;
1905e4b17023SJohn Marino       edge_iterator ei;
1906e4b17023SJohn Marino 
1907e4b17023SJohn Marino       if (JUMP_P (BB_END (bb))
1908e4b17023SJohn Marino 	  && (note = find_reg_note (BB_END (bb), REG_BR_PROB, NULL_RTX))
1909e4b17023SJohn Marino 	  && EDGE_COUNT (bb->succs) >= 2
1910e4b17023SJohn Marino 	  && any_condjump_p (BB_END (bb)))
1911e4b17023SJohn Marino 	{
1912e4b17023SJohn Marino 	  if (INTVAL (XEXP (note, 0)) != BRANCH_EDGE (bb)->probability
1913e4b17023SJohn Marino 	      && profile_status != PROFILE_ABSENT)
1914e4b17023SJohn Marino 	    {
1915e4b17023SJohn Marino 	      error ("verify_flow_info: REG_BR_PROB does not match cfg %wi %i",
1916e4b17023SJohn Marino 		     INTVAL (XEXP (note, 0)), BRANCH_EDGE (bb)->probability);
1917e4b17023SJohn Marino 	      err = 1;
1918e4b17023SJohn Marino 	    }
1919e4b17023SJohn Marino 	}
1920e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, bb->succs)
1921e4b17023SJohn Marino 	{
1922e4b17023SJohn Marino 	  bool is_crossing;
1923e4b17023SJohn Marino 
1924e4b17023SJohn Marino 	  if (e->flags & EDGE_FALLTHRU)
1925e4b17023SJohn Marino 	    n_fallthru++, fallthru = e;
1926e4b17023SJohn Marino 
1927e4b17023SJohn Marino 	  is_crossing = (BB_PARTITION (e->src) != BB_PARTITION (e->dest)
1928e4b17023SJohn Marino 			 && e->src != ENTRY_BLOCK_PTR
1929e4b17023SJohn Marino 			 && e->dest != EXIT_BLOCK_PTR);
1930e4b17023SJohn Marino 	  if (e->flags & EDGE_CROSSING)
1931e4b17023SJohn Marino 	    {
1932e4b17023SJohn Marino 	      if (!is_crossing)
1933e4b17023SJohn Marino 		{
1934e4b17023SJohn Marino 		  error ("EDGE_CROSSING incorrectly set across same section");
1935e4b17023SJohn Marino 		  err = 1;
1936e4b17023SJohn Marino 		}
1937e4b17023SJohn Marino 	      if (e->flags & EDGE_FALLTHRU)
1938e4b17023SJohn Marino 		{
1939e4b17023SJohn Marino 		  error ("fallthru edge crosses section boundary (bb %i)",
1940e4b17023SJohn Marino 			 e->src->index);
1941e4b17023SJohn Marino 		  err = 1;
1942e4b17023SJohn Marino 		}
1943e4b17023SJohn Marino 	      if (e->flags & EDGE_EH)
1944e4b17023SJohn Marino 		{
1945e4b17023SJohn Marino 		  error ("EH edge crosses section boundary (bb %i)",
1946e4b17023SJohn Marino 			 e->src->index);
1947e4b17023SJohn Marino 		  err = 1;
1948e4b17023SJohn Marino 		}
1949e4b17023SJohn Marino 	    }
1950e4b17023SJohn Marino 	  else if (is_crossing)
1951e4b17023SJohn Marino 	    {
1952e4b17023SJohn Marino 	      error ("EDGE_CROSSING missing across section boundary");
1953e4b17023SJohn Marino 	      err = 1;
1954e4b17023SJohn Marino 	    }
1955e4b17023SJohn Marino 
1956e4b17023SJohn Marino 	  if ((e->flags & ~(EDGE_DFS_BACK
1957e4b17023SJohn Marino 			    | EDGE_CAN_FALLTHRU
1958e4b17023SJohn Marino 			    | EDGE_IRREDUCIBLE_LOOP
1959e4b17023SJohn Marino 			    | EDGE_LOOP_EXIT
1960e4b17023SJohn Marino 			    | EDGE_CROSSING
1961e4b17023SJohn Marino 			    | EDGE_PRESERVE)) == 0)
1962e4b17023SJohn Marino 	    n_branch++;
1963e4b17023SJohn Marino 
1964e4b17023SJohn Marino 	  if (e->flags & EDGE_ABNORMAL_CALL)
1965e4b17023SJohn Marino 	    n_call++;
1966e4b17023SJohn Marino 
1967e4b17023SJohn Marino 	  if (e->flags & EDGE_EH)
1968e4b17023SJohn Marino 	    n_eh++;
1969e4b17023SJohn Marino 	  else if (e->flags & EDGE_ABNORMAL)
1970e4b17023SJohn Marino 	    n_abnormal++;
1971e4b17023SJohn Marino 	}
1972e4b17023SJohn Marino 
1973e4b17023SJohn Marino       if (n_eh && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX))
1974e4b17023SJohn Marino 	{
1975e4b17023SJohn Marino 	  error ("missing REG_EH_REGION note in the end of bb %i", bb->index);
1976e4b17023SJohn Marino 	  err = 1;
1977e4b17023SJohn Marino 	}
1978e4b17023SJohn Marino       if (n_eh > 1)
1979e4b17023SJohn Marino 	{
1980e4b17023SJohn Marino 	  error ("too many eh edges %i", bb->index);
1981e4b17023SJohn Marino 	  err = 1;
1982e4b17023SJohn Marino 	}
1983e4b17023SJohn Marino       if (n_branch
1984e4b17023SJohn Marino 	  && (!JUMP_P (BB_END (bb))
1985e4b17023SJohn Marino 	      || (n_branch > 1 && (any_uncondjump_p (BB_END (bb))
1986e4b17023SJohn Marino 				   || any_condjump_p (BB_END (bb))))))
1987e4b17023SJohn Marino 	{
1988e4b17023SJohn Marino 	  error ("too many outgoing branch edges from bb %i", bb->index);
1989e4b17023SJohn Marino 	  err = 1;
1990e4b17023SJohn Marino 	}
1991e4b17023SJohn Marino       if (n_fallthru && any_uncondjump_p (BB_END (bb)))
1992e4b17023SJohn Marino 	{
1993e4b17023SJohn Marino 	  error ("fallthru edge after unconditional jump %i", bb->index);
1994e4b17023SJohn Marino 	  err = 1;
1995e4b17023SJohn Marino 	}
1996e4b17023SJohn Marino       if (n_branch != 1 && any_uncondjump_p (BB_END (bb)))
1997e4b17023SJohn Marino 	{
1998e4b17023SJohn Marino 	  error ("wrong number of branch edges after unconditional jump %i",
1999e4b17023SJohn Marino 		 bb->index);
2000e4b17023SJohn Marino 	  err = 1;
2001e4b17023SJohn Marino 	}
2002e4b17023SJohn Marino       if (n_branch != 1 && any_condjump_p (BB_END (bb))
2003e4b17023SJohn Marino 	  && JUMP_LABEL (BB_END (bb)) != BB_HEAD (fallthru->dest))
2004e4b17023SJohn Marino 	{
2005e4b17023SJohn Marino 	  error ("wrong amount of branch edges after conditional jump %i",
2006e4b17023SJohn Marino 		 bb->index);
2007e4b17023SJohn Marino 	  err = 1;
2008e4b17023SJohn Marino 	}
2009e4b17023SJohn Marino       if (n_call && !CALL_P (BB_END (bb)))
2010e4b17023SJohn Marino 	{
2011e4b17023SJohn Marino 	  error ("call edges for non-call insn in bb %i", bb->index);
2012e4b17023SJohn Marino 	  err = 1;
2013e4b17023SJohn Marino 	}
2014e4b17023SJohn Marino       if (n_abnormal
2015e4b17023SJohn Marino 	  && (!CALL_P (BB_END (bb)) && n_call != n_abnormal)
2016e4b17023SJohn Marino 	  && (!JUMP_P (BB_END (bb))
2017e4b17023SJohn Marino 	      || any_condjump_p (BB_END (bb))
2018e4b17023SJohn Marino 	      || any_uncondjump_p (BB_END (bb))))
2019e4b17023SJohn Marino 	{
2020e4b17023SJohn Marino 	  error ("abnormal edges for no purpose in bb %i", bb->index);
2021e4b17023SJohn Marino 	  err = 1;
2022e4b17023SJohn Marino 	}
2023e4b17023SJohn Marino 
2024e4b17023SJohn Marino       for (x = BB_HEAD (bb); x != NEXT_INSN (BB_END (bb)); x = NEXT_INSN (x))
2025e4b17023SJohn Marino 	/* We may have a barrier inside a basic block before dead code
2026e4b17023SJohn Marino 	   elimination.  There is no BLOCK_FOR_INSN field in a barrier.  */
2027e4b17023SJohn Marino 	if (!BARRIER_P (x) && BLOCK_FOR_INSN (x) != bb)
2028e4b17023SJohn Marino 	  {
2029e4b17023SJohn Marino 	    debug_rtx (x);
2030e4b17023SJohn Marino 	    if (! BLOCK_FOR_INSN (x))
2031e4b17023SJohn Marino 	      error
2032e4b17023SJohn Marino 		("insn %d inside basic block %d but block_for_insn is NULL",
2033e4b17023SJohn Marino 		 INSN_UID (x), bb->index);
2034e4b17023SJohn Marino 	    else
2035e4b17023SJohn Marino 	      error
2036e4b17023SJohn Marino 		("insn %d inside basic block %d but block_for_insn is %i",
2037e4b17023SJohn Marino 		 INSN_UID (x), bb->index, BLOCK_FOR_INSN (x)->index);
2038e4b17023SJohn Marino 
2039e4b17023SJohn Marino 	    err = 1;
2040e4b17023SJohn Marino 	  }
2041e4b17023SJohn Marino 
2042e4b17023SJohn Marino       /* OK pointers are correct.  Now check the header of basic
2043e4b17023SJohn Marino 	 block.  It ought to contain optional CODE_LABEL followed
2044e4b17023SJohn Marino 	 by NOTE_BASIC_BLOCK.  */
2045e4b17023SJohn Marino       x = BB_HEAD (bb);
2046e4b17023SJohn Marino       if (LABEL_P (x))
2047e4b17023SJohn Marino 	{
2048e4b17023SJohn Marino 	  if (BB_END (bb) == x)
2049e4b17023SJohn Marino 	    {
2050e4b17023SJohn Marino 	      error ("NOTE_INSN_BASIC_BLOCK is missing for block %d",
2051e4b17023SJohn Marino 		     bb->index);
2052e4b17023SJohn Marino 	      err = 1;
2053e4b17023SJohn Marino 	    }
2054e4b17023SJohn Marino 
2055e4b17023SJohn Marino 	  x = NEXT_INSN (x);
2056e4b17023SJohn Marino 	}
2057e4b17023SJohn Marino 
2058e4b17023SJohn Marino       if (!NOTE_INSN_BASIC_BLOCK_P (x) || NOTE_BASIC_BLOCK (x) != bb)
2059e4b17023SJohn Marino 	{
2060e4b17023SJohn Marino 	  error ("NOTE_INSN_BASIC_BLOCK is missing for block %d",
2061e4b17023SJohn Marino 		 bb->index);
2062e4b17023SJohn Marino 	  err = 1;
2063e4b17023SJohn Marino 	}
2064e4b17023SJohn Marino 
2065e4b17023SJohn Marino       if (BB_END (bb) == x)
2066e4b17023SJohn Marino 	/* Do checks for empty blocks here.  */
2067e4b17023SJohn Marino 	;
2068e4b17023SJohn Marino       else
2069e4b17023SJohn Marino 	for (x = NEXT_INSN (x); x; x = NEXT_INSN (x))
2070e4b17023SJohn Marino 	  {
2071e4b17023SJohn Marino 	    if (NOTE_INSN_BASIC_BLOCK_P (x))
2072e4b17023SJohn Marino 	      {
2073e4b17023SJohn Marino 		error ("NOTE_INSN_BASIC_BLOCK %d in middle of basic block %d",
2074e4b17023SJohn Marino 		       INSN_UID (x), bb->index);
2075e4b17023SJohn Marino 		err = 1;
2076e4b17023SJohn Marino 	      }
2077e4b17023SJohn Marino 
2078e4b17023SJohn Marino 	    if (x == BB_END (bb))
2079e4b17023SJohn Marino 	      break;
2080e4b17023SJohn Marino 
2081e4b17023SJohn Marino 	    if (control_flow_insn_p (x))
2082e4b17023SJohn Marino 	      {
2083e4b17023SJohn Marino 		error ("in basic block %d:", bb->index);
2084e4b17023SJohn Marino 		fatal_insn ("flow control insn inside a basic block", x);
2085e4b17023SJohn Marino 	      }
2086e4b17023SJohn Marino 	  }
2087e4b17023SJohn Marino     }
2088e4b17023SJohn Marino 
2089e4b17023SJohn Marino   /* Clean up.  */
2090e4b17023SJohn Marino   return err;
2091e4b17023SJohn Marino }
2092e4b17023SJohn Marino 
2093e4b17023SJohn Marino /* Verify the CFG and RTL consistency common for both underlying RTL and
2094e4b17023SJohn Marino    cfglayout RTL.
2095e4b17023SJohn Marino 
2096e4b17023SJohn Marino    Currently it does following checks:
2097e4b17023SJohn Marino    - all checks of rtl_verify_flow_info_1
2098e4b17023SJohn Marino    - test head/end pointers
2099e4b17023SJohn Marino    - check that all insns are in the basic blocks
2100e4b17023SJohn Marino      (except the switch handling code, barriers and notes)
2101e4b17023SJohn Marino    - check that all returns are followed by barriers
2102e4b17023SJohn Marino    - check that all fallthru edge points to the adjacent blocks.  */
2103e4b17023SJohn Marino 
2104e4b17023SJohn Marino static int
rtl_verify_flow_info(void)2105e4b17023SJohn Marino rtl_verify_flow_info (void)
2106e4b17023SJohn Marino {
2107e4b17023SJohn Marino   basic_block bb;
2108e4b17023SJohn Marino   int err = rtl_verify_flow_info_1 ();
2109e4b17023SJohn Marino   rtx x;
2110e4b17023SJohn Marino   rtx last_head = get_last_insn ();
2111e4b17023SJohn Marino   basic_block *bb_info;
2112e4b17023SJohn Marino   int num_bb_notes;
2113e4b17023SJohn Marino   const rtx rtx_first = get_insns ();
2114e4b17023SJohn Marino   basic_block last_bb_seen = ENTRY_BLOCK_PTR, curr_bb = NULL;
2115e4b17023SJohn Marino   const int max_uid = get_max_uid ();
2116e4b17023SJohn Marino 
2117e4b17023SJohn Marino   bb_info = XCNEWVEC (basic_block, max_uid);
2118e4b17023SJohn Marino 
2119e4b17023SJohn Marino   FOR_EACH_BB_REVERSE (bb)
2120e4b17023SJohn Marino     {
2121e4b17023SJohn Marino       edge e;
2122e4b17023SJohn Marino       rtx head = BB_HEAD (bb);
2123e4b17023SJohn Marino       rtx end = BB_END (bb);
2124e4b17023SJohn Marino 
2125e4b17023SJohn Marino       for (x = last_head; x != NULL_RTX; x = PREV_INSN (x))
2126e4b17023SJohn Marino 	{
2127e4b17023SJohn Marino 	  /* Verify the end of the basic block is in the INSN chain.  */
2128e4b17023SJohn Marino 	  if (x == end)
2129e4b17023SJohn Marino 	    break;
2130e4b17023SJohn Marino 
2131e4b17023SJohn Marino 	  /* And that the code outside of basic blocks has NULL bb field.  */
2132e4b17023SJohn Marino 	if (!BARRIER_P (x)
2133e4b17023SJohn Marino 	    && BLOCK_FOR_INSN (x) != NULL)
2134e4b17023SJohn Marino 	  {
2135e4b17023SJohn Marino 	    error ("insn %d outside of basic blocks has non-NULL bb field",
2136e4b17023SJohn Marino 		   INSN_UID (x));
2137e4b17023SJohn Marino 	    err = 1;
2138e4b17023SJohn Marino 	  }
2139e4b17023SJohn Marino 	}
2140e4b17023SJohn Marino 
2141e4b17023SJohn Marino       if (!x)
2142e4b17023SJohn Marino 	{
2143e4b17023SJohn Marino 	  error ("end insn %d for block %d not found in the insn stream",
2144e4b17023SJohn Marino 		 INSN_UID (end), bb->index);
2145e4b17023SJohn Marino 	  err = 1;
2146e4b17023SJohn Marino 	}
2147e4b17023SJohn Marino 
2148e4b17023SJohn Marino       /* Work backwards from the end to the head of the basic block
2149e4b17023SJohn Marino 	 to verify the head is in the RTL chain.  */
2150e4b17023SJohn Marino       for (; x != NULL_RTX; x = PREV_INSN (x))
2151e4b17023SJohn Marino 	{
2152e4b17023SJohn Marino 	  /* While walking over the insn chain, verify insns appear
2153e4b17023SJohn Marino 	     in only one basic block.  */
2154e4b17023SJohn Marino 	  if (bb_info[INSN_UID (x)] != NULL)
2155e4b17023SJohn Marino 	    {
2156e4b17023SJohn Marino 	      error ("insn %d is in multiple basic blocks (%d and %d)",
2157e4b17023SJohn Marino 		     INSN_UID (x), bb->index, bb_info[INSN_UID (x)]->index);
2158e4b17023SJohn Marino 	      err = 1;
2159e4b17023SJohn Marino 	    }
2160e4b17023SJohn Marino 
2161e4b17023SJohn Marino 	  bb_info[INSN_UID (x)] = bb;
2162e4b17023SJohn Marino 
2163e4b17023SJohn Marino 	  if (x == head)
2164e4b17023SJohn Marino 	    break;
2165e4b17023SJohn Marino 	}
2166e4b17023SJohn Marino       if (!x)
2167e4b17023SJohn Marino 	{
2168e4b17023SJohn Marino 	  error ("head insn %d for block %d not found in the insn stream",
2169e4b17023SJohn Marino 		 INSN_UID (head), bb->index);
2170e4b17023SJohn Marino 	  err = 1;
2171e4b17023SJohn Marino 	}
2172e4b17023SJohn Marino 
2173e4b17023SJohn Marino       last_head = PREV_INSN (x);
2174e4b17023SJohn Marino 
2175e4b17023SJohn Marino       e = find_fallthru_edge (bb->succs);
2176e4b17023SJohn Marino       if (!e)
2177e4b17023SJohn Marino 	{
2178e4b17023SJohn Marino 	  rtx insn;
2179e4b17023SJohn Marino 
2180e4b17023SJohn Marino 	  /* Ensure existence of barrier in BB with no fallthru edges.  */
2181e4b17023SJohn Marino 	  for (insn = NEXT_INSN (BB_END (bb)); ; insn = NEXT_INSN (insn))
2182e4b17023SJohn Marino 	    {
2183e4b17023SJohn Marino 	      if (!insn || NOTE_INSN_BASIC_BLOCK_P (insn))
2184e4b17023SJohn Marino 		{
2185e4b17023SJohn Marino 		  error ("missing barrier after block %i", bb->index);
2186e4b17023SJohn Marino 		  err = 1;
2187e4b17023SJohn Marino 		  break;
2188e4b17023SJohn Marino 		}
2189e4b17023SJohn Marino 	      if (BARRIER_P (insn))
2190e4b17023SJohn Marino 		break;
2191e4b17023SJohn Marino 	    }
2192e4b17023SJohn Marino 	}
2193e4b17023SJohn Marino       else if (e->src != ENTRY_BLOCK_PTR
2194e4b17023SJohn Marino 	       && e->dest != EXIT_BLOCK_PTR)
2195e4b17023SJohn Marino 	{
2196e4b17023SJohn Marino 	  rtx insn;
2197e4b17023SJohn Marino 
2198e4b17023SJohn Marino 	  if (e->src->next_bb != e->dest)
2199e4b17023SJohn Marino 	    {
2200e4b17023SJohn Marino 	      error
2201e4b17023SJohn Marino 		("verify_flow_info: Incorrect blocks for fallthru %i->%i",
2202e4b17023SJohn Marino 		 e->src->index, e->dest->index);
2203e4b17023SJohn Marino 	      err = 1;
2204e4b17023SJohn Marino 	    }
2205e4b17023SJohn Marino 	  else
2206e4b17023SJohn Marino 	    for (insn = NEXT_INSN (BB_END (e->src)); insn != BB_HEAD (e->dest);
2207e4b17023SJohn Marino 		 insn = NEXT_INSN (insn))
2208e4b17023SJohn Marino 	      if (BARRIER_P (insn) || INSN_P (insn))
2209e4b17023SJohn Marino 		{
2210e4b17023SJohn Marino 		  error ("verify_flow_info: Incorrect fallthru %i->%i",
2211e4b17023SJohn Marino 			 e->src->index, e->dest->index);
2212e4b17023SJohn Marino 		  fatal_insn ("wrong insn in the fallthru edge", insn);
2213e4b17023SJohn Marino 		  err = 1;
2214e4b17023SJohn Marino 		}
2215e4b17023SJohn Marino 	}
2216e4b17023SJohn Marino     }
2217e4b17023SJohn Marino 
2218e4b17023SJohn Marino   for (x = last_head; x != NULL_RTX; x = PREV_INSN (x))
2219e4b17023SJohn Marino     {
2220e4b17023SJohn Marino       /* Check that the code before the first basic block has NULL
2221e4b17023SJohn Marino 	 bb field.  */
2222e4b17023SJohn Marino       if (!BARRIER_P (x)
2223e4b17023SJohn Marino 	  && BLOCK_FOR_INSN (x) != NULL)
2224e4b17023SJohn Marino 	{
2225e4b17023SJohn Marino 	  error ("insn %d outside of basic blocks has non-NULL bb field",
2226e4b17023SJohn Marino 		 INSN_UID (x));
2227e4b17023SJohn Marino 	  err = 1;
2228e4b17023SJohn Marino 	}
2229e4b17023SJohn Marino     }
2230e4b17023SJohn Marino   free (bb_info);
2231e4b17023SJohn Marino 
2232e4b17023SJohn Marino   num_bb_notes = 0;
2233e4b17023SJohn Marino   last_bb_seen = ENTRY_BLOCK_PTR;
2234e4b17023SJohn Marino 
2235e4b17023SJohn Marino   for (x = rtx_first; x; x = NEXT_INSN (x))
2236e4b17023SJohn Marino     {
2237e4b17023SJohn Marino       if (NOTE_INSN_BASIC_BLOCK_P (x))
2238e4b17023SJohn Marino 	{
2239e4b17023SJohn Marino 	  bb = NOTE_BASIC_BLOCK (x);
2240e4b17023SJohn Marino 
2241e4b17023SJohn Marino 	  num_bb_notes++;
2242e4b17023SJohn Marino 	  if (bb != last_bb_seen->next_bb)
2243e4b17023SJohn Marino 	    internal_error ("basic blocks not laid down consecutively");
2244e4b17023SJohn Marino 
2245e4b17023SJohn Marino 	  curr_bb = last_bb_seen = bb;
2246e4b17023SJohn Marino 	}
2247e4b17023SJohn Marino 
2248e4b17023SJohn Marino       if (!curr_bb)
2249e4b17023SJohn Marino 	{
2250e4b17023SJohn Marino 	  switch (GET_CODE (x))
2251e4b17023SJohn Marino 	    {
2252e4b17023SJohn Marino 	    case BARRIER:
2253e4b17023SJohn Marino 	    case NOTE:
2254e4b17023SJohn Marino 	      break;
2255e4b17023SJohn Marino 
2256e4b17023SJohn Marino 	    case CODE_LABEL:
2257e4b17023SJohn Marino 	      /* An addr_vec is placed outside any basic block.  */
2258e4b17023SJohn Marino 	      if (NEXT_INSN (x)
2259e4b17023SJohn Marino 		  && JUMP_TABLE_DATA_P (NEXT_INSN (x)))
2260e4b17023SJohn Marino 		x = NEXT_INSN (x);
2261e4b17023SJohn Marino 
2262e4b17023SJohn Marino 	      /* But in any case, non-deletable labels can appear anywhere.  */
2263e4b17023SJohn Marino 	      break;
2264e4b17023SJohn Marino 
2265e4b17023SJohn Marino 	    default:
2266e4b17023SJohn Marino 	      fatal_insn ("insn outside basic block", x);
2267e4b17023SJohn Marino 	    }
2268e4b17023SJohn Marino 	}
2269e4b17023SJohn Marino 
2270e4b17023SJohn Marino       if (JUMP_P (x)
2271e4b17023SJohn Marino 	  && returnjump_p (x) && ! condjump_p (x)
2272e4b17023SJohn Marino 	  && ! (next_nonnote_insn (x) && BARRIER_P (next_nonnote_insn (x))))
2273e4b17023SJohn Marino 	    fatal_insn ("return not followed by barrier", x);
2274e4b17023SJohn Marino       if (curr_bb && x == BB_END (curr_bb))
2275e4b17023SJohn Marino 	curr_bb = NULL;
2276e4b17023SJohn Marino     }
2277e4b17023SJohn Marino 
2278e4b17023SJohn Marino   if (num_bb_notes != n_basic_blocks - NUM_FIXED_BLOCKS)
2279e4b17023SJohn Marino     internal_error
2280e4b17023SJohn Marino       ("number of bb notes in insn chain (%d) != n_basic_blocks (%d)",
2281e4b17023SJohn Marino        num_bb_notes, n_basic_blocks);
2282e4b17023SJohn Marino 
2283e4b17023SJohn Marino    return err;
2284e4b17023SJohn Marino }
2285e4b17023SJohn Marino 
2286e4b17023SJohn Marino /* Assume that the preceding pass has possibly eliminated jump instructions
2287e4b17023SJohn Marino    or converted the unconditional jumps.  Eliminate the edges from CFG.
2288e4b17023SJohn Marino    Return true if any edges are eliminated.  */
2289e4b17023SJohn Marino 
2290e4b17023SJohn Marino bool
purge_dead_edges(basic_block bb)2291e4b17023SJohn Marino purge_dead_edges (basic_block bb)
2292e4b17023SJohn Marino {
2293e4b17023SJohn Marino   edge e;
2294e4b17023SJohn Marino   rtx insn = BB_END (bb), note;
2295e4b17023SJohn Marino   bool purged = false;
2296e4b17023SJohn Marino   bool found;
2297e4b17023SJohn Marino   edge_iterator ei;
2298e4b17023SJohn Marino 
2299e4b17023SJohn Marino   if (DEBUG_INSN_P (insn) && insn != BB_HEAD (bb))
2300e4b17023SJohn Marino     do
2301e4b17023SJohn Marino       insn = PREV_INSN (insn);
2302e4b17023SJohn Marino     while ((DEBUG_INSN_P (insn) || NOTE_P (insn)) && insn != BB_HEAD (bb));
2303e4b17023SJohn Marino 
2304e4b17023SJohn Marino   /* If this instruction cannot trap, remove REG_EH_REGION notes.  */
2305e4b17023SJohn Marino   if (NONJUMP_INSN_P (insn)
2306e4b17023SJohn Marino       && (note = find_reg_note (insn, REG_EH_REGION, NULL)))
2307e4b17023SJohn Marino     {
2308e4b17023SJohn Marino       rtx eqnote;
2309e4b17023SJohn Marino 
2310e4b17023SJohn Marino       if (! may_trap_p (PATTERN (insn))
2311e4b17023SJohn Marino 	  || ((eqnote = find_reg_equal_equiv_note (insn))
2312e4b17023SJohn Marino 	      && ! may_trap_p (XEXP (eqnote, 0))))
2313e4b17023SJohn Marino 	remove_note (insn, note);
2314e4b17023SJohn Marino     }
2315e4b17023SJohn Marino 
2316e4b17023SJohn Marino   /* Cleanup abnormal edges caused by exceptions or non-local gotos.  */
2317e4b17023SJohn Marino   for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
2318e4b17023SJohn Marino     {
2319e4b17023SJohn Marino       bool remove = false;
2320e4b17023SJohn Marino 
2321e4b17023SJohn Marino       /* There are three types of edges we need to handle correctly here: EH
2322e4b17023SJohn Marino 	 edges, abnormal call EH edges, and abnormal call non-EH edges.  The
2323e4b17023SJohn Marino 	 latter can appear when nonlocal gotos are used.  */
2324e4b17023SJohn Marino       if (e->flags & EDGE_ABNORMAL_CALL)
2325e4b17023SJohn Marino 	{
2326e4b17023SJohn Marino 	  if (!CALL_P (insn))
2327e4b17023SJohn Marino 	    remove = true;
2328e4b17023SJohn Marino 	  else if (can_nonlocal_goto (insn))
2329e4b17023SJohn Marino 	    ;
2330e4b17023SJohn Marino 	  else if ((e->flags & EDGE_EH) && can_throw_internal (insn))
2331e4b17023SJohn Marino 	    ;
2332e4b17023SJohn Marino 	  else if (flag_tm && find_reg_note (insn, REG_TM, NULL))
2333e4b17023SJohn Marino 	    ;
2334e4b17023SJohn Marino 	  else
2335e4b17023SJohn Marino 	    remove = true;
2336e4b17023SJohn Marino 	}
2337e4b17023SJohn Marino       else if (e->flags & EDGE_EH)
2338e4b17023SJohn Marino 	remove = !can_throw_internal (insn);
2339e4b17023SJohn Marino 
2340e4b17023SJohn Marino       if (remove)
2341e4b17023SJohn Marino 	{
2342e4b17023SJohn Marino 	  remove_edge (e);
2343e4b17023SJohn Marino 	  df_set_bb_dirty (bb);
2344e4b17023SJohn Marino 	  purged = true;
2345e4b17023SJohn Marino 	}
2346e4b17023SJohn Marino       else
2347e4b17023SJohn Marino 	ei_next (&ei);
2348e4b17023SJohn Marino     }
2349e4b17023SJohn Marino 
2350e4b17023SJohn Marino   if (JUMP_P (insn))
2351e4b17023SJohn Marino     {
2352e4b17023SJohn Marino       rtx note;
2353e4b17023SJohn Marino       edge b,f;
2354e4b17023SJohn Marino       edge_iterator ei;
2355e4b17023SJohn Marino 
2356e4b17023SJohn Marino       /* We do care only about conditional jumps and simplejumps.  */
2357e4b17023SJohn Marino       if (!any_condjump_p (insn)
2358e4b17023SJohn Marino 	  && !returnjump_p (insn)
2359e4b17023SJohn Marino 	  && !simplejump_p (insn))
2360e4b17023SJohn Marino 	return purged;
2361e4b17023SJohn Marino 
2362e4b17023SJohn Marino       /* Branch probability/prediction notes are defined only for
2363e4b17023SJohn Marino 	 condjumps.  We've possibly turned condjump into simplejump.  */
2364e4b17023SJohn Marino       if (simplejump_p (insn))
2365e4b17023SJohn Marino 	{
2366e4b17023SJohn Marino 	  note = find_reg_note (insn, REG_BR_PROB, NULL);
2367e4b17023SJohn Marino 	  if (note)
2368e4b17023SJohn Marino 	    remove_note (insn, note);
2369e4b17023SJohn Marino 	  while ((note = find_reg_note (insn, REG_BR_PRED, NULL)))
2370e4b17023SJohn Marino 	    remove_note (insn, note);
2371e4b17023SJohn Marino 	}
2372e4b17023SJohn Marino 
2373e4b17023SJohn Marino       for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
2374e4b17023SJohn Marino 	{
2375e4b17023SJohn Marino 	  /* Avoid abnormal flags to leak from computed jumps turned
2376e4b17023SJohn Marino 	     into simplejumps.  */
2377e4b17023SJohn Marino 
2378e4b17023SJohn Marino 	  e->flags &= ~EDGE_ABNORMAL;
2379e4b17023SJohn Marino 
2380e4b17023SJohn Marino 	  /* See if this edge is one we should keep.  */
2381e4b17023SJohn Marino 	  if ((e->flags & EDGE_FALLTHRU) && any_condjump_p (insn))
2382e4b17023SJohn Marino 	    /* A conditional jump can fall through into the next
2383e4b17023SJohn Marino 	       block, so we should keep the edge.  */
2384e4b17023SJohn Marino 	    {
2385e4b17023SJohn Marino 	      ei_next (&ei);
2386e4b17023SJohn Marino 	      continue;
2387e4b17023SJohn Marino 	    }
2388e4b17023SJohn Marino 	  else if (e->dest != EXIT_BLOCK_PTR
2389e4b17023SJohn Marino 		   && BB_HEAD (e->dest) == JUMP_LABEL (insn))
2390e4b17023SJohn Marino 	    /* If the destination block is the target of the jump,
2391e4b17023SJohn Marino 	       keep the edge.  */
2392e4b17023SJohn Marino 	    {
2393e4b17023SJohn Marino 	      ei_next (&ei);
2394e4b17023SJohn Marino 	      continue;
2395e4b17023SJohn Marino 	    }
2396e4b17023SJohn Marino 	  else if (e->dest == EXIT_BLOCK_PTR && returnjump_p (insn))
2397e4b17023SJohn Marino 	    /* If the destination block is the exit block, and this
2398e4b17023SJohn Marino 	       instruction is a return, then keep the edge.  */
2399e4b17023SJohn Marino 	    {
2400e4b17023SJohn Marino 	      ei_next (&ei);
2401e4b17023SJohn Marino 	      continue;
2402e4b17023SJohn Marino 	    }
2403e4b17023SJohn Marino 	  else if ((e->flags & EDGE_EH) && can_throw_internal (insn))
2404e4b17023SJohn Marino 	    /* Keep the edges that correspond to exceptions thrown by
2405e4b17023SJohn Marino 	       this instruction and rematerialize the EDGE_ABNORMAL
2406e4b17023SJohn Marino 	       flag we just cleared above.  */
2407e4b17023SJohn Marino 	    {
2408e4b17023SJohn Marino 	      e->flags |= EDGE_ABNORMAL;
2409e4b17023SJohn Marino 	      ei_next (&ei);
2410e4b17023SJohn Marino 	      continue;
2411e4b17023SJohn Marino 	    }
2412e4b17023SJohn Marino 
2413e4b17023SJohn Marino 	  /* We do not need this edge.  */
2414e4b17023SJohn Marino 	  df_set_bb_dirty (bb);
2415e4b17023SJohn Marino 	  purged = true;
2416e4b17023SJohn Marino 	  remove_edge (e);
2417e4b17023SJohn Marino 	}
2418e4b17023SJohn Marino 
2419e4b17023SJohn Marino       if (EDGE_COUNT (bb->succs) == 0 || !purged)
2420e4b17023SJohn Marino 	return purged;
2421e4b17023SJohn Marino 
2422e4b17023SJohn Marino       if (dump_file)
2423e4b17023SJohn Marino 	fprintf (dump_file, "Purged edges from bb %i\n", bb->index);
2424e4b17023SJohn Marino 
2425e4b17023SJohn Marino       if (!optimize)
2426e4b17023SJohn Marino 	return purged;
2427e4b17023SJohn Marino 
2428e4b17023SJohn Marino       /* Redistribute probabilities.  */
2429e4b17023SJohn Marino       if (single_succ_p (bb))
2430e4b17023SJohn Marino 	{
2431e4b17023SJohn Marino 	  single_succ_edge (bb)->probability = REG_BR_PROB_BASE;
2432e4b17023SJohn Marino 	  single_succ_edge (bb)->count = bb->count;
2433e4b17023SJohn Marino 	}
2434e4b17023SJohn Marino       else
2435e4b17023SJohn Marino 	{
2436e4b17023SJohn Marino 	  note = find_reg_note (insn, REG_BR_PROB, NULL);
2437e4b17023SJohn Marino 	  if (!note)
2438e4b17023SJohn Marino 	    return purged;
2439e4b17023SJohn Marino 
2440e4b17023SJohn Marino 	  b = BRANCH_EDGE (bb);
2441e4b17023SJohn Marino 	  f = FALLTHRU_EDGE (bb);
2442e4b17023SJohn Marino 	  b->probability = INTVAL (XEXP (note, 0));
2443e4b17023SJohn Marino 	  f->probability = REG_BR_PROB_BASE - b->probability;
2444e4b17023SJohn Marino 	  b->count = bb->count * b->probability / REG_BR_PROB_BASE;
2445e4b17023SJohn Marino 	  f->count = bb->count * f->probability / REG_BR_PROB_BASE;
2446e4b17023SJohn Marino 	}
2447e4b17023SJohn Marino 
2448e4b17023SJohn Marino       return purged;
2449e4b17023SJohn Marino     }
2450e4b17023SJohn Marino   else if (CALL_P (insn) && SIBLING_CALL_P (insn))
2451e4b17023SJohn Marino     {
2452e4b17023SJohn Marino       /* First, there should not be any EH or ABCALL edges resulting
2453e4b17023SJohn Marino 	 from non-local gotos and the like.  If there were, we shouldn't
2454e4b17023SJohn Marino 	 have created the sibcall in the first place.  Second, there
2455e4b17023SJohn Marino 	 should of course never have been a fallthru edge.  */
2456e4b17023SJohn Marino       gcc_assert (single_succ_p (bb));
2457e4b17023SJohn Marino       gcc_assert (single_succ_edge (bb)->flags
2458e4b17023SJohn Marino 		  == (EDGE_SIBCALL | EDGE_ABNORMAL));
2459e4b17023SJohn Marino 
2460e4b17023SJohn Marino       return 0;
2461e4b17023SJohn Marino     }
2462e4b17023SJohn Marino 
2463e4b17023SJohn Marino   /* If we don't see a jump insn, we don't know exactly why the block would
2464e4b17023SJohn Marino      have been broken at this point.  Look for a simple, non-fallthru edge,
2465e4b17023SJohn Marino      as these are only created by conditional branches.  If we find such an
2466e4b17023SJohn Marino      edge we know that there used to be a jump here and can then safely
2467e4b17023SJohn Marino      remove all non-fallthru edges.  */
2468e4b17023SJohn Marino   found = false;
2469e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, bb->succs)
2470e4b17023SJohn Marino     if (! (e->flags & (EDGE_COMPLEX | EDGE_FALLTHRU)))
2471e4b17023SJohn Marino       {
2472e4b17023SJohn Marino 	found = true;
2473e4b17023SJohn Marino 	break;
2474e4b17023SJohn Marino       }
2475e4b17023SJohn Marino 
2476e4b17023SJohn Marino   if (!found)
2477e4b17023SJohn Marino     return purged;
2478e4b17023SJohn Marino 
2479e4b17023SJohn Marino   /* Remove all but the fake and fallthru edges.  The fake edge may be
2480e4b17023SJohn Marino      the only successor for this block in the case of noreturn
2481e4b17023SJohn Marino      calls.  */
2482e4b17023SJohn Marino   for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
2483e4b17023SJohn Marino     {
2484e4b17023SJohn Marino       if (!(e->flags & (EDGE_FALLTHRU | EDGE_FAKE)))
2485e4b17023SJohn Marino 	{
2486e4b17023SJohn Marino 	  df_set_bb_dirty (bb);
2487e4b17023SJohn Marino 	  remove_edge (e);
2488e4b17023SJohn Marino 	  purged = true;
2489e4b17023SJohn Marino 	}
2490e4b17023SJohn Marino       else
2491e4b17023SJohn Marino 	ei_next (&ei);
2492e4b17023SJohn Marino     }
2493e4b17023SJohn Marino 
2494e4b17023SJohn Marino   gcc_assert (single_succ_p (bb));
2495e4b17023SJohn Marino 
2496e4b17023SJohn Marino   single_succ_edge (bb)->probability = REG_BR_PROB_BASE;
2497e4b17023SJohn Marino   single_succ_edge (bb)->count = bb->count;
2498e4b17023SJohn Marino 
2499e4b17023SJohn Marino   if (dump_file)
2500e4b17023SJohn Marino     fprintf (dump_file, "Purged non-fallthru edges from bb %i\n",
2501e4b17023SJohn Marino 	     bb->index);
2502e4b17023SJohn Marino   return purged;
2503e4b17023SJohn Marino }
2504e4b17023SJohn Marino 
2505e4b17023SJohn Marino /* Search all basic blocks for potentially dead edges and purge them.  Return
2506e4b17023SJohn Marino    true if some edge has been eliminated.  */
2507e4b17023SJohn Marino 
2508e4b17023SJohn Marino bool
purge_all_dead_edges(void)2509e4b17023SJohn Marino purge_all_dead_edges (void)
2510e4b17023SJohn Marino {
2511e4b17023SJohn Marino   int purged = false;
2512e4b17023SJohn Marino   basic_block bb;
2513e4b17023SJohn Marino 
2514e4b17023SJohn Marino   FOR_EACH_BB (bb)
2515e4b17023SJohn Marino     {
2516e4b17023SJohn Marino       bool purged_here = purge_dead_edges (bb);
2517e4b17023SJohn Marino 
2518e4b17023SJohn Marino       purged |= purged_here;
2519e4b17023SJohn Marino     }
2520e4b17023SJohn Marino 
2521e4b17023SJohn Marino   return purged;
2522e4b17023SJohn Marino }
2523e4b17023SJohn Marino 
2524e4b17023SJohn Marino /* This is used by a few passes that emit some instructions after abnormal
2525e4b17023SJohn Marino    calls, moving the basic block's end, while they in fact do want to emit
2526e4b17023SJohn Marino    them on the fallthru edge.  Look for abnormal call edges, find backward
2527e4b17023SJohn Marino    the call in the block and insert the instructions on the edge instead.
2528e4b17023SJohn Marino 
2529e4b17023SJohn Marino    Similarly, handle instructions throwing exceptions internally.
2530e4b17023SJohn Marino 
2531e4b17023SJohn Marino    Return true when instructions have been found and inserted on edges.  */
2532e4b17023SJohn Marino 
2533e4b17023SJohn Marino bool
fixup_abnormal_edges(void)2534e4b17023SJohn Marino fixup_abnormal_edges (void)
2535e4b17023SJohn Marino {
2536e4b17023SJohn Marino   bool inserted = false;
2537e4b17023SJohn Marino   basic_block bb;
2538e4b17023SJohn Marino 
2539e4b17023SJohn Marino   FOR_EACH_BB (bb)
2540e4b17023SJohn Marino     {
2541e4b17023SJohn Marino       edge e;
2542e4b17023SJohn Marino       edge_iterator ei;
2543e4b17023SJohn Marino 
2544e4b17023SJohn Marino       /* Look for cases we are interested in - calls or instructions causing
2545e4b17023SJohn Marino          exceptions.  */
2546e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, bb->succs)
2547e4b17023SJohn Marino 	if ((e->flags & EDGE_ABNORMAL_CALL)
2548e4b17023SJohn Marino 	    || ((e->flags & (EDGE_ABNORMAL | EDGE_EH))
2549e4b17023SJohn Marino 		== (EDGE_ABNORMAL | EDGE_EH)))
2550e4b17023SJohn Marino 	  break;
2551e4b17023SJohn Marino 
2552e4b17023SJohn Marino       if (e && !CALL_P (BB_END (bb)) && !can_throw_internal (BB_END (bb)))
2553e4b17023SJohn Marino 	{
2554e4b17023SJohn Marino 	  rtx insn;
2555e4b17023SJohn Marino 
2556e4b17023SJohn Marino 	  /* Get past the new insns generated.  Allow notes, as the insns
2557e4b17023SJohn Marino 	     may be already deleted.  */
2558e4b17023SJohn Marino 	  insn = BB_END (bb);
2559e4b17023SJohn Marino 	  while ((NONJUMP_INSN_P (insn) || NOTE_P (insn))
2560e4b17023SJohn Marino 		 && !can_throw_internal (insn)
2561e4b17023SJohn Marino 		 && insn != BB_HEAD (bb))
2562e4b17023SJohn Marino 	    insn = PREV_INSN (insn);
2563e4b17023SJohn Marino 
2564e4b17023SJohn Marino 	  if (CALL_P (insn) || can_throw_internal (insn))
2565e4b17023SJohn Marino 	    {
2566e4b17023SJohn Marino 	      rtx stop, next;
2567e4b17023SJohn Marino 
2568e4b17023SJohn Marino 	      e = find_fallthru_edge (bb->succs);
2569e4b17023SJohn Marino 
2570e4b17023SJohn Marino 	      stop = NEXT_INSN (BB_END (bb));
2571e4b17023SJohn Marino 	      BB_END (bb) = insn;
2572e4b17023SJohn Marino 
2573e4b17023SJohn Marino 	      for (insn = NEXT_INSN (insn); insn != stop; insn = next)
2574e4b17023SJohn Marino 		{
2575e4b17023SJohn Marino 		  next = NEXT_INSN (insn);
2576e4b17023SJohn Marino 		  if (INSN_P (insn))
2577e4b17023SJohn Marino 		    {
2578e4b17023SJohn Marino 		      delete_insn (insn);
2579e4b17023SJohn Marino 
2580e4b17023SJohn Marino 		      /* Sometimes there's still the return value USE.
2581e4b17023SJohn Marino 			 If it's placed after a trapping call (i.e. that
2582e4b17023SJohn Marino 			 call is the last insn anyway), we have no fallthru
2583e4b17023SJohn Marino 			 edge.  Simply delete this use and don't try to insert
2584e4b17023SJohn Marino 			 on the non-existent edge.  */
2585e4b17023SJohn Marino 		      if (GET_CODE (PATTERN (insn)) != USE)
2586e4b17023SJohn Marino 			{
2587e4b17023SJohn Marino 			  /* We're not deleting it, we're moving it.  */
2588e4b17023SJohn Marino 			  INSN_DELETED_P (insn) = 0;
2589e4b17023SJohn Marino 			  PREV_INSN (insn) = NULL_RTX;
2590e4b17023SJohn Marino 			  NEXT_INSN (insn) = NULL_RTX;
2591e4b17023SJohn Marino 
2592e4b17023SJohn Marino 			  insert_insn_on_edge (insn, e);
2593e4b17023SJohn Marino 			  inserted = true;
2594e4b17023SJohn Marino 			}
2595e4b17023SJohn Marino 		    }
2596e4b17023SJohn Marino 		  else if (!BARRIER_P (insn))
2597e4b17023SJohn Marino 		    set_block_for_insn (insn, NULL);
2598e4b17023SJohn Marino 		}
2599e4b17023SJohn Marino 	    }
2600e4b17023SJohn Marino 
2601e4b17023SJohn Marino 	  /* It may be that we don't find any trapping insn.  In this
2602e4b17023SJohn Marino 	     case we discovered quite late that the insn that had been
2603e4b17023SJohn Marino 	     marked as can_throw_internal in fact couldn't trap at all.
2604e4b17023SJohn Marino 	     So we should in fact delete the EH edges out of the block.  */
2605e4b17023SJohn Marino 	  else
2606e4b17023SJohn Marino 	    purge_dead_edges (bb);
2607e4b17023SJohn Marino 	}
2608e4b17023SJohn Marino     }
2609e4b17023SJohn Marino 
2610e4b17023SJohn Marino   return inserted;
2611e4b17023SJohn Marino }
2612e4b17023SJohn Marino 
2613e4b17023SJohn Marino /* Same as split_block but update cfg_layout structures.  */
2614e4b17023SJohn Marino 
2615e4b17023SJohn Marino static basic_block
cfg_layout_split_block(basic_block bb,void * insnp)2616e4b17023SJohn Marino cfg_layout_split_block (basic_block bb, void *insnp)
2617e4b17023SJohn Marino {
2618e4b17023SJohn Marino   rtx insn = (rtx) insnp;
2619e4b17023SJohn Marino   basic_block new_bb = rtl_split_block (bb, insn);
2620e4b17023SJohn Marino 
2621e4b17023SJohn Marino   new_bb->il.rtl->footer = bb->il.rtl->footer;
2622e4b17023SJohn Marino   bb->il.rtl->footer = NULL;
2623e4b17023SJohn Marino 
2624e4b17023SJohn Marino   return new_bb;
2625e4b17023SJohn Marino }
2626e4b17023SJohn Marino 
2627e4b17023SJohn Marino /* Redirect Edge to DEST.  */
2628e4b17023SJohn Marino static edge
cfg_layout_redirect_edge_and_branch(edge e,basic_block dest)2629e4b17023SJohn Marino cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
2630e4b17023SJohn Marino {
2631e4b17023SJohn Marino   basic_block src = e->src;
2632e4b17023SJohn Marino   edge ret;
2633e4b17023SJohn Marino 
2634e4b17023SJohn Marino   if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
2635e4b17023SJohn Marino     return NULL;
2636e4b17023SJohn Marino 
2637e4b17023SJohn Marino   if (e->dest == dest)
2638e4b17023SJohn Marino     return e;
2639e4b17023SJohn Marino 
2640e4b17023SJohn Marino   if (e->src != ENTRY_BLOCK_PTR
2641e4b17023SJohn Marino       && (ret = try_redirect_by_replacing_jump (e, dest, true)))
2642e4b17023SJohn Marino     {
2643e4b17023SJohn Marino       df_set_bb_dirty (src);
2644e4b17023SJohn Marino       return ret;
2645e4b17023SJohn Marino     }
2646e4b17023SJohn Marino 
2647e4b17023SJohn Marino   if (e->src == ENTRY_BLOCK_PTR
2648e4b17023SJohn Marino       && (e->flags & EDGE_FALLTHRU) && !(e->flags & EDGE_COMPLEX))
2649e4b17023SJohn Marino     {
2650e4b17023SJohn Marino       if (dump_file)
2651e4b17023SJohn Marino 	fprintf (dump_file, "Redirecting entry edge from bb %i to %i\n",
2652e4b17023SJohn Marino 		 e->src->index, dest->index);
2653e4b17023SJohn Marino 
2654e4b17023SJohn Marino       df_set_bb_dirty (e->src);
2655e4b17023SJohn Marino       redirect_edge_succ (e, dest);
2656e4b17023SJohn Marino       return e;
2657e4b17023SJohn Marino     }
2658e4b17023SJohn Marino 
2659e4b17023SJohn Marino   /* Redirect_edge_and_branch may decide to turn branch into fallthru edge
2660e4b17023SJohn Marino      in the case the basic block appears to be in sequence.  Avoid this
2661e4b17023SJohn Marino      transformation.  */
2662e4b17023SJohn Marino 
2663e4b17023SJohn Marino   if (e->flags & EDGE_FALLTHRU)
2664e4b17023SJohn Marino     {
2665e4b17023SJohn Marino       /* Redirect any branch edges unified with the fallthru one.  */
2666e4b17023SJohn Marino       if (JUMP_P (BB_END (src))
2667e4b17023SJohn Marino 	  && label_is_jump_target_p (BB_HEAD (e->dest),
2668e4b17023SJohn Marino 				     BB_END (src)))
2669e4b17023SJohn Marino 	{
2670e4b17023SJohn Marino 	  edge redirected;
2671e4b17023SJohn Marino 
2672e4b17023SJohn Marino 	  if (dump_file)
2673e4b17023SJohn Marino 	    fprintf (dump_file, "Fallthru edge unified with branch "
2674e4b17023SJohn Marino 		     "%i->%i redirected to %i\n",
2675e4b17023SJohn Marino 		     e->src->index, e->dest->index, dest->index);
2676e4b17023SJohn Marino 	  e->flags &= ~EDGE_FALLTHRU;
2677e4b17023SJohn Marino 	  redirected = redirect_branch_edge (e, dest);
2678e4b17023SJohn Marino 	  gcc_assert (redirected);
2679e4b17023SJohn Marino 	  redirected->flags |= EDGE_FALLTHRU;
2680e4b17023SJohn Marino 	  df_set_bb_dirty (redirected->src);
2681e4b17023SJohn Marino 	  return redirected;
2682e4b17023SJohn Marino 	}
2683e4b17023SJohn Marino       /* In case we are redirecting fallthru edge to the branch edge
2684e4b17023SJohn Marino 	 of conditional jump, remove it.  */
2685e4b17023SJohn Marino       if (EDGE_COUNT (src->succs) == 2)
2686e4b17023SJohn Marino 	{
2687e4b17023SJohn Marino 	  /* Find the edge that is different from E.  */
2688e4b17023SJohn Marino 	  edge s = EDGE_SUCC (src, EDGE_SUCC (src, 0) == e);
2689e4b17023SJohn Marino 
2690e4b17023SJohn Marino 	  if (s->dest == dest
2691e4b17023SJohn Marino 	      && any_condjump_p (BB_END (src))
2692e4b17023SJohn Marino 	      && onlyjump_p (BB_END (src)))
2693e4b17023SJohn Marino 	    delete_insn (BB_END (src));
2694e4b17023SJohn Marino 	}
2695e4b17023SJohn Marino       if (dump_file)
2696e4b17023SJohn Marino 	fprintf (dump_file, "Redirecting fallthru edge %i->%i to %i\n",
2697e4b17023SJohn Marino 		 e->src->index, e->dest->index, dest->index);
2698e4b17023SJohn Marino       ret = redirect_edge_succ_nodup (e, dest);
2699e4b17023SJohn Marino     }
2700e4b17023SJohn Marino   else
2701e4b17023SJohn Marino     ret = redirect_branch_edge (e, dest);
2702e4b17023SJohn Marino 
2703e4b17023SJohn Marino   /* We don't want simplejumps in the insn stream during cfglayout.  */
2704e4b17023SJohn Marino   gcc_assert (!simplejump_p (BB_END (src)));
2705e4b17023SJohn Marino 
2706e4b17023SJohn Marino   df_set_bb_dirty (src);
2707e4b17023SJohn Marino   return ret;
2708e4b17023SJohn Marino }
2709e4b17023SJohn Marino 
2710e4b17023SJohn Marino /* Simple wrapper as we always can redirect fallthru edges.  */
2711e4b17023SJohn Marino static basic_block
cfg_layout_redirect_edge_and_branch_force(edge e,basic_block dest)2712e4b17023SJohn Marino cfg_layout_redirect_edge_and_branch_force (edge e, basic_block dest)
2713e4b17023SJohn Marino {
2714e4b17023SJohn Marino   edge redirected = cfg_layout_redirect_edge_and_branch (e, dest);
2715e4b17023SJohn Marino 
2716e4b17023SJohn Marino   gcc_assert (redirected);
2717e4b17023SJohn Marino   return NULL;
2718e4b17023SJohn Marino }
2719e4b17023SJohn Marino 
2720e4b17023SJohn Marino /* Same as delete_basic_block but update cfg_layout structures.  */
2721e4b17023SJohn Marino 
2722e4b17023SJohn Marino static void
cfg_layout_delete_block(basic_block bb)2723e4b17023SJohn Marino cfg_layout_delete_block (basic_block bb)
2724e4b17023SJohn Marino {
2725e4b17023SJohn Marino   rtx insn, next, prev = PREV_INSN (BB_HEAD (bb)), *to, remaints;
2726e4b17023SJohn Marino 
2727e4b17023SJohn Marino   if (bb->il.rtl->header)
2728e4b17023SJohn Marino     {
2729e4b17023SJohn Marino       next = BB_HEAD (bb);
2730e4b17023SJohn Marino       if (prev)
2731e4b17023SJohn Marino 	NEXT_INSN (prev) = bb->il.rtl->header;
2732e4b17023SJohn Marino       else
2733e4b17023SJohn Marino 	set_first_insn (bb->il.rtl->header);
2734e4b17023SJohn Marino       PREV_INSN (bb->il.rtl->header) = prev;
2735e4b17023SJohn Marino       insn = bb->il.rtl->header;
2736e4b17023SJohn Marino       while (NEXT_INSN (insn))
2737e4b17023SJohn Marino 	insn = NEXT_INSN (insn);
2738e4b17023SJohn Marino       NEXT_INSN (insn) = next;
2739e4b17023SJohn Marino       PREV_INSN (next) = insn;
2740e4b17023SJohn Marino     }
2741e4b17023SJohn Marino   next = NEXT_INSN (BB_END (bb));
2742e4b17023SJohn Marino   if (bb->il.rtl->footer)
2743e4b17023SJohn Marino     {
2744e4b17023SJohn Marino       insn = bb->il.rtl->footer;
2745e4b17023SJohn Marino       while (insn)
2746e4b17023SJohn Marino 	{
2747e4b17023SJohn Marino 	  if (BARRIER_P (insn))
2748e4b17023SJohn Marino 	    {
2749e4b17023SJohn Marino 	      if (PREV_INSN (insn))
2750e4b17023SJohn Marino 		NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
2751e4b17023SJohn Marino 	      else
2752e4b17023SJohn Marino 		bb->il.rtl->footer = NEXT_INSN (insn);
2753e4b17023SJohn Marino 	      if (NEXT_INSN (insn))
2754e4b17023SJohn Marino 		PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
2755e4b17023SJohn Marino 	    }
2756e4b17023SJohn Marino 	  if (LABEL_P (insn))
2757e4b17023SJohn Marino 	    break;
2758e4b17023SJohn Marino 	  insn = NEXT_INSN (insn);
2759e4b17023SJohn Marino 	}
2760e4b17023SJohn Marino       if (bb->il.rtl->footer)
2761e4b17023SJohn Marino 	{
2762e4b17023SJohn Marino 	  insn = BB_END (bb);
2763e4b17023SJohn Marino 	  NEXT_INSN (insn) = bb->il.rtl->footer;
2764e4b17023SJohn Marino 	  PREV_INSN (bb->il.rtl->footer) = insn;
2765e4b17023SJohn Marino 	  while (NEXT_INSN (insn))
2766e4b17023SJohn Marino 	    insn = NEXT_INSN (insn);
2767e4b17023SJohn Marino 	  NEXT_INSN (insn) = next;
2768e4b17023SJohn Marino 	  if (next)
2769e4b17023SJohn Marino 	    PREV_INSN (next) = insn;
2770e4b17023SJohn Marino 	  else
2771e4b17023SJohn Marino 	    set_last_insn (insn);
2772e4b17023SJohn Marino 	}
2773e4b17023SJohn Marino     }
2774e4b17023SJohn Marino   if (bb->next_bb != EXIT_BLOCK_PTR)
2775e4b17023SJohn Marino     to = &bb->next_bb->il.rtl->header;
2776e4b17023SJohn Marino   else
2777e4b17023SJohn Marino     to = &cfg_layout_function_footer;
2778e4b17023SJohn Marino 
2779e4b17023SJohn Marino   rtl_delete_block (bb);
2780e4b17023SJohn Marino 
2781e4b17023SJohn Marino   if (prev)
2782e4b17023SJohn Marino     prev = NEXT_INSN (prev);
2783e4b17023SJohn Marino   else
2784e4b17023SJohn Marino     prev = get_insns ();
2785e4b17023SJohn Marino   if (next)
2786e4b17023SJohn Marino     next = PREV_INSN (next);
2787e4b17023SJohn Marino   else
2788e4b17023SJohn Marino     next = get_last_insn ();
2789e4b17023SJohn Marino 
2790e4b17023SJohn Marino   if (next && NEXT_INSN (next) != prev)
2791e4b17023SJohn Marino     {
2792e4b17023SJohn Marino       remaints = unlink_insn_chain (prev, next);
2793e4b17023SJohn Marino       insn = remaints;
2794e4b17023SJohn Marino       while (NEXT_INSN (insn))
2795e4b17023SJohn Marino 	insn = NEXT_INSN (insn);
2796e4b17023SJohn Marino       NEXT_INSN (insn) = *to;
2797e4b17023SJohn Marino       if (*to)
2798e4b17023SJohn Marino 	PREV_INSN (*to) = insn;
2799e4b17023SJohn Marino       *to = remaints;
2800e4b17023SJohn Marino     }
2801e4b17023SJohn Marino }
2802e4b17023SJohn Marino 
2803e4b17023SJohn Marino /* Return true when blocks A and B can be safely merged.  */
2804e4b17023SJohn Marino 
2805e4b17023SJohn Marino static bool
cfg_layout_can_merge_blocks_p(basic_block a,basic_block b)2806e4b17023SJohn Marino cfg_layout_can_merge_blocks_p (basic_block a, basic_block b)
2807e4b17023SJohn Marino {
2808e4b17023SJohn Marino   /* If we are partitioning hot/cold basic blocks, we don't want to
2809e4b17023SJohn Marino      mess up unconditional or indirect jumps that cross between hot
2810e4b17023SJohn Marino      and cold sections.
2811e4b17023SJohn Marino 
2812e4b17023SJohn Marino      Basic block partitioning may result in some jumps that appear to
2813e4b17023SJohn Marino      be optimizable (or blocks that appear to be mergeable), but which really
2814e4b17023SJohn Marino      must be left untouched (they are required to make it safely across
2815e4b17023SJohn Marino      partition boundaries).  See  the comments at the top of
2816e4b17023SJohn Marino      bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
2817e4b17023SJohn Marino 
2818e4b17023SJohn Marino   if (BB_PARTITION (a) != BB_PARTITION (b))
2819e4b17023SJohn Marino     return false;
2820e4b17023SJohn Marino 
2821e4b17023SJohn Marino   /* If we would end up moving B's instructions, make sure it doesn't fall
2822e4b17023SJohn Marino      through into the exit block, since we cannot recover from a fallthrough
2823e4b17023SJohn Marino      edge into the exit block occurring in the middle of a function.  */
2824e4b17023SJohn Marino   if (NEXT_INSN (BB_END (a)) != BB_HEAD (b))
2825e4b17023SJohn Marino     {
2826e4b17023SJohn Marino       edge e = find_fallthru_edge (b->succs);
2827e4b17023SJohn Marino       if (e && e->dest == EXIT_BLOCK_PTR)
2828e4b17023SJohn Marino 	return false;
2829e4b17023SJohn Marino     }
2830e4b17023SJohn Marino 
2831e4b17023SJohn Marino   /* There must be exactly one edge in between the blocks.  */
2832e4b17023SJohn Marino   return (single_succ_p (a)
2833e4b17023SJohn Marino 	  && single_succ (a) == b
2834e4b17023SJohn Marino 	  && single_pred_p (b) == 1
2835e4b17023SJohn Marino 	  && a != b
2836e4b17023SJohn Marino 	  /* Must be simple edge.  */
2837e4b17023SJohn Marino 	  && !(single_succ_edge (a)->flags & EDGE_COMPLEX)
2838e4b17023SJohn Marino 	  && a != ENTRY_BLOCK_PTR && b != EXIT_BLOCK_PTR
2839e4b17023SJohn Marino 	  /* If the jump insn has side effects, we can't kill the edge.
2840e4b17023SJohn Marino 	     When not optimizing, try_redirect_by_replacing_jump will
2841e4b17023SJohn Marino 	     not allow us to redirect an edge by replacing a table jump.  */
2842e4b17023SJohn Marino 	  && (!JUMP_P (BB_END (a))
2843e4b17023SJohn Marino 	      || ((!optimize || reload_completed)
2844e4b17023SJohn Marino 		  ? simplejump_p (BB_END (a)) : onlyjump_p (BB_END (a)))));
2845e4b17023SJohn Marino }
2846e4b17023SJohn Marino 
2847e4b17023SJohn Marino /* Merge block A and B.  The blocks must be mergeable.  */
2848e4b17023SJohn Marino 
2849e4b17023SJohn Marino static void
cfg_layout_merge_blocks(basic_block a,basic_block b)2850e4b17023SJohn Marino cfg_layout_merge_blocks (basic_block a, basic_block b)
2851e4b17023SJohn Marino {
2852e4b17023SJohn Marino   bool forwarder_p = (b->flags & BB_FORWARDER_BLOCK) != 0;
2853e4b17023SJohn Marino 
2854e4b17023SJohn Marino   gcc_checking_assert (cfg_layout_can_merge_blocks_p (a, b));
2855e4b17023SJohn Marino 
2856e4b17023SJohn Marino   if (dump_file)
2857e4b17023SJohn Marino     fprintf (dump_file, "Merging block %d into block %d...\n", b->index,
2858e4b17023SJohn Marino 			 a->index);
2859e4b17023SJohn Marino 
2860e4b17023SJohn Marino   /* If there was a CODE_LABEL beginning B, delete it.  */
2861e4b17023SJohn Marino   if (LABEL_P (BB_HEAD (b)))
2862e4b17023SJohn Marino     {
2863e4b17023SJohn Marino       delete_insn (BB_HEAD (b));
2864e4b17023SJohn Marino     }
2865e4b17023SJohn Marino 
2866e4b17023SJohn Marino   /* We should have fallthru edge in a, or we can do dummy redirection to get
2867e4b17023SJohn Marino      it cleaned up.  */
2868e4b17023SJohn Marino   if (JUMP_P (BB_END (a)))
2869e4b17023SJohn Marino     try_redirect_by_replacing_jump (EDGE_SUCC (a, 0), b, true);
2870e4b17023SJohn Marino   gcc_assert (!JUMP_P (BB_END (a)));
2871e4b17023SJohn Marino 
2872e4b17023SJohn Marino   /* When not optimizing and the edge is the only place in RTL which holds
2873e4b17023SJohn Marino      some unique locus, emit a nop with that locus in between.  */
2874e4b17023SJohn Marino   if (!optimize && EDGE_SUCC (a, 0)->goto_locus)
2875e4b17023SJohn Marino     {
2876e4b17023SJohn Marino       rtx insn = BB_END (a), end = PREV_INSN (BB_HEAD (a));
2877e4b17023SJohn Marino       int goto_locus = EDGE_SUCC (a, 0)->goto_locus;
2878e4b17023SJohn Marino 
2879e4b17023SJohn Marino       while (insn != end && (!INSN_P (insn) || INSN_LOCATOR (insn) == 0))
2880e4b17023SJohn Marino 	insn = PREV_INSN (insn);
2881e4b17023SJohn Marino       if (insn != end && locator_eq (INSN_LOCATOR (insn), goto_locus))
2882e4b17023SJohn Marino 	goto_locus = 0;
2883e4b17023SJohn Marino       else
2884e4b17023SJohn Marino 	{
2885e4b17023SJohn Marino 	  insn = BB_HEAD (b);
2886e4b17023SJohn Marino 	  end = NEXT_INSN (BB_END (b));
2887e4b17023SJohn Marino 	  while (insn != end && !INSN_P (insn))
2888e4b17023SJohn Marino 	    insn = NEXT_INSN (insn);
2889e4b17023SJohn Marino 	  if (insn != end && INSN_LOCATOR (insn) != 0
2890e4b17023SJohn Marino 	      && locator_eq (INSN_LOCATOR (insn), goto_locus))
2891e4b17023SJohn Marino 	    goto_locus = 0;
2892e4b17023SJohn Marino 	}
2893e4b17023SJohn Marino       if (goto_locus)
2894e4b17023SJohn Marino 	{
2895e4b17023SJohn Marino 	  BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
2896e4b17023SJohn Marino 	  INSN_LOCATOR (BB_END (a)) = goto_locus;
2897e4b17023SJohn Marino 	}
2898e4b17023SJohn Marino     }
2899e4b17023SJohn Marino 
2900e4b17023SJohn Marino   /* Possible line number notes should appear in between.  */
2901e4b17023SJohn Marino   if (b->il.rtl->header)
2902e4b17023SJohn Marino     {
2903e4b17023SJohn Marino       rtx first = BB_END (a), last;
2904e4b17023SJohn Marino 
2905e4b17023SJohn Marino       last = emit_insn_after_noloc (b->il.rtl->header, BB_END (a), a);
2906e4b17023SJohn Marino       /* The above might add a BARRIER as BB_END, but as barriers
2907e4b17023SJohn Marino 	 aren't valid parts of a bb, remove_insn doesn't update
2908e4b17023SJohn Marino 	 BB_END if it is a barrier.  So adjust BB_END here.  */
2909e4b17023SJohn Marino       while (BB_END (a) != first && BARRIER_P (BB_END (a)))
2910e4b17023SJohn Marino 	BB_END (a) = PREV_INSN (BB_END (a));
2911e4b17023SJohn Marino       delete_insn_chain (NEXT_INSN (first), last, false);
2912e4b17023SJohn Marino       b->il.rtl->header = NULL;
2913e4b17023SJohn Marino     }
2914e4b17023SJohn Marino 
2915e4b17023SJohn Marino   /* In the case basic blocks are not adjacent, move them around.  */
2916e4b17023SJohn Marino   if (NEXT_INSN (BB_END (a)) != BB_HEAD (b))
2917e4b17023SJohn Marino     {
2918e4b17023SJohn Marino       rtx first = unlink_insn_chain (BB_HEAD (b), BB_END (b));
2919e4b17023SJohn Marino 
2920e4b17023SJohn Marino       emit_insn_after_noloc (first, BB_END (a), a);
2921e4b17023SJohn Marino       /* Skip possible DELETED_LABEL insn.  */
2922e4b17023SJohn Marino       if (!NOTE_INSN_BASIC_BLOCK_P (first))
2923e4b17023SJohn Marino 	first = NEXT_INSN (first);
2924e4b17023SJohn Marino       gcc_assert (NOTE_INSN_BASIC_BLOCK_P (first));
2925e4b17023SJohn Marino       BB_HEAD (b) = NULL;
2926e4b17023SJohn Marino 
2927e4b17023SJohn Marino       /* emit_insn_after_noloc doesn't call df_insn_change_bb.
2928e4b17023SJohn Marino          We need to explicitly call. */
2929e4b17023SJohn Marino       update_bb_for_insn_chain (NEXT_INSN (first),
2930e4b17023SJohn Marino 				BB_END (b),
2931e4b17023SJohn Marino 				a);
2932e4b17023SJohn Marino 
2933e4b17023SJohn Marino       delete_insn (first);
2934e4b17023SJohn Marino     }
2935e4b17023SJohn Marino   /* Otherwise just re-associate the instructions.  */
2936e4b17023SJohn Marino   else
2937e4b17023SJohn Marino     {
2938e4b17023SJohn Marino       rtx insn;
2939e4b17023SJohn Marino 
2940e4b17023SJohn Marino       update_bb_for_insn_chain (BB_HEAD (b), BB_END (b), a);
2941e4b17023SJohn Marino 
2942e4b17023SJohn Marino       insn = BB_HEAD (b);
2943e4b17023SJohn Marino       /* Skip possible DELETED_LABEL insn.  */
2944e4b17023SJohn Marino       if (!NOTE_INSN_BASIC_BLOCK_P (insn))
2945e4b17023SJohn Marino 	insn = NEXT_INSN (insn);
2946e4b17023SJohn Marino       gcc_assert (NOTE_INSN_BASIC_BLOCK_P (insn));
2947e4b17023SJohn Marino       BB_HEAD (b) = NULL;
2948e4b17023SJohn Marino       BB_END (a) = BB_END (b);
2949e4b17023SJohn Marino       delete_insn (insn);
2950e4b17023SJohn Marino     }
2951e4b17023SJohn Marino 
2952e4b17023SJohn Marino   df_bb_delete (b->index);
2953e4b17023SJohn Marino 
2954e4b17023SJohn Marino   /* Possible tablejumps and barriers should appear after the block.  */
2955e4b17023SJohn Marino   if (b->il.rtl->footer)
2956e4b17023SJohn Marino     {
2957e4b17023SJohn Marino       if (!a->il.rtl->footer)
2958e4b17023SJohn Marino 	a->il.rtl->footer = b->il.rtl->footer;
2959e4b17023SJohn Marino       else
2960e4b17023SJohn Marino 	{
2961e4b17023SJohn Marino 	  rtx last = a->il.rtl->footer;
2962e4b17023SJohn Marino 
2963e4b17023SJohn Marino 	  while (NEXT_INSN (last))
2964e4b17023SJohn Marino 	    last = NEXT_INSN (last);
2965e4b17023SJohn Marino 	  NEXT_INSN (last) = b->il.rtl->footer;
2966e4b17023SJohn Marino 	  PREV_INSN (b->il.rtl->footer) = last;
2967e4b17023SJohn Marino 	}
2968e4b17023SJohn Marino       b->il.rtl->footer = NULL;
2969e4b17023SJohn Marino     }
2970e4b17023SJohn Marino 
2971e4b17023SJohn Marino   /* If B was a forwarder block, propagate the locus on the edge.  */
2972e4b17023SJohn Marino   if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
2973e4b17023SJohn Marino     EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;
2974e4b17023SJohn Marino 
2975e4b17023SJohn Marino   if (dump_file)
2976e4b17023SJohn Marino     fprintf (dump_file, "Merged blocks %d and %d.\n", a->index, b->index);
2977e4b17023SJohn Marino }
2978e4b17023SJohn Marino 
2979e4b17023SJohn Marino /* Split edge E.  */
2980e4b17023SJohn Marino 
2981e4b17023SJohn Marino static basic_block
cfg_layout_split_edge(edge e)2982e4b17023SJohn Marino cfg_layout_split_edge (edge e)
2983e4b17023SJohn Marino {
2984e4b17023SJohn Marino   basic_block new_bb =
2985e4b17023SJohn Marino     create_basic_block (e->src != ENTRY_BLOCK_PTR
2986e4b17023SJohn Marino 			? NEXT_INSN (BB_END (e->src)) : get_insns (),
2987e4b17023SJohn Marino 			NULL_RTX, e->src);
2988e4b17023SJohn Marino 
2989e4b17023SJohn Marino   if (e->dest == EXIT_BLOCK_PTR)
2990e4b17023SJohn Marino     BB_COPY_PARTITION (new_bb, e->src);
2991e4b17023SJohn Marino   else
2992e4b17023SJohn Marino     BB_COPY_PARTITION (new_bb, e->dest);
2993e4b17023SJohn Marino   make_edge (new_bb, e->dest, EDGE_FALLTHRU);
2994e4b17023SJohn Marino   redirect_edge_and_branch_force (e, new_bb);
2995e4b17023SJohn Marino 
2996e4b17023SJohn Marino   return new_bb;
2997e4b17023SJohn Marino }
2998e4b17023SJohn Marino 
2999e4b17023SJohn Marino /* Do postprocessing after making a forwarder block joined by edge FALLTHRU.  */
3000e4b17023SJohn Marino 
3001e4b17023SJohn Marino static void
rtl_make_forwarder_block(edge fallthru ATTRIBUTE_UNUSED)3002e4b17023SJohn Marino rtl_make_forwarder_block (edge fallthru ATTRIBUTE_UNUSED)
3003e4b17023SJohn Marino {
3004e4b17023SJohn Marino }
3005e4b17023SJohn Marino 
3006e4b17023SJohn Marino /* Return 1 if BB ends with a call, possibly followed by some
3007e4b17023SJohn Marino    instructions that must stay with the call, 0 otherwise.  */
3008e4b17023SJohn Marino 
3009e4b17023SJohn Marino static bool
rtl_block_ends_with_call_p(basic_block bb)3010e4b17023SJohn Marino rtl_block_ends_with_call_p (basic_block bb)
3011e4b17023SJohn Marino {
3012e4b17023SJohn Marino   rtx insn = BB_END (bb);
3013e4b17023SJohn Marino 
3014e4b17023SJohn Marino   while (!CALL_P (insn)
3015e4b17023SJohn Marino 	 && insn != BB_HEAD (bb)
3016e4b17023SJohn Marino 	 && (keep_with_call_p (insn)
3017e4b17023SJohn Marino 	     || NOTE_P (insn)
3018e4b17023SJohn Marino 	     || DEBUG_INSN_P (insn)))
3019e4b17023SJohn Marino     insn = PREV_INSN (insn);
3020e4b17023SJohn Marino   return (CALL_P (insn));
3021e4b17023SJohn Marino }
3022e4b17023SJohn Marino 
3023e4b17023SJohn Marino /* Return 1 if BB ends with a conditional branch, 0 otherwise.  */
3024e4b17023SJohn Marino 
3025e4b17023SJohn Marino static bool
rtl_block_ends_with_condjump_p(const_basic_block bb)3026e4b17023SJohn Marino rtl_block_ends_with_condjump_p (const_basic_block bb)
3027e4b17023SJohn Marino {
3028e4b17023SJohn Marino   return any_condjump_p (BB_END (bb));
3029e4b17023SJohn Marino }
3030e4b17023SJohn Marino 
3031e4b17023SJohn Marino /* Return true if we need to add fake edge to exit.
3032e4b17023SJohn Marino    Helper function for rtl_flow_call_edges_add.  */
3033e4b17023SJohn Marino 
3034e4b17023SJohn Marino static bool
need_fake_edge_p(const_rtx insn)3035e4b17023SJohn Marino need_fake_edge_p (const_rtx insn)
3036e4b17023SJohn Marino {
3037e4b17023SJohn Marino   if (!INSN_P (insn))
3038e4b17023SJohn Marino     return false;
3039e4b17023SJohn Marino 
3040e4b17023SJohn Marino   if ((CALL_P (insn)
3041e4b17023SJohn Marino        && !SIBLING_CALL_P (insn)
3042e4b17023SJohn Marino        && !find_reg_note (insn, REG_NORETURN, NULL)
3043e4b17023SJohn Marino        && !(RTL_CONST_OR_PURE_CALL_P (insn))))
3044e4b17023SJohn Marino     return true;
3045e4b17023SJohn Marino 
3046e4b17023SJohn Marino   return ((GET_CODE (PATTERN (insn)) == ASM_OPERANDS
3047e4b17023SJohn Marino 	   && MEM_VOLATILE_P (PATTERN (insn)))
3048e4b17023SJohn Marino 	  || (GET_CODE (PATTERN (insn)) == PARALLEL
3049e4b17023SJohn Marino 	      && asm_noperands (insn) != -1
3050e4b17023SJohn Marino 	      && MEM_VOLATILE_P (XVECEXP (PATTERN (insn), 0, 0)))
3051e4b17023SJohn Marino 	  || GET_CODE (PATTERN (insn)) == ASM_INPUT);
3052e4b17023SJohn Marino }
3053e4b17023SJohn Marino 
3054e4b17023SJohn Marino /* Add fake edges to the function exit for any non constant and non noreturn
3055e4b17023SJohn Marino    calls, volatile inline assembly in the bitmap of blocks specified by
3056e4b17023SJohn Marino    BLOCKS or to the whole CFG if BLOCKS is zero.  Return the number of blocks
3057e4b17023SJohn Marino    that were split.
3058e4b17023SJohn Marino 
3059e4b17023SJohn Marino    The goal is to expose cases in which entering a basic block does not imply
3060e4b17023SJohn Marino    that all subsequent instructions must be executed.  */
3061e4b17023SJohn Marino 
3062e4b17023SJohn Marino static int
rtl_flow_call_edges_add(sbitmap blocks)3063e4b17023SJohn Marino rtl_flow_call_edges_add (sbitmap blocks)
3064e4b17023SJohn Marino {
3065e4b17023SJohn Marino   int i;
3066e4b17023SJohn Marino   int blocks_split = 0;
3067e4b17023SJohn Marino   int last_bb = last_basic_block;
3068e4b17023SJohn Marino   bool check_last_block = false;
3069e4b17023SJohn Marino 
3070e4b17023SJohn Marino   if (n_basic_blocks == NUM_FIXED_BLOCKS)
3071e4b17023SJohn Marino     return 0;
3072e4b17023SJohn Marino 
3073e4b17023SJohn Marino   if (! blocks)
3074e4b17023SJohn Marino     check_last_block = true;
3075e4b17023SJohn Marino   else
3076e4b17023SJohn Marino     check_last_block = TEST_BIT (blocks, EXIT_BLOCK_PTR->prev_bb->index);
3077e4b17023SJohn Marino 
3078e4b17023SJohn Marino   /* In the last basic block, before epilogue generation, there will be
3079e4b17023SJohn Marino      a fallthru edge to EXIT.  Special care is required if the last insn
3080e4b17023SJohn Marino      of the last basic block is a call because make_edge folds duplicate
3081e4b17023SJohn Marino      edges, which would result in the fallthru edge also being marked
3082e4b17023SJohn Marino      fake, which would result in the fallthru edge being removed by
3083e4b17023SJohn Marino      remove_fake_edges, which would result in an invalid CFG.
3084e4b17023SJohn Marino 
3085e4b17023SJohn Marino      Moreover, we can't elide the outgoing fake edge, since the block
3086e4b17023SJohn Marino      profiler needs to take this into account in order to solve the minimal
3087e4b17023SJohn Marino      spanning tree in the case that the call doesn't return.
3088e4b17023SJohn Marino 
3089e4b17023SJohn Marino      Handle this by adding a dummy instruction in a new last basic block.  */
3090e4b17023SJohn Marino   if (check_last_block)
3091e4b17023SJohn Marino     {
3092e4b17023SJohn Marino       basic_block bb = EXIT_BLOCK_PTR->prev_bb;
3093e4b17023SJohn Marino       rtx insn = BB_END (bb);
3094e4b17023SJohn Marino 
3095e4b17023SJohn Marino       /* Back up past insns that must be kept in the same block as a call.  */
3096e4b17023SJohn Marino       while (insn != BB_HEAD (bb)
3097e4b17023SJohn Marino 	     && keep_with_call_p (insn))
3098e4b17023SJohn Marino 	insn = PREV_INSN (insn);
3099e4b17023SJohn Marino 
3100e4b17023SJohn Marino       if (need_fake_edge_p (insn))
3101e4b17023SJohn Marino 	{
3102e4b17023SJohn Marino 	  edge e;
3103e4b17023SJohn Marino 
3104e4b17023SJohn Marino 	  e = find_edge (bb, EXIT_BLOCK_PTR);
3105e4b17023SJohn Marino 	  if (e)
3106e4b17023SJohn Marino 	    {
3107e4b17023SJohn Marino 	      insert_insn_on_edge (gen_use (const0_rtx), e);
3108e4b17023SJohn Marino 	      commit_edge_insertions ();
3109e4b17023SJohn Marino 	    }
3110e4b17023SJohn Marino 	}
3111e4b17023SJohn Marino     }
3112e4b17023SJohn Marino 
3113e4b17023SJohn Marino   /* Now add fake edges to the function exit for any non constant
3114e4b17023SJohn Marino      calls since there is no way that we can determine if they will
3115e4b17023SJohn Marino      return or not...  */
3116e4b17023SJohn Marino 
3117e4b17023SJohn Marino   for (i = NUM_FIXED_BLOCKS; i < last_bb; i++)
3118e4b17023SJohn Marino     {
3119e4b17023SJohn Marino       basic_block bb = BASIC_BLOCK (i);
3120e4b17023SJohn Marino       rtx insn;
3121e4b17023SJohn Marino       rtx prev_insn;
3122e4b17023SJohn Marino 
3123e4b17023SJohn Marino       if (!bb)
3124e4b17023SJohn Marino 	continue;
3125e4b17023SJohn Marino 
3126e4b17023SJohn Marino       if (blocks && !TEST_BIT (blocks, i))
3127e4b17023SJohn Marino 	continue;
3128e4b17023SJohn Marino 
3129e4b17023SJohn Marino       for (insn = BB_END (bb); ; insn = prev_insn)
3130e4b17023SJohn Marino 	{
3131e4b17023SJohn Marino 	  prev_insn = PREV_INSN (insn);
3132e4b17023SJohn Marino 	  if (need_fake_edge_p (insn))
3133e4b17023SJohn Marino 	    {
3134e4b17023SJohn Marino 	      edge e;
3135e4b17023SJohn Marino 	      rtx split_at_insn = insn;
3136e4b17023SJohn Marino 
3137e4b17023SJohn Marino 	      /* Don't split the block between a call and an insn that should
3138e4b17023SJohn Marino 		 remain in the same block as the call.  */
3139e4b17023SJohn Marino 	      if (CALL_P (insn))
3140e4b17023SJohn Marino 		while (split_at_insn != BB_END (bb)
3141e4b17023SJohn Marino 		       && keep_with_call_p (NEXT_INSN (split_at_insn)))
3142e4b17023SJohn Marino 		  split_at_insn = NEXT_INSN (split_at_insn);
3143e4b17023SJohn Marino 
3144e4b17023SJohn Marino 	      /* The handling above of the final block before the epilogue
3145e4b17023SJohn Marino 		 should be enough to verify that there is no edge to the exit
3146e4b17023SJohn Marino 		 block in CFG already.  Calling make_edge in such case would
3147e4b17023SJohn Marino 		 cause us to mark that edge as fake and remove it later.  */
3148e4b17023SJohn Marino 
3149e4b17023SJohn Marino #ifdef ENABLE_CHECKING
3150e4b17023SJohn Marino 	      if (split_at_insn == BB_END (bb))
3151e4b17023SJohn Marino 		{
3152e4b17023SJohn Marino 		  e = find_edge (bb, EXIT_BLOCK_PTR);
3153e4b17023SJohn Marino 		  gcc_assert (e == NULL);
3154e4b17023SJohn Marino 		}
3155e4b17023SJohn Marino #endif
3156e4b17023SJohn Marino 
3157e4b17023SJohn Marino 	      /* Note that the following may create a new basic block
3158e4b17023SJohn Marino 		 and renumber the existing basic blocks.  */
3159e4b17023SJohn Marino 	      if (split_at_insn != BB_END (bb))
3160e4b17023SJohn Marino 		{
3161e4b17023SJohn Marino 		  e = split_block (bb, split_at_insn);
3162e4b17023SJohn Marino 		  if (e)
3163e4b17023SJohn Marino 		    blocks_split++;
3164e4b17023SJohn Marino 		}
3165e4b17023SJohn Marino 
3166e4b17023SJohn Marino 	      make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
3167e4b17023SJohn Marino 	    }
3168e4b17023SJohn Marino 
3169e4b17023SJohn Marino 	  if (insn == BB_HEAD (bb))
3170e4b17023SJohn Marino 	    break;
3171e4b17023SJohn Marino 	}
3172e4b17023SJohn Marino     }
3173e4b17023SJohn Marino 
3174e4b17023SJohn Marino   if (blocks_split)
3175e4b17023SJohn Marino     verify_flow_info ();
3176e4b17023SJohn Marino 
3177e4b17023SJohn Marino   return blocks_split;
3178e4b17023SJohn Marino }
3179e4b17023SJohn Marino 
3180e4b17023SJohn Marino /* Add COMP_RTX as a condition at end of COND_BB.  FIRST_HEAD is
3181e4b17023SJohn Marino    the conditional branch target, SECOND_HEAD should be the fall-thru
3182e4b17023SJohn Marino    there is no need to handle this here the loop versioning code handles
3183e4b17023SJohn Marino    this.  the reason for SECON_HEAD is that it is needed for condition
3184e4b17023SJohn Marino    in trees, and this should be of the same type since it is a hook.  */
3185e4b17023SJohn Marino static void
rtl_lv_add_condition_to_bb(basic_block first_head,basic_block second_head ATTRIBUTE_UNUSED,basic_block cond_bb,void * comp_rtx)3186e4b17023SJohn Marino rtl_lv_add_condition_to_bb (basic_block first_head ,
3187e4b17023SJohn Marino 			    basic_block second_head ATTRIBUTE_UNUSED,
3188e4b17023SJohn Marino 			    basic_block cond_bb, void *comp_rtx)
3189e4b17023SJohn Marino {
3190e4b17023SJohn Marino   rtx label, seq, jump;
3191e4b17023SJohn Marino   rtx op0 = XEXP ((rtx)comp_rtx, 0);
3192e4b17023SJohn Marino   rtx op1 = XEXP ((rtx)comp_rtx, 1);
3193e4b17023SJohn Marino   enum rtx_code comp = GET_CODE ((rtx)comp_rtx);
3194e4b17023SJohn Marino   enum machine_mode mode;
3195e4b17023SJohn Marino 
3196e4b17023SJohn Marino 
3197e4b17023SJohn Marino   label = block_label (first_head);
3198e4b17023SJohn Marino   mode = GET_MODE (op0);
3199e4b17023SJohn Marino   if (mode == VOIDmode)
3200e4b17023SJohn Marino     mode = GET_MODE (op1);
3201e4b17023SJohn Marino 
3202e4b17023SJohn Marino   start_sequence ();
3203e4b17023SJohn Marino   op0 = force_operand (op0, NULL_RTX);
3204e4b17023SJohn Marino   op1 = force_operand (op1, NULL_RTX);
3205e4b17023SJohn Marino   do_compare_rtx_and_jump (op0, op1, comp, 0,
3206e4b17023SJohn Marino 			   mode, NULL_RTX, NULL_RTX, label, -1);
3207e4b17023SJohn Marino   jump = get_last_insn ();
3208e4b17023SJohn Marino   JUMP_LABEL (jump) = label;
3209e4b17023SJohn Marino   LABEL_NUSES (label)++;
3210e4b17023SJohn Marino   seq = get_insns ();
3211e4b17023SJohn Marino   end_sequence ();
3212e4b17023SJohn Marino 
3213e4b17023SJohn Marino   /* Add the new cond , in the new head.  */
3214e4b17023SJohn Marino   emit_insn_after(seq, BB_END(cond_bb));
3215e4b17023SJohn Marino }
3216e4b17023SJohn Marino 
3217e4b17023SJohn Marino 
3218e4b17023SJohn Marino /* Given a block B with unconditional branch at its end, get the
3219e4b17023SJohn Marino    store the return the branch edge and the fall-thru edge in
3220e4b17023SJohn Marino    BRANCH_EDGE and FALLTHRU_EDGE respectively.  */
3221e4b17023SJohn Marino static void
rtl_extract_cond_bb_edges(basic_block b,edge * branch_edge,edge * fallthru_edge)3222e4b17023SJohn Marino rtl_extract_cond_bb_edges (basic_block b, edge *branch_edge,
3223e4b17023SJohn Marino 			   edge *fallthru_edge)
3224e4b17023SJohn Marino {
3225e4b17023SJohn Marino   edge e = EDGE_SUCC (b, 0);
3226e4b17023SJohn Marino 
3227e4b17023SJohn Marino   if (e->flags & EDGE_FALLTHRU)
3228e4b17023SJohn Marino     {
3229e4b17023SJohn Marino       *fallthru_edge = e;
3230e4b17023SJohn Marino       *branch_edge = EDGE_SUCC (b, 1);
3231e4b17023SJohn Marino     }
3232e4b17023SJohn Marino   else
3233e4b17023SJohn Marino     {
3234e4b17023SJohn Marino       *branch_edge = e;
3235e4b17023SJohn Marino       *fallthru_edge = EDGE_SUCC (b, 1);
3236e4b17023SJohn Marino     }
3237e4b17023SJohn Marino }
3238e4b17023SJohn Marino 
3239e4b17023SJohn Marino void
init_rtl_bb_info(basic_block bb)3240e4b17023SJohn Marino init_rtl_bb_info (basic_block bb)
3241e4b17023SJohn Marino {
3242e4b17023SJohn Marino   gcc_assert (!bb->il.rtl);
3243e4b17023SJohn Marino   bb->il.rtl = ggc_alloc_cleared_rtl_bb_info ();
3244e4b17023SJohn Marino }
3245e4b17023SJohn Marino 
3246e4b17023SJohn Marino /* Returns true if it is possible to remove edge E by redirecting
3247e4b17023SJohn Marino    it to the destination of the other edge from E->src.  */
3248e4b17023SJohn Marino 
3249e4b17023SJohn Marino static bool
rtl_can_remove_branch_p(const_edge e)3250e4b17023SJohn Marino rtl_can_remove_branch_p (const_edge e)
3251e4b17023SJohn Marino {
3252e4b17023SJohn Marino   const_basic_block src = e->src;
3253e4b17023SJohn Marino   const_basic_block target = EDGE_SUCC (src, EDGE_SUCC (src, 0) == e)->dest;
3254e4b17023SJohn Marino   const_rtx insn = BB_END (src), set;
3255e4b17023SJohn Marino 
3256e4b17023SJohn Marino   /* The conditions are taken from try_redirect_by_replacing_jump.  */
3257e4b17023SJohn Marino   if (target == EXIT_BLOCK_PTR)
3258e4b17023SJohn Marino     return false;
3259e4b17023SJohn Marino 
3260e4b17023SJohn Marino   if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
3261e4b17023SJohn Marino     return false;
3262e4b17023SJohn Marino 
3263e4b17023SJohn Marino   if (find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX)
3264e4b17023SJohn Marino       || BB_PARTITION (src) != BB_PARTITION (target))
3265e4b17023SJohn Marino     return false;
3266e4b17023SJohn Marino 
3267e4b17023SJohn Marino   if (!onlyjump_p (insn)
3268e4b17023SJohn Marino       || tablejump_p (insn, NULL, NULL))
3269e4b17023SJohn Marino     return false;
3270e4b17023SJohn Marino 
3271e4b17023SJohn Marino   set = single_set (insn);
3272e4b17023SJohn Marino   if (!set || side_effects_p (set))
3273e4b17023SJohn Marino     return false;
3274e4b17023SJohn Marino 
3275e4b17023SJohn Marino   return true;
3276e4b17023SJohn Marino }
3277e4b17023SJohn Marino 
3278e4b17023SJohn Marino /* We do not want to declare these functions in a header file, since they
3279e4b17023SJohn Marino    should only be used through the cfghooks interface, and we do not want to
3280e4b17023SJohn Marino    move them here since it would require also moving quite a lot of related
3281e4b17023SJohn Marino    code.  They are in cfglayout.c.  */
3282e4b17023SJohn Marino extern bool cfg_layout_can_duplicate_bb_p (const_basic_block);
3283e4b17023SJohn Marino extern basic_block cfg_layout_duplicate_bb (basic_block);
3284e4b17023SJohn Marino 
3285e4b17023SJohn Marino static basic_block
rtl_duplicate_bb(basic_block bb)3286e4b17023SJohn Marino rtl_duplicate_bb (basic_block bb)
3287e4b17023SJohn Marino {
3288e4b17023SJohn Marino   bb = cfg_layout_duplicate_bb (bb);
3289e4b17023SJohn Marino   bb->aux = NULL;
3290e4b17023SJohn Marino   return bb;
3291e4b17023SJohn Marino }
3292e4b17023SJohn Marino 
3293e4b17023SJohn Marino /* Implementation of CFG manipulation for linearized RTL.  */
3294e4b17023SJohn Marino struct cfg_hooks rtl_cfg_hooks = {
3295e4b17023SJohn Marino   "rtl",
3296e4b17023SJohn Marino   rtl_verify_flow_info,
3297e4b17023SJohn Marino   rtl_dump_bb,
3298e4b17023SJohn Marino   rtl_create_basic_block,
3299e4b17023SJohn Marino   rtl_redirect_edge_and_branch,
3300e4b17023SJohn Marino   rtl_redirect_edge_and_branch_force,
3301e4b17023SJohn Marino   rtl_can_remove_branch_p,
3302e4b17023SJohn Marino   rtl_delete_block,
3303e4b17023SJohn Marino   rtl_split_block,
3304e4b17023SJohn Marino   rtl_move_block_after,
3305e4b17023SJohn Marino   rtl_can_merge_blocks,  /* can_merge_blocks_p */
3306e4b17023SJohn Marino   rtl_merge_blocks,
3307e4b17023SJohn Marino   rtl_predict_edge,
3308e4b17023SJohn Marino   rtl_predicted_by_p,
3309e4b17023SJohn Marino   cfg_layout_can_duplicate_bb_p,
3310e4b17023SJohn Marino   rtl_duplicate_bb,
3311e4b17023SJohn Marino   rtl_split_edge,
3312e4b17023SJohn Marino   rtl_make_forwarder_block,
3313e4b17023SJohn Marino   rtl_tidy_fallthru_edge,
3314e4b17023SJohn Marino   rtl_force_nonfallthru,
3315e4b17023SJohn Marino   rtl_block_ends_with_call_p,
3316e4b17023SJohn Marino   rtl_block_ends_with_condjump_p,
3317e4b17023SJohn Marino   rtl_flow_call_edges_add,
3318e4b17023SJohn Marino   NULL, /* execute_on_growing_pred */
3319e4b17023SJohn Marino   NULL, /* execute_on_shrinking_pred */
3320e4b17023SJohn Marino   NULL, /* duplicate loop for trees */
3321e4b17023SJohn Marino   NULL, /* lv_add_condition_to_bb */
3322e4b17023SJohn Marino   NULL, /* lv_adjust_loop_header_phi*/
3323e4b17023SJohn Marino   NULL, /* extract_cond_bb_edges */
3324e4b17023SJohn Marino   NULL		/* flush_pending_stmts */
3325e4b17023SJohn Marino };
3326e4b17023SJohn Marino 
3327e4b17023SJohn Marino /* Implementation of CFG manipulation for cfg layout RTL, where
3328e4b17023SJohn Marino    basic block connected via fallthru edges does not have to be adjacent.
3329e4b17023SJohn Marino    This representation will hopefully become the default one in future
3330e4b17023SJohn Marino    version of the compiler.  */
3331e4b17023SJohn Marino 
3332e4b17023SJohn Marino struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
3333e4b17023SJohn Marino   "cfglayout mode",
3334e4b17023SJohn Marino   rtl_verify_flow_info_1,
3335e4b17023SJohn Marino   rtl_dump_bb,
3336e4b17023SJohn Marino   cfg_layout_create_basic_block,
3337e4b17023SJohn Marino   cfg_layout_redirect_edge_and_branch,
3338e4b17023SJohn Marino   cfg_layout_redirect_edge_and_branch_force,
3339e4b17023SJohn Marino   rtl_can_remove_branch_p,
3340e4b17023SJohn Marino   cfg_layout_delete_block,
3341e4b17023SJohn Marino   cfg_layout_split_block,
3342e4b17023SJohn Marino   rtl_move_block_after,
3343e4b17023SJohn Marino   cfg_layout_can_merge_blocks_p,
3344e4b17023SJohn Marino   cfg_layout_merge_blocks,
3345e4b17023SJohn Marino   rtl_predict_edge,
3346e4b17023SJohn Marino   rtl_predicted_by_p,
3347e4b17023SJohn Marino   cfg_layout_can_duplicate_bb_p,
3348e4b17023SJohn Marino   cfg_layout_duplicate_bb,
3349e4b17023SJohn Marino   cfg_layout_split_edge,
3350e4b17023SJohn Marino   rtl_make_forwarder_block,
3351e4b17023SJohn Marino   NULL, /* tidy_fallthru_edge */
3352e4b17023SJohn Marino   rtl_force_nonfallthru,
3353e4b17023SJohn Marino   rtl_block_ends_with_call_p,
3354e4b17023SJohn Marino   rtl_block_ends_with_condjump_p,
3355e4b17023SJohn Marino   rtl_flow_call_edges_add,
3356e4b17023SJohn Marino   NULL, /* execute_on_growing_pred */
3357e4b17023SJohn Marino   NULL, /* execute_on_shrinking_pred */
3358e4b17023SJohn Marino   duplicate_loop_to_header_edge, /* duplicate loop for trees */
3359e4b17023SJohn Marino   rtl_lv_add_condition_to_bb, /* lv_add_condition_to_bb */
3360e4b17023SJohn Marino   NULL, /* lv_adjust_loop_header_phi*/
3361e4b17023SJohn Marino   rtl_extract_cond_bb_edges, /* extract_cond_bb_edges */
3362e4b17023SJohn Marino   NULL		/* flush_pending_stmts */
3363e4b17023SJohn Marino };
3364