00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef GENERATOR_FILE
00025 #include "bconfig.h"
00026 #else
00027 #include "config.h"
00028 #endif
00029
00030 #include "system.h"
00031 #include "coretypes.h"
00032 #include "tm.h"
00033 #include "rtl.h"
00034 #include "real.h"
00035 #include "ggc.h"
00036 #ifdef GENERATOR_FILE
00037 # include "errors.h"
00038 #else
00039 # include "toplev.h"
00040 #endif
00041
00042
00043
00044
00045
00046 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) sizeof FORMAT - 1 ,
00047
00048 const unsigned char rtx_length[NUM_RTX_CODE] = {
00049 #include "rtl.def"
00050 };
00051
00052 #undef DEF_RTL_EXPR
00053
00054
00055
00056 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
00057
00058 const char * const rtx_name[NUM_RTX_CODE] = {
00059 #include "rtl.def"
00060 };
00061
00062 #undef DEF_RTL_EXPR
00063
00064
00065
00066
00067
00068 const char * const rtx_format[NUM_RTX_CODE] = {
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
00097 #include "rtl.def"
00098 #undef DEF_RTL_EXPR
00099 };
00100
00101
00102
00103
00104 const enum rtx_class rtx_class[NUM_RTX_CODE] = {
00105 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) CLASS,
00106 #include "rtl.def"
00107 #undef DEF_RTL_EXPR
00108 };
00109
00110
00111
00112 const unsigned char rtx_code_size[NUM_RTX_CODE] = {
00113 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) \
00114 ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE \
00115 ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT) \
00116 : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)),
00117
00118 #include "rtl.def"
00119 #undef DEF_RTL_EXPR
00120 };
00121
00122
00123 extern char NOTE_INSN_MAX_isnt_negative_adjust_NOTE_INSN_BIAS
00124 [NOTE_INSN_MAX < 0 ? 1 : -1];
00125
00126
00127
00128 const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS] =
00129 {
00130 "",
00131 #define DEF_INSN_NOTE(NAME) #NAME,
00132 #include "insn-notes.def"
00133 #undef DEF_INSN_NOTE
00134 };
00135
00136 const char * const reg_note_name[REG_NOTE_MAX] =
00137 {
00138 #define DEF_REG_NOTE(NAME) #NAME,
00139 #include "reg-notes.def"
00140 #undef DEF_REG_NOTE
00141 };
00142
00143 #ifdef GATHER_STATISTICS
00144 static int rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE];
00145 static int rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE];
00146 static int rtvec_alloc_counts;
00147 static int rtvec_alloc_sizes;
00148 #endif
00149
00150
00151
00152
00153
00154 rtvec
00155 rtvec_alloc (int n)
00156 {
00157 rtvec rt;
00158
00159 rt = ggc_alloc_rtvec (n);
00160
00161 memset (&rt->elem[0], 0, n * sizeof (rtx));
00162
00163 PUT_NUM_ELEM (rt, n);
00164
00165 #ifdef GATHER_STATISTICS
00166 rtvec_alloc_counts++;
00167 rtvec_alloc_sizes += n * sizeof (rtx);
00168 #endif
00169
00170 return rt;
00171 }
00172
00173
00174
00175 unsigned int
00176 rtx_size (rtx x)
00177 {
00178 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_HAS_BLOCK_INFO_P (x))
00179 return RTX_HDR_SIZE + sizeof (struct block_symbol);
00180 return RTX_CODE_SIZE (GET_CODE (x));
00181 }
00182
00183
00184
00185
00186 rtx
00187 rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL)
00188 {
00189 rtx rt;
00190
00191 rt = (rtx) ggc_alloc_zone_pass_stat (RTX_CODE_SIZE (code), &rtl_zone);
00192
00193
00194
00195
00196
00197 memset (rt, 0, RTX_HDR_SIZE);
00198 PUT_CODE (rt, code);
00199
00200 #ifdef GATHER_STATISTICS
00201 rtx_alloc_counts[code]++;
00202 rtx_alloc_sizes[code] += RTX_CODE_SIZE (code);
00203 #endif
00204
00205 return rt;
00206 }
00207
00208
00209
00210
00211
00212
00213 rtx
00214 copy_rtx (rtx orig)
00215 {
00216 rtx copy;
00217 int i, j;
00218 RTX_CODE code;
00219 const char *format_ptr;
00220
00221 code = GET_CODE (orig);
00222
00223 switch (code)
00224 {
00225 case REG:
00226 case CONST_INT:
00227 case CONST_DOUBLE:
00228 case CONST_VECTOR:
00229 case SYMBOL_REF:
00230 case CODE_LABEL:
00231 case PC:
00232 case CC0:
00233 case SCRATCH:
00234
00235 return orig;
00236 case CLOBBER:
00237 if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER)
00238 return orig;
00239 break;
00240
00241 case CONST:
00242
00243
00244 if (GET_CODE (XEXP (orig, 0)) == PLUS
00245 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
00246 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
00247 return orig;
00248 break;
00249
00250
00251
00252
00253
00254
00255 default:
00256 break;
00257 }
00258
00259
00260
00261
00262
00263 copy = shallow_copy_rtx (orig);
00264
00265
00266
00267 RTX_FLAG (copy, used) = 0;
00268
00269
00270 if (INSN_P (orig))
00271 RTX_FLAG (copy, frame_related) = 0;
00272 RTX_FLAG (copy, jump) = RTX_FLAG (orig, jump);
00273 RTX_FLAG (copy, call) = RTX_FLAG (orig, call);
00274
00275 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
00276
00277 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
00278 switch (*format_ptr++)
00279 {
00280 case 'e':
00281 if (XEXP (orig, i) != NULL)
00282 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
00283 break;
00284
00285 case 'E':
00286 case 'V':
00287 if (XVEC (orig, i) != NULL)
00288 {
00289 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
00290 for (j = 0; j < XVECLEN (copy, i); j++)
00291 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
00292 }
00293 break;
00294
00295 case 't':
00296 case 'w':
00297 case 'i':
00298 case 's':
00299 case 'S':
00300 case 'T':
00301 case 'u':
00302 case 'B':
00303 case '0':
00304
00305 break;
00306
00307 default:
00308 gcc_unreachable ();
00309 }
00310 return copy;
00311 }
00312
00313
00314
00315 rtx
00316 shallow_copy_rtx_stat (rtx orig MEM_STAT_DECL)
00317 {
00318 unsigned int size;
00319 rtx copy;
00320
00321 size = rtx_size (orig);
00322 copy = (rtx) ggc_alloc_zone_pass_stat (size, &rtl_zone);
00323 memcpy (copy, orig, size);
00324 return copy;
00325 }
00326
00327
00328 int generating_concat_p;
00329
00330
00331 int currently_expanding_to_rtl;
00332
00333
00334
00335
00336
00337 int
00338 rtx_equal_p (rtx x, rtx y)
00339 {
00340 int i;
00341 int j;
00342 enum rtx_code code;
00343 const char *fmt;
00344
00345 if (x == y)
00346 return 1;
00347 if (x == 0 || y == 0)
00348 return 0;
00349
00350 code = GET_CODE (x);
00351
00352 if (code != GET_CODE (y))
00353 return 0;
00354
00355
00356
00357
00358 if (GET_MODE (x) != GET_MODE (y))
00359 return 0;
00360
00361
00362 switch (code)
00363 {
00364 case REG:
00365 return (REGNO (x) == REGNO (y));
00366
00367 case LABEL_REF:
00368 return XEXP (x, 0) == XEXP (y, 0);
00369
00370 case SYMBOL_REF:
00371 return XSTR (x, 0) == XSTR (y, 0);
00372
00373 case SCRATCH:
00374 case CONST_DOUBLE:
00375 case CONST_INT:
00376 return 0;
00377
00378 default:
00379 break;
00380 }
00381
00382
00383
00384
00385 fmt = GET_RTX_FORMAT (code);
00386 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00387 {
00388 switch (fmt[i])
00389 {
00390 case 'w':
00391 if (XWINT (x, i) != XWINT (y, i))
00392 return 0;
00393 break;
00394
00395 case 'n':
00396 case 'i':
00397 if (XINT (x, i) != XINT (y, i))
00398 return 0;
00399 break;
00400
00401 case 'V':
00402 case 'E':
00403
00404 if (XVECLEN (x, i) != XVECLEN (y, i))
00405 return 0;
00406
00407
00408 for (j = 0; j < XVECLEN (x, i); j++)
00409 if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
00410 return 0;
00411 break;
00412
00413 case 'e':
00414 if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
00415 return 0;
00416 break;
00417
00418 case 'S':
00419 case 's':
00420 if ((XSTR (x, i) || XSTR (y, i))
00421 && (! XSTR (x, i) || ! XSTR (y, i)
00422 || strcmp (XSTR (x, i), XSTR (y, i))))
00423 return 0;
00424 break;
00425
00426 case 'u':
00427
00428 break;
00429
00430 case '0':
00431 case 't':
00432 break;
00433
00434
00435
00436
00437 default:
00438 gcc_unreachable ();
00439 }
00440 }
00441 return 1;
00442 }
00443
00444 void
00445 dump_rtx_statistics (void)
00446 {
00447 #ifdef GATHER_STATISTICS
00448 int i;
00449 int total_counts = 0;
00450 int total_sizes = 0;
00451 fprintf (stderr, "\nRTX Kind Count Bytes\n");
00452 fprintf (stderr, "---------------------------------------\n");
00453 for (i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
00454 if (rtx_alloc_counts[i])
00455 {
00456 fprintf (stderr, "%-20s %7d %10d\n", GET_RTX_NAME (i),
00457 rtx_alloc_counts[i], rtx_alloc_sizes[i]);
00458 total_counts += rtx_alloc_counts[i];
00459 total_sizes += rtx_alloc_sizes[i];
00460 }
00461 if (rtvec_alloc_counts)
00462 {
00463 fprintf (stderr, "%-20s %7d %10d\n", "rtvec",
00464 rtvec_alloc_counts, rtvec_alloc_sizes);
00465 total_counts += rtvec_alloc_counts;
00466 total_sizes += rtvec_alloc_sizes;
00467 }
00468 fprintf (stderr, "---------------------------------------\n");
00469 fprintf (stderr, "%-20s %7d %10d\n",
00470 "Total", total_counts, total_sizes);
00471 fprintf (stderr, "---------------------------------------\n");
00472 #endif
00473 }
00474
00475 #if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
00476 void
00477 rtl_check_failed_bounds (rtx r, int n, const char *file, int line,
00478 const char *func)
00479 {
00480 internal_error
00481 ("RTL check: access of elt %d of '%s' with last elt %d in %s, at %s:%d",
00482 n, GET_RTX_NAME (GET_CODE (r)), GET_RTX_LENGTH (GET_CODE (r)) - 1,
00483 func, trim_filename (file), line);
00484 }
00485
00486 void
00487 rtl_check_failed_type1 (rtx r, int n, int c1, const char *file, int line,
00488 const char *func)
00489 {
00490 internal_error
00491 ("RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d",
00492 n, c1, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
00493 func, trim_filename (file), line);
00494 }
00495
00496 void
00497 rtl_check_failed_type2 (rtx r, int n, int c1, int c2, const char *file,
00498 int line, const char *func)
00499 {
00500 internal_error
00501 ("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d",
00502 n, c1, c2, GET_RTX_FORMAT (GET_CODE (r))[n], GET_RTX_NAME (GET_CODE (r)),
00503 func, trim_filename (file), line);
00504 }
00505
00506 void
00507 rtl_check_failed_code1 (rtx r, enum rtx_code code, const char *file,
00508 int line, const char *func)
00509 {
00510 internal_error ("RTL check: expected code '%s', have '%s' in %s, at %s:%d",
00511 GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func,
00512 trim_filename (file), line);
00513 }
00514
00515 void
00516 rtl_check_failed_code2 (rtx r, enum rtx_code code1, enum rtx_code code2,
00517 const char *file, int line, const char *func)
00518 {
00519 internal_error
00520 ("RTL check: expected code '%s' or '%s', have '%s' in %s, at %s:%d",
00521 GET_RTX_NAME (code1), GET_RTX_NAME (code2), GET_RTX_NAME (GET_CODE (r)),
00522 func, trim_filename (file), line);
00523 }
00524
00525 void
00526 rtl_check_failed_code_mode (rtx r, enum rtx_code code, enum machine_mode mode,
00527 bool not_mode, const char *file, int line,
00528 const char *func)
00529 {
00530 internal_error ((not_mode
00531 ? ("RTL check: expected code '%s' and not mode '%s', "
00532 "have code '%s' and mode '%s' in %s, at %s:%d")
00533 : ("RTL check: expected code '%s' and mode '%s', "
00534 "have code '%s' and mode '%s' in %s, at %s:%d")),
00535 GET_RTX_NAME (code), GET_MODE_NAME (mode),
00536 GET_RTX_NAME (GET_CODE (r)), GET_MODE_NAME (GET_MODE (r)),
00537 func, trim_filename (file), line);
00538 }
00539
00540
00541
00542
00543 void
00544 rtl_check_failed_block_symbol (const char *file, int line, const char *func)
00545 {
00546 internal_error
00547 ("RTL check: attempt to treat non-block symbol as a block symbol "
00548 "in %s, at %s:%d", func, trim_filename (file), line);
00549 }
00550
00551
00552 void
00553 rtvec_check_failed_bounds (rtvec r, int n, const char *file, int line,
00554 const char *func)
00555 {
00556 internal_error
00557 ("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d",
00558 n, GET_NUM_ELEM (r) - 1, func, trim_filename (file), line);
00559 }
00560 #endif
00561
00562 #if defined ENABLE_RTL_FLAG_CHECKING
00563 void
00564 rtl_check_failed_flag (const char *name, rtx r, const char *file,
00565 int line, const char *func)
00566 {
00567 internal_error
00568 ("RTL flag check: %s used with unexpected rtx code '%s' in %s, at %s:%d",
00569 name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
00570 }
00571 #endif