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