Import a stripped down version of gcc-4.1.1
[dragonfly.git] / contrib / gcc-4.1 / gcc / tree-ssa-loop-ch.c
1 /* Loop header copying on trees.
2    Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3    
4 This file is part of GCC.
5    
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
9 later version.
10    
11 GCC is distributed in the hope that it will be useful, but WITHOUT
12 ANY 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.
15    
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, 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "rtl.h"
27 #include "tm_p.h"
28 #include "hard-reg-set.h"
29 #include "basic-block.h"
30 #include "output.h"
31 #include "diagnostic.h"
32 #include "tree-flow.h"
33 #include "tree-dump.h"
34 #include "tree-pass.h"
35 #include "timevar.h"
36 #include "cfgloop.h"
37 #include "tree-inline.h"
38 #include "flags.h"
39 #include "tree-inline.h"
40
41 /* Duplicates headers of loops if they are small enough, so that the statements
42    in the loop body are always executed when the loop is entered.  This
43    increases effectiveness of code motion optimizations, and reduces the need
44    for loop preconditioning.  */
45
46 /* Check whether we should duplicate HEADER of LOOP.  At most *LIMIT
47    instructions should be duplicated, limit is decreased by the actual
48    amount.  */
49
50 static bool
51 should_duplicate_loop_header_p (basic_block header, struct loop *loop,
52                                 int *limit)
53 {
54   block_stmt_iterator bsi;
55   tree last;
56
57   /* Do not copy one block more than once (we do not really want to do
58      loop peeling here).  */
59   if (header->aux)
60     return false;
61
62   gcc_assert (EDGE_COUNT (header->succs) > 0);
63   if (single_succ_p (header))
64     return false;
65   if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest)
66       && flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 1)->dest))
67     return false;
68
69   /* If this is not the original loop header, we want it to have just
70      one predecessor in order to match the && pattern.  */
71   if (header != loop->header && !single_pred_p (header))
72     return false;
73
74   last = last_stmt (header);
75   if (TREE_CODE (last) != COND_EXPR)
76     return false;
77
78   /* Approximately copy the conditions that used to be used in jump.c --
79      at most 20 insns and no calls.  */
80   for (bsi = bsi_start (header); !bsi_end_p (bsi); bsi_next (&bsi))
81     {
82       last = bsi_stmt (bsi);
83
84       if (TREE_CODE (last) == LABEL_EXPR)
85         continue;
86
87       if (get_call_expr_in (last))
88         return false;
89
90       *limit -= estimate_num_insns (last);
91       if (*limit < 0)
92         return false;
93     }
94
95   return true;
96 }
97
98 /* Checks whether LOOP is a do-while style loop.  */
99
100 static bool
101 do_while_loop_p (struct loop *loop)
102 {
103   tree stmt = last_stmt (loop->latch);
104
105   /* If the latch of the loop is not empty, it is not a do-while loop.  */
106   if (stmt
107       && TREE_CODE (stmt) != LABEL_EXPR)
108     return false;
109
110   /* If the header contains just a condition, it is not a do-while loop.  */
111   stmt = last_and_only_stmt (loop->header);
112   if (stmt
113       && TREE_CODE (stmt) == COND_EXPR)
114     return false;
115
116   return true;
117 }
118
119 /* For all loops, copy the condition at the end of the loop body in front
120    of the loop.  This is beneficial since it increases efficiency of
121    code motion optimizations.  It also saves one jump on entry to the loop.  */
122
123 static void
124 copy_loop_headers (void)
125 {
126   struct loops *loops;
127   unsigned i;
128   struct loop *loop;
129   basic_block header;
130   edge exit, entry;
131   basic_block *bbs, *copied_bbs;
132   unsigned n_bbs;
133   unsigned bbs_size;
134   bool copied_p;
135
136   loops = loop_optimizer_init (dump_file);
137   if (!loops)
138     return;
139   
140   /* We do not try to keep the information about irreducible regions
141      up-to-date.  */
142   loops->state &= ~LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
143
144 #ifdef ENABLE_CHECKING
145   verify_loop_structure (loops);
146 #endif
147
148   bbs = xmalloc (sizeof (basic_block) * n_basic_blocks);
149   copied_bbs = xmalloc (sizeof (basic_block) * n_basic_blocks);
150   bbs_size = n_basic_blocks;
151
152   copied_p = 0;
153   for (i = 1; i < loops->num; i++)
154     {
155       /* Copy at most 20 insns.  */
156       int limit = 20;
157
158       loop = loops->parray[i];
159       if (!loop)
160         continue;
161       header = loop->header;
162
163       /* If the loop is already a do-while style one (either because it was
164          written as such, or because jump threading transformed it into one),
165          we might be in fact peeling the first iteration of the loop.  This
166          in general is not a good idea.  */
167       if (do_while_loop_p (loop))
168         continue;
169
170       /* Iterate the header copying up to limit; this takes care of the cases
171          like while (a && b) {...}, where we want to have both of the conditions
172          copied.  TODO -- handle while (a || b) - like cases, by not requiring
173          the header to have just a single successor and copying up to
174          postdominator.  */
175
176       exit = NULL;
177       n_bbs = 0;
178       while (should_duplicate_loop_header_p (header, loop, &limit))
179         {
180           /* Find a successor of header that is inside a loop; i.e. the new
181              header after the condition is copied.  */
182           if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest))
183             exit = EDGE_SUCC (header, 0);
184           else
185             exit = EDGE_SUCC (header, 1);
186           bbs[n_bbs++] = header;
187           gcc_assert (bbs_size > n_bbs);
188           header = exit->dest;
189         }
190
191       if (!exit)
192         continue;
193
194       if (dump_file && (dump_flags & TDF_DETAILS))
195         fprintf (dump_file,
196                  "Duplicating header of the loop %d up to edge %d->%d.\n",
197                  loop->num, exit->src->index, exit->dest->index);
198
199       /* Ensure that the header will have just the latch as a predecessor
200          inside the loop.  */
201       if (!single_pred_p (exit->dest))
202         exit = single_pred_edge (loop_split_edge_with (exit, NULL));
203
204       entry = loop_preheader_edge (loop);
205
206       if (tree_duplicate_sese_region (entry, exit, bbs, n_bbs, copied_bbs))
207         copied_p = true;
208       else
209         {
210           fprintf (dump_file, "Duplication failed.\n");
211           continue;
212         }
213
214       /* Ensure that the latch and the preheader is simple (we know that they
215          are not now, since there was the loop exit condition.  */
216       loop_split_edge_with (loop_preheader_edge (loop), NULL);
217       loop_split_edge_with (loop_latch_edge (loop), NULL);
218     }
219
220   if (copied_p)
221     update_ssa (TODO_update_ssa);
222
223   free (bbs);
224   free (copied_bbs);
225
226   loop_optimizer_finalize (loops, NULL);
227 }
228
229 static bool
230 gate_ch (void)
231 {
232   return flag_tree_ch != 0;
233 }
234
235 struct tree_opt_pass pass_ch = 
236 {
237   "ch",                                 /* name */
238   gate_ch,                              /* gate */
239   copy_loop_headers,                    /* execute */
240   NULL,                                 /* sub */
241   NULL,                                 /* next */
242   0,                                    /* static_pass_number */
243   TV_TREE_CH,                           /* tv_id */
244   PROP_cfg | PROP_ssa,                  /* properties_required */
245   0,                                    /* properties_provided */
246   0,                                    /* properties_destroyed */
247   0,                                    /* todo_flags_start */
248   TODO_cleanup_cfg | TODO_dump_func 
249   | TODO_verify_ssa,                    /* todo_flags_finish */
250   0                                     /* letter */
251 };