OSDN Git Service

PR java/8473:
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-loop.c
1 /* Loop optimizations over tree-ssa.
2    Copyright (C) 2003 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 "basic-block.h"
33 #include "tree-flow.h"
34 #include "tree-dump.h"
35 #include "tree-pass.h"
36 #include "timevar.h"
37 #include "cfgloop.h"
38 #include "flags.h"
39 #include "tree-inline.h"
40
41 /* The loop tree currently optimized.  */
42
43 struct loops *current_loops;
44
45 /* Initializes the loop structures.  DUMP is the file to that the details
46    about the analysis should be dumped.  */
47
48 static struct loops *
49 tree_loop_optimizer_init (FILE *dump)
50 {
51   struct loops *loops = loop_optimizer_init (dump);
52
53   if (!loops)
54     return NULL;
55
56   /* Creation of preheaders may create redundant phi nodes if the loop is
57      entered by more than one edge, but the initial value of the induction
58      variable is the same on all of them.  */
59   kill_redundant_phi_nodes ();
60   rewrite_into_ssa (false);
61   bitmap_clear (vars_to_rename);
62
63   rewrite_into_loop_closed_ssa ();
64 #ifdef ENABLE_CHECKING
65   verify_loop_closed_ssa ();
66 #endif
67
68   return loops;
69 }
70
71 /* The loop superpass.  */
72
73 static bool
74 gate_loop (void)
75 {
76   return flag_tree_loop_optimize != 0;
77 }
78
79 struct tree_opt_pass pass_loop = 
80 {
81   "loop",                               /* name */
82   gate_loop,                            /* gate */
83   NULL,                                 /* execute */
84   NULL,                                 /* sub */
85   NULL,                                 /* next */
86   0,                                    /* static_pass_number */
87   TV_TREE_LOOP,                         /* tv_id */
88   PROP_cfg,                             /* properties_required */
89   0,                                    /* properties_provided */
90   0,                                    /* properties_destroyed */
91   TODO_ggc_collect,                     /* todo_flags_start */
92   TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect   /* todo_flags_finish */
93 };
94
95 /* Loop optimizer initialization.  */
96
97 static void
98 tree_ssa_loop_init (void)
99 {
100   current_loops = tree_loop_optimizer_init (dump_file);
101 }
102   
103 struct tree_opt_pass pass_loop_init = 
104 {
105   "loopinit",                           /* name */
106   NULL,                                 /* gate */
107   tree_ssa_loop_init,                   /* execute */
108   NULL,                                 /* sub */
109   NULL,                                 /* next */
110   0,                                    /* static_pass_number */
111   0,                                    /* tv_id */
112   PROP_cfg,                             /* properties_required */
113   0,                                    /* properties_provided */
114   0,                                    /* properties_destroyed */
115   0,                                    /* todo_flags_start */
116   0                                     /* todo_flags_finish */
117 };
118
119 /* Loop invariant motion pass.  */
120
121 static void
122 tree_ssa_loop_im (void)
123 {
124   if (!current_loops)
125     return;
126
127   tree_ssa_lim (current_loops);
128 }
129
130 static bool
131 gate_tree_ssa_loop_im (void)
132 {
133   return flag_tree_lim != 0;
134 }
135
136 struct tree_opt_pass pass_lim = 
137 {
138   "lim",                                /* name */
139   gate_tree_ssa_loop_im,                /* gate */
140   tree_ssa_loop_im,                     /* execute */
141   NULL,                                 /* sub */
142   NULL,                                 /* next */
143   0,                                    /* static_pass_number */
144   TV_LIM,                               /* tv_id */
145   PROP_cfg,                             /* properties_required */
146   0,                                    /* properties_provided */
147   0,                                    /* properties_destroyed */
148   0,                                    /* todo_flags_start */
149   TODO_dump_func                        /* todo_flags_finish */
150 };
151
152 /* Loop optimizer finalization.  */
153
154 static void
155 tree_ssa_loop_done (void)
156 {
157   if (!current_loops)
158     return;
159
160 #ifdef ENABLE_CHECKING
161   verify_loop_closed_ssa ();
162 #endif
163
164   loop_optimizer_finalize (current_loops,
165                            (dump_flags & TDF_DETAILS ? dump_file : NULL));
166   current_loops = NULL;
167   cleanup_tree_cfg ();
168 }
169   
170 struct tree_opt_pass pass_loop_done = 
171 {
172   "loopdone",                           /* name */
173   NULL,                                 /* gate */
174   tree_ssa_loop_done,                   /* execute */
175   NULL,                                 /* sub */
176   NULL,                                 /* next */
177   0,                                    /* static_pass_number */
178   0,                                    /* tv_id */
179   PROP_cfg,                             /* properties_required */
180   0,                                    /* properties_provided */
181   0,                                    /* properties_destroyed */
182   0,                                    /* todo_flags_start */
183   0                                     /* todo_flags_finish */
184 };
185