00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "tm.h"
00025 #include "tree.h"
00026 #include "rtl.h"
00027 #include "tm_p.h"
00028 #include "hard-reg-set.h"
00029 #include "basic-block.h"
00030 #include "output.h"
00031 #include "diagnostic.h"
00032 #include "tree-flow.h"
00033 #include "tree-dump.h"
00034 #include "tree-pass.h"
00035 #include "timevar.h"
00036 #include "cfgloop.h"
00037 #include "flags.h"
00038 #include "tree-inline.h"
00039 #include "tree-scalar-evolution.h"
00040
00041
00042
00043 struct loops *current_loops;
00044
00045
00046
00047
00048 static struct loops *
00049 tree_loop_optimizer_init (FILE *dump)
00050 {
00051 struct loops *loops = loop_optimizer_init (dump);
00052
00053 if (!loops)
00054 return NULL;
00055
00056
00057
00058
00059 kill_redundant_phi_nodes ();
00060 rewrite_into_ssa (false);
00061 bitmap_clear (vars_to_rename);
00062
00063 rewrite_into_loop_closed_ssa ();
00064 #ifdef ENABLE_CHECKING
00065 verify_loop_closed_ssa ();
00066 #endif
00067
00068 return loops;
00069 }
00070
00071
00072
00073 static bool
00074 gate_loop (void)
00075 {
00076 return flag_tree_loop_optimize != 0;
00077 }
00078
00079 struct tree_opt_pass pass_loop =
00080 {
00081 "loop",
00082 gate_loop,
00083 NULL,
00084 NULL,
00085 NULL,
00086 0,
00087 TV_TREE_LOOP,
00088 PROP_cfg,
00089 0,
00090 0,
00091 TODO_ggc_collect,
00092 TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect,
00093 0
00094 };
00095
00096
00097
00098 static void
00099 tree_ssa_loop_init (void)
00100 {
00101 current_loops = tree_loop_optimizer_init (dump_file);
00102 if (!current_loops)
00103 return;
00104
00105
00106 mark_single_exit_loops (current_loops);
00107
00108 scev_initialize (current_loops);
00109 }
00110
00111 struct tree_opt_pass pass_loop_init =
00112 {
00113 "loopinit",
00114 NULL,
00115 tree_ssa_loop_init,
00116 NULL,
00117 NULL,
00118 0,
00119 TV_TREE_LOOP_INIT,
00120 PROP_cfg,
00121 0,
00122 0,
00123 0,
00124 TODO_dump_func,
00125 0
00126 };
00127
00128
00129
00130 static void
00131 tree_ssa_loop_im (void)
00132 {
00133 if (!current_loops)
00134 return;
00135
00136 tree_ssa_lim (current_loops);
00137 }
00138
00139 static bool
00140 gate_tree_ssa_loop_im (void)
00141 {
00142 return flag_tree_loop_im != 0;
00143 }
00144
00145 struct tree_opt_pass pass_lim =
00146 {
00147 "lim",
00148 gate_tree_ssa_loop_im,
00149 tree_ssa_loop_im,
00150 NULL,
00151 NULL,
00152 0,
00153 TV_LIM,
00154 PROP_cfg,
00155 0,
00156 0,
00157 0,
00158 TODO_dump_func,
00159 0
00160 };
00161
00162
00163
00164 static void
00165 tree_ssa_loop_unswitch (void)
00166 {
00167 if (!current_loops)
00168 return;
00169
00170 tree_ssa_unswitch_loops (current_loops);
00171 }
00172
00173 static bool
00174 gate_tree_ssa_loop_unswitch (void)
00175 {
00176 return flag_unswitch_loops != 0;
00177 }
00178
00179 struct tree_opt_pass pass_unswitch =
00180 {
00181 "unswitch",
00182 gate_tree_ssa_loop_unswitch,
00183 tree_ssa_loop_unswitch,
00184 NULL,
00185 NULL,
00186 0,
00187 TV_TREE_LOOP_UNSWITCH,
00188 PROP_cfg,
00189 0,
00190 0,
00191 0,
00192 TODO_dump_func,
00193 0
00194 };
00195
00196
00197
00198 static void
00199 tree_vectorize (void)
00200 {
00201 if (!current_loops)
00202 return;
00203
00204 bitmap_clear (vars_to_rename);
00205 vectorize_loops (current_loops);
00206 }
00207
00208 static bool
00209 gate_tree_vectorize (void)
00210 {
00211 return flag_tree_vectorize != 0;
00212 }
00213
00214 struct tree_opt_pass pass_vectorize =
00215 {
00216 "vect",
00217 gate_tree_vectorize,
00218 tree_vectorize,
00219 NULL,
00220 NULL,
00221 0,
00222 TV_TREE_VECTORIZATION,
00223 PROP_cfg | PROP_ssa,
00224 0,
00225 0,
00226 0,
00227 TODO_dump_func,
00228 0
00229 };
00230
00231
00232
00233
00234 static void
00235 tree_linear_transform (void)
00236 {
00237 if (!current_loops)
00238 return;
00239
00240 linear_transform_loops (current_loops);
00241 }
00242
00243 static bool
00244 gate_tree_linear_transform (void)
00245 {
00246 return flag_tree_loop_linear != 0;
00247 }
00248
00249 struct tree_opt_pass pass_linear_transform =
00250 {
00251 "ltrans",
00252 gate_tree_linear_transform,
00253 tree_linear_transform,
00254 NULL,
00255 NULL,
00256 0,
00257 TV_TREE_LINEAR_TRANSFORM,
00258 PROP_cfg | PROP_ssa,
00259 0,
00260 0,
00261 0,
00262 TODO_dump_func,
00263 0
00264 };
00265
00266
00267
00268 static void
00269 tree_ssa_loop_ivcanon (void)
00270 {
00271 if (!current_loops)
00272 return;
00273
00274 canonicalize_induction_variables (current_loops);
00275 }
00276
00277 static bool
00278 gate_tree_ssa_loop_ivcanon (void)
00279 {
00280 return flag_tree_loop_ivcanon != 0;
00281 }
00282
00283 struct tree_opt_pass pass_iv_canon =
00284 {
00285 "ivcanon",
00286 gate_tree_ssa_loop_ivcanon,
00287 tree_ssa_loop_ivcanon,
00288 NULL,
00289 NULL,
00290 0,
00291 TV_TREE_LOOP_IVCANON,
00292 PROP_cfg | PROP_ssa,
00293 0,
00294 0,
00295 0,
00296 TODO_dump_func,
00297 0
00298 };
00299
00300
00301
00302 static void
00303 tree_ssa_loop_bounds (void)
00304 {
00305 if (!current_loops)
00306 return;
00307
00308 estimate_numbers_of_iterations (current_loops);
00309 scev_reset ();
00310 }
00311
00312 struct tree_opt_pass pass_record_bounds =
00313 {
00314 NULL,
00315 NULL,
00316 tree_ssa_loop_bounds,
00317 NULL,
00318 NULL,
00319 0,
00320 TV_TREE_LOOP_BOUNDS,
00321 PROP_cfg | PROP_ssa,
00322 0,
00323 0,
00324 0,
00325 0,
00326 0
00327 };
00328
00329
00330
00331 static void
00332 tree_complete_unroll (void)
00333 {
00334 if (!current_loops)
00335 return;
00336
00337 tree_unroll_loops_completely (current_loops);
00338 }
00339
00340 static bool
00341 gate_tree_complete_unroll (void)
00342 {
00343 return flag_peel_loops || flag_unroll_loops;
00344 }
00345
00346 struct tree_opt_pass pass_complete_unroll =
00347 {
00348 "cunroll",
00349 gate_tree_complete_unroll,
00350 tree_complete_unroll,
00351 NULL,
00352 NULL,
00353 0,
00354 TV_COMPLETE_UNROLL,
00355 PROP_cfg | PROP_ssa,
00356 0,
00357 0,
00358 0,
00359 TODO_dump_func,
00360 0
00361 };
00362
00363
00364
00365 static void
00366 tree_ssa_loop_ivopts (void)
00367 {
00368 if (!current_loops)
00369 return;
00370
00371 tree_ssa_iv_optimize (current_loops);
00372 }
00373
00374 static bool
00375 gate_tree_ssa_loop_ivopts (void)
00376 {
00377 return flag_ivopts != 0;
00378 }
00379
00380 struct tree_opt_pass pass_iv_optimize =
00381 {
00382 "ivopts",
00383 gate_tree_ssa_loop_ivopts,
00384 tree_ssa_loop_ivopts,
00385 NULL,
00386 NULL,
00387 0,
00388 TV_TREE_LOOP_IVOPTS,
00389 PROP_cfg | PROP_ssa,
00390 0,
00391 0,
00392 0,
00393 TODO_dump_func,
00394 0
00395 };
00396
00397
00398
00399 static void
00400 tree_ssa_loop_done (void)
00401 {
00402 if (!current_loops)
00403 return;
00404
00405 #ifdef ENABLE_CHECKING
00406 verify_loop_closed_ssa ();
00407 #endif
00408
00409 free_numbers_of_iterations_estimates (current_loops);
00410 scev_finalize ();
00411 loop_optimizer_finalize (current_loops,
00412 (dump_flags & TDF_DETAILS ? dump_file : NULL));
00413 current_loops = NULL;
00414 }
00415
00416 struct tree_opt_pass pass_loop_done =
00417 {
00418 "loopdone",
00419 NULL,
00420 tree_ssa_loop_done,
00421 NULL,
00422 NULL,
00423 0,
00424 TV_TREE_LOOP_FINI,
00425 PROP_cfg,
00426 0,
00427 0,
00428 0,
00429 TODO_cleanup_cfg | TODO_dump_func,
00430 0
00431 };
00432