* cfgloopmanip.c (force_single_succ_latches): Fix missindentation.
[official-gcc.git] / gcc / cfgloopmanip.c
blobe22cb12caf73dc5a5109e9ccbd3789605bf6d041
1 /* Loop manipulation code for GNU compiler.
2 Copyright (C) 2002, 2003 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "hard-reg-set.h"
27 #include "basic-block.h"
28 #include "cfgloop.h"
29 #include "cfglayout.h"
30 #include "output.h"
32 static basic_block create_preheader PARAMS ((struct loop *, dominance_info,
33 int));
35 /* Creates a pre-header for a LOOP. Returns newly created block. Unless
36 CP_SIMPLE_PREHEADERS is set in FLAGS, we only force LOOP to have single
37 entry; otherwise we also force preheader block to have only one successor.
39 static basic_block
40 create_preheader (loop, dom, flags)
41 struct loop *loop;
42 dominance_info dom;
43 int flags;
45 edge e, fallthru;
46 basic_block dummy;
47 basic_block jump, src = 0;
48 struct loop *cloop, *ploop;
49 int nentry = 0;
50 rtx insn;
52 cloop = loop->outer;
54 for (e = loop->header->pred; e; e = e->pred_next)
56 if (e->src == loop->latch)
57 continue;
58 nentry++;
60 if (!nentry)
61 abort ();
62 if (nentry == 1)
64 for (e = loop->header->pred; e->src == loop->latch; e = e->pred_next);
65 if (!(flags & CP_SIMPLE_PREHEADERS)
66 || !e->src->succ->succ_next)
67 return NULL;
70 insn = first_insn_after_basic_block_note (loop->header);
71 if (insn)
72 insn = PREV_INSN (insn);
73 else
74 insn = get_last_insn ();
75 if (insn == loop->header->end)
77 /* Split_block would not split block after its end. */
78 emit_note_after (NOTE_INSN_DELETED, insn);
80 if (flags & CP_INSIDE_CFGLAYOUT)
81 fallthru = cfg_layout_split_block (loop->header, insn);
82 else
83 fallthru = split_block (loop->header, insn);
84 dummy = fallthru->src;
85 loop->header = fallthru->dest;
87 /* The header could be a latch of some superloop(s); due to design of
88 split_block, it would now move to fallthru->dest. */
89 for (ploop = loop; ploop; ploop = ploop->outer)
90 if (ploop->latch == dummy)
91 ploop->latch = fallthru->dest;
93 add_to_dominance_info (dom, fallthru->dest);
95 /* Redirect edges. */
96 for (e = dummy->pred; e; e = e->pred_next)
98 src = e->src;
99 if (src == loop->latch)
100 break;
102 if (!e)
103 abort ();
105 dummy->frequency -= EDGE_FREQUENCY (e);
106 dummy->count -= e->count;
107 fallthru->count -= e->count;
108 if (flags & CP_INSIDE_CFGLAYOUT)
109 cfg_layout_redirect_edge (e, loop->header);
110 else
112 jump = redirect_edge_and_branch_force (e, loop->header);
113 if (jump)
115 add_to_dominance_info (dom, jump);
116 set_immediate_dominator (dom, jump, src);
117 add_bb_to_loop (jump, loop);
118 loop->latch = jump;
122 /* Update structures. */
123 redirect_immediate_dominators (dom, dummy, loop->header);
124 set_immediate_dominator (dom, loop->header, dummy);
125 loop->header->loop_father = loop;
126 add_bb_to_loop (dummy, cloop);
127 if (rtl_dump_file)
128 fprintf (rtl_dump_file, "Created preheader block for loop %i\n",
129 loop->num);
131 return dummy;
134 /* Create preheaders for each loop; for meaning of flags see
135 create_preheader. */
136 void
137 create_preheaders (loops, flags)
138 struct loops *loops;
139 int flags;
141 unsigned i;
142 for (i = 1; i < loops->num; i++)
143 create_preheader (loops->parray[i], loops->cfg.dom, flags);
144 loops->state |= LOOPS_HAVE_PREHEADERS;
147 /* Forces all loop latches to have only single successor. */
148 void
149 force_single_succ_latches (loops)
150 struct loops *loops;
152 unsigned i;
153 struct loop *loop;
154 edge e;
156 for (i = 1; i < loops->num; i++)
158 loop = loops->parray[i];
159 if (!loop->latch->succ->succ_next)
160 continue;
162 for (e = loop->header->pred; e->src != loop->latch; e = e->pred_next)
163 continue;
165 loop_split_edge_with (e, NULL_RTX, loops);
167 loops->state |= LOOPS_HAVE_SIMPLE_LATCHES;
170 /* A quite stupid function to put INSNS on E. They are supposed to form
171 just one basic block. Jumps out are not handled, so cfg do not have to
172 be ok after this function. */
173 basic_block
174 loop_split_edge_with (e, insns, loops)
175 edge e;
176 rtx insns;
177 struct loops *loops;
179 basic_block src, dest, new_bb;
180 struct loop *loop_c;
181 edge new_e;
183 src = e->src;
184 dest = e->dest;
186 loop_c = find_common_loop (src->loop_father, dest->loop_father);
188 /* Create basic block for it. */
190 new_bb = create_basic_block (NULL_RTX, NULL_RTX, EXIT_BLOCK_PTR->prev_bb);
191 add_to_dominance_info (loops->cfg.dom, new_bb);
192 add_bb_to_loop (new_bb, loop_c);
193 new_bb->flags = insns ? BB_SUPERBLOCK : 0;
194 if (src->flags & BB_IRREDUCIBLE_LOOP)
196 /* We expect simple preheaders here. */
197 if ((dest->flags & BB_IRREDUCIBLE_LOOP)
198 || dest->loop_father->header == dest)
199 new_bb->flags |= BB_IRREDUCIBLE_LOOP;
202 new_e = make_edge (new_bb, dest, EDGE_FALLTHRU);
203 new_e->probability = REG_BR_PROB_BASE;
204 new_e->count = e->count;
206 new_bb->count = e->count;
207 new_bb->frequency = EDGE_FREQUENCY (e);
208 cfg_layout_redirect_edge (e, new_bb);
210 alloc_aux_for_block (new_bb, sizeof (struct reorder_block_def));
211 if (insns)
213 start_sequence ();
214 emit_insn (insns);
215 insns = get_insns ();
216 end_sequence ();
217 emit_insn_after (insns, new_bb->end);
220 set_immediate_dominator (loops->cfg.dom, new_bb, src);
221 set_immediate_dominator (loops->cfg.dom, dest,
222 recount_dominator (loops->cfg.dom, dest));
224 if (dest->loop_father->latch == src)
225 dest->loop_father->latch = new_bb;
227 return new_bb;