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 "rtl.h"
00026 #include "hard-reg-set.h"
00027 #include "obstack.h"
00028 #include "basic-block.h"
00029 #include "cfgloop.h"
00030 #include "expr.h"
00031 #include "output.h"
00032
00033
00034
00035 bool
00036 just_once_each_iteration_p (const struct loop *loop, basic_block bb)
00037 {
00038
00039 if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
00040 return false;
00041
00042
00043 if (bb->loop_father != loop)
00044 return false;
00045
00046
00047 if (bb->flags & BB_IRREDUCIBLE_LOOP)
00048 return false;
00049
00050 return true;
00051 }
00052
00053
00054
00055 struct edge
00056 {
00057 int src, dest;
00058 struct edge *pred_next, *succ_next;
00059
00060 void *data;
00061 };
00062
00063
00064
00065 struct vertex
00066 {
00067 struct edge *pred, *succ;
00068
00069 int component;
00070
00071 int post;
00072 };
00073
00074
00075
00076 struct graph
00077 {
00078 int n_vertices;
00079 struct vertex *vertices;
00080
00081 };
00082
00083
00084
00085 extern void dump_graph (FILE *, struct graph *);
00086
00087 void
00088 dump_graph (FILE *f, struct graph *g)
00089 {
00090 int i;
00091 struct edge *e;
00092
00093 for (i = 0; i < g->n_vertices; i++)
00094 {
00095 if (!g->vertices[i].pred
00096 && !g->vertices[i].succ)
00097 continue;
00098
00099 fprintf (f, "%d (%d)\t<-", i, g->vertices[i].component);
00100 for (e = g->vertices[i].pred; e; e = e->pred_next)
00101 fprintf (f, " %d", e->src);
00102 fprintf (f, "\n");
00103
00104 fprintf (f, "\t->");
00105 for (e = g->vertices[i].succ; e; e = e->succ_next)
00106 fprintf (f, " %d", e->dest);
00107 fprintf (f, "\n");
00108 }
00109 }
00110
00111
00112
00113 static struct graph *
00114 new_graph (int n_vertices)
00115 {
00116 struct graph *g = XNEW (struct graph);
00117
00118 g->n_vertices = n_vertices;
00119 g->vertices = XCNEWVEC (struct vertex, n_vertices);
00120
00121 return g;
00122 }
00123
00124
00125
00126 static void
00127 add_edge (struct graph *g, int f, int t, void *data)
00128 {
00129 struct edge *e = xmalloc (sizeof (struct edge));
00130
00131 e->src = f;
00132 e->dest = t;
00133 e->data = data;
00134
00135 e->pred_next = g->vertices[t].pred;
00136 g->vertices[t].pred = e;
00137
00138 e->succ_next = g->vertices[f].succ;
00139 g->vertices[f].succ = e;
00140 }
00141
00142
00143
00144
00145
00146 static void
00147 dfs (struct graph *g, int *qs, int nq, int *qt, bool forward)
00148 {
00149 int i, tick = 0, v, comp = 0, top;
00150 struct edge *e;
00151 struct edge **stack = xmalloc (sizeof (struct edge *) * g->n_vertices);
00152
00153 for (i = 0; i < g->n_vertices; i++)
00154 {
00155 g->vertices[i].component = -1;
00156 g->vertices[i].post = -1;
00157 }
00158
00159 #define FST_EDGE(V) (forward ? g->vertices[(V)].succ : g->vertices[(V)].pred)
00160 #define NEXT_EDGE(E) (forward ? (E)->succ_next : (E)->pred_next)
00161 #define EDGE_SRC(E) (forward ? (E)->src : (E)->dest)
00162 #define EDGE_DEST(E) (forward ? (E)->dest : (E)->src)
00163
00164 for (i = 0; i < nq; i++)
00165 {
00166 v = qs[i];
00167 if (g->vertices[v].post != -1)
00168 continue;
00169
00170 g->vertices[v].component = comp++;
00171 e = FST_EDGE (v);
00172 top = 0;
00173
00174 while (1)
00175 {
00176 while (e && g->vertices[EDGE_DEST (e)].component != -1)
00177 e = NEXT_EDGE (e);
00178
00179 if (!e)
00180 {
00181 if (qt)
00182 qt[tick] = v;
00183 g->vertices[v].post = tick++;
00184
00185 if (!top)
00186 break;
00187
00188 e = stack[--top];
00189 v = EDGE_SRC (e);
00190 e = NEXT_EDGE (e);
00191 continue;
00192 }
00193
00194 stack[top++] = e;
00195 v = EDGE_DEST (e);
00196 e = FST_EDGE (v);
00197 g->vertices[v].component = comp - 1;
00198 }
00199 }
00200
00201 free (stack);
00202 }
00203
00204
00205
00206
00207 static void
00208 check_irred (struct graph *g, struct edge *e)
00209 {
00210 edge real = e->data;
00211
00212
00213
00214 gcc_assert (g->vertices[e->src].component >= g->vertices[e->dest].component);
00215
00216 if (g->vertices[e->src].component != g->vertices[e->dest].component)
00217 return;
00218
00219 real->flags |= EDGE_IRREDUCIBLE_LOOP;
00220 if (flow_bb_inside_loop_p (real->src->loop_father, real->dest))
00221 real->src->flags |= BB_IRREDUCIBLE_LOOP;
00222 }
00223
00224
00225
00226 static void
00227 for_each_edge (struct graph *g,
00228 void (callback) (struct graph *, struct edge *))
00229 {
00230 struct edge *e;
00231 int i;
00232
00233 for (i = 0; i < g->n_vertices; i++)
00234 for (e = g->vertices[i].succ; e; e = e->succ_next)
00235 callback (g, e);
00236 }
00237
00238
00239
00240 static void
00241 free_graph (struct graph *g)
00242 {
00243 struct edge *e, *n;
00244 int i;
00245
00246 for (i = 0; i < g->n_vertices; i++)
00247 for (e = g->vertices[i].succ; e; e = n)
00248 {
00249 n = e->succ_next;
00250 free (e);
00251 }
00252 free (g->vertices);
00253 free (g);
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 #define LOOP_REPR(LOOP) ((LOOP)->num + last_basic_block)
00266 #define BB_REPR(BB) ((BB)->index + 1)
00267
00268 void
00269 mark_irreducible_loops (struct loops *loops)
00270 {
00271 basic_block act;
00272 edge e;
00273 edge_iterator ei;
00274 int i, src, dest;
00275 struct graph *g;
00276 int *queue1 = XNEWVEC (int, last_basic_block + loops->num);
00277 int *queue2 = XNEWVEC (int, last_basic_block + loops->num);
00278 int nq, depth;
00279 struct loop *cloop;
00280
00281
00282 FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
00283 {
00284 act->flags &= ~BB_IRREDUCIBLE_LOOP;
00285 FOR_EACH_EDGE (e, ei, act->succs)
00286 e->flags &= ~EDGE_IRREDUCIBLE_LOOP;
00287 }
00288
00289
00290 g = new_graph (last_basic_block + loops->num);
00291
00292 FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
00293 FOR_EACH_EDGE (e, ei, act->succs)
00294 {
00295
00296 if (e->dest == EXIT_BLOCK_PTR)
00297 continue;
00298
00299
00300 if (e->dest->loop_father->header == e->dest
00301 && e->dest->loop_father->latch == act)
00302 continue;
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 src = BB_REPR (act);
00313 dest = BB_REPR (e->dest);
00314
00315 if (e->dest->loop_father->header == e->dest)
00316 dest = LOOP_REPR (e->dest->loop_father);
00317
00318 if (!flow_bb_inside_loop_p (act->loop_father, e->dest))
00319 {
00320 depth = find_common_loop (act->loop_father,
00321 e->dest->loop_father)->depth + 1;
00322 if (depth == act->loop_father->depth)
00323 cloop = act->loop_father;
00324 else
00325 cloop = act->loop_father->pred[depth];
00326
00327 src = LOOP_REPR (cloop);
00328 }
00329
00330 add_edge (g, src, dest, e);
00331 }
00332
00333
00334
00335
00336
00337 nq = 0;
00338 FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
00339 {
00340 queue1[nq++] = BB_REPR (act);
00341 }
00342 for (i = 1; i < (int) loops->num; i++)
00343 if (loops->parray[i])
00344 queue1[nq++] = LOOP_REPR (loops->parray[i]);
00345 dfs (g, queue1, nq, queue2, false);
00346 for (i = 0; i < nq; i++)
00347 queue1[i] = queue2[nq - i - 1];
00348 dfs (g, queue1, nq, NULL, true);
00349
00350
00351 for_each_edge (g, check_irred);
00352
00353 free_graph (g);
00354 free (queue1);
00355 free (queue2);
00356
00357 loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
00358 }
00359
00360
00361 int
00362 num_loop_insns (struct loop *loop)
00363 {
00364 basic_block *bbs, bb;
00365 unsigned i, ninsns = 0;
00366 rtx insn;
00367
00368 bbs = get_loop_body (loop);
00369 for (i = 0; i < loop->num_nodes; i++)
00370 {
00371 bb = bbs[i];
00372 ninsns++;
00373 for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
00374 if (INSN_P (insn))
00375 ninsns++;
00376 }
00377 free(bbs);
00378
00379 return ninsns;
00380 }
00381
00382
00383 int
00384 average_num_loop_insns (struct loop *loop)
00385 {
00386 basic_block *bbs, bb;
00387 unsigned i, binsns, ninsns, ratio;
00388 rtx insn;
00389
00390 ninsns = 0;
00391 bbs = get_loop_body (loop);
00392 for (i = 0; i < loop->num_nodes; i++)
00393 {
00394 bb = bbs[i];
00395
00396 binsns = 1;
00397 for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
00398 if (INSN_P (insn))
00399 binsns++;
00400
00401 ratio = loop->header->frequency == 0
00402 ? BB_FREQ_MAX
00403 : (bb->frequency * BB_FREQ_MAX) / loop->header->frequency;
00404 ninsns += binsns * ratio;
00405 }
00406 free(bbs);
00407
00408 ninsns /= BB_FREQ_MAX;
00409 if (!ninsns)
00410 ninsns = 1;
00411
00412 return ninsns;
00413 }
00414
00415
00416
00417
00418 unsigned
00419 expected_loop_iterations (const struct loop *loop)
00420 {
00421 edge e;
00422 edge_iterator ei;
00423
00424 if (loop->latch->count || loop->header->count)
00425 {
00426 gcov_type count_in, count_latch, expected;
00427
00428 count_in = 0;
00429 count_latch = 0;
00430
00431 FOR_EACH_EDGE (e, ei, loop->header->preds)
00432 if (e->src == loop->latch)
00433 count_latch = e->count;
00434 else
00435 count_in += e->count;
00436
00437 if (count_in == 0)
00438 expected = count_latch * 2;
00439 else
00440 expected = (count_latch + count_in - 1) / count_in;
00441
00442
00443 return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected);
00444 }
00445 else
00446 {
00447 int freq_in, freq_latch;
00448
00449 freq_in = 0;
00450 freq_latch = 0;
00451
00452 FOR_EACH_EDGE (e, ei, loop->header->preds)
00453 if (e->src == loop->latch)
00454 freq_latch = EDGE_FREQUENCY (e);
00455 else
00456 freq_in += EDGE_FREQUENCY (e);
00457
00458 if (freq_in == 0)
00459 return freq_latch * 2;
00460
00461 return (freq_latch + freq_in - 1) / freq_in;
00462 }
00463 }
00464
00465
00466
00467 unsigned
00468 get_loop_level (const struct loop *loop)
00469 {
00470 const struct loop *ploop;
00471 unsigned mx = 0, l;
00472
00473 for (ploop = loop->inner; ploop; ploop = ploop->next)
00474 {
00475 l = get_loop_level (ploop);
00476 if (l >= mx)
00477 mx = l + 1;
00478 }
00479 return mx;
00480 }
00481
00482
00483
00484 static unsigned
00485 seq_cost (rtx seq)
00486 {
00487 unsigned cost = 0;
00488 rtx set;
00489
00490 for (; seq; seq = NEXT_INSN (seq))
00491 {
00492 set = single_set (seq);
00493 if (set)
00494 cost += rtx_cost (set, SET);
00495 else
00496 cost++;
00497 }
00498
00499 return cost;
00500 }
00501
00502
00503
00504 unsigned target_avail_regs;
00505 unsigned target_res_regs;
00506 unsigned target_small_cost;
00507 unsigned target_pres_cost;
00508
00509 unsigned target_spill_cost;
00510
00511
00512
00513 void
00514 init_set_costs (void)
00515 {
00516 rtx seq;
00517 rtx reg1 = gen_raw_REG (SImode, FIRST_PSEUDO_REGISTER);
00518 rtx reg2 = gen_raw_REG (SImode, FIRST_PSEUDO_REGISTER + 1);
00519 rtx addr = gen_raw_REG (Pmode, FIRST_PSEUDO_REGISTER + 2);
00520 rtx mem = validize_mem (gen_rtx_MEM (SImode, addr));
00521 unsigned i;
00522
00523 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00524 if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
00525 && !fixed_regs[i])
00526 target_avail_regs++;
00527
00528 target_res_regs = 3;
00529
00530
00531
00532 start_sequence ();
00533 emit_move_insn (reg1, reg2);
00534 seq = get_insns ();
00535 end_sequence ();
00536 target_small_cost = seq_cost (seq);
00537 target_pres_cost = 2 * target_small_cost;
00538
00539 start_sequence ();
00540 emit_move_insn (mem, reg1);
00541 emit_move_insn (reg2, mem);
00542 seq = get_insns ();
00543 end_sequence ();
00544 target_spill_cost = seq_cost (seq);
00545 }
00546
00547
00548
00549
00550
00551 unsigned
00552 global_cost_for_size (unsigned size, unsigned regs_used, unsigned n_uses)
00553 {
00554 unsigned regs_needed = regs_used + size;
00555 unsigned cost = 0;
00556
00557 if (regs_needed + target_res_regs <= target_avail_regs)
00558 cost += target_small_cost * size;
00559 else if (regs_needed <= target_avail_regs)
00560 cost += target_pres_cost * size;
00561 else
00562 {
00563 cost += target_pres_cost * size;
00564 cost += target_spill_cost * n_uses * (regs_needed - target_avail_regs) / regs_needed;
00565 }
00566
00567 return cost;
00568 }
00569
00570
00571
00572 void
00573 mark_loop_exit_edges (struct loops *loops)
00574 {
00575 basic_block bb;
00576 edge e;
00577
00578 if (loops->num <= 1)
00579 return;
00580
00581 FOR_EACH_BB (bb)
00582 {
00583 edge_iterator ei;
00584
00585 FOR_EACH_EDGE (e, ei, bb->succs)
00586 {
00587 if (bb->loop_father->outer
00588 && loop_exit_edge_p (bb->loop_father, e))
00589 e->flags |= EDGE_LOOP_EXIT;
00590 else
00591 e->flags &= ~EDGE_LOOP_EXIT;
00592 }
00593 }
00594 }
00595