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, ¬e))
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