OSDN Git Service

2004-12-02 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop-ch.c
1 /* Loop header copying on trees.
2    Copyright (C) 2004 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, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, 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 (EDGE_COUNT (header->succs) == 1)
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 && EDGE_COUNT (header->preds) >= 2)
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;
131   basic_block *bbs;
132   unsigned n_bbs;
133
134   loops = loop_optimizer_init (dump_file);
135   if (!loops)
136     return;
137   rewrite_into_loop_closed_ssa ();
138   
139   /* We do not try to keep the information about irreducible regions
140      up-to-date.  */
141   loops->state &= ~LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
142
143 #ifdef ENABLE_CHECKING
144   verify_loop_structure (loops);
145 #endif
146
147   bbs = xmalloc (sizeof (basic_block) * n_basic_blocks);
148
149   for (i = 1; i < loops->num; i++)
150     {
151       /* Copy at most 20 insns.  */
152       int limit = 20;
153
154       loop = loops->parray[i];
155       header = loop->header;
156
157       /* If the loop is already a do-while style one (either because it was
158          written as such, or because jump threading transformed it into one),
159          we might be in fact peeling the first iteration of the loop.  This
160          in general is not a good idea.  */
161       if (do_while_loop_p (loop))
162         continue;
163
164       /* Iterate the header copying up to limit; this takes care of the cases
165          like while (a && b) {...}, where we want to have both of the conditions
166          copied.  TODO -- handle while (a || b) - like cases, by not requiring
167          the header to have just a single successor and copying up to
168          postdominator.  */
169
170       exit = NULL;
171       n_bbs = 0;
172       while (should_duplicate_loop_header_p (header, loop, &limit))
173         {
174           /* Find a successor of header that is inside a loop; i.e. the new
175              header after the condition is copied.  */
176           if (flow_bb_inside_loop_p (loop, EDGE_SUCC (header, 0)->dest))
177             exit = EDGE_SUCC (header, 0);
178           else
179             exit = EDGE_SUCC (header, 1);
180           bbs[n_bbs++] = header;
181           header = exit->dest;
182         }
183
184       if (!exit)
185         continue;
186
187       if (dump_file && (dump_flags & TDF_DETAILS))
188         fprintf (dump_file,
189                  "Duplicating header of the loop %d up to edge %d->%d.\n",
190                  loop->num, exit->src->index, exit->dest->index);
191
192       /* Ensure that the header will have just the latch as a predecessor
193          inside the loop.  */
194       if (EDGE_COUNT (exit->dest->preds) > 1)
195         exit = EDGE_SUCC (loop_split_edge_with (exit, NULL), 0);
196
197       if (!tree_duplicate_sese_region (loop_preheader_edge (loop), exit,
198                                        bbs, n_bbs, NULL))
199         {
200           fprintf (dump_file, "Duplication failed.\n");
201           continue;
202         }
203
204       /* Ensure that the latch and the preheader is simple (we know that they
205          are not now, since there was the loop exit condition.  */
206       loop_split_edge_with (loop_preheader_edge (loop), NULL);
207       loop_split_edge_with (loop_latch_edge (loop), NULL);
208     }
209
210   free (bbs);
211
212 #ifdef ENABLE_CHECKING
213   verify_loop_closed_ssa ();
214 #endif
215
216   loop_optimizer_finalize (loops, NULL);
217 }
218
219 static bool
220 gate_ch (void)
221 {
222   return flag_tree_ch != 0;
223 }
224
225 struct tree_opt_pass pass_ch = 
226 {
227   "ch",                                 /* name */
228   gate_ch,                              /* gate */
229   copy_loop_headers,                    /* execute */
230   NULL,                                 /* sub */
231   NULL,                                 /* next */
232   0,                                    /* static_pass_number */
233   TV_TREE_CH,                           /* tv_id */
234   PROP_cfg | PROP_ssa,                  /* properties_required */
235   0,                                    /* properties_provided */
236   0,                                    /* properties_destroyed */
237   0,                                    /* todo_flags_start */
238   TODO_cleanup_cfg | TODO_dump_func 
239   | TODO_verify_ssa,                    /* todo_flags_finish */
240   0                                     /* letter */
241 };