Mercurial > hg > CbC > CbC_gcc
annotate gcc/sel-sched-dump.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
rev | line source |
---|---|
0 | 1 /* Instruction scheduling pass. Log dumping infrastructure. |
2 Copyright (C) 2006, 2007, 2008 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 "toplev.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" | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
37 #include "target.h" |
0 | 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); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
78 |
0 | 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 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
92 /* Functions for dumping instructions, av sets, and exprs. */ |
0 | 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 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 void | |
218 debug_vinsn (vinsn_t vi) | |
219 { | |
220 switch_dump (stderr); | |
221 dump_vinsn_1 (vi, debug_vinsn_flags); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
222 sel_print ("\n"); |
0 | 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 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
284 |
0 | 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 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 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; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
371 |
0 | 372 if (!sched_dump_to_dot_p) |
373 sel_print ("{"); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
374 |
0 | 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 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
383 |
0 | 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 flow.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; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
402 |
0 | 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 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
411 |
0 | 412 ++count; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
413 |
0 | 414 if (sched_dump_to_dot_p && count == 12) |
415 { | |
416 count = 0; | |
417 sel_print ("\n"); | |
418 } | |
419 } | |
420 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
421 |
0 | 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); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
443 |
0 | 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; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
468 |
0 | 469 for (i = 0; VEC_iterate (rtx, succs, i, succ); i++) |
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 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
504 /* '+' before insn means it is a new cycle start and it's not been |
0 | 505 scheduled yet. '>' - has been scheduled. */ |
506 if (s_i_d && INSN_LUID (insn) > 0) | |
507 if (GET_MODE (insn) == TImode) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
508 sprintf (buf, "%s %4d", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
509 INSN_SCHED_TIMES (insn) > 0 ? "> " : "< ", |
0 | 510 INSN_UID (insn)); |
511 else | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
512 sprintf (buf, "%s %4d", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
513 INSN_SCHED_TIMES (insn) > 0 ? "! " : " ", |
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); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
541 if (p) |
0 | 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]; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
559 |
0 | 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 void | |
570 sel_prepare_string_for_dot_label (char *buf) | |
571 { | |
572 static char specials_from[7][2] = { "<", ">", "{", "|", "}", "\"", | |
573 "\n" }; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
574 static char specials_to[7][3] = { "\\<", "\\>", "\\{", "\\|", "\\}", |
0 | 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 /* Dump INSN with FLAGS. */ | |
583 static void | |
584 sel_dump_cfg_insn (insn_t insn, int flags) | |
585 { | |
586 int insn_flags = DUMP_INSN_UID | DUMP_INSN_PATTERN; | |
587 | |
588 if (sched_luids != NULL && INSN_LUID (insn) > 0) | |
589 { | |
590 if (flags & SEL_DUMP_CFG_INSN_SEQNO) | |
591 insn_flags |= DUMP_INSN_SEQNO | DUMP_INSN_SCHED_CYCLE | DUMP_INSN_EXPR; | |
592 } | |
593 | |
594 dump_insn_1 (insn, insn_flags); | |
595 } | |
596 | |
597 /* Dump E to the dot file F. */ | |
598 static void | |
599 sel_dump_cfg_edge (FILE *f, edge e) | |
600 { | |
601 int w; | |
602 const char *color; | |
603 | |
604 if (e->flags & EDGE_FALLTHRU) | |
605 { | |
606 w = 10; | |
607 color = ", color = red"; | |
608 } | |
609 else if (e->src->next_bb == e->dest) | |
610 { | |
611 w = 3; | |
612 color = ", color = blue"; | |
613 } | |
614 else | |
615 { | |
616 w = 1; | |
617 color = ""; | |
618 } | |
619 | |
620 fprintf (f, "\tbb%d -> bb%d [weight = %d%s];\n", | |
621 e->src->index, e->dest->index, w, color); | |
622 } | |
623 | |
624 | |
625 /* Return true if BB has a predesessor from current region. | |
626 TODO: Either make this function to trace back through empty block | |
627 or just remove those empty blocks. */ | |
628 static bool | |
629 has_preds_in_current_region_p (basic_block bb) | |
630 { | |
631 edge e; | |
632 edge_iterator ei; | |
633 | |
634 gcc_assert (!in_current_region_p (bb)); | |
635 | |
636 FOR_EACH_EDGE (e, ei, bb->preds) | |
637 if (in_current_region_p (e->src)) | |
638 return true; | |
639 | |
640 return false; | |
641 } | |
642 | |
643 /* Dump a cfg region to the dot file F honoring FLAGS. */ | |
644 static void | |
645 sel_dump_cfg_2 (FILE *f, int flags) | |
646 { | |
647 basic_block bb; | |
648 | |
649 sched_dump_to_dot_p = true; | |
650 switch_dump (f); | |
651 | |
652 fprintf (f, "digraph G {\n" | |
653 "\tratio = 2.25;\n" | |
654 "\tnode [shape = record, fontsize = 9];\n"); | |
655 | |
656 if (flags & SEL_DUMP_CFG_FUNCTION_NAME) | |
657 fprintf (f, "function [label = \"%s\"];\n", current_function_name ()); | |
658 | |
659 FOR_EACH_BB (bb) | |
660 { | |
661 insn_t insn = BB_HEAD (bb); | |
662 insn_t next_tail = NEXT_INSN (BB_END (bb)); | |
663 edge e; | |
664 edge_iterator ei; | |
665 bool in_region_p = ((flags & SEL_DUMP_CFG_CURRENT_REGION) | |
666 && in_current_region_p (bb)); | |
667 bool full_p = (!(flags & SEL_DUMP_CFG_CURRENT_REGION) | |
668 || in_region_p); | |
669 bool some_p = full_p || has_preds_in_current_region_p (bb); | |
670 const char *color; | |
671 const char *style; | |
672 | |
673 if (!some_p) | |
674 continue; | |
675 | |
676 if ((flags & SEL_DUMP_CFG_CURRENT_REGION) | |
677 && in_current_region_p (bb) | |
678 && BLOCK_TO_BB (bb->index) == 0) | |
679 color = "color = green, "; | |
680 else | |
681 color = ""; | |
682 | |
683 if ((flags & SEL_DUMP_CFG_FENCES) | |
684 && in_region_p) | |
685 { | |
686 style = ""; | |
687 | |
688 if (!sel_bb_empty_p (bb)) | |
689 { | |
690 bool first_p = true; | |
691 insn_t tail = BB_END (bb); | |
692 insn_t cur_insn; | |
693 | |
694 cur_insn = bb_note (bb); | |
695 | |
696 do | |
697 { | |
698 fence_t fence; | |
699 | |
700 cur_insn = NEXT_INSN (cur_insn); | |
701 fence = flist_lookup (fences, cur_insn); | |
702 | |
703 if (fence != NULL) | |
704 { | |
705 if (!FENCE_SCHEDULED_P (fence)) | |
706 { | |
707 if (first_p) | |
708 color = "color = red, "; | |
709 else | |
710 color = "color = yellow, "; | |
711 } | |
712 else | |
713 color = "color = blue, "; | |
714 } | |
715 | |
716 first_p = false; | |
717 } | |
718 while (cur_insn != tail); | |
719 } | |
720 } | |
721 else if (!full_p) | |
722 style = "style = dashed, "; | |
723 else | |
724 style = ""; | |
725 | |
726 fprintf (f, "\tbb%d [%s%slabel = \"{Basic block %d", bb->index, | |
727 style, color, bb->index); | |
728 | |
729 if ((flags & SEL_DUMP_CFG_BB_LOOP) | |
730 && bb->loop_father != NULL) | |
731 fprintf (f, ", loop %d", bb->loop_father->num); | |
732 | |
733 if (full_p | |
734 && (flags & SEL_DUMP_CFG_BB_NOTES_LIST)) | |
735 { | |
736 insn_t notes = BB_NOTE_LIST (bb); | |
737 | |
738 if (notes != NULL_RTX) | |
739 { | |
740 fprintf (f, "|"); | |
741 | |
742 /* For simplicity, we dump notes from note_list in reversed order | |
743 to that what they will appear in the code. */ | |
744 while (notes != NULL_RTX) | |
745 { | |
746 sel_dump_cfg_insn (notes, flags); | |
747 fprintf (f, "\\l"); | |
748 | |
749 notes = PREV_INSN (notes); | |
750 } | |
751 } | |
752 } | |
753 | |
754 if (full_p | |
755 && (flags & SEL_DUMP_CFG_AV_SET) | |
756 && in_current_region_p (bb) | |
757 && !sel_bb_empty_p (bb)) | |
758 { | |
759 fprintf (f, "|"); | |
760 | |
761 if (BB_AV_SET_VALID_P (bb)) | |
762 dump_av_set (BB_AV_SET (bb)); | |
763 else if (BB_AV_LEVEL (bb) == -1) | |
764 fprintf (f, "AV_SET needs update"); | |
765 } | |
766 | |
767 if ((flags & SEL_DUMP_CFG_LV_SET) | |
768 && !sel_bb_empty_p (bb)) | |
769 { | |
770 fprintf (f, "|"); | |
771 | |
772 if (BB_LV_SET_VALID_P (bb)) | |
773 dump_lv_set (BB_LV_SET (bb)); | |
774 else | |
775 fprintf (f, "LV_SET needs update"); | |
776 } | |
777 | |
778 if (full_p | |
779 && (flags & SEL_DUMP_CFG_BB_INSNS)) | |
780 { | |
781 fprintf (f, "|"); | |
782 while (insn != next_tail) | |
783 { | |
784 sel_dump_cfg_insn (insn, flags); | |
785 fprintf (f, "\\l"); | |
786 | |
787 insn = NEXT_INSN (insn); | |
788 } | |
789 } | |
790 | |
791 fprintf (f, "}\"];\n"); | |
792 | |
793 FOR_EACH_EDGE (e, ei, bb->succs) | |
794 if (full_p || in_current_region_p (e->dest)) | |
795 sel_dump_cfg_edge (f, e); | |
796 } | |
797 | |
798 fprintf (f, "}"); | |
799 | |
800 restore_dump (); | |
801 sched_dump_to_dot_p = false; | |
802 } | |
803 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
804 /* Dump a cfg region to the file specified by TAG honoring flags. |
0 | 805 The file is created by the function. */ |
806 static void | |
807 sel_dump_cfg_1 (const char *tag, int flags) | |
808 { | |
809 char *buf; | |
810 int i; | |
811 FILE *f; | |
812 | |
813 ++sel_dump_cfg_fileno; | |
814 | |
815 if (!sel_dump_cfg_p) | |
816 return; | |
817 | |
818 i = 1 + snprintf (NULL, 0, "%s/%s%05d-%s.dot", sel_debug_cfg_root, | |
819 sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag); | |
820 buf = XNEWVEC (char, i); | |
821 snprintf (buf, i, "%s/%s%05d-%s.dot", sel_debug_cfg_root, | |
822 sel_debug_cfg_root_postfix, sel_dump_cfg_fileno, tag); | |
823 | |
824 f = fopen (buf, "w"); | |
825 | |
826 if (f == NULL) | |
827 fprintf (stderr, "Can't create file: %s.\n", buf); | |
828 else | |
829 { | |
830 sel_dump_cfg_2 (f, flags); | |
831 | |
832 fclose (f); | |
833 } | |
834 | |
835 free (buf); | |
836 } | |
837 | |
838 /* Setup cfg dumping flags. Used for debugging. */ | |
839 void | |
840 setup_dump_cfg_params (void) | |
841 { | |
842 sel_dump_cfg_flags = SEL_DUMP_CFG_FLAGS; | |
843 sel_dump_cfg_p = 0; | |
844 sel_debug_cfg_root_postfix = sel_debug_cfg_root_postfix_default; | |
845 } | |
846 | |
847 /* Debug a cfg region with FLAGS. */ | |
848 void | |
849 sel_debug_cfg_1 (int flags) | |
850 { | |
851 bool t1 = sel_dump_cfg_p; | |
852 int t2 = sel_dump_cfg_fileno; | |
853 | |
854 sel_dump_cfg_p = true; | |
855 sel_dump_cfg_fileno = ++sel_debug_cfg_fileno; | |
856 | |
857 sel_dump_cfg_1 ("sel-debug-cfg", flags); | |
858 | |
859 sel_dump_cfg_fileno = t2; | |
860 sel_dump_cfg_p = t1; | |
861 } | |
862 | |
863 /* Dumps av_set AV to stderr. */ | |
864 void | |
865 debug_av_set (av_set_t av) | |
866 { | |
867 switch_dump (stderr); | |
868 dump_av_set (av); | |
869 sel_print ("\n"); | |
870 restore_dump (); | |
871 } | |
872 | |
873 /* Dump LV to stderr. */ | |
874 void | |
875 debug_lv_set (regset lv) | |
876 { | |
877 switch_dump (stderr); | |
878 dump_lv_set (lv); | |
879 sel_print ("\n"); | |
880 restore_dump (); | |
881 } | |
882 | |
883 /* Dump an instruction list P to stderr. */ | |
884 void | |
885 debug_ilist (ilist_t p) | |
886 { | |
887 switch_dump (stderr); | |
888 dump_ilist (p); | |
889 sel_print ("\n"); | |
890 restore_dump (); | |
891 } | |
892 | |
893 /* Dump a boundary list BNDS to stderr. */ | |
894 void | |
895 debug_blist (blist_t bnds) | |
896 { | |
897 switch_dump (stderr); | |
898 dump_blist (bnds); | |
899 sel_print ("\n"); | |
900 restore_dump (); | |
901 } | |
902 | |
903 /* Dump an insn vector SUCCS. */ | |
904 void | |
905 debug_insn_vector (rtx_vec_t succs) | |
906 { | |
907 switch_dump (stderr); | |
908 dump_insn_vector (succs); | |
909 sel_print ("\n"); | |
910 restore_dump (); | |
911 } | |
912 | |
913 /* Dump a hard reg set SET to stderr. */ | |
914 void | |
915 debug_hard_reg_set (HARD_REG_SET set) | |
916 { | |
917 switch_dump (stderr); | |
918 dump_hard_reg_set ("", set); | |
919 sel_print ("\n"); | |
920 restore_dump (); | |
921 } | |
922 | |
923 /* Debug a cfg region with default flags. */ | |
924 void | |
925 sel_debug_cfg (void) | |
926 { | |
927 sel_debug_cfg_1 (sel_debug_cfg_flags); | |
928 } | |
929 | |
930 /* Print a current cselib value for X's address to stderr. */ | |
931 rtx | |
932 debug_mem_addr_value (rtx x) | |
933 { | |
934 rtx t, addr; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
935 enum machine_mode address_mode; |
0 | 936 |
937 gcc_assert (MEM_P (x)); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
938 address_mode = targetm.addr_space.address_mode (MEM_ADDR_SPACE (x)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
939 |
0 | 940 t = shallow_copy_rtx (x); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
941 if (cselib_lookup (XEXP (t, 0), address_mode, 0)) |
0 | 942 XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0)); |
943 | |
944 t = canon_rtx (t); | |
945 addr = get_addr (XEXP (t, 0)); | |
946 debug_rtx (t); | |
947 debug_rtx (addr); | |
948 return t; | |
949 } | |
950 #endif | |
951 |