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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [sel-sched-dump.c] - Blame information for rev 714

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

Line No. Rev Author Line
1 684 jeremybenn
/* Instruction scheduling pass.   Log dumping infrastructure.
2
   Copyright (C) 2006, 2007, 2008, 2010 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 under
7
the terms of the GNU General Public License as published by the Free
8
Software Foundation; either version 3, or (at your option) any later
9
version.
10
 
11
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12
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 "diagnostic-core.h"
25
#include "rtl.h"
26
#include "tm_p.h"
27
#include "hard-reg-set.h"
28
#include "regs.h"
29
#include "function.h"
30
#include "flags.h"
31
#include "insn-config.h"
32
#include "insn-attr.h"
33
#include "params.h"
34
#include "output.h"
35
#include "basic-block.h"
36
#include "cselib.h"
37
#include "target.h"
38
 
39
#ifdef INSN_SCHEDULING
40
#include "sel-sched-ir.h"
41
#include "sel-sched-dump.h"
42
 
43
 
44
/* These variables control high-level pretty printing.  */
45
static int sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS;
46
static int sel_debug_cfg_flags = SEL_DUMP_CFG_FLAGS;
47
 
48
/* True when a cfg should be dumped.  */
49
static bool sel_dump_cfg_p;
50
 
51
/* Variables that are used to build the cfg dump file name.  */
52
static const char * const sel_debug_cfg_root = "./";
53
static const char * const sel_debug_cfg_root_postfix_default = "";
54
static const char *sel_debug_cfg_root_postfix = "";
55
static int sel_dump_cfg_fileno = -1;
56
static int sel_debug_cfg_fileno = -1;
57
 
58
/* When this flag is on, we are dumping to the .dot file.
59
   When it is off, we are dumping to log.
60
   This is useful to differentiate formatting between log and .dot
61
   files.  */
62
bool sched_dump_to_dot_p = false;
63
 
64
/* Controls how insns from a fence list should be dumped.  */
65
static int dump_flist_insn_flags = (DUMP_INSN_UID | DUMP_INSN_BBN
66
                                    | DUMP_INSN_SEQNO);
67
 
68
 
69
/* The variable used to hold the value of sched_dump when temporarily
70
   switching dump output to the other source, e.g. the .dot file.  */
71
static FILE *saved_sched_dump = NULL;
72
 
73
/* Switch sched_dump to TO.  It must not be called twice.  */
74
static void
75
switch_dump (FILE *to)
76
{
77
  gcc_assert (saved_sched_dump == NULL);
78
 
79
  saved_sched_dump = sched_dump;
80
  sched_dump = to;
81
}
82
 
83
/* Restore previously switched dump.  */
84
static void
85
restore_dump (void)
86
{
87
  sched_dump = saved_sched_dump;
88
  saved_sched_dump = NULL;
89
}
90
 
91
 
92
/* Functions for dumping instructions, av sets, and exprs.  */
93
 
94
/* Default flags for dumping insns.  */
95
static int dump_insn_rtx_flags = DUMP_INSN_RTX_PATTERN;
96
 
97
/* Default flags for dumping vinsns.  */
98
static int dump_vinsn_flags = (DUMP_VINSN_INSN_RTX | DUMP_VINSN_TYPE
99
                               | DUMP_VINSN_COUNT);
100
 
101
/* Default flags for dumping expressions.  */
102
static int dump_expr_flags = DUMP_EXPR_ALL;
103
 
104
/* Default flags for dumping insns when debugging.  */
105
static int debug_insn_rtx_flags = DUMP_INSN_RTX_ALL;
106
 
107
/* Default flags for dumping vinsns when debugging.  */
108
static int debug_vinsn_flags = DUMP_VINSN_ALL;
109
 
110
/* Default flags for dumping expressions when debugging.  */
111
static int debug_expr_flags = DUMP_EXPR_ALL;
112
 
113
/* Controls how an insn from stream should be dumped when debugging.  */
114
static int debug_insn_flags = DUMP_INSN_ALL;
115
 
116
/* Print an rtx X.  */
117
void
118
sel_print_rtl (rtx x)
119
{
120
  print_rtl_single (sched_dump, x);
121
}
122
 
123
/* Dump insn INSN honoring FLAGS.  */
124
void
125
dump_insn_rtx_1 (rtx insn, int flags)
126
{
127
  int all;
128
 
129
  /* flags == -1 also means dumping all.  */
130
  all = (flags & 1);;
131
  if (all)
132
    flags |= DUMP_INSN_RTX_ALL;
133
 
134
  sel_print ("(");
135
 
136
  if (flags & DUMP_INSN_RTX_UID)
137
    sel_print ("%d;", INSN_UID (insn));
138
 
139
  if (flags & DUMP_INSN_RTX_PATTERN)
140
    {
141
      char buf[2048];
142
 
143
      print_insn (buf, insn, 0);
144
      sel_print ("%s;", buf);
145
    }
146
 
147
  if (flags & DUMP_INSN_RTX_BBN)
148
    {
149
      basic_block bb = BLOCK_FOR_INSN (insn);
150
 
151
      sel_print ("bb:%d;", bb != NULL ? bb->index : -1);
152
    }
153
 
154
  sel_print (")");
155
}
156
 
157
 
158
/* Dump INSN with default flags.  */
159
void
160
dump_insn_rtx (rtx insn)
161
{
162
  dump_insn_rtx_1 (insn, dump_insn_rtx_flags);
163
}
164
 
165
 
166
/* Dump INSN to stderr.  */
167
DEBUG_FUNCTION void
168
debug_insn_rtx (rtx insn)
169
{
170
  switch_dump (stderr);
171
  dump_insn_rtx_1 (insn, debug_insn_rtx_flags);
172
  sel_print ("\n");
173
  restore_dump ();
174
}
175
 
176
/* Dump vinsn VI honoring flags.  */
177
void
178
dump_vinsn_1 (vinsn_t vi, int flags)
179
{
180
  int all;
181
 
182
  /* flags == -1 also means dumping all.  */
183
  all = flags & 1;
184
  if (all)
185
    flags |= DUMP_VINSN_ALL;
186
 
187
  sel_print ("(");
188
 
189
  if (flags & DUMP_VINSN_INSN_RTX)
190
    dump_insn_rtx_1 (VINSN_INSN_RTX (vi), dump_insn_rtx_flags | all);
191
 
192
  if (flags & DUMP_VINSN_TYPE)
193
    sel_print ("type:%s;", GET_RTX_NAME (VINSN_TYPE (vi)));
194
 
195
  if (flags & DUMP_VINSN_COUNT)
196
    sel_print ("count:%d;", VINSN_COUNT (vi));
197
 
198
  if (flags & DUMP_VINSN_COST)
199
    {
200
      int cost = vi->cost;
201
 
202
      if (cost != -1)
203
        sel_print ("cost:%d;", cost);
204
    }
205
 
206
  sel_print (")");
207
}
208
 
209
/* Dump vinsn VI with default flags.  */
210
void
211
dump_vinsn (vinsn_t vi)
212
{
213
  dump_vinsn_1 (vi, dump_vinsn_flags);
214
}
215
 
216
/* Dump vinsn VI to stderr.  */
217
DEBUG_FUNCTION void
218
debug_vinsn (vinsn_t vi)
219
{
220
  switch_dump (stderr);
221
  dump_vinsn_1 (vi, debug_vinsn_flags);
222
  sel_print ("\n");
223
  restore_dump ();
224
}
225
 
226
/* Dump EXPR honoring flags.  */
227
void
228
dump_expr_1 (expr_t expr, int flags)
229
{
230
  int all;
231
 
232
  /* flags == -1 also means dumping all.  */
233
  all = flags & 1;
234
  if (all)
235
    flags |= DUMP_EXPR_ALL;
236
 
237
  sel_print ("[");
238
 
239
  if (flags & DUMP_EXPR_VINSN)
240
    dump_vinsn_1 (EXPR_VINSN (expr), dump_vinsn_flags | all);
241
 
242
  if (flags & DUMP_EXPR_SPEC)
243
    {
244
      int spec = EXPR_SPEC (expr);
245
 
246
      if (spec != 0)
247
        sel_print ("spec:%d;", spec);
248
    }
249
 
250
  if (flags & DUMP_EXPR_USEFULNESS)
251
    {
252
      int use = EXPR_USEFULNESS (expr);
253
 
254
      if (use != REG_BR_PROB_BASE)
255
        sel_print ("use:%d;", use);
256
    }
257
 
258
  if (flags & DUMP_EXPR_PRIORITY)
259
    sel_print ("prio:%d;", EXPR_PRIORITY (expr));
260
 
261
  if (flags & DUMP_EXPR_SCHED_TIMES)
262
    {
263
      int times = EXPR_SCHED_TIMES (expr);
264
 
265
      if (times != 0)
266
        sel_print ("times:%d;", times);
267
    }
268
 
269
  if (flags & DUMP_EXPR_SPEC_DONE_DS)
270
    {
271
      ds_t spec_done_ds = EXPR_SPEC_DONE_DS (expr);
272
 
273
      if (spec_done_ds != 0)
274
        sel_print ("ds:%d;", spec_done_ds);
275
    }
276
 
277
  if (flags & DUMP_EXPR_ORIG_BB)
278
    {
279
      int orig_bb = EXPR_ORIG_BB_INDEX (expr);
280
 
281
      if (orig_bb != 0)
282
        sel_print ("orig_bb:%d;", orig_bb);
283
    }
284
 
285
  if (EXPR_TARGET_AVAILABLE (expr) < 1)
286
    sel_print ("target:%d;", EXPR_TARGET_AVAILABLE (expr));
287
  sel_print ("]");
288
}
289
 
290
/* Dump expression EXPR with default flags.  */
291
void
292
dump_expr (expr_t expr)
293
{
294
  dump_expr_1 (expr, dump_expr_flags);
295
}
296
 
297
/* Dump expression EXPR to stderr.  */
298
DEBUG_FUNCTION void
299
debug_expr (expr_t expr)
300
{
301
  switch_dump (stderr);
302
  dump_expr_1 (expr, debug_expr_flags);
303
  sel_print ("\n");
304
  restore_dump ();
305
}
306
 
307
/* Dump insn I honoring FLAGS.  */
308
void
309
dump_insn_1 (insn_t i, int flags)
310
{
311
  int all;
312
 
313
  all = flags & 1;
314
  if (all)
315
    flags |= DUMP_INSN_ALL;
316
 
317
  if (!sched_dump_to_dot_p)
318
    sel_print ("(");
319
 
320
  if (flags & DUMP_INSN_EXPR)
321
    {
322
      dump_expr_1 (INSN_EXPR (i), dump_expr_flags | all);
323
      sel_print (";");
324
    }
325
  else if (flags & DUMP_INSN_PATTERN)
326
    {
327
      dump_insn_rtx_1 (i, DUMP_INSN_RTX_PATTERN | all);
328
      sel_print (";");
329
    }
330
  else if (flags & DUMP_INSN_UID)
331
    sel_print ("uid:%d;", INSN_UID (i));
332
 
333
  if (flags & DUMP_INSN_SEQNO)
334
    sel_print ("seqno:%d;", INSN_SEQNO (i));
335
 
336
  if (flags & DUMP_INSN_SCHED_CYCLE)
337
    {
338
      int cycle = INSN_SCHED_CYCLE (i);
339
 
340
      if (cycle != 0)
341
        sel_print ("cycle:%d;", cycle);
342
    }
343
 
344
  if (!sched_dump_to_dot_p)
345
    sel_print (")");
346
}
347
 
348
/* Dump insn I with default flags.  */
349
void
350
dump_insn (insn_t i)
351
{
352
  dump_insn_1 (i, DUMP_INSN_EXPR | DUMP_INSN_SCHED_CYCLE);
353
}
354
 
355
/* Dump INSN to stderr.  */
356
DEBUG_FUNCTION void
357
debug_insn (insn_t insn)
358
{
359
  switch_dump (stderr);
360
  dump_insn_1 (insn, debug_insn_flags);
361
  sel_print ("\n");
362
  restore_dump ();
363
}
364
 
365
/* Dumps av_set AV.  */
366
void
367
dump_av_set (av_set_t av)
368
{
369
  av_set_iterator i;
370
  expr_t expr;
371
 
372
  if (!sched_dump_to_dot_p)
373
    sel_print ("{");
374
 
375
  FOR_EACH_EXPR (expr, i, av)
376
    {
377
      dump_expr (expr);
378
      if (!sched_dump_to_dot_p)
379
        sel_print (" ");
380
      else
381
        sel_print ("\n");
382
    }
383
 
384
  if (!sched_dump_to_dot_p)
385
    sel_print ("}");
386
}
387
 
388
/* Dumps lvset LV.  */
389
void
390
dump_lv_set (regset lv)
391
{
392
  sel_print ("{");
393
 
394
  /* This code was adapted from cfg.c: dump_regset ().  */
395
  if (lv == NULL)
396
    sel_print ("nil");
397
  else
398
    {
399
      unsigned i;
400
      reg_set_iterator rsi;
401
      int count = 0;
402
 
403
      EXECUTE_IF_SET_IN_REG_SET (lv, 0, i, rsi)
404
        {
405
          sel_print (" %d", i);
406
          if (i < FIRST_PSEUDO_REGISTER)
407
            {
408
              sel_print (" [%s]", reg_names[i]);
409
              ++count;
410
            }
411
 
412
          ++count;
413
 
414
          if (sched_dump_to_dot_p && count == 12)
415
            {
416
              count = 0;
417
              sel_print ("\n");
418
            }
419
        }
420
    }
421
 
422
  sel_print ("}\n");
423
}
424
 
425
/* Dumps a list of instructions pointed to by P.  */
426
static void
427
dump_ilist (ilist_t p)
428
{
429
  while (p)
430
    {
431
      dump_insn (ILIST_INSN (p));
432
      p = ILIST_NEXT (p);
433
    }
434
}
435
 
436
/* Dumps a list of boundaries pointed to by BNDS.  */
437
void
438
dump_blist (blist_t bnds)
439
{
440
  for (; bnds; bnds = BLIST_NEXT (bnds))
441
    {
442
      bnd_t bnd = BLIST_BND (bnds);
443
 
444
      sel_print ("[to: %d; ptr: ", INSN_UID (BND_TO (bnd)));
445
      dump_ilist (BND_PTR (bnd));
446
      sel_print ("] ");
447
    }
448
}
449
 
450
/* Dumps a list of fences pointed to by L.  */
451
void
452
dump_flist (flist_t l)
453
{
454
  while (l)
455
    {
456
      dump_insn_1 (FENCE_INSN (FLIST_FENCE (l)), dump_flist_insn_flags);
457
      sel_print (" ");
458
      l = FLIST_NEXT (l);
459
    }
460
}
461
 
462
/* Dumps an insn vector SUCCS.  */
463
void
464
dump_insn_vector (rtx_vec_t succs)
465
{
466
  int i;
467
  rtx succ;
468
 
469
  FOR_EACH_VEC_ELT (rtx, succs, i, succ)
470
    if (succ)
471
      dump_insn (succ);
472
    else
473
      sel_print ("NULL ");
474
}
475
 
476
/* Dumps a hard reg set SET to FILE using PREFIX.  */
477
static void
478
print_hard_reg_set (FILE *file, const char *prefix, HARD_REG_SET set)
479
{
480
  int i;
481
 
482
  fprintf (file, "%s{ ", prefix);
483
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
484
    {
485
      if (TEST_HARD_REG_BIT (set, i))
486
        fprintf (file, "%d ", i);
487
    }
488
  fprintf (file, "}\n");
489
}
490
 
491
/* Dumps a hard reg set SET using PREFIX.  */
492
void
493
dump_hard_reg_set (const char *prefix, HARD_REG_SET set)
494
{
495
  print_hard_reg_set (sched_dump, prefix, set);
496
}
497
 
498
/* Pretty print INSN.  This is used as a hook.  */
499
const char *
500
sel_print_insn (const_rtx insn, int aligned ATTRIBUTE_UNUSED)
501
{
502
  static char buf[80];
503
 
504
  /* '+' before insn means it is a new cycle start and it's not been
505
     scheduled yet.  '>' - has been scheduled.  */
506
  if (s_i_d && INSN_LUID (insn) > 0)
507
    if (GET_MODE (insn) == TImode)
508
      sprintf (buf, "%s %4d",
509
               INSN_SCHED_TIMES (insn) > 0 ? "> " : "< ",
510
               INSN_UID (insn));
511
    else
512
      sprintf (buf, "%s %4d",
513
               INSN_SCHED_TIMES (insn) > 0 ? "! " : "  ",
514
               INSN_UID (insn));
515
  else
516
    if (GET_MODE (insn) == TImode)
517
      sprintf (buf, "+ %4d", INSN_UID (insn));
518
    else
519
      sprintf (buf, "  %4d", INSN_UID (insn));
520
 
521
  return buf;
522
}
523
 
524
 
525
/* Functions for pretty printing of CFG.  */
526
 
527
/* Replace all occurencies of STR1 to STR2 in BUF.
528
   The BUF must be large enough to hold the result.  */
529
static void
530
replace_str_in_buf (char *buf, const char *str1, const char *str2)
531
{
532
  int buf_len = strlen (buf);
533
  int str1_len = strlen (str1);
534
  int str2_len = strlen (str2);
535
  int diff = str2_len - str1_len;
536
 
537
  char *p = buf;
538
  do
539
    {
540
      p = strstr (p, str1);
541
      if (p)
542
        {
543
          char *p1 = p + str1_len;
544
          /* Copy the rest of buf and '\0'.  */
545
          int n = buf + buf_len - p1;
546
          int i;
547
 
548
          /* Shift str by DIFF chars.  */
549
          if (diff > 0)
550
            for (i = n; i >= 0; i--)
551
              p1[i + diff] = p1[i];
552
          else
553
            for (i = 0; i <= n; i++)
554
              p1[i + diff] = p1[i];
555
 
556
          /* Copy str2.  */
557
          for (i = 0; i < str2_len; i++)
558
            p[i] = str2[i];
559
 
560
          p += str2_len;
561
          buf_len += diff;
562
        }
563
 
564
    }
565
  while (p);
566
}
567
 
568
/* Replace characters in BUF that have special meaning in .dot file.  */
569
static void
570
sel_prepare_string_for_dot_label (char *buf)
571
{
572
  static char specials_from[7][2] = { "<", ">", "{", "|", "}", "\"",
573
                                      "\n" };
574
  static char specials_to[7][3] = { "\\<", "\\>", "\\{", "\\|", "\\}",
575
                                    "\\\"", "\\l" };
576
  unsigned i;
577
 
578
  for (i = 0; i < 7; i++)
579
    replace_str_in_buf (buf, specials_from[i], specials_to[i]);
580
}
581
 
582
/* This function acts like printf but dumps to the sched_dump file.  */
583
void
584
sel_print (const char *fmt, ...)
585
{
586
  va_list ap;
587
  va_start (ap, fmt);
588
  if (sched_dump_to_dot_p)
589
    {
590
      char *message;
591
      if (vasprintf (&message, fmt, ap) >= 0 && message != NULL)
592
        {
593
          message = (char *) xrealloc (message, 2 * strlen (message) + 1);
594
          sel_prepare_string_for_dot_label (message);
595
          fprintf (sched_dump, "%s", message);
596
          free (message);
597
        }
598
    }
599
  else
600
    vfprintf (sched_dump, fmt, ap);
601
  va_end (ap);
602
}
603
 
604
/* Dump INSN with FLAGS.  */
605
static void
606
sel_dump_cfg_insn (insn_t insn, int flags)
607
{
608
  int insn_flags = DUMP_INSN_UID | DUMP_INSN_PATTERN;
609
 
610
  if (sched_luids != NULL && INSN_LUID (insn) > 0)
611
    {
612
      if (flags & SEL_DUMP_CFG_INSN_SEQNO)
613
        insn_flags |= DUMP_INSN_SEQNO | DUMP_INSN_SCHED_CYCLE | DUMP_INSN_EXPR;
614
    }
615
 
616
  dump_insn_1 (insn, insn_flags);
617
}
618
 
619
/* Dump E to the dot file F.  */
620
static void
621
sel_dump_cfg_edge (FILE *f, edge e)
622
{
623
  int w;
624
  const char *color;
625
 
626
  if (e->flags & EDGE_FALLTHRU)
627
    {
628
      w = 10;
629
      color = ", color = red";
630
    }
631
  else if (e->src->next_bb == e->dest)
632
    {
633
      w = 3;
634
      color = ", color = blue";
635
    }
636
  else
637
    {
638
      w = 1;
639
      color = "";
640
    }
641
 
642
  fprintf (f, "\tbb%d -> bb%d [weight = %d%s];\n",
643
           e->src->index, e->dest->index, w, color);
644
}
645
 
646
 
647
/* Return true if BB has a predesessor from current region.
648
   TODO: Either make this function to trace back through empty block
649
   or just remove those empty blocks.  */
650
static bool
651
has_preds_in_current_region_p (basic_block bb)
652
{
653
  edge e;
654
  edge_iterator ei;
655
 
656
  gcc_assert (!in_current_region_p (bb));
657
 
658
  FOR_EACH_EDGE (e, ei, bb->preds)
659
    if (in_current_region_p (e->src))
660
      return true;
661
 
662
  return false;
663
}
664
 
665
/* Dump a cfg region to the dot file F honoring FLAGS.  */
666
static void
667
sel_dump_cfg_2 (FILE *f, int flags)
668
{
669
  basic_block bb;
670
 
671
  sched_dump_to_dot_p = true;
672
  switch_dump (f);
673
 
674
  fprintf (f, "digraph G {\n"
675
           "\tratio = 2.25;\n"
676
           "\tnode [shape = record, fontsize = 9];\n");
677
 
678
  if (flags & SEL_DUMP_CFG_FUNCTION_NAME)
679
    fprintf (f, "function [label = \"%s\"];\n", current_function_name ());
680
 
681
  FOR_EACH_BB (bb)
682
    {
683
      insn_t insn = BB_HEAD (bb);
684
      insn_t next_tail = NEXT_INSN (BB_END (bb));
685
      edge e;
686
      edge_iterator ei;
687
      bool in_region_p = ((flags & SEL_DUMP_CFG_CURRENT_REGION)
688
                          && in_current_region_p (bb));
689
      bool full_p = (!(flags & SEL_DUMP_CFG_CURRENT_REGION)
690
                     || in_region_p);
691
      bool some_p = full_p || has_preds_in_current_region_p (bb);
692
      const char *color;
693
      const char *style;
694
 
695
      if (!some_p)
696
        continue;
697
 
698
      if ((flags & SEL_DUMP_CFG_CURRENT_REGION)
699
          && in_current_region_p (bb)
700
          && BLOCK_TO_BB (bb->index) == 0)
701
        color = "color = green, ";
702
      else
703
        color = "";
704
 
705
      if ((flags & SEL_DUMP_CFG_FENCES)
706
          && in_region_p)
707
        {
708
          style = "";
709
 
710
          if (!sel_bb_empty_p (bb))
711
            {
712
              bool first_p = true;
713
              insn_t tail = BB_END (bb);
714
              insn_t cur_insn;
715
 
716
              cur_insn = bb_note (bb);
717
 
718
              do
719
                {
720
                  fence_t fence;
721
 
722
                  cur_insn = NEXT_INSN (cur_insn);
723
                  fence = flist_lookup (fences, cur_insn);
724
 
725
                  if (fence != NULL)
726
                    {
727
                      if (!FENCE_SCHEDULED_P (fence))
728
                        {
729
                          if (first_p)
730
                            color = "color = red, ";
731
                          else
732
                            color = "color = yellow, ";
733
                        }
734
                      else
735
                        color = "color = blue, ";
736
                    }
737
 
738
                  first_p = false;
739
                }
740
              while (cur_insn != tail);
741
            }
742
        }
743
      else if (!full_p)
744
        style = "style = dashed, ";
745
      else
746
        style = "";
747
 
748
      fprintf (f, "\tbb%d [%s%slabel = \"{Basic block %d", bb->index,
749
               style, color, bb->index);
750
 
751
      if ((flags & SEL_DUMP_CFG_BB_LOOP)
752
          && bb->loop_father != NULL)
753
        fprintf (f, ", loop %d", bb->loop_father->num);
754
 
755
      if (full_p
756
          && (flags & SEL_DUMP_CFG_BB_NOTES_LIST))
757
        {
758
          insn_t notes = BB_NOTE_LIST (bb);
759
 
760
          if (notes != NULL_RTX)
761
            {
762
              fprintf (f, "|");
763
 
764
              /* For simplicity, we dump notes from note_list in reversed order
765
                 to that what they will appear in the code.  */
766
              while (notes != NULL_RTX)
767
                {
768
                  sel_dump_cfg_insn (notes, flags);
769
                  fprintf (f, "\\l");
770
 
771
                  notes = PREV_INSN (notes);
772
                }
773
            }
774
        }
775
 
776
      if (full_p
777
          && (flags & SEL_DUMP_CFG_AV_SET)
778
          && in_current_region_p (bb)
779
          && !sel_bb_empty_p (bb))
780
        {
781
          fprintf (f, "|");
782
 
783
          if (BB_AV_SET_VALID_P (bb))
784
            dump_av_set (BB_AV_SET (bb));
785
          else if (BB_AV_LEVEL (bb) == -1)
786
            fprintf (f, "AV_SET needs update");
787
        }
788
 
789
      if ((flags & SEL_DUMP_CFG_LV_SET)
790
          && !sel_bb_empty_p (bb))
791
        {
792
          fprintf (f, "|");
793
 
794
          if (BB_LV_SET_VALID_P (bb))
795
            dump_lv_set (BB_LV_SET (bb));
796
          else
797
            fprintf (f, "LV_SET needs update");
798
        }
799
 
800
      if (full_p
801
          && (flags & SEL_DUMP_CFG_BB_INSNS))
802
        {
803
          fprintf (f, "|");
804
          while (insn != next_tail)
805
            {
806
              sel_dump_cfg_insn (insn, flags);
807
              fprintf (f, "\\l");
808
 
809
              insn = NEXT_INSN (insn);
810
            }
811
        }
812
 
813
      fprintf (f, "}\"];\n");
814
 
815
      FOR_EACH_EDGE (e, ei, bb->succs)
816
        if (full_p || in_current_region_p (e->dest))
817
          sel_dump_cfg_edge (f, e);
818
    }
819
 
820
  fprintf (f, "}");
821
 
822
  restore_dump ();
823
  sched_dump_to_dot_p = false;
824
}
825
 
826
/* Dump a cfg region to the file specified by TAG honoring flags.
827
   The file is created by the function.  */
828
static void
829
sel_dump_cfg_1 (const char *tag, int flags)
830
{
831
  char *buf;
832
  int i;
833
  FILE *f;
834
 
835
  ++sel_dump_cfg_fileno;
836
 
837
  if (!sel_dump_cfg_p)
838
    return;
839
 
840
  i = 1 + snprintf (NULL, 0, "%s/%s%05d-%s.dot", sel_debug_cfg_root,
841
                    sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag);
842
  buf = XNEWVEC (char, i);
843
  snprintf (buf, i, "%s/%s%05d-%s.dot", sel_debug_cfg_root,
844
            sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag);
845
 
846
  f = fopen (buf, "w");
847
 
848
  if (f == NULL)
849
    fprintf (stderr, "Can't create file: %s.\n", buf);
850
  else
851
    {
852
      sel_dump_cfg_2 (f, flags);
853
 
854
      fclose (f);
855
    }
856
 
857
  free (buf);
858
}
859
 
860
/* Setup cfg dumping flags.  Used for debugging.  */
861
void
862
setup_dump_cfg_params (void)
863
{
864
  sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS;
865
  sel_dump_cfg_p = 0;
866
  sel_debug_cfg_root_postfix = sel_debug_cfg_root_postfix_default;
867
}
868
 
869
/* Debug a cfg region with FLAGS.  */
870
void
871
sel_debug_cfg_1 (int flags)
872
{
873
  bool t1 = sel_dump_cfg_p;
874
  int t2 = sel_dump_cfg_fileno;
875
 
876
  sel_dump_cfg_p = true;
877
  sel_dump_cfg_fileno = ++sel_debug_cfg_fileno;
878
 
879
  sel_dump_cfg_1 ("sel-debug-cfg", flags);
880
 
881
  sel_dump_cfg_fileno = t2;
882
  sel_dump_cfg_p = t1;
883
}
884
 
885
/* Dumps av_set AV to stderr.  */
886
DEBUG_FUNCTION void
887
debug_av_set (av_set_t av)
888
{
889
  switch_dump (stderr);
890
  dump_av_set (av);
891
  sel_print ("\n");
892
  restore_dump ();
893
}
894
 
895
/* Dump LV to stderr.  */
896
DEBUG_FUNCTION void
897
debug_lv_set (regset lv)
898
{
899
  switch_dump (stderr);
900
  dump_lv_set (lv);
901
  sel_print ("\n");
902
  restore_dump ();
903
}
904
 
905
/* Dump an instruction list P to stderr.  */
906
DEBUG_FUNCTION void
907
debug_ilist (ilist_t p)
908
{
909
  switch_dump (stderr);
910
  dump_ilist (p);
911
  sel_print ("\n");
912
  restore_dump ();
913
}
914
 
915
/* Dump a boundary list BNDS to stderr.  */
916
DEBUG_FUNCTION void
917
debug_blist (blist_t bnds)
918
{
919
  switch_dump (stderr);
920
  dump_blist (bnds);
921
  sel_print ("\n");
922
  restore_dump ();
923
}
924
 
925
/* Dump an insn vector SUCCS.  */
926
DEBUG_FUNCTION void
927
debug_insn_vector (rtx_vec_t succs)
928
{
929
  switch_dump (stderr);
930
  dump_insn_vector (succs);
931
  sel_print ("\n");
932
  restore_dump ();
933
}
934
 
935
/* Dump a hard reg set SET to stderr.  */
936
DEBUG_FUNCTION void
937
debug_hard_reg_set (HARD_REG_SET set)
938
{
939
  switch_dump (stderr);
940
  dump_hard_reg_set ("", set);
941
  sel_print ("\n");
942
  restore_dump ();
943
}
944
 
945
/* Debug a cfg region with default flags.  */
946
void
947
sel_debug_cfg (void)
948
{
949
  sel_debug_cfg_1 (sel_debug_cfg_flags);
950
}
951
 
952
/* Print a current cselib value for X's address to stderr.  */
953
DEBUG_FUNCTION rtx
954
debug_mem_addr_value (rtx x)
955
{
956
  rtx t, addr;
957
  enum machine_mode address_mode;
958
 
959
  gcc_assert (MEM_P (x));
960
  address_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x));
961
 
962
  t = shallow_copy_rtx (x);
963
  if (cselib_lookup (XEXP (t, 0), address_mode, 0, GET_MODE (t)))
964
    XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0), GET_MODE (t));
965
 
966
  t = canon_rtx (t);
967
  addr = get_addr (XEXP (t, 0));
968
  debug_rtx (t);
969
  debug_rtx (addr);
970
  return t;
971
}
972
#endif
973
 

powered by: WebSVN 2.1.0

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