Mercurial > hg > CbC > CbC_gcc
comparison gcc/sched-vis.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Instruction scheduling pass. | |
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, | |
3 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. | |
4 Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by, | |
5 and currently maintained by, Jim Wilson (wilson@cygnus.com) | |
6 | |
7 This file is part of GCC. | |
8 | |
9 GCC is free software; you can redistribute it and/or modify it under | |
10 the terms of the GNU General Public License as published by the Free | |
11 Software Foundation; either version 3, or (at your option) any later | |
12 version. | |
13 | |
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with GCC; see the file COPYING3. If not see | |
21 <http://www.gnu.org/licenses/>. */ | |
22 | |
23 #include "config.h" | |
24 #include "system.h" | |
25 #include "coretypes.h" | |
26 #include "tm.h" | |
27 #include "rtl.h" | |
28 #include "obstack.h" | |
29 #include "hard-reg-set.h" | |
30 #include "basic-block.h" | |
31 #include "real.h" | |
32 #include "insn-attr.h" | |
33 #include "sched-int.h" | |
34 #include "tree-pass.h" | |
35 | |
36 static char *safe_concat (char *, char *, const char *); | |
37 | |
38 #define BUF_LEN 2048 | |
39 | |
40 static char * | |
41 safe_concat (char *buf, char *cur, const char *str) | |
42 { | |
43 char *end = buf + BUF_LEN - 2; /* Leave room for null. */ | |
44 int c; | |
45 | |
46 if (cur > end) | |
47 { | |
48 *end = '\0'; | |
49 return end; | |
50 } | |
51 | |
52 while (cur < end && (c = *str++) != '\0') | |
53 *cur++ = c; | |
54 | |
55 *cur = '\0'; | |
56 return cur; | |
57 } | |
58 | |
59 /* This recognizes rtx, I classified as expressions. These are always | |
60 represent some action on values or results of other expression, that | |
61 may be stored in objects representing values. */ | |
62 | |
63 static void | |
64 print_exp (char *buf, const_rtx x, int verbose) | |
65 { | |
66 char tmp[BUF_LEN]; | |
67 const char *st[4]; | |
68 char *cur = buf; | |
69 const char *fun = (char *) 0; | |
70 const char *sep; | |
71 rtx op[4]; | |
72 int i; | |
73 | |
74 for (i = 0; i < 4; i++) | |
75 { | |
76 st[i] = (char *) 0; | |
77 op[i] = NULL_RTX; | |
78 } | |
79 | |
80 switch (GET_CODE (x)) | |
81 { | |
82 case PLUS: | |
83 op[0] = XEXP (x, 0); | |
84 if (GET_CODE (XEXP (x, 1)) == CONST_INT | |
85 && INTVAL (XEXP (x, 1)) < 0) | |
86 { | |
87 st[1] = "-"; | |
88 op[1] = GEN_INT (-INTVAL (XEXP (x, 1))); | |
89 } | |
90 else | |
91 { | |
92 st[1] = "+"; | |
93 op[1] = XEXP (x, 1); | |
94 } | |
95 break; | |
96 case LO_SUM: | |
97 op[0] = XEXP (x, 0); | |
98 st[1] = "+low("; | |
99 op[1] = XEXP (x, 1); | |
100 st[2] = ")"; | |
101 break; | |
102 case MINUS: | |
103 op[0] = XEXP (x, 0); | |
104 st[1] = "-"; | |
105 op[1] = XEXP (x, 1); | |
106 break; | |
107 case COMPARE: | |
108 fun = "cmp"; | |
109 op[0] = XEXP (x, 0); | |
110 op[1] = XEXP (x, 1); | |
111 break; | |
112 case NEG: | |
113 st[0] = "-"; | |
114 op[0] = XEXP (x, 0); | |
115 break; | |
116 case MULT: | |
117 op[0] = XEXP (x, 0); | |
118 st[1] = "*"; | |
119 op[1] = XEXP (x, 1); | |
120 break; | |
121 case DIV: | |
122 op[0] = XEXP (x, 0); | |
123 st[1] = "/"; | |
124 op[1] = XEXP (x, 1); | |
125 break; | |
126 case UDIV: | |
127 fun = "udiv"; | |
128 op[0] = XEXP (x, 0); | |
129 op[1] = XEXP (x, 1); | |
130 break; | |
131 case MOD: | |
132 op[0] = XEXP (x, 0); | |
133 st[1] = "%"; | |
134 op[1] = XEXP (x, 1); | |
135 break; | |
136 case UMOD: | |
137 fun = "umod"; | |
138 op[0] = XEXP (x, 0); | |
139 op[1] = XEXP (x, 1); | |
140 break; | |
141 case SMIN: | |
142 fun = "smin"; | |
143 op[0] = XEXP (x, 0); | |
144 op[1] = XEXP (x, 1); | |
145 break; | |
146 case SMAX: | |
147 fun = "smax"; | |
148 op[0] = XEXP (x, 0); | |
149 op[1] = XEXP (x, 1); | |
150 break; | |
151 case UMIN: | |
152 fun = "umin"; | |
153 op[0] = XEXP (x, 0); | |
154 op[1] = XEXP (x, 1); | |
155 break; | |
156 case UMAX: | |
157 fun = "umax"; | |
158 op[0] = XEXP (x, 0); | |
159 op[1] = XEXP (x, 1); | |
160 break; | |
161 case NOT: | |
162 st[0] = "!"; | |
163 op[0] = XEXP (x, 0); | |
164 break; | |
165 case AND: | |
166 op[0] = XEXP (x, 0); | |
167 st[1] = "&"; | |
168 op[1] = XEXP (x, 1); | |
169 break; | |
170 case IOR: | |
171 op[0] = XEXP (x, 0); | |
172 st[1] = "|"; | |
173 op[1] = XEXP (x, 1); | |
174 break; | |
175 case XOR: | |
176 op[0] = XEXP (x, 0); | |
177 st[1] = "^"; | |
178 op[1] = XEXP (x, 1); | |
179 break; | |
180 case ASHIFT: | |
181 op[0] = XEXP (x, 0); | |
182 st[1] = "<<"; | |
183 op[1] = XEXP (x, 1); | |
184 break; | |
185 case LSHIFTRT: | |
186 op[0] = XEXP (x, 0); | |
187 st[1] = " 0>>"; | |
188 op[1] = XEXP (x, 1); | |
189 break; | |
190 case ASHIFTRT: | |
191 op[0] = XEXP (x, 0); | |
192 st[1] = ">>"; | |
193 op[1] = XEXP (x, 1); | |
194 break; | |
195 case ROTATE: | |
196 op[0] = XEXP (x, 0); | |
197 st[1] = "<-<"; | |
198 op[1] = XEXP (x, 1); | |
199 break; | |
200 case ROTATERT: | |
201 op[0] = XEXP (x, 0); | |
202 st[1] = ">->"; | |
203 op[1] = XEXP (x, 1); | |
204 break; | |
205 case ABS: | |
206 fun = "abs"; | |
207 op[0] = XEXP (x, 0); | |
208 break; | |
209 case SQRT: | |
210 fun = "sqrt"; | |
211 op[0] = XEXP (x, 0); | |
212 break; | |
213 case FFS: | |
214 fun = "ffs"; | |
215 op[0] = XEXP (x, 0); | |
216 break; | |
217 case EQ: | |
218 op[0] = XEXP (x, 0); | |
219 st[1] = "=="; | |
220 op[1] = XEXP (x, 1); | |
221 break; | |
222 case NE: | |
223 op[0] = XEXP (x, 0); | |
224 st[1] = "!="; | |
225 op[1] = XEXP (x, 1); | |
226 break; | |
227 case GT: | |
228 op[0] = XEXP (x, 0); | |
229 st[1] = ">"; | |
230 op[1] = XEXP (x, 1); | |
231 break; | |
232 case GTU: | |
233 fun = "gtu"; | |
234 op[0] = XEXP (x, 0); | |
235 op[1] = XEXP (x, 1); | |
236 break; | |
237 case LT: | |
238 op[0] = XEXP (x, 0); | |
239 st[1] = "<"; | |
240 op[1] = XEXP (x, 1); | |
241 break; | |
242 case LTU: | |
243 fun = "ltu"; | |
244 op[0] = XEXP (x, 0); | |
245 op[1] = XEXP (x, 1); | |
246 break; | |
247 case GE: | |
248 op[0] = XEXP (x, 0); | |
249 st[1] = ">="; | |
250 op[1] = XEXP (x, 1); | |
251 break; | |
252 case GEU: | |
253 fun = "geu"; | |
254 op[0] = XEXP (x, 0); | |
255 op[1] = XEXP (x, 1); | |
256 break; | |
257 case LE: | |
258 op[0] = XEXP (x, 0); | |
259 st[1] = "<="; | |
260 op[1] = XEXP (x, 1); | |
261 break; | |
262 case LEU: | |
263 fun = "leu"; | |
264 op[0] = XEXP (x, 0); | |
265 op[1] = XEXP (x, 1); | |
266 break; | |
267 case SIGN_EXTRACT: | |
268 fun = (verbose) ? "sign_extract" : "sxt"; | |
269 op[0] = XEXP (x, 0); | |
270 op[1] = XEXP (x, 1); | |
271 op[2] = XEXP (x, 2); | |
272 break; | |
273 case ZERO_EXTRACT: | |
274 fun = (verbose) ? "zero_extract" : "zxt"; | |
275 op[0] = XEXP (x, 0); | |
276 op[1] = XEXP (x, 1); | |
277 op[2] = XEXP (x, 2); | |
278 break; | |
279 case SIGN_EXTEND: | |
280 fun = (verbose) ? "sign_extend" : "sxn"; | |
281 op[0] = XEXP (x, 0); | |
282 break; | |
283 case ZERO_EXTEND: | |
284 fun = (verbose) ? "zero_extend" : "zxn"; | |
285 op[0] = XEXP (x, 0); | |
286 break; | |
287 case FLOAT_EXTEND: | |
288 fun = (verbose) ? "float_extend" : "fxn"; | |
289 op[0] = XEXP (x, 0); | |
290 break; | |
291 case TRUNCATE: | |
292 fun = (verbose) ? "trunc" : "trn"; | |
293 op[0] = XEXP (x, 0); | |
294 break; | |
295 case FLOAT_TRUNCATE: | |
296 fun = (verbose) ? "float_trunc" : "ftr"; | |
297 op[0] = XEXP (x, 0); | |
298 break; | |
299 case FLOAT: | |
300 fun = (verbose) ? "float" : "flt"; | |
301 op[0] = XEXP (x, 0); | |
302 break; | |
303 case UNSIGNED_FLOAT: | |
304 fun = (verbose) ? "uns_float" : "ufl"; | |
305 op[0] = XEXP (x, 0); | |
306 break; | |
307 case FIX: | |
308 fun = "fix"; | |
309 op[0] = XEXP (x, 0); | |
310 break; | |
311 case UNSIGNED_FIX: | |
312 fun = (verbose) ? "uns_fix" : "ufx"; | |
313 op[0] = XEXP (x, 0); | |
314 break; | |
315 case PRE_DEC: | |
316 st[0] = "--"; | |
317 op[0] = XEXP (x, 0); | |
318 break; | |
319 case PRE_INC: | |
320 st[0] = "++"; | |
321 op[0] = XEXP (x, 0); | |
322 break; | |
323 case POST_DEC: | |
324 op[0] = XEXP (x, 0); | |
325 st[1] = "--"; | |
326 break; | |
327 case POST_INC: | |
328 op[0] = XEXP (x, 0); | |
329 st[1] = "++"; | |
330 break; | |
331 case PRE_MODIFY: | |
332 st[0] = "pre "; | |
333 op[0] = XEXP (XEXP (x, 1), 0); | |
334 st[1] = "+="; | |
335 op[1] = XEXP (XEXP (x, 1), 1); | |
336 break; | |
337 case POST_MODIFY: | |
338 st[0] = "post "; | |
339 op[0] = XEXP (XEXP (x, 1), 0); | |
340 st[1] = "+="; | |
341 op[1] = XEXP (XEXP (x, 1), 1); | |
342 break; | |
343 case CALL: | |
344 st[0] = "call "; | |
345 op[0] = XEXP (x, 0); | |
346 if (verbose) | |
347 { | |
348 st[1] = " argc:"; | |
349 op[1] = XEXP (x, 1); | |
350 } | |
351 break; | |
352 case IF_THEN_ELSE: | |
353 st[0] = "{("; | |
354 op[0] = XEXP (x, 0); | |
355 st[1] = ")?"; | |
356 op[1] = XEXP (x, 1); | |
357 st[2] = ":"; | |
358 op[2] = XEXP (x, 2); | |
359 st[3] = "}"; | |
360 break; | |
361 case TRAP_IF: | |
362 fun = "trap_if"; | |
363 op[0] = TRAP_CONDITION (x); | |
364 break; | |
365 case PREFETCH: | |
366 fun = "prefetch"; | |
367 op[0] = XEXP (x, 0); | |
368 op[1] = XEXP (x, 1); | |
369 op[2] = XEXP (x, 2); | |
370 break; | |
371 case UNSPEC: | |
372 case UNSPEC_VOLATILE: | |
373 { | |
374 cur = safe_concat (buf, cur, "unspec"); | |
375 if (GET_CODE (x) == UNSPEC_VOLATILE) | |
376 cur = safe_concat (buf, cur, "/v"); | |
377 cur = safe_concat (buf, cur, "["); | |
378 sep = ""; | |
379 for (i = 0; i < XVECLEN (x, 0); i++) | |
380 { | |
381 print_pattern (tmp, XVECEXP (x, 0, i), verbose); | |
382 cur = safe_concat (buf, cur, sep); | |
383 cur = safe_concat (buf, cur, tmp); | |
384 sep = ","; | |
385 } | |
386 cur = safe_concat (buf, cur, "] "); | |
387 sprintf (tmp, "%d", XINT (x, 1)); | |
388 cur = safe_concat (buf, cur, tmp); | |
389 } | |
390 break; | |
391 default: | |
392 /* If (verbose) debug_rtx (x); */ | |
393 st[0] = GET_RTX_NAME (GET_CODE (x)); | |
394 break; | |
395 } | |
396 | |
397 /* Print this as a function? */ | |
398 if (fun) | |
399 { | |
400 cur = safe_concat (buf, cur, fun); | |
401 cur = safe_concat (buf, cur, "("); | |
402 } | |
403 | |
404 for (i = 0; i < 4; i++) | |
405 { | |
406 if (st[i]) | |
407 cur = safe_concat (buf, cur, st[i]); | |
408 | |
409 if (op[i]) | |
410 { | |
411 if (fun && i != 0) | |
412 cur = safe_concat (buf, cur, ","); | |
413 | |
414 print_value (tmp, op[i], verbose); | |
415 cur = safe_concat (buf, cur, tmp); | |
416 } | |
417 } | |
418 | |
419 if (fun) | |
420 cur = safe_concat (buf, cur, ")"); | |
421 } /* print_exp */ | |
422 | |
423 /* Prints rtxes, I customarily classified as values. They're constants, | |
424 registers, labels, symbols and memory accesses. */ | |
425 | |
426 void | |
427 print_value (char *buf, const_rtx x, int verbose) | |
428 { | |
429 char t[BUF_LEN]; | |
430 char *cur = buf; | |
431 | |
432 switch (GET_CODE (x)) | |
433 { | |
434 case CONST_INT: | |
435 sprintf (t, HOST_WIDE_INT_PRINT_HEX, | |
436 (unsigned HOST_WIDE_INT) INTVAL (x)); | |
437 cur = safe_concat (buf, cur, t); | |
438 break; | |
439 case CONST_DOUBLE: | |
440 if (FLOAT_MODE_P (GET_MODE (x))) | |
441 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1); | |
442 else | |
443 sprintf (t, | |
444 "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">", | |
445 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x), | |
446 (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x)); | |
447 cur = safe_concat (buf, cur, t); | |
448 break; | |
449 case CONST_FIXED: | |
450 fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t)); | |
451 cur = safe_concat (buf, cur, t); | |
452 break; | |
453 case CONST_STRING: | |
454 cur = safe_concat (buf, cur, "\""); | |
455 cur = safe_concat (buf, cur, XSTR (x, 0)); | |
456 cur = safe_concat (buf, cur, "\""); | |
457 break; | |
458 case SYMBOL_REF: | |
459 cur = safe_concat (buf, cur, "`"); | |
460 cur = safe_concat (buf, cur, XSTR (x, 0)); | |
461 cur = safe_concat (buf, cur, "'"); | |
462 break; | |
463 case LABEL_REF: | |
464 sprintf (t, "L%d", INSN_UID (XEXP (x, 0))); | |
465 cur = safe_concat (buf, cur, t); | |
466 break; | |
467 case CONST: | |
468 print_value (t, XEXP (x, 0), verbose); | |
469 cur = safe_concat (buf, cur, "const("); | |
470 cur = safe_concat (buf, cur, t); | |
471 cur = safe_concat (buf, cur, ")"); | |
472 break; | |
473 case HIGH: | |
474 print_value (t, XEXP (x, 0), verbose); | |
475 cur = safe_concat (buf, cur, "high("); | |
476 cur = safe_concat (buf, cur, t); | |
477 cur = safe_concat (buf, cur, ")"); | |
478 break; | |
479 case REG: | |
480 if (REGNO (x) < FIRST_PSEUDO_REGISTER) | |
481 { | |
482 int c = reg_names[REGNO (x)][0]; | |
483 if (ISDIGIT (c)) | |
484 cur = safe_concat (buf, cur, "%"); | |
485 | |
486 cur = safe_concat (buf, cur, reg_names[REGNO (x)]); | |
487 } | |
488 else | |
489 { | |
490 sprintf (t, "r%d", REGNO (x)); | |
491 cur = safe_concat (buf, cur, t); | |
492 } | |
493 if (verbose | |
494 #ifdef INSN_SCHEDULING | |
495 && !current_sched_info | |
496 #endif | |
497 ) | |
498 { | |
499 sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x))); | |
500 cur = safe_concat (buf, cur, t); | |
501 } | |
502 break; | |
503 case SUBREG: | |
504 print_value (t, SUBREG_REG (x), verbose); | |
505 cur = safe_concat (buf, cur, t); | |
506 sprintf (t, "#%d", SUBREG_BYTE (x)); | |
507 cur = safe_concat (buf, cur, t); | |
508 break; | |
509 case SCRATCH: | |
510 cur = safe_concat (buf, cur, "scratch"); | |
511 break; | |
512 case CC0: | |
513 cur = safe_concat (buf, cur, "cc0"); | |
514 break; | |
515 case PC: | |
516 cur = safe_concat (buf, cur, "pc"); | |
517 break; | |
518 case MEM: | |
519 print_value (t, XEXP (x, 0), verbose); | |
520 cur = safe_concat (buf, cur, "["); | |
521 cur = safe_concat (buf, cur, t); | |
522 cur = safe_concat (buf, cur, "]"); | |
523 break; | |
524 default: | |
525 print_exp (t, x, verbose); | |
526 cur = safe_concat (buf, cur, t); | |
527 break; | |
528 } | |
529 } /* print_value */ | |
530 | |
531 /* The next step in insn detalization, its pattern recognition. */ | |
532 | |
533 void | |
534 print_pattern (char *buf, const_rtx x, int verbose) | |
535 { | |
536 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN]; | |
537 | |
538 switch (GET_CODE (x)) | |
539 { | |
540 case SET: | |
541 print_value (t1, SET_DEST (x), verbose); | |
542 print_value (t2, SET_SRC (x), verbose); | |
543 sprintf (buf, "%s=%s", t1, t2); | |
544 break; | |
545 case RETURN: | |
546 sprintf (buf, "return"); | |
547 break; | |
548 case CALL: | |
549 print_exp (buf, x, verbose); | |
550 break; | |
551 case CLOBBER: | |
552 print_value (t1, XEXP (x, 0), verbose); | |
553 sprintf (buf, "clobber %s", t1); | |
554 break; | |
555 case USE: | |
556 print_value (t1, XEXP (x, 0), verbose); | |
557 sprintf (buf, "use %s", t1); | |
558 break; | |
559 case COND_EXEC: | |
560 if (GET_CODE (COND_EXEC_TEST (x)) == NE | |
561 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx) | |
562 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose); | |
563 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ | |
564 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx) | |
565 { | |
566 t1[0] = '!'; | |
567 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose); | |
568 } | |
569 else | |
570 print_value (t1, COND_EXEC_TEST (x), verbose); | |
571 print_pattern (t2, COND_EXEC_CODE (x), verbose); | |
572 sprintf (buf, "(%s) %s", t1, t2); | |
573 break; | |
574 case PARALLEL: | |
575 { | |
576 int i; | |
577 | |
578 sprintf (t1, "{"); | |
579 for (i = 0; i < XVECLEN (x, 0); i++) | |
580 { | |
581 print_pattern (t2, XVECEXP (x, 0, i), verbose); | |
582 sprintf (t3, "%s%s;", t1, t2); | |
583 strcpy (t1, t3); | |
584 } | |
585 sprintf (buf, "%s}", t1); | |
586 } | |
587 break; | |
588 case SEQUENCE: | |
589 /* Should never see SEQUENCE codes until after reorg. */ | |
590 gcc_unreachable (); | |
591 case ASM_INPUT: | |
592 sprintf (buf, "asm {%s}", XSTR (x, 0)); | |
593 break; | |
594 case ADDR_VEC: | |
595 break; | |
596 case ADDR_DIFF_VEC: | |
597 print_value (buf, XEXP (x, 0), verbose); | |
598 break; | |
599 case TRAP_IF: | |
600 print_value (t1, TRAP_CONDITION (x), verbose); | |
601 sprintf (buf, "trap_if %s", t1); | |
602 break; | |
603 case UNSPEC: | |
604 { | |
605 int i; | |
606 | |
607 sprintf (t1, "unspec{"); | |
608 for (i = 0; i < XVECLEN (x, 0); i++) | |
609 { | |
610 print_pattern (t2, XVECEXP (x, 0, i), verbose); | |
611 sprintf (t3, "%s%s;", t1, t2); | |
612 strcpy (t1, t3); | |
613 } | |
614 sprintf (buf, "%s}", t1); | |
615 } | |
616 break; | |
617 case UNSPEC_VOLATILE: | |
618 { | |
619 int i; | |
620 | |
621 sprintf (t1, "unspec/v{"); | |
622 for (i = 0; i < XVECLEN (x, 0); i++) | |
623 { | |
624 print_pattern (t2, XVECEXP (x, 0, i), verbose); | |
625 sprintf (t3, "%s%s;", t1, t2); | |
626 strcpy (t1, t3); | |
627 } | |
628 sprintf (buf, "%s}", t1); | |
629 } | |
630 break; | |
631 default: | |
632 print_value (buf, x, verbose); | |
633 } | |
634 } /* print_pattern */ | |
635 | |
636 /* This is the main function in rtl visualization mechanism. It | |
637 accepts an rtx and tries to recognize it as an insn, then prints it | |
638 properly in human readable form, resembling assembler mnemonics. | |
639 For every insn it prints its UID and BB the insn belongs too. | |
640 (Probably the last "option" should be extended somehow, since it | |
641 depends now on sched.c inner variables ...) */ | |
642 | |
643 void | |
644 print_insn (char *buf, const_rtx x, int verbose) | |
645 { | |
646 char t[BUF_LEN]; | |
647 const_rtx insn = x; | |
648 | |
649 switch (GET_CODE (x)) | |
650 { | |
651 case INSN: | |
652 print_pattern (t, PATTERN (x), verbose); | |
653 #ifdef INSN_SCHEDULING | |
654 if (verbose && current_sched_info) | |
655 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), | |
656 t); | |
657 else | |
658 #endif | |
659 sprintf (buf, " %4d %s", INSN_UID (x), t); | |
660 break; | |
661 case JUMP_INSN: | |
662 print_pattern (t, PATTERN (x), verbose); | |
663 #ifdef INSN_SCHEDULING | |
664 if (verbose && current_sched_info) | |
665 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1), | |
666 t); | |
667 else | |
668 #endif | |
669 sprintf (buf, " %4d %s", INSN_UID (x), t); | |
670 break; | |
671 case CALL_INSN: | |
672 x = PATTERN (insn); | |
673 if (GET_CODE (x) == PARALLEL) | |
674 { | |
675 x = XVECEXP (x, 0, 0); | |
676 print_pattern (t, x, verbose); | |
677 } | |
678 else | |
679 strcpy (t, "call <...>"); | |
680 #ifdef INSN_SCHEDULING | |
681 if (verbose && current_sched_info) | |
682 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (insn, 1), t); | |
683 else | |
684 #endif | |
685 sprintf (buf, " %4d %s", INSN_UID (insn), t); | |
686 break; | |
687 case CODE_LABEL: | |
688 sprintf (buf, "L%d:", INSN_UID (x)); | |
689 break; | |
690 case BARRIER: | |
691 sprintf (buf, "i%4d: barrier", INSN_UID (x)); | |
692 break; | |
693 case NOTE: | |
694 sprintf (buf, " %4d %s", INSN_UID (x), | |
695 GET_NOTE_INSN_NAME (NOTE_KIND (x))); | |
696 break; | |
697 default: | |
698 sprintf (buf, "i%4d <What %s?>", INSN_UID (x), | |
699 GET_RTX_NAME (GET_CODE (x))); | |
700 } | |
701 } /* print_insn */ | |
702 | |
703 /* Emit a slim dump of X (an insn) to the file F, including any register | |
704 note attached to the instruction. */ | |
705 void | |
706 dump_insn_slim (FILE *f, rtx x) | |
707 { | |
708 char t[BUF_LEN + 32]; | |
709 rtx note; | |
710 | |
711 print_insn (t, x, 1); | |
712 fputs (t, f); | |
713 putc ('\n', f); | |
714 if (INSN_P (x) && REG_NOTES (x)) | |
715 for (note = REG_NOTES (x); note; note = XEXP (note, 1)) | |
716 { | |
717 print_value (t, XEXP (note, 0), 1); | |
718 fprintf (f, " %s: %s\n", | |
719 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t); | |
720 } | |
721 } | |
722 | |
723 /* Emit a slim dump of X (an insn) to stderr. */ | |
724 void | |
725 debug_insn_slim (rtx x) | |
726 { | |
727 dump_insn_slim (stderr, x); | |
728 } | |
729 | |
730 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring | |
731 the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS | |
732 include more information on the basic blocks. */ | |
733 void | |
734 print_rtl_slim_with_bb (FILE *f, rtx first, int flags) | |
735 { | |
736 print_rtl_slim (f, first, NULL, -1, flags); | |
737 } | |
738 | |
739 /* Same as above, but stop at LAST or when COUNT == 0. | |
740 If COUNT < 0 it will stop only at LAST or NULL rtx. */ | |
741 void | |
742 print_rtl_slim (FILE *f, rtx first, rtx last, int count, int flags) | |
743 { | |
744 basic_block current_bb = NULL; | |
745 rtx insn, tail; | |
746 | |
747 tail = last ? NEXT_INSN (last) : NULL_RTX; | |
748 for (insn = first; | |
749 (insn != NULL) && (insn != tail) && (count != 0); | |
750 insn = NEXT_INSN (insn)) | |
751 { | |
752 if ((flags & TDF_BLOCKS) | |
753 && (INSN_P (insn) || GET_CODE (insn) == NOTE) | |
754 && BLOCK_FOR_INSN (insn) | |
755 && !current_bb) | |
756 { | |
757 current_bb = BLOCK_FOR_INSN (insn); | |
758 dump_bb_info (current_bb, true, false, flags, ";; ", f); | |
759 } | |
760 | |
761 dump_insn_slim (f, insn); | |
762 | |
763 if ((flags & TDF_BLOCKS) | |
764 && current_bb | |
765 && insn == BB_END (current_bb)) | |
766 { | |
767 dump_bb_info (current_bb, false, true, flags, ";; ", f); | |
768 current_bb = NULL; | |
769 } | |
770 if (count > 0) | |
771 count--; | |
772 } | |
773 } | |
774 | |
775 void | |
776 debug_bb_slim (struct basic_block_def *bb) | |
777 { | |
778 print_rtl_slim (stderr, BB_HEAD (bb), BB_END (bb), -1, 32); | |
779 } | |
780 | |
781 void | |
782 debug_bb_n_slim (int n) | |
783 { | |
784 struct basic_block_def *bb = BASIC_BLOCK (n); | |
785 debug_bb_slim (bb); | |
786 } | |
787 |