print-rtl.c revision 18334
1/* Print RTL for GNU C Compiler. 2 Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc. 3 4This file is part of GNU CC. 5 6GNU CC is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 2, or (at your option) 9any later version. 10 11GNU CC is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GNU CC; see the file COPYING. If not, write to 18the Free Software Foundation, 59 Temple Place - Suite 330, 19Boston, MA 02111-1307, USA. */ 20 21 22#include "config.h" 23#include <ctype.h> 24#include <stdio.h> 25#include "rtl.h" 26 27 28/* How to print out a register name. 29 We don't use PRINT_REG because some definitions of PRINT_REG 30 don't work here. */ 31#ifndef DEBUG_PRINT_REG 32#define DEBUG_PRINT_REG(RTX, CODE, FILE) \ 33 fprintf ((FILE), "%d %s", REGNO (RTX), reg_names[REGNO (RTX)]) 34#endif 35 36/* Array containing all of the register names */ 37 38#ifdef DEBUG_REGISTER_NAMES 39static char *reg_names[] = DEBUG_REGISTER_NAMES; 40#else 41static char *reg_names[] = REGISTER_NAMES; 42#endif 43 44static FILE *outfile; 45 46char spaces[] = " "; 47 48static int sawclose = 0; 49 50/* Names for patterns. Non-zero only when linked with insn-output.c. */ 51 52extern char **insn_name_ptr; 53 54/* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */ 55 56static void 57print_rtx (in_rtx) 58 register rtx in_rtx; 59{ 60 static int indent; 61 register int i, j; 62 register char *format_ptr; 63 register int is_insn; 64 65 if (sawclose) 66 { 67 fprintf (outfile, "\n%s", 68 (spaces + (sizeof spaces - 1 - indent * 2))); 69 sawclose = 0; 70 } 71 72 if (in_rtx == 0) 73 { 74 fprintf (outfile, "(nil)"); 75 sawclose = 1; 76 return; 77 } 78 79 /* print name of expression code */ 80 fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx))); 81 82 if (in_rtx->in_struct) 83 fprintf (outfile, "/s"); 84 85 if (in_rtx->volatil) 86 fprintf (outfile, "/v"); 87 88 if (in_rtx->unchanging) 89 fprintf (outfile, "/u"); 90 91 if (in_rtx->integrated) 92 fprintf (outfile, "/i"); 93 94 if (GET_MODE (in_rtx) != VOIDmode) 95 { 96 /* Print REG_NOTE names for EXPR_LIST and INSN_LIST. */ 97 if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST) 98 fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx))); 99 else 100 fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx))); 101 } 102 103 is_insn = (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i'); 104 format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)); 105 106 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++) 107 switch (*format_ptr++) 108 { 109 case 'S': 110 case 's': 111 if (XSTR (in_rtx, i) == 0) 112 fprintf (outfile, " \"\""); 113 else 114 fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i)); 115 sawclose = 1; 116 break; 117 118 /* 0 indicates a field for internal use that should not be printed. */ 119 case '0': 120 break; 121 122 case 'e': 123 indent += 2; 124 if (!sawclose) 125 fprintf (outfile, " "); 126 print_rtx (XEXP (in_rtx, i)); 127 indent -= 2; 128 break; 129 130 case 'E': 131 case 'V': 132 indent += 2; 133 if (sawclose) 134 { 135 fprintf (outfile, "\n%s", 136 (spaces + (sizeof spaces - 1 - indent * 2))); 137 sawclose = 0; 138 } 139 fprintf (outfile, "[ "); 140 if (NULL != XVEC (in_rtx, i)) 141 { 142 indent += 2; 143 if (XVECLEN (in_rtx, i)) 144 sawclose = 1; 145 146 for (j = 0; j < XVECLEN (in_rtx, i); j++) 147 print_rtx (XVECEXP (in_rtx, i, j)); 148 149 indent -= 2; 150 } 151 if (sawclose) 152 fprintf (outfile, "\n%s", 153 (spaces + (sizeof spaces - 1 - indent * 2))); 154 155 fprintf (outfile, "] "); 156 sawclose = 1; 157 indent -= 2; 158 break; 159 160 case 'w': 161 fprintf (outfile, 162#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT 163 " %d", 164#else 165 " %ld", 166#endif 167 XWINT (in_rtx, i)); 168 break; 169 170 case 'i': 171 { 172 register int value = XINT (in_rtx, i); 173 174 if (GET_CODE (in_rtx) == REG && value < FIRST_PSEUDO_REGISTER) 175 { 176 fputc (' ', outfile); 177 DEBUG_PRINT_REG (in_rtx, 0, outfile); 178 } 179 else 180 fprintf (outfile, " %d", value); 181 } 182 if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i) 183 && insn_name_ptr 184 && XINT (in_rtx, i) >= 0) 185 fprintf (outfile, " {%s}", insn_name_ptr[XINT (in_rtx, i)]); 186 sawclose = 0; 187 break; 188 189 /* Print NOTE_INSN names rather than integer codes. */ 190 191 case 'n': 192 if (XINT (in_rtx, i) <= 0) 193 fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i))); 194 else 195 fprintf (outfile, " %d", XINT (in_rtx, i)); 196 sawclose = 0; 197 break; 198 199 case 'u': 200 if (XEXP (in_rtx, i) != NULL) 201 fprintf (outfile, " %d", INSN_UID (XEXP (in_rtx, i))); 202 else 203 fprintf (outfile, " 0"); 204 sawclose = 0; 205 break; 206 207 case '*': 208 fprintf (outfile, " Unknown"); 209 sawclose = 0; 210 break; 211 212 default: 213 fprintf (stderr, 214 "switch format wrong in rtl.print_rtx(). format was: %c.\n", 215 format_ptr[-1]); 216 abort (); 217 } 218 219 fprintf (outfile, ")"); 220 sawclose = 1; 221} 222 223/* Call this function from the debugger to see what X looks like. */ 224 225void 226debug_rtx (x) 227 rtx x; 228{ 229 outfile = stderr; 230 print_rtx (x); 231 fprintf (stderr, "\n"); 232} 233 234/* Count of rtx's to print with debug_rtx_list. 235 This global exists because gdb user defined commands have no arguments. */ 236 237int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */ 238 239/* Call this function to print list from X on. 240 241 N is a count of the rtx's to print. Positive values print from the specified 242 rtx on. Negative values print a window around the rtx. 243 EG: -5 prints 2 rtx's on either side (in addition to the specified rtx). */ 244 245void 246debug_rtx_list (x, n) 247 rtx x; 248 int n; 249{ 250 int i,count; 251 rtx insn; 252 253 count = n == 0 ? 1 : n < 0 ? -n : n; 254 255 /* If we are printing a window, back up to the start. */ 256 257 if (n < 0) 258 for (i = count / 2; i > 0; i--) 259 { 260 if (PREV_INSN (x) == 0) 261 break; 262 x = PREV_INSN (x); 263 } 264 265 for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn)) 266 debug_rtx (insn); 267} 268 269/* Call this function to search an rtx list to find one with insn uid UID, 270 and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT. 271 The found insn is returned to enable further debugging analysis. */ 272 273rtx 274debug_rtx_find(x, uid) 275 rtx x; 276 int uid; 277{ 278 while (x != 0 && INSN_UID (x) != uid) 279 x = NEXT_INSN (x); 280 if (x != 0) 281 { 282 debug_rtx_list (x, debug_rtx_count); 283 return x; 284 } 285 else 286 { 287 fprintf (stderr, "insn uid %d not found\n", uid); 288 return 0; 289 } 290} 291 292/* External entry point for printing a chain of insns 293 starting with RTX_FIRST onto file OUTF. 294 A blank line separates insns. 295 296 If RTX_FIRST is not an insn, then it alone is printed, with no newline. */ 297 298void 299print_rtl (outf, rtx_first) 300 FILE *outf; 301 rtx rtx_first; 302{ 303 register rtx tmp_rtx; 304 305 outfile = outf; 306 sawclose = 0; 307 308 if (rtx_first == 0) 309 fprintf (outf, "(nil)\n"); 310 else 311 switch (GET_CODE (rtx_first)) 312 { 313 case INSN: 314 case JUMP_INSN: 315 case CALL_INSN: 316 case NOTE: 317 case CODE_LABEL: 318 case BARRIER: 319 for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx)) 320 { 321 print_rtx (tmp_rtx); 322 fprintf (outfile, "\n"); 323 } 324 break; 325 326 default: 327 print_rtx (rtx_first); 328 } 329} 330