OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [tree-ssa-loop.c] - Blame information for rev 867

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Loop optimizations over tree-ssa.
2
   Copyright (C) 2003, 2005, 2007 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 3, 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 COPYING3.  If not see
18
<http://www.gnu.org/licenses/>.  */
19
 
20
#include "config.h"
21
#include "system.h"
22
#include "coretypes.h"
23
#include "tm.h"
24
#include "tree.h"
25
#include "rtl.h"
26
#include "tm_p.h"
27
#include "hard-reg-set.h"
28
#include "basic-block.h"
29
#include "output.h"
30
#include "diagnostic.h"
31
#include "tree-flow.h"
32
#include "tree-dump.h"
33
#include "tree-pass.h"
34
#include "timevar.h"
35
#include "cfgloop.h"
36
#include "flags.h"
37
#include "tree-inline.h"
38
#include "tree-scalar-evolution.h"
39
 
40
/* The loop tree currently optimized.  */
41
 
42
struct loops *current_loops = NULL;
43
 
44
/* Initializes the loop structures.  */
45
 
46
static struct loops *
47
tree_loop_optimizer_init (void)
48
{
49
  struct loops *loops;
50
 
51
  loops = loop_optimizer_init (LOOPS_NORMAL
52
                               | LOOPS_HAVE_MARKED_SINGLE_EXITS);
53
 
54
  if (!loops)
55
    return NULL;
56
 
57
  rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
58
 
59
  return loops;
60
}
61
 
62
/* The loop superpass.  */
63
 
64
static bool
65
gate_tree_loop (void)
66
{
67
  return flag_tree_loop_optimize != 0;
68
}
69
 
70
struct tree_opt_pass pass_tree_loop =
71
{
72
  "loop",                               /* name */
73
  gate_tree_loop,                       /* gate */
74
  NULL,                                 /* execute */
75
  NULL,                                 /* sub */
76
  NULL,                                 /* next */
77
  0,                                     /* static_pass_number */
78
  TV_TREE_LOOP,                         /* tv_id */
79
  PROP_cfg,                             /* properties_required */
80
  0,                                     /* properties_provided */
81
  0,                                     /* properties_destroyed */
82
  TODO_ggc_collect,                     /* todo_flags_start */
83
  TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect,  /* todo_flags_finish */
84
 
85
};
86
 
87
/* Loop optimizer initialization.  */
88
 
89
static unsigned int
90
tree_ssa_loop_init (void)
91
{
92
  current_loops = tree_loop_optimizer_init ();
93
  if (!current_loops)
94
    return 0;
95
 
96
  scev_initialize (current_loops);
97
  return 0;
98
}
99
 
100
struct tree_opt_pass pass_tree_loop_init =
101
{
102
  "loopinit",                           /* name */
103
  NULL,                                 /* gate */
104
  tree_ssa_loop_init,                   /* execute */
105
  NULL,                                 /* sub */
106
  NULL,                                 /* next */
107
  0,                                     /* static_pass_number */
108
  TV_TREE_LOOP_INIT,                    /* tv_id */
109
  PROP_cfg,                             /* properties_required */
110
  0,                                     /* properties_provided */
111
  0,                                     /* properties_destroyed */
112
  0,                                     /* todo_flags_start */
113
  TODO_dump_func | TODO_verify_loops,   /* todo_flags_finish */
114
 
115
};
116
 
117
/* Loop invariant motion pass.  */
118
 
119
static unsigned int
120
tree_ssa_loop_im (void)
121
{
122
  if (!current_loops)
123
    return 0;
124
 
125
  tree_ssa_lim (current_loops);
126
  return 0;
127
}
128
 
129
static bool
130
gate_tree_ssa_loop_im (void)
131
{
132
  return flag_tree_loop_im != 0;
133
}
134
 
135
struct tree_opt_pass pass_lim =
136
{
137
  "lim",                                /* name */
138
  gate_tree_ssa_loop_im,                /* gate */
139
  tree_ssa_loop_im,                     /* execute */
140
  NULL,                                 /* sub */
141
  NULL,                                 /* next */
142
  0,                                     /* static_pass_number */
143
  TV_LIM,                               /* tv_id */
144
  PROP_cfg,                             /* properties_required */
145
  0,                                     /* properties_provided */
146
  0,                                     /* properties_destroyed */
147
  0,                                     /* todo_flags_start */
148
  TODO_dump_func | TODO_verify_loops,   /* todo_flags_finish */
149
 
150
};
151
 
152
/* Loop unswitching pass.  */
153
 
154
static unsigned int
155
tree_ssa_loop_unswitch (void)
156
{
157
  if (!current_loops)
158
    return 0;
159
 
160
  return tree_ssa_unswitch_loops (current_loops);
161
}
162
 
163
static bool
164
gate_tree_ssa_loop_unswitch (void)
165
{
166
  return flag_unswitch_loops != 0;
167
}
168
 
169
struct tree_opt_pass pass_tree_unswitch =
170
{
171
  "unswitch",                           /* name */
172
  gate_tree_ssa_loop_unswitch,          /* gate */
173
  tree_ssa_loop_unswitch,               /* execute */
174
  NULL,                                 /* sub */
175
  NULL,                                 /* next */
176
  0,                                     /* static_pass_number */
177
  TV_TREE_LOOP_UNSWITCH,                /* tv_id */
178
  PROP_cfg,                             /* properties_required */
179
  0,                                     /* properties_provided */
180
  0,                                     /* properties_destroyed */
181
  0,                                     /* todo_flags_start */
182
  TODO_dump_func | TODO_verify_loops,   /* todo_flags_finish */
183
 
184
};
185
 
186
/* Loop autovectorization.  */
187
 
188
static unsigned int
189
tree_vectorize (void)
190
{
191
  vectorize_loops (current_loops);
192
  return 0;
193
}
194
 
195
static bool
196
gate_tree_vectorize (void)
197
{
198
  return flag_tree_vectorize && current_loops;
199
}
200
 
201
struct tree_opt_pass pass_vectorize =
202
{
203
  "vect",                               /* name */
204
  gate_tree_vectorize,                  /* gate */
205
  tree_vectorize,                       /* execute */
206
  NULL,                                 /* sub */
207
  NULL,                                 /* next */
208
  0,                                    /* static_pass_number */
209
  TV_TREE_VECTORIZATION,                /* tv_id */
210
  PROP_cfg | PROP_ssa,                  /* properties_required */
211
  0,                                    /* properties_provided */
212
  0,                                    /* properties_destroyed */
213
  TODO_verify_loops,                    /* todo_flags_start */
214
  TODO_dump_func | TODO_update_ssa,     /* todo_flags_finish */
215
 
216
};
217
 
218
/* Loop nest optimizations.  */
219
 
220
static unsigned int
221
tree_linear_transform (void)
222
{
223
  if (!current_loops)
224
    return 0;
225
 
226
  linear_transform_loops (current_loops);
227
  return 0;
228
}
229
 
230
static bool
231
gate_tree_linear_transform (void)
232
{
233
  return flag_tree_loop_linear != 0;
234
}
235
 
236
struct tree_opt_pass pass_linear_transform =
237
{
238
  "ltrans",                             /* name */
239
  gate_tree_linear_transform,           /* gate */
240
  tree_linear_transform,                /* execute */
241
  NULL,                                 /* sub */
242
  NULL,                                 /* next */
243
  0,                                     /* static_pass_number */
244
  TV_TREE_LINEAR_TRANSFORM,             /* tv_id */
245
  PROP_cfg | PROP_ssa,                  /* properties_required */
246
  0,                                     /* properties_provided */
247
  0,                                     /* properties_destroyed */
248
  0,                                     /* todo_flags_start */
249
  TODO_dump_func | TODO_verify_loops,   /* todo_flags_finish */
250
 
251
};
252
 
253
/* Canonical induction variable creation pass.  */
254
 
255
static unsigned int
256
tree_ssa_loop_ivcanon (void)
257
{
258
  if (!current_loops)
259
    return 0;
260
 
261
  return canonicalize_induction_variables (current_loops);
262
}
263
 
264
static bool
265
gate_tree_ssa_loop_ivcanon (void)
266
{
267
  return flag_tree_loop_ivcanon != 0;
268
}
269
 
270
struct tree_opt_pass pass_iv_canon =
271
{
272
  "ivcanon",                            /* name */
273
  gate_tree_ssa_loop_ivcanon,           /* gate */
274
  tree_ssa_loop_ivcanon,                /* execute */
275
  NULL,                                 /* sub */
276
  NULL,                                 /* next */
277
  0,                                     /* static_pass_number */
278
  TV_TREE_LOOP_IVCANON,                 /* tv_id */
279
  PROP_cfg | PROP_ssa,                  /* properties_required */
280
  0,                                     /* properties_provided */
281
  0,                                     /* properties_destroyed */
282
  0,                                     /* todo_flags_start */
283
  TODO_dump_func | TODO_verify_loops,   /* todo_flags_finish */
284
 
285
};
286
 
287
/* Propagation of constants using scev.  */
288
 
289
static bool
290
gate_scev_const_prop (void)
291
{
292
  return true;
293
}
294
 
295
struct tree_opt_pass pass_scev_cprop =
296
{
297
  "sccp",                               /* name */
298
  gate_scev_const_prop,                 /* gate */
299
  scev_const_prop,                      /* execute */
300
  NULL,                                 /* sub */
301
  NULL,                                 /* next */
302
  0,                                     /* static_pass_number */
303
  TV_SCEV_CONST,                        /* tv_id */
304
  PROP_cfg | PROP_ssa,                  /* properties_required */
305
  0,                                     /* properties_provided */
306
  0,                                     /* properties_destroyed */
307
  0,                                     /* todo_flags_start */
308
  TODO_dump_func | TODO_cleanup_cfg
309
    | TODO_update_ssa_only_virtuals,
310
                                        /* todo_flags_finish */
311
 
312
};
313
 
314
/* Remove empty loops.  */
315
 
316
static unsigned int
317
tree_ssa_empty_loop (void)
318
{
319
  if (!current_loops)
320
    return 0;
321
 
322
  return remove_empty_loops (current_loops);
323
}
324
 
325
struct tree_opt_pass pass_empty_loop =
326
{
327
  "empty",                              /* name */
328
  NULL,                                 /* gate */
329
  tree_ssa_empty_loop,                  /* execute */
330
  NULL,                                 /* sub */
331
  NULL,                                 /* next */
332
  0,                                     /* static_pass_number */
333
  TV_COMPLETE_UNROLL,                   /* tv_id */
334
  PROP_cfg | PROP_ssa,                  /* properties_required */
335
  0,                                     /* properties_provided */
336
  0,                                     /* properties_destroyed */
337
  0,                                     /* todo_flags_start */
338
  TODO_dump_func | TODO_verify_loops,   /* todo_flags_finish */
339
 
340
};
341
 
342
/* Record bounds on numbers of iterations of loops.  */
343
 
344
static unsigned int
345
tree_ssa_loop_bounds (void)
346
{
347
  if (!current_loops)
348
    return 0;
349
 
350
  estimate_numbers_of_iterations (current_loops);
351
  scev_reset ();
352
  return 0;
353
}
354
 
355
struct tree_opt_pass pass_record_bounds =
356
{
357
  NULL,                                 /* name */
358
  NULL,                                 /* gate */
359
  tree_ssa_loop_bounds,                 /* execute */
360
  NULL,                                 /* sub */
361
  NULL,                                 /* next */
362
  0,                                     /* static_pass_number */
363
  TV_TREE_LOOP_BOUNDS,                  /* tv_id */
364
  PROP_cfg | PROP_ssa,                  /* properties_required */
365
  0,                                     /* properties_provided */
366
  0,                                     /* properties_destroyed */
367
  0,                                     /* todo_flags_start */
368
  0,                                     /* todo_flags_finish */
369
 
370
};
371
 
372
/* Complete unrolling of loops.  */
373
 
374
static unsigned int
375
tree_complete_unroll (void)
376
{
377
  if (!current_loops)
378
    return 0;
379
 
380
  return tree_unroll_loops_completely (current_loops,
381
                                       flag_unroll_loops
382
                                        || flag_peel_loops
383
                                        || optimize >= 3);
384
}
385
 
386
static bool
387
gate_tree_complete_unroll (void)
388
{
389
  return true;
390
}
391
 
392
struct tree_opt_pass pass_complete_unroll =
393
{
394
  "cunroll",                            /* name */
395
  gate_tree_complete_unroll,            /* gate */
396
  tree_complete_unroll,                 /* execute */
397
  NULL,                                 /* sub */
398
  NULL,                                 /* next */
399
  0,                                     /* static_pass_number */
400
  TV_COMPLETE_UNROLL,                   /* tv_id */
401
  PROP_cfg | PROP_ssa,                  /* properties_required */
402
  0,                                     /* properties_provided */
403
  0,                                     /* properties_destroyed */
404
  0,                                     /* todo_flags_start */
405
  TODO_dump_func | TODO_verify_loops,   /* todo_flags_finish */
406
 
407
};
408
 
409
/* Prefetching.  */
410
 
411
static unsigned int
412
tree_ssa_loop_prefetch (void)
413
{
414
  if (!current_loops)
415
    return 0;
416
 
417
  return tree_ssa_prefetch_arrays (current_loops);
418
}
419
 
420
static bool
421
gate_tree_ssa_loop_prefetch (void)
422
{
423
  return flag_prefetch_loop_arrays != 0;
424
}
425
 
426
struct tree_opt_pass pass_loop_prefetch =
427
{
428
  "prefetch",                           /* name */
429
  gate_tree_ssa_loop_prefetch,          /* gate */
430
  tree_ssa_loop_prefetch,               /* execute */
431
  NULL,                                 /* sub */
432
  NULL,                                 /* next */
433
  0,                                     /* static_pass_number */
434
  TV_TREE_PREFETCH,                     /* tv_id */
435
  PROP_cfg | PROP_ssa,                  /* properties_required */
436
  0,                                     /* properties_provided */
437
  0,                                     /* properties_destroyed */
438
  0,                                     /* todo_flags_start */
439
  TODO_dump_func | TODO_verify_loops,   /* todo_flags_finish */
440
 
441
};
442
 
443
/* Induction variable optimizations.  */
444
 
445
static unsigned int
446
tree_ssa_loop_ivopts (void)
447
{
448
  if (!current_loops)
449
    return 0;
450
 
451
  tree_ssa_iv_optimize (current_loops);
452
  return 0;
453
}
454
 
455
static bool
456
gate_tree_ssa_loop_ivopts (void)
457
{
458
  return flag_ivopts != 0;
459
}
460
 
461
struct tree_opt_pass pass_iv_optimize =
462
{
463
  "ivopts",                             /* name */
464
  gate_tree_ssa_loop_ivopts,            /* gate */
465
  tree_ssa_loop_ivopts,                 /* execute */
466
  NULL,                                 /* sub */
467
  NULL,                                 /* next */
468
  0,                                     /* static_pass_number */
469
  TV_TREE_LOOP_IVOPTS,                  /* tv_id */
470
  PROP_cfg | PROP_ssa,                  /* properties_required */
471
  0,                                     /* properties_provided */
472
  0,                                     /* properties_destroyed */
473
  0,                                     /* todo_flags_start */
474
  TODO_dump_func
475
  | TODO_verify_loops
476
  | TODO_update_ssa,                    /* todo_flags_finish */
477
 
478
};
479
 
480
/* Loop optimizer finalization.  */
481
 
482
static unsigned int
483
tree_ssa_loop_done (void)
484
{
485
  if (!current_loops)
486
    return 0;
487
 
488
  free_numbers_of_iterations_estimates (current_loops);
489
  scev_finalize ();
490
  loop_optimizer_finalize (current_loops);
491
  current_loops = NULL;
492
  return 0;
493
}
494
 
495
struct tree_opt_pass pass_tree_loop_done =
496
{
497
  "loopdone",                           /* name */
498
  NULL,                                 /* gate */
499
  tree_ssa_loop_done,                   /* execute */
500
  NULL,                                 /* sub */
501
  NULL,                                 /* next */
502
  0,                                     /* static_pass_number */
503
  TV_TREE_LOOP_FINI,                    /* tv_id */
504
  PROP_cfg,                             /* properties_required */
505
  0,                                     /* properties_provided */
506
  0,                                     /* properties_destroyed */
507
  0,                                     /* todo_flags_start */
508
  TODO_cleanup_cfg | TODO_dump_func,    /* todo_flags_finish */
509
 
510
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.