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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [cfghooks.c] - Blame information for rev 816

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Hooks for cfg representation specific functions.
2
   Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
3
   Contributed by Sebastian Pop <s.pop@laposte.net>
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3, or (at your option)
10
any later version.
11
 
12
GCC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
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 "basic-block.h"
28
#include "tree-flow.h"
29
#include "timevar.h"
30
#include "toplev.h"
31
 
32
/* A pointer to one of the hooks containers.  */
33
static struct cfg_hooks *cfg_hooks;
34
 
35
/* Initialization of functions specific to the rtl IR.  */
36
void
37
rtl_register_cfg_hooks (void)
38
{
39
  cfg_hooks = &rtl_cfg_hooks;
40
}
41
 
42
/* Initialization of functions specific to the rtl IR.  */
43
void
44
cfg_layout_rtl_register_cfg_hooks (void)
45
{
46
  cfg_hooks = &cfg_layout_rtl_cfg_hooks;
47
}
48
 
49
/* Initialization of functions specific to the tree IR.  */
50
 
51
void
52
tree_register_cfg_hooks (void)
53
{
54
  cfg_hooks = &tree_cfg_hooks;
55
}
56
 
57
/* Returns current ir type (rtl = 0, trees = 1).  */
58
 
59
int
60
ir_type (void)
61
{
62
  return cfg_hooks == &tree_cfg_hooks ? 1 : 0;
63
}
64
 
65
/* Verify the CFG consistency.
66
 
67
   Currently it does following: checks edge and basic block list correctness
68
   and calls into IL dependent checking then.  */
69
 
70
void
71
verify_flow_info (void)
72
{
73
  size_t *edge_checksum;
74
  int err = 0;
75
  basic_block bb, last_bb_seen;
76
  basic_block *last_visited;
77
 
78
  timevar_push (TV_CFG_VERIFY);
79
  last_visited = XCNEWVEC (basic_block, last_basic_block);
80
  edge_checksum = XCNEWVEC (size_t, last_basic_block);
81
 
82
  /* Check bb chain & numbers.  */
83
  last_bb_seen = ENTRY_BLOCK_PTR;
84
  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
85
    {
86
      if (bb != EXIT_BLOCK_PTR
87
          && bb != BASIC_BLOCK (bb->index))
88
        {
89
          error ("bb %d on wrong place", bb->index);
90
          err = 1;
91
        }
92
 
93
      if (bb->prev_bb != last_bb_seen)
94
        {
95
          error ("prev_bb of %d should be %d, not %d",
96
                 bb->index, last_bb_seen->index, bb->prev_bb->index);
97
          err = 1;
98
        }
99
 
100
      last_bb_seen = bb;
101
    }
102
 
103
  /* Now check the basic blocks (boundaries etc.) */
104
  FOR_EACH_BB_REVERSE (bb)
105
    {
106
      int n_fallthru = 0;
107
      edge e;
108
      edge_iterator ei;
109
 
110
      if (bb->count < 0)
111
        {
112
          error ("verify_flow_info: Wrong count of block %i %i",
113
                 bb->index, (int)bb->count);
114
          err = 1;
115
        }
116
      if (bb->frequency < 0)
117
        {
118
          error ("verify_flow_info: Wrong frequency of block %i %i",
119
                 bb->index, bb->frequency);
120
          err = 1;
121
        }
122
      FOR_EACH_EDGE (e, ei, bb->succs)
123
        {
124
          if (last_visited [e->dest->index] == bb)
125
            {
126
              error ("verify_flow_info: Duplicate edge %i->%i",
127
                     e->src->index, e->dest->index);
128
              err = 1;
129
            }
130
          if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
131
            {
132
              error ("verify_flow_info: Wrong probability of edge %i->%i %i",
133
                     e->src->index, e->dest->index, e->probability);
134
              err = 1;
135
            }
136
          if (e->count < 0)
137
            {
138
              error ("verify_flow_info: Wrong count of edge %i->%i %i",
139
                     e->src->index, e->dest->index, (int)e->count);
140
              err = 1;
141
            }
142
 
143
          last_visited [e->dest->index] = bb;
144
 
145
          if (e->flags & EDGE_FALLTHRU)
146
            n_fallthru++;
147
 
148
          if (e->src != bb)
149
            {
150
              error ("verify_flow_info: Basic block %d succ edge is corrupted",
151
                     bb->index);
152
              fprintf (stderr, "Predecessor: ");
153
              dump_edge_info (stderr, e, 0);
154
              fprintf (stderr, "\nSuccessor: ");
155
              dump_edge_info (stderr, e, 1);
156
              fprintf (stderr, "\n");
157
              err = 1;
158
            }
159
 
160
          edge_checksum[e->dest->index] += (size_t) e;
161
        }
162
      if (n_fallthru > 1)
163
        {
164
          error ("wrong amount of branch edges after unconditional jump %i", bb->index);
165
          err = 1;
166
        }
167
 
168
      FOR_EACH_EDGE (e, ei, bb->preds)
169
        {
170
          if (e->dest != bb)
171
            {
172
              error ("basic block %d pred edge is corrupted", bb->index);
173
              fputs ("Predecessor: ", stderr);
174
              dump_edge_info (stderr, e, 0);
175
              fputs ("\nSuccessor: ", stderr);
176
              dump_edge_info (stderr, e, 1);
177
              fputc ('\n', stderr);
178
              err = 1;
179
            }
180
 
181
          if (ei.index != e->dest_idx)
182
            {
183
              error ("basic block %d pred edge is corrupted", bb->index);
184
              error ("its dest_idx should be %d, not %d",
185
                     ei.index, e->dest_idx);
186
              fputs ("Predecessor: ", stderr);
187
              dump_edge_info (stderr, e, 0);
188
              fputs ("\nSuccessor: ", stderr);
189
              dump_edge_info (stderr, e, 1);
190
              fputc ('\n', stderr);
191
              err = 1;
192
            }
193
 
194
          edge_checksum[e->dest->index] -= (size_t) e;
195
        }
196
    }
197
 
198
  /* Complete edge checksumming for ENTRY and EXIT.  */
199
  {
200
    edge e;
201
    edge_iterator ei;
202
 
203
    FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
204
      edge_checksum[e->dest->index] += (size_t) e;
205
 
206
    FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
207
      edge_checksum[e->dest->index] -= (size_t) e;
208
  }
209
 
210
  FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
211
    if (edge_checksum[bb->index])
212
      {
213
        error ("basic block %i edge lists are corrupted", bb->index);
214
        err = 1;
215
      }
216
 
217
  last_bb_seen = ENTRY_BLOCK_PTR;
218
 
219
  /* Clean up.  */
220
  free (last_visited);
221
  free (edge_checksum);
222
 
223
  if (cfg_hooks->verify_flow_info)
224
    err |= cfg_hooks->verify_flow_info ();
225
  if (err)
226
    internal_error ("verify_flow_info failed");
227
  timevar_pop (TV_CFG_VERIFY);
228
}
229
 
230
/* Print out one basic block.  This function takes care of the purely
231
   graph related information.  The cfg hook for the active representation
232
   should dump representation-specific information.  */
233
 
234
void
235
dump_bb (basic_block bb, FILE *outf, int indent)
236
{
237
  edge e;
238
  edge_iterator ei;
239
  char *s_indent;
240
 
241
  s_indent = alloca ((size_t) indent + 1);
242
  memset (s_indent, ' ', (size_t) indent);
243
  s_indent[indent] = '\0';
244
 
245
  fprintf (outf, ";;%s basic block %d, loop depth %d, count ",
246
           s_indent, bb->index, bb->loop_depth);
247
  fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
248
  putc ('\n', outf);
249
 
250
  fprintf (outf, ";;%s prev block ", s_indent);
251
  if (bb->prev_bb)
252
    fprintf (outf, "%d, ", bb->prev_bb->index);
253
  else
254
    fprintf (outf, "(nil), ");
255
  fprintf (outf, "next block ");
256
  if (bb->next_bb)
257
    fprintf (outf, "%d", bb->next_bb->index);
258
  else
259
    fprintf (outf, "(nil)");
260
  putc ('\n', outf);
261
 
262
  fprintf (outf, ";;%s pred:      ", s_indent);
263
  FOR_EACH_EDGE (e, ei, bb->preds)
264
    dump_edge_info (outf, e, 0);
265
  putc ('\n', outf);
266
 
267
  fprintf (outf, ";;%s succ:      ", s_indent);
268
  FOR_EACH_EDGE (e, ei, bb->succs)
269
    dump_edge_info (outf, e, 1);
270
  putc ('\n', outf);
271
 
272
  if (cfg_hooks->dump_bb)
273
    cfg_hooks->dump_bb (bb, outf, indent);
274
}
275
 
276
/* Redirect edge E to the given basic block DEST and update underlying program
277
   representation.  Returns edge representing redirected branch (that may not
278
   be equivalent to E in the case of duplicate edges being removed) or NULL
279
   if edge is not easily redirectable for whatever reason.  */
280
 
281
edge
282
redirect_edge_and_branch (edge e, basic_block dest)
283
{
284
  edge ret;
285
 
286
  if (!cfg_hooks->redirect_edge_and_branch)
287
    internal_error ("%s does not support redirect_edge_and_branch",
288
                    cfg_hooks->name);
289
 
290
  ret = cfg_hooks->redirect_edge_and_branch (e, dest);
291
 
292
  return ret;
293
}
294
 
295
/* Redirect the edge E to basic block DEST even if it requires creating
296
   of a new basic block; then it returns the newly created basic block.
297
   Aborts when redirection is impossible.  */
298
 
299
basic_block
300
redirect_edge_and_branch_force (edge e, basic_block dest)
301
{
302
  basic_block ret;
303
 
304
  if (!cfg_hooks->redirect_edge_and_branch_force)
305
    internal_error ("%s does not support redirect_edge_and_branch_force",
306
                    cfg_hooks->name);
307
 
308
  ret = cfg_hooks->redirect_edge_and_branch_force (e, dest);
309
 
310
  return ret;
311
}
312
 
313
/* Splits basic block BB after the specified instruction I (but at least after
314
   the labels).  If I is NULL, splits just after labels.  The newly created edge
315
   is returned.  The new basic block is created just after the old one.  */
316
 
317
edge
318
split_block (basic_block bb, void *i)
319
{
320
  basic_block new_bb;
321
 
322
  if (!cfg_hooks->split_block)
323
    internal_error ("%s does not support split_block", cfg_hooks->name);
324
 
325
  new_bb = cfg_hooks->split_block (bb, i);
326
  if (!new_bb)
327
    return NULL;
328
 
329
  new_bb->count = bb->count;
330
  new_bb->frequency = bb->frequency;
331
  new_bb->loop_depth = bb->loop_depth;
332
 
333
  if (dom_info_available_p (CDI_DOMINATORS))
334
    {
335
      redirect_immediate_dominators (CDI_DOMINATORS, bb, new_bb);
336
      set_immediate_dominator (CDI_DOMINATORS, new_bb, bb);
337
    }
338
 
339
  return make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU);
340
}
341
 
342
/* Splits block BB just after labels.  The newly created edge is returned.  */
343
 
344
edge
345
split_block_after_labels (basic_block bb)
346
{
347
  return split_block (bb, NULL);
348
}
349
 
350
/* Moves block BB immediately after block AFTER.  Returns false if the
351
   movement was impossible.  */
352
 
353
bool
354
move_block_after (basic_block bb, basic_block after)
355
{
356
  bool ret;
357
 
358
  if (!cfg_hooks->move_block_after)
359
    internal_error ("%s does not support move_block_after", cfg_hooks->name);
360
 
361
  ret = cfg_hooks->move_block_after (bb, after);
362
 
363
  return ret;
364
}
365
 
366
/* Deletes the basic block BB.  */
367
 
368
void
369
delete_basic_block (basic_block bb)
370
{
371
  if (!cfg_hooks->delete_basic_block)
372
    internal_error ("%s does not support delete_basic_block", cfg_hooks->name);
373
 
374
  cfg_hooks->delete_basic_block (bb);
375
 
376
  /* Remove the edges into and out of this block.  Note that there may
377
     indeed be edges in, if we are removing an unreachable loop.  */
378
  while (EDGE_COUNT (bb->preds) != 0)
379
    remove_edge (EDGE_PRED (bb, 0));
380
  while (EDGE_COUNT (bb->succs) != 0)
381
    remove_edge (EDGE_SUCC (bb, 0));
382
 
383
  if (dom_computed[CDI_DOMINATORS])
384
    delete_from_dominance_info (CDI_DOMINATORS, bb);
385
  if (dom_computed[CDI_POST_DOMINATORS])
386
    delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
387
 
388
  /* Remove the basic block from the array.  */
389
  expunge_block (bb);
390
}
391
 
392
/* Splits edge E and returns the newly created basic block.  */
393
 
394
basic_block
395
split_edge (edge e)
396
{
397
  basic_block ret;
398
  gcov_type count = e->count;
399
  int freq = EDGE_FREQUENCY (e);
400
  edge f;
401
  bool irr = (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
402
 
403
  if (!cfg_hooks->split_edge)
404
    internal_error ("%s does not support split_edge", cfg_hooks->name);
405
 
406
  ret = cfg_hooks->split_edge (e);
407
  ret->count = count;
408
  ret->frequency = freq;
409
  single_succ_edge (ret)->probability = REG_BR_PROB_BASE;
410
  single_succ_edge (ret)->count = count;
411
 
412
  if (irr)
413
    {
414
      ret->flags |= BB_IRREDUCIBLE_LOOP;
415
      single_pred_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
416
      single_succ_edge (ret)->flags |= EDGE_IRREDUCIBLE_LOOP;
417
    }
418
 
419
  if (dom_computed[CDI_DOMINATORS])
420
    set_immediate_dominator (CDI_DOMINATORS, ret, single_pred (ret));
421
 
422
  if (dom_computed[CDI_DOMINATORS] >= DOM_NO_FAST_QUERY)
423
    {
424
      /* There are two cases:
425
 
426
         If the immediate dominator of e->dest is not e->src, it
427
         remains unchanged.
428
 
429
         If immediate dominator of e->dest is e->src, it may become
430
         ret, provided that all other predecessors of e->dest are
431
         dominated by e->dest.  */
432
 
433
      if (get_immediate_dominator (CDI_DOMINATORS, single_succ (ret))
434
          == single_pred (ret))
435
        {
436
          edge_iterator ei;
437
          FOR_EACH_EDGE (f, ei, single_succ (ret)->preds)
438
            {
439
              if (f == single_succ_edge (ret))
440
                continue;
441
 
442
              if (!dominated_by_p (CDI_DOMINATORS, f->src,
443
                                   single_succ (ret)))
444
                break;
445
            }
446
 
447
          if (!f)
448
            set_immediate_dominator (CDI_DOMINATORS, single_succ (ret), ret);
449
        }
450
    };
451
 
452
  return ret;
453
}
454
 
455
/* Creates a new basic block just after the basic block AFTER.
456
   HEAD and END are the first and the last statement belonging
457
   to the block.  If both are NULL, an empty block is created.  */
458
 
459
basic_block
460
create_basic_block (void *head, void *end, basic_block after)
461
{
462
  basic_block ret;
463
 
464
  if (!cfg_hooks->create_basic_block)
465
    internal_error ("%s does not support create_basic_block", cfg_hooks->name);
466
 
467
  ret = cfg_hooks->create_basic_block (head, end, after);
468
 
469
  if (dom_computed[CDI_DOMINATORS])
470
    add_to_dominance_info (CDI_DOMINATORS, ret);
471
  if (dom_computed[CDI_POST_DOMINATORS])
472
    add_to_dominance_info (CDI_POST_DOMINATORS, ret);
473
 
474
  return ret;
475
}
476
 
477
/* Creates an empty basic block just after basic block AFTER.  */
478
 
479
basic_block
480
create_empty_bb (basic_block after)
481
{
482
  return create_basic_block (NULL, NULL, after);
483
}
484
 
485
/* Checks whether we may merge blocks BB1 and BB2.  */
486
 
487
bool
488
can_merge_blocks_p (basic_block bb1, basic_block bb2)
489
{
490
  bool ret;
491
 
492
  if (!cfg_hooks->can_merge_blocks_p)
493
    internal_error ("%s does not support can_merge_blocks_p", cfg_hooks->name);
494
 
495
  ret = cfg_hooks->can_merge_blocks_p (bb1, bb2);
496
 
497
  return ret;
498
}
499
 
500
void
501
predict_edge (edge e, enum br_predictor predictor, int probability)
502
{
503
  if (!cfg_hooks->predict_edge)
504
    internal_error ("%s does not support predict_edge", cfg_hooks->name);
505
 
506
  cfg_hooks->predict_edge (e, predictor, probability);
507
}
508
 
509
bool
510
predicted_by_p (basic_block bb, enum br_predictor predictor)
511
{
512
  if (!cfg_hooks->predict_edge)
513
    internal_error ("%s does not support predicted_by_p", cfg_hooks->name);
514
 
515
  return cfg_hooks->predicted_by_p (bb, predictor);
516
}
517
 
518
/* Merges basic block B into basic block A.  */
519
 
520
void
521
merge_blocks (basic_block a, basic_block b)
522
{
523
  edge e;
524
  edge_iterator ei;
525
 
526
  if (!cfg_hooks->merge_blocks)
527
    internal_error ("%s does not support merge_blocks", cfg_hooks->name);
528
 
529
  cfg_hooks->merge_blocks (a, b);
530
 
531
  /* Normally there should only be one successor of A and that is B, but
532
     partway though the merge of blocks for conditional_execution we'll
533
     be merging a TEST block with THEN and ELSE successors.  Free the
534
     whole lot of them and hope the caller knows what they're doing.  */
535
 
536
  while (EDGE_COUNT (a->succs) != 0)
537
   remove_edge (EDGE_SUCC (a, 0));
538
 
539
  /* Adjust the edges out of B for the new owner.  */
540
  FOR_EACH_EDGE (e, ei, b->succs)
541
    e->src = a;
542
  a->succs = b->succs;
543
  a->flags |= b->flags;
544
 
545
  /* B hasn't quite yet ceased to exist.  Attempt to prevent mishap.  */
546
  b->preds = b->succs = NULL;
547
 
548
  if (dom_computed[CDI_DOMINATORS])
549
    redirect_immediate_dominators (CDI_DOMINATORS, b, a);
550
 
551
  if (dom_computed[CDI_DOMINATORS])
552
    delete_from_dominance_info (CDI_DOMINATORS, b);
553
  if (dom_computed[CDI_POST_DOMINATORS])
554
    delete_from_dominance_info (CDI_POST_DOMINATORS, b);
555
 
556
  expunge_block (b);
557
}
558
 
559
/* Split BB into entry part and the rest (the rest is the newly created block).
560
   Redirect those edges for that REDIRECT_EDGE_P returns true to the entry
561
   part.  Returns the edge connecting the entry part to the rest.  */
562
 
563
edge
564
make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
565
                      void (*new_bb_cbk) (basic_block))
566
{
567
  edge e, fallthru;
568
  edge_iterator ei;
569
  basic_block dummy, jump;
570
 
571
  if (!cfg_hooks->make_forwarder_block)
572
    internal_error ("%s does not support make_forwarder_block",
573
                    cfg_hooks->name);
574
 
575
  fallthru = split_block_after_labels (bb);
576
  dummy = fallthru->src;
577
  bb = fallthru->dest;
578
 
579
  /* Redirect back edges we want to keep.  */
580
  for (ei = ei_start (dummy->preds); (e = ei_safe_edge (ei)); )
581
    {
582
      if (redirect_edge_p (e))
583
        {
584
          ei_next (&ei);
585
          continue;
586
        }
587
 
588
      dummy->frequency -= EDGE_FREQUENCY (e);
589
      dummy->count -= e->count;
590
      if (dummy->frequency < 0)
591
        dummy->frequency = 0;
592
      if (dummy->count < 0)
593
        dummy->count = 0;
594
      fallthru->count -= e->count;
595
      if (fallthru->count < 0)
596
        fallthru->count = 0;
597
 
598
      jump = redirect_edge_and_branch_force (e, bb);
599
      if (jump)
600
        new_bb_cbk (jump);
601
    }
602
 
603
  if (dom_info_available_p (CDI_DOMINATORS))
604
    {
605
      basic_block doms_to_fix[2];
606
 
607
      doms_to_fix[0] = dummy;
608
      doms_to_fix[1] = bb;
609
      iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, 2);
610
    }
611
 
612
  cfg_hooks->make_forwarder_block (fallthru);
613
 
614
  return fallthru;
615
}
616
 
617
void
618
tidy_fallthru_edge (edge e)
619
{
620
  if (cfg_hooks->tidy_fallthru_edge)
621
    cfg_hooks->tidy_fallthru_edge (e);
622
}
623
 
624
/* Fix up edges that now fall through, or rather should now fall through
625
   but previously required a jump around now deleted blocks.  Simplify
626
   the search by only examining blocks numerically adjacent, since this
627
   is how find_basic_blocks created them.  */
628
 
629
void
630
tidy_fallthru_edges (void)
631
{
632
  basic_block b, c;
633
 
634
  if (!cfg_hooks->tidy_fallthru_edge)
635
    return;
636
 
637
  if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
638
    return;
639
 
640
  FOR_BB_BETWEEN (b, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR->prev_bb, next_bb)
641
    {
642
      edge s;
643
 
644
      c = b->next_bb;
645
 
646
      /* We care about simple conditional or unconditional jumps with
647
         a single successor.
648
 
649
         If we had a conditional branch to the next instruction when
650
         find_basic_blocks was called, then there will only be one
651
         out edge for the block which ended with the conditional
652
         branch (since we do not create duplicate edges).
653
 
654
         Furthermore, the edge will be marked as a fallthru because we
655
         merge the flags for the duplicate edges.  So we do not want to
656
         check that the edge is not a FALLTHRU edge.  */
657
 
658
      if (single_succ_p (b))
659
        {
660
          s = single_succ_edge (b);
661
          if (! (s->flags & EDGE_COMPLEX)
662
              && s->dest == c
663
              && !find_reg_note (BB_END (b), REG_CROSSING_JUMP, NULL_RTX))
664
            tidy_fallthru_edge (s);
665
        }
666
    }
667
}
668
 
669
/* Returns true if we can duplicate basic block BB.  */
670
 
671
bool
672
can_duplicate_block_p (basic_block bb)
673
{
674
  edge e;
675
 
676
  if (!cfg_hooks->can_duplicate_block_p)
677
    internal_error ("%s does not support can_duplicate_block_p",
678
                    cfg_hooks->name);
679
 
680
  if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR)
681
    return false;
682
 
683
  /* Duplicating fallthru block to exit would require adding a jump
684
     and splitting the real last BB.  */
685
  e = find_edge (bb, EXIT_BLOCK_PTR);
686
  if (e && (e->flags & EDGE_FALLTHRU))
687
    return false;
688
 
689
  return cfg_hooks->can_duplicate_block_p (bb);
690
}
691
 
692
/* Duplicates basic block BB and redirects edge E to it.  Returns the
693
   new basic block.  The new basic block is placed after the basic block
694
   AFTER.  */
695
 
696
basic_block
697
duplicate_block (basic_block bb, edge e, basic_block after)
698
{
699
  edge s, n;
700
  basic_block new_bb;
701
  gcov_type new_count = e ? e->count : 0;
702
  edge_iterator ei;
703
 
704
  if (!cfg_hooks->duplicate_block)
705
    internal_error ("%s does not support duplicate_block",
706
                    cfg_hooks->name);
707
 
708
  if (bb->count < new_count)
709
    new_count = bb->count;
710
 
711
#ifdef ENABLE_CHECKING
712
  gcc_assert (can_duplicate_block_p (bb));
713
#endif
714
 
715
  new_bb = cfg_hooks->duplicate_block (bb);
716
  if (after)
717
    move_block_after (new_bb, after);
718
 
719
  new_bb->loop_depth = bb->loop_depth;
720
  new_bb->flags = bb->flags;
721
  FOR_EACH_EDGE (s, ei, bb->succs)
722
    {
723
      /* Since we are creating edges from a new block to successors
724
         of another block (which therefore are known to be disjoint), there
725
         is no need to actually check for duplicated edges.  */
726
      n = unchecked_make_edge (new_bb, s->dest, s->flags);
727
      n->probability = s->probability;
728
      if (e && bb->count)
729
        {
730
          /* Take care for overflows!  */
731
          n->count = s->count * (new_count * 10000 / bb->count) / 10000;
732
          s->count -= n->count;
733
        }
734
      else
735
        n->count = s->count;
736
      n->aux = s->aux;
737
    }
738
 
739
  if (e)
740
    {
741
      new_bb->count = new_count;
742
      bb->count -= new_count;
743
 
744
      new_bb->frequency = EDGE_FREQUENCY (e);
745
      bb->frequency -= EDGE_FREQUENCY (e);
746
 
747
      redirect_edge_and_branch_force (e, new_bb);
748
 
749
      if (bb->count < 0)
750
        bb->count = 0;
751
      if (bb->frequency < 0)
752
        bb->frequency = 0;
753
    }
754
  else
755
    {
756
      new_bb->count = bb->count;
757
      new_bb->frequency = bb->frequency;
758
    }
759
 
760
  set_bb_original (new_bb, bb);
761
  set_bb_copy (bb, new_bb);
762
 
763
  return new_bb;
764
}
765
 
766
/* Return 1 if BB ends with a call, possibly followed by some
767
   instructions that must stay with the call, 0 otherwise.  */
768
 
769
bool
770
block_ends_with_call_p (basic_block bb)
771
{
772
  if (!cfg_hooks->block_ends_with_call_p)
773
    internal_error ("%s does not support block_ends_with_call_p", cfg_hooks->name);
774
 
775
  return (cfg_hooks->block_ends_with_call_p) (bb);
776
}
777
 
778
/* Return 1 if BB ends with a conditional branch, 0 otherwise.  */
779
 
780
bool
781
block_ends_with_condjump_p (basic_block bb)
782
{
783
  if (!cfg_hooks->block_ends_with_condjump_p)
784
    internal_error ("%s does not support block_ends_with_condjump_p",
785
                    cfg_hooks->name);
786
 
787
  return (cfg_hooks->block_ends_with_condjump_p) (bb);
788
}
789
 
790
/* Add fake edges to the function exit for any non constant and non noreturn
791
   calls, volatile inline assembly in the bitmap of blocks specified by
792
   BLOCKS or to the whole CFG if BLOCKS is zero.  Return the number of blocks
793
   that were split.
794
 
795
   The goal is to expose cases in which entering a basic block does not imply
796
   that all subsequent instructions must be executed.  */
797
 
798
int
799
flow_call_edges_add (sbitmap blocks)
800
{
801
  if (!cfg_hooks->flow_call_edges_add)
802
    internal_error ("%s does not support flow_call_edges_add",
803
                    cfg_hooks->name);
804
 
805
  return (cfg_hooks->flow_call_edges_add) (blocks);
806
}
807
 
808
/* This function is called immediately after edge E is added to the
809
   edge vector E->dest->preds.  */
810
 
811
void
812
execute_on_growing_pred (edge e)
813
{
814
  if (cfg_hooks->execute_on_growing_pred)
815
    cfg_hooks->execute_on_growing_pred (e);
816
}
817
 
818
/* This function is called immediately before edge E is removed from
819
   the edge vector E->dest->preds.  */
820
 
821
void
822
execute_on_shrinking_pred (edge e)
823
{
824
  if (cfg_hooks->execute_on_shrinking_pred)
825
    cfg_hooks->execute_on_shrinking_pred (e);
826
}
827
 
828
/* This is used inside loop versioning when we want to insert
829
   stmts/insns on the edges, which have a different behavior
830
   in tree's and in RTL, so we made a CFG hook.  */
831
void
832
lv_flush_pending_stmts (edge e)
833
{
834
  if (cfg_hooks->flush_pending_stmts)
835
    cfg_hooks->flush_pending_stmts (e);
836
}
837
 
838
/* Loop versioning uses the duplicate_loop_to_header_edge to create
839
   a new version of the loop basic-blocks, the parameters here are
840
   exactly the same as in duplicate_loop_to_header_edge or
841
   tree_duplicate_loop_to_header_edge; while in tree-ssa there is
842
   additional work to maintain ssa information that's why there is
843
   a need to call the tree_duplicate_loop_to_header_edge rather
844
   than duplicate_loop_to_header_edge when we are in tree mode.  */
845
bool
846
cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge e,
847
                                        struct loops *loops, unsigned int ndupl,
848
                                        sbitmap wont_exit, edge orig,
849
                                        edge *to_remove,
850
                                        unsigned int *n_to_remove, int flags)
851
{
852
  gcc_assert (cfg_hooks->cfg_hook_duplicate_loop_to_header_edge);
853
  return cfg_hooks->cfg_hook_duplicate_loop_to_header_edge (loop, e, loops,
854
                                                            ndupl, wont_exit,
855
                                                            orig, to_remove,
856
                                                            n_to_remove, flags);
857
}
858
 
859
/* Conditional jumps are represented differently in trees and RTL,
860
   this hook takes a basic block that is known to have a cond jump
861
   at its end and extracts the taken and not taken eges out of it
862
   and store it in E1 and E2 respectively.  */
863
void
864
extract_cond_bb_edges (basic_block b, edge *e1, edge *e2)
865
{
866
  gcc_assert (cfg_hooks->extract_cond_bb_edges);
867
  cfg_hooks->extract_cond_bb_edges (b, e1, e2);
868
}
869
 
870
/* Responsible for updating the ssa info (PHI nodes) on the
871
   new condition basic block that guards the versioned loop.  */
872
void
873
lv_adjust_loop_header_phi (basic_block first, basic_block second,
874
                           basic_block new, edge e)
875
{
876
  if (cfg_hooks->lv_adjust_loop_header_phi)
877
    cfg_hooks->lv_adjust_loop_header_phi (first, second, new, e);
878
}
879
 
880
/* Conditions in trees and RTL are different so we need
881
   a different handling when we add the condition to the
882
   versioning code.  */
883
void
884
lv_add_condition_to_bb (basic_block first, basic_block second,
885
                        basic_block new, void *cond)
886
{
887
  gcc_assert (cfg_hooks->lv_add_condition_to_bb);
888
  cfg_hooks->lv_add_condition_to_bb (first, second, new, cond);
889
}

powered by: WebSVN 2.1.0

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