00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "toplev.h"
00026 #include "rtl.h"
00027 #include "hard-reg-set.h"
00028 #include "insn-config.h"
00029 #include "recog.h"
00030 #include "tm_p.h"
00031 #include "flags.h"
00032 #include "basic-block.h"
00033 #include "real.h"
00034
00035
00036 static int global_reg_mentioned_p_1 PARAMS ((rtx *, void *));
00037 static void set_of_1 PARAMS ((rtx, rtx, void *));
00038 static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *));
00039 static int computed_jump_p_1 PARAMS ((rtx));
00040 static void parms_set PARAMS ((rtx, rtx, void *));
00041 static bool hoist_test_store PARAMS ((rtx, rtx, regset));
00042 static void hoist_update_store PARAMS ((rtx, rtx *, rtx, rtx));
00043
00044
00045
00046
00047
00048 int target_flags;
00049
00050
00051
00052
00053
00054
00055 int
00056 rtx_unstable_p (x)
00057 rtx x;
00058 {
00059 RTX_CODE code = GET_CODE (x);
00060 int i;
00061 const char *fmt;
00062
00063 switch (code)
00064 {
00065 case MEM:
00066 return ! RTX_UNCHANGING_P (x) || rtx_unstable_p (XEXP (x, 0));
00067
00068 case QUEUED:
00069 return 1;
00070
00071 case ADDRESSOF:
00072 case CONST:
00073 case CONST_INT:
00074 case CONST_DOUBLE:
00075 case CONST_VECTOR:
00076 case SYMBOL_REF:
00077 case LABEL_REF:
00078 return 0;
00079
00080 case REG:
00081
00082 if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
00083
00084 || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])
00085 || RTX_UNCHANGING_P (x))
00086 return 0;
00087 #ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
00088
00089
00090
00091 if (x == pic_offset_table_rtx)
00092 return 0;
00093 #endif
00094 return 1;
00095
00096 case ASM_OPERANDS:
00097 if (MEM_VOLATILE_P (x))
00098 return 1;
00099
00100
00101
00102 default:
00103 break;
00104 }
00105
00106 fmt = GET_RTX_FORMAT (code);
00107 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00108 if (fmt[i] == 'e')
00109 {
00110 if (rtx_unstable_p (XEXP (x, i)))
00111 return 1;
00112 }
00113 else if (fmt[i] == 'E')
00114 {
00115 int j;
00116 for (j = 0; j < XVECLEN (x, i); j++)
00117 if (rtx_unstable_p (XVECEXP (x, i, j)))
00118 return 1;
00119 }
00120
00121 return 0;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131 int
00132 rtx_varies_p (x, for_alias)
00133 rtx x;
00134 int for_alias;
00135 {
00136 RTX_CODE code = GET_CODE (x);
00137 int i;
00138 const char *fmt;
00139
00140 switch (code)
00141 {
00142 case MEM:
00143 return ! RTX_UNCHANGING_P (x) || rtx_varies_p (XEXP (x, 0), for_alias);
00144
00145 case QUEUED:
00146 return 1;
00147
00148 case CONST:
00149 case CONST_INT:
00150 case CONST_DOUBLE:
00151 case CONST_VECTOR:
00152 case SYMBOL_REF:
00153 case LABEL_REF:
00154 return 0;
00155
00156 case REG:
00157
00158
00159
00160
00161 if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
00162
00163 || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
00164 return 0;
00165 if (x == pic_offset_table_rtx
00166 #ifdef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
00167
00168
00169
00170
00171 && for_alias
00172 #endif
00173 )
00174 return 0;
00175 return 1;
00176
00177 case LO_SUM:
00178
00179
00180
00181 return (! for_alias && rtx_varies_p (XEXP (x, 0), for_alias))
00182 || rtx_varies_p (XEXP (x, 1), for_alias);
00183
00184 case ASM_OPERANDS:
00185 if (MEM_VOLATILE_P (x))
00186 return 1;
00187
00188
00189
00190 default:
00191 break;
00192 }
00193
00194 fmt = GET_RTX_FORMAT (code);
00195 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00196 if (fmt[i] == 'e')
00197 {
00198 if (rtx_varies_p (XEXP (x, i), for_alias))
00199 return 1;
00200 }
00201 else if (fmt[i] == 'E')
00202 {
00203 int j;
00204 for (j = 0; j < XVECLEN (x, i); j++)
00205 if (rtx_varies_p (XVECEXP (x, i, j), for_alias))
00206 return 1;
00207 }
00208
00209 return 0;
00210 }
00211
00212
00213
00214 int
00215 rtx_addr_can_trap_p (x)
00216 rtx x;
00217 {
00218 enum rtx_code code = GET_CODE (x);
00219
00220 switch (code)
00221 {
00222 case SYMBOL_REF:
00223 return SYMBOL_REF_WEAK (x);
00224
00225 case LABEL_REF:
00226 return 0;
00227
00228 case REG:
00229
00230 if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
00231 || x == stack_pointer_rtx
00232
00233 || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
00234 return 0;
00235
00236 if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
00237 && REGNO (x) <= LAST_VIRTUAL_REGISTER)
00238 return 0;
00239 return 1;
00240
00241 case CONST:
00242 return rtx_addr_can_trap_p (XEXP (x, 0));
00243
00244 case PLUS:
00245
00246
00247
00248 return ! ((! rtx_addr_can_trap_p (XEXP (x, 0))
00249 && GET_CODE (XEXP (x, 1)) == CONST_INT)
00250 || (XEXP (x, 0) == pic_offset_table_rtx
00251 && CONSTANT_P (XEXP (x, 1))));
00252
00253 case LO_SUM:
00254 case PRE_MODIFY:
00255 return rtx_addr_can_trap_p (XEXP (x, 1));
00256
00257 case PRE_DEC:
00258 case PRE_INC:
00259 case POST_DEC:
00260 case POST_INC:
00261 case POST_MODIFY:
00262 return rtx_addr_can_trap_p (XEXP (x, 0));
00263
00264 default:
00265 break;
00266 }
00267
00268
00269 return 1;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278 int
00279 rtx_addr_varies_p (x, for_alias)
00280 rtx x;
00281 int for_alias;
00282 {
00283 enum rtx_code code;
00284 int i;
00285 const char *fmt;
00286
00287 if (x == 0)
00288 return 0;
00289
00290 code = GET_CODE (x);
00291 if (code == MEM)
00292 return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0), for_alias);
00293
00294 fmt = GET_RTX_FORMAT (code);
00295 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00296 if (fmt[i] == 'e')
00297 {
00298 if (rtx_addr_varies_p (XEXP (x, i), for_alias))
00299 return 1;
00300 }
00301 else if (fmt[i] == 'E')
00302 {
00303 int j;
00304 for (j = 0; j < XVECLEN (x, i); j++)
00305 if (rtx_addr_varies_p (XVECEXP (x, i, j), for_alias))
00306 return 1;
00307 }
00308 return 0;
00309 }
00310
00311
00312
00313
00314
00315
00316 HOST_WIDE_INT
00317 get_integer_term (x)
00318 rtx x;
00319 {
00320 if (GET_CODE (x) == CONST)
00321 x = XEXP (x, 0);
00322
00323 if (GET_CODE (x) == MINUS
00324 && GET_CODE (XEXP (x, 1)) == CONST_INT)
00325 return - INTVAL (XEXP (x, 1));
00326 if (GET_CODE (x) == PLUS
00327 && GET_CODE (XEXP (x, 1)) == CONST_INT)
00328 return INTVAL (XEXP (x, 1));
00329 return 0;
00330 }
00331
00332
00333
00334
00335
00336 rtx
00337 get_related_value (x)
00338 rtx x;
00339 {
00340 if (GET_CODE (x) != CONST)
00341 return 0;
00342 x = XEXP (x, 0);
00343 if (GET_CODE (x) == PLUS
00344 && GET_CODE (XEXP (x, 1)) == CONST_INT)
00345 return XEXP (x, 0);
00346 else if (GET_CODE (x) == MINUS
00347 && GET_CODE (XEXP (x, 1)) == CONST_INT)
00348 return XEXP (x, 0);
00349 return 0;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359 rtx
00360 get_jump_table_offset (insn, earliest)
00361 rtx insn;
00362 rtx *earliest;
00363 {
00364 rtx label;
00365 rtx table;
00366 rtx set;
00367 rtx old_insn;
00368 rtx x;
00369 rtx old_x;
00370 rtx y;
00371 rtx old_y;
00372 int i;
00373
00374 if (GET_CODE (insn) != JUMP_INSN
00375 || ! (label = JUMP_LABEL (insn))
00376 || ! (table = NEXT_INSN (label))
00377 || GET_CODE (table) != JUMP_INSN
00378 || (GET_CODE (PATTERN (table)) != ADDR_VEC
00379 && GET_CODE (PATTERN (table)) != ADDR_DIFF_VEC)
00380 || ! (set = single_set (insn)))
00381 return NULL_RTX;
00382
00383 x = SET_SRC (set);
00384
00385
00386
00387 if (GET_CODE (x) == IF_THEN_ELSE
00388 && GET_CODE (XEXP (x, 2)) == LABEL_REF)
00389 x = XEXP (x, 1);
00390
00391
00392 for (old_x = NULL_RTX; GET_CODE (x) == REG && x != old_x;
00393 old_x = x, x = find_last_value (x, &insn, NULL_RTX, 0))
00394 ;
00395
00396
00397
00398
00399 if (GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC
00400 && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS))
00401 {
00402 for (i = 0; i < 2; i++)
00403 {
00404 old_insn = insn;
00405 y = XEXP (x, i);
00406
00407 if (y == pc_rtx || y == pic_offset_table_rtx)
00408 break;
00409
00410 for (old_y = NULL_RTX; GET_CODE (y) == REG && y != old_y;
00411 old_y = y, y = find_last_value (y, &old_insn, NULL_RTX, 0))
00412 ;
00413
00414 if ((GET_CODE (y) == LABEL_REF && XEXP (y, 0) == label))
00415 break;
00416 }
00417
00418 if (i >= 2)
00419 return NULL_RTX;
00420
00421 x = XEXP (x, 1 - i);
00422
00423 for (old_x = NULL_RTX; GET_CODE (x) == REG && x != old_x;
00424 old_x = x, x = find_last_value (x, &insn, NULL_RTX, 0))
00425 ;
00426 }
00427
00428
00429 if (GET_CODE (x) == SIGN_EXTEND || GET_CODE (x) == ZERO_EXTEND)
00430 {
00431 x = XEXP (x, 0);
00432
00433 for (old_x = NULL_RTX; GET_CODE (x) == REG && x != old_x;
00434 old_x = x, x = find_last_value (x, &insn, NULL_RTX, 0))
00435 ;
00436 }
00437
00438
00439 if (GET_CODE (x) != MEM)
00440 return NULL_RTX;
00441
00442
00443 x = XEXP (x, 0);
00444
00445 for (old_x = NULL_RTX; GET_CODE (x) == REG && x != old_x;
00446 old_x = x, x = find_last_value (x, &insn, NULL_RTX, 0))
00447 ;
00448
00449
00450 if (GET_CODE (x) != PLUS)
00451 return NULL_RTX;
00452
00453
00454
00455
00456
00457 for (i = 0; i < 2; i++)
00458 {
00459 old_insn = insn;
00460 y = XEXP (x, i);
00461
00462 for (old_y = NULL_RTX; GET_CODE (y) == REG && y != old_y;
00463 old_y = y, y = find_last_value (y, &old_insn, NULL_RTX, 0))
00464 ;
00465
00466 if ((GET_CODE (y) == CONST || GET_CODE (y) == LABEL_REF)
00467 && reg_mentioned_p (label, y))
00468 break;
00469 }
00470
00471 if (i >= 2)
00472 return NULL_RTX;
00473
00474 x = XEXP (x, 1 - i);
00475
00476
00477 if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS)
00478 for (i = 0; i < 2; i++)
00479 if (XEXP (x, i) == pic_offset_table_rtx)
00480 {
00481 x = XEXP (x, 1 - i);
00482 break;
00483 }
00484
00485 if (earliest)
00486 *earliest = insn;
00487
00488
00489 return x;
00490 }
00491
00492
00493
00494
00495 static int
00496 global_reg_mentioned_p_1 (loc, data)
00497 rtx *loc;
00498 void *data ATTRIBUTE_UNUSED;
00499 {
00500 int regno;
00501 rtx x = *loc;
00502
00503 if (! x)
00504 return 0;
00505
00506 switch (GET_CODE (x))
00507 {
00508 case SUBREG:
00509 if (GET_CODE (SUBREG_REG (x)) == REG)
00510 {
00511 if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER
00512 && global_regs[subreg_regno (x)])
00513 return 1;
00514 return 0;
00515 }
00516 break;
00517
00518 case REG:
00519 regno = REGNO (x);
00520 if (regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
00521 return 1;
00522 return 0;
00523
00524 case SCRATCH:
00525 case PC:
00526 case CC0:
00527 case CONST_INT:
00528 case CONST_DOUBLE:
00529 case CONST:
00530 case LABEL_REF:
00531 return 0;
00532
00533 case CALL:
00534
00535 return 1;
00536
00537 default:
00538 break;
00539 }
00540
00541 return 0;
00542 }
00543
00544
00545
00546 int
00547 global_reg_mentioned_p (x)
00548 rtx x;
00549 {
00550
00551 if (INSN_P (x))
00552 {
00553 if (GET_CODE (x) == CALL_INSN)
00554 {
00555 if (! CONST_OR_PURE_CALL_P (x))
00556 return 1;
00557 x = CALL_INSN_FUNCTION_USAGE (x);
00558 if (x == 0)
00559 return 0;
00560 }
00561 else
00562 x = PATTERN (x);
00563 }
00564
00565 return for_each_rtx (&x, global_reg_mentioned_p_1, NULL);
00566 }
00567
00568
00569
00570
00571 int
00572 count_occurrences (x, find, count_dest)
00573 rtx x, find;
00574 int count_dest;
00575 {
00576 int i, j;
00577 enum rtx_code code;
00578 const char *format_ptr;
00579 int count;
00580
00581 if (x == find)
00582 return 1;
00583
00584 code = GET_CODE (x);
00585
00586 switch (code)
00587 {
00588 case REG:
00589 case CONST_INT:
00590 case CONST_DOUBLE:
00591 case CONST_VECTOR:
00592 case SYMBOL_REF:
00593 case CODE_LABEL:
00594 case PC:
00595 case CC0:
00596 return 0;
00597
00598 case MEM:
00599 if (GET_CODE (find) == MEM && rtx_equal_p (x, find))
00600 return 1;
00601 break;
00602
00603 case SET:
00604 if (SET_DEST (x) == find && ! count_dest)
00605 return count_occurrences (SET_SRC (x), find, count_dest);
00606 break;
00607
00608 default:
00609 break;
00610 }
00611
00612 format_ptr = GET_RTX_FORMAT (code);
00613 count = 0;
00614
00615 for (i = 0; i < GET_RTX_LENGTH (code); i++)
00616 {
00617 switch (*format_ptr++)
00618 {
00619 case 'e':
00620 count += count_occurrences (XEXP (x, i), find, count_dest);
00621 break;
00622
00623 case 'E':
00624 for (j = 0; j < XVECLEN (x, i); j++)
00625 count += count_occurrences (XVECEXP (x, i, j), find, count_dest);
00626 break;
00627 }
00628 }
00629 return count;
00630 }
00631
00632
00633
00634
00635
00636 int
00637 reg_mentioned_p (reg, in)
00638 rtx reg, in;
00639 {
00640 const char *fmt;
00641 int i;
00642 enum rtx_code code;
00643
00644 if (in == 0)
00645 return 0;
00646
00647 if (reg == in)
00648 return 1;
00649
00650 if (GET_CODE (in) == LABEL_REF)
00651 return reg == XEXP (in, 0);
00652
00653 code = GET_CODE (in);
00654
00655 switch (code)
00656 {
00657
00658 case REG:
00659 return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg);
00660
00661
00662
00663 case SCRATCH:
00664 case CC0:
00665 case PC:
00666 return 0;
00667
00668 case CONST_INT:
00669 return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);
00670
00671 case CONST_VECTOR:
00672 case CONST_DOUBLE:
00673
00674 return 0;
00675
00676 default:
00677 break;
00678 }
00679
00680 if (GET_CODE (reg) == code && rtx_equal_p (reg, in))
00681 return 1;
00682
00683 fmt = GET_RTX_FORMAT (code);
00684
00685 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00686 {
00687 if (fmt[i] == 'E')
00688 {
00689 int j;
00690 for (j = XVECLEN (in, i) - 1; j >= 0; j--)
00691 if (reg_mentioned_p (reg, XVECEXP (in, i, j)))
00692 return 1;
00693 }
00694 else if (fmt[i] == 'e'
00695 && reg_mentioned_p (reg, XEXP (in, i)))
00696 return 1;
00697 }
00698 return 0;
00699 }
00700
00701
00702
00703
00704 int
00705 no_labels_between_p (beg, end)
00706 rtx beg, end;
00707 {
00708 rtx p;
00709 if (beg == end)
00710 return 0;
00711 for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
00712 if (GET_CODE (p) == CODE_LABEL)
00713 return 0;
00714 return 1;
00715 }
00716
00717
00718
00719
00720 int
00721 no_jumps_between_p (beg, end)
00722 rtx beg, end;
00723 {
00724 rtx p;
00725 for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
00726 if (GET_CODE (p) == JUMP_INSN)
00727 return 0;
00728 return 1;
00729 }
00730
00731
00732
00733
00734 int
00735 reg_used_between_p (reg, from_insn, to_insn)
00736 rtx reg, from_insn, to_insn;
00737 {
00738 rtx insn;
00739
00740 if (from_insn == to_insn)
00741 return 0;
00742
00743 for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
00744 if (INSN_P (insn)
00745 && (reg_overlap_mentioned_p (reg, PATTERN (insn))
00746 || (GET_CODE (insn) == CALL_INSN
00747 && (find_reg_fusage (insn, USE, reg)
00748 || find_reg_fusage (insn, CLOBBER, reg)))))
00749 return 1;
00750 return 0;
00751 }
00752
00753
00754
00755
00756
00757 int
00758 reg_referenced_p (x, body)
00759 rtx x;
00760 rtx body;
00761 {
00762 int i;
00763
00764 switch (GET_CODE (body))
00765 {
00766 case SET:
00767 if (reg_overlap_mentioned_p (x, SET_SRC (body)))
00768 return 1;
00769
00770
00771
00772
00773 if (GET_CODE (SET_DEST (body)) != CC0
00774 && GET_CODE (SET_DEST (body)) != PC
00775 && GET_CODE (SET_DEST (body)) != REG
00776 && ! (GET_CODE (SET_DEST (body)) == SUBREG
00777 && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG
00778 && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (body))))
00779 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
00780 == ((GET_MODE_SIZE (GET_MODE (SET_DEST (body)))
00781 + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
00782 && reg_overlap_mentioned_p (x, SET_DEST (body)))
00783 return 1;
00784 return 0;
00785
00786 case ASM_OPERANDS:
00787 for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--)
00788 if (reg_overlap_mentioned_p (x, ASM_OPERANDS_INPUT (body, i)))
00789 return 1;
00790 return 0;
00791
00792 case CALL:
00793 case USE:
00794 case IF_THEN_ELSE:
00795 return reg_overlap_mentioned_p (x, body);
00796
00797 case TRAP_IF:
00798 return reg_overlap_mentioned_p (x, TRAP_CONDITION (body));
00799
00800 case PREFETCH:
00801 return reg_overlap_mentioned_p (x, XEXP (body, 0));
00802
00803 case UNSPEC:
00804 case UNSPEC_VOLATILE:
00805 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
00806 if (reg_overlap_mentioned_p (x, XVECEXP (body, 0, i)))
00807 return 1;
00808 return 0;
00809
00810 case PARALLEL:
00811 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
00812 if (reg_referenced_p (x, XVECEXP (body, 0, i)))
00813 return 1;
00814 return 0;
00815
00816 case CLOBBER:
00817 if (GET_CODE (XEXP (body, 0)) == MEM)
00818 if (reg_overlap_mentioned_p (x, XEXP (XEXP (body, 0), 0)))
00819 return 1;
00820 return 0;
00821
00822 case COND_EXEC:
00823 if (reg_overlap_mentioned_p (x, COND_EXEC_TEST (body)))
00824 return 1;
00825 return reg_referenced_p (x, COND_EXEC_CODE (body));
00826
00827 default:
00828 return 0;
00829 }
00830 }
00831
00832
00833
00834
00835
00836 int
00837 reg_referenced_between_p (reg, from_insn, to_insn)
00838 rtx reg, from_insn, to_insn;
00839 {
00840 rtx insn;
00841
00842 if (from_insn == to_insn)
00843 return 0;
00844
00845 for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
00846 if (INSN_P (insn)
00847 && (reg_referenced_p (reg, PATTERN (insn))
00848 || (GET_CODE (insn) == CALL_INSN
00849 && find_reg_fusage (insn, USE, reg))))
00850 return 1;
00851 return 0;
00852 }
00853
00854
00855
00856
00857 int
00858 reg_set_between_p (reg, from_insn, to_insn)
00859 rtx reg, from_insn, to_insn;
00860 {
00861 rtx insn;
00862
00863 if (from_insn == to_insn)
00864 return 0;
00865
00866 for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
00867 if (INSN_P (insn) && reg_set_p (reg, insn))
00868 return 1;
00869 return 0;
00870 }
00871
00872
00873 int
00874 reg_set_p (reg, insn)
00875 rtx reg, insn;
00876 {
00877 rtx body = insn;
00878
00879
00880
00881 if (INSN_P (insn))
00882 {
00883 if (FIND_REG_INC_NOTE (insn, reg)
00884 || (GET_CODE (insn) == CALL_INSN
00885
00886
00887
00888
00889
00890
00891 && ((GET_CODE (reg) == REG
00892 && REGNO (reg) < FIRST_PSEUDO_REGISTER)
00893 || GET_CODE (reg) == MEM
00894 || find_reg_fusage (insn, CLOBBER, reg))))
00895 return 1;
00896
00897 body = PATTERN (insn);
00898 }
00899
00900 return set_of (reg, insn) != NULL_RTX;
00901 }
00902
00903
00904
00905
00906
00907 int
00908 regs_set_between_p (x, start, end)
00909 rtx x;
00910 rtx start, end;
00911 {
00912 enum rtx_code code = GET_CODE (x);
00913 const char *fmt;
00914 int i, j;
00915
00916 switch (code)
00917 {
00918 case CONST_INT:
00919 case CONST_DOUBLE:
00920 case CONST_VECTOR:
00921 case CONST:
00922 case SYMBOL_REF:
00923 case LABEL_REF:
00924 case PC:
00925 case CC0:
00926 return 0;
00927
00928 case REG:
00929 return reg_set_between_p (x, start, end);
00930
00931 default:
00932 break;
00933 }
00934
00935 fmt = GET_RTX_FORMAT (code);
00936 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00937 {
00938 if (fmt[i] == 'e' && regs_set_between_p (XEXP (x, i), start, end))
00939 return 1;
00940
00941 else if (fmt[i] == 'E')
00942 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
00943 if (regs_set_between_p (XVECEXP (x, i, j), start, end))
00944 return 1;
00945 }
00946
00947 return 0;
00948 }
00949
00950
00951
00952
00953
00954 int
00955 modified_between_p (x, start, end)
00956 rtx x;
00957 rtx start, end;
00958 {
00959 enum rtx_code code = GET_CODE (x);
00960 const char *fmt;
00961 int i, j;
00962
00963 switch (code)
00964 {
00965 case CONST_INT:
00966 case CONST_DOUBLE:
00967 case CONST_VECTOR:
00968 case CONST:
00969 case SYMBOL_REF:
00970 case LABEL_REF:
00971 return 0;
00972
00973 case PC:
00974 case CC0:
00975 return 1;
00976
00977 case MEM:
00978
00979
00980 if (! RTX_UNCHANGING_P (x))
00981 return 1;
00982 break;
00983
00984 case REG:
00985 return reg_set_between_p (x, start, end);
00986
00987 default:
00988 break;
00989 }
00990
00991 fmt = GET_RTX_FORMAT (code);
00992 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
00993 {
00994 if (fmt[i] == 'e' && modified_between_p (XEXP (x, i), start, end))
00995 return 1;
00996
00997 else if (fmt[i] == 'E')
00998 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
00999 if (modified_between_p (XVECEXP (x, i, j), start, end))
01000 return 1;
01001 }
01002
01003 return 0;
01004 }
01005
01006
01007
01008
01009
01010 int
01011 modified_in_p (x, insn)
01012 rtx x;
01013 rtx insn;
01014 {
01015 enum rtx_code code = GET_CODE (x);
01016 const char *fmt;
01017 int i, j;
01018
01019 switch (code)
01020 {
01021 case CONST_INT:
01022 case CONST_DOUBLE:
01023 case CONST_VECTOR:
01024 case CONST:
01025 case SYMBOL_REF:
01026 case LABEL_REF:
01027 return 0;
01028
01029 case PC:
01030 case CC0:
01031 return 1;
01032
01033 case MEM:
01034
01035
01036 if (! RTX_UNCHANGING_P (x))
01037 return 1;
01038 break;
01039
01040 case REG:
01041 return reg_set_p (x, insn);
01042
01043 default:
01044 break;
01045 }
01046
01047 fmt = GET_RTX_FORMAT (code);
01048 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
01049 {
01050 if (fmt[i] == 'e' && modified_in_p (XEXP (x, i), insn))
01051 return 1;
01052
01053 else if (fmt[i] == 'E')
01054 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
01055 if (modified_in_p (XVECEXP (x, i, j), insn))
01056 return 1;
01057 }
01058
01059 return 0;
01060 }
01061
01062
01063
01064
01065 int
01066 insn_dependent_p (x, y)
01067 rtx x, y;
01068 {
01069 rtx tmp;
01070
01071 if (! INSN_P (x) || ! INSN_P (y))
01072 abort ();
01073
01074 tmp = PATTERN (y);
01075 note_stores (PATTERN (x), insn_dependent_p_1, &tmp);
01076 if (tmp == NULL_RTX)
01077 return 1;
01078
01079 tmp = PATTERN (x);
01080 note_stores (PATTERN (y), insn_dependent_p_1, &tmp);
01081 if (tmp == NULL_RTX)
01082 return 1;
01083
01084 return 0;
01085 }
01086
01087
01088
01089 static void
01090 insn_dependent_p_1 (x, pat, data)
01091 rtx x;
01092 rtx pat ATTRIBUTE_UNUSED;
01093 void *data;
01094 {
01095 rtx * pinsn = (rtx *) data;
01096
01097 if (*pinsn && reg_mentioned_p (x, *pinsn))
01098 *pinsn = NULL_RTX;
01099 }
01100
01101
01102 struct set_of_data
01103 {
01104 rtx found;
01105 rtx pat;
01106 };
01107
01108 static void
01109 set_of_1 (x, pat, data1)
01110 rtx x;
01111 rtx pat;
01112 void *data1;
01113 {
01114 struct set_of_data *data = (struct set_of_data *) (data1);
01115 if (rtx_equal_p (x, data->pat)
01116 || (GET_CODE (x) != MEM && reg_overlap_mentioned_p (data->pat, x)))
01117 data->found = pat;
01118 }
01119
01120
01121
01122 rtx
01123 set_of (pat, insn)
01124 rtx pat, insn;
01125 {
01126 struct set_of_data data;
01127 data.found = NULL_RTX;
01128 data.pat = pat;
01129 note_stores (INSN_P (insn) ? PATTERN (insn) : insn, set_of_1, &data);
01130 return data.found;
01131 }
01132
01133
01134
01135
01136
01137 rtx
01138 single_set_2 (insn, pat)
01139 rtx insn, pat;
01140 {
01141 rtx set = NULL;
01142 int set_verified = 1;
01143 int i;
01144
01145 if (GET_CODE (pat) == PARALLEL)
01146 {
01147 for (i = 0; i < XVECLEN (pat, 0); i++)
01148 {
01149 rtx sub = XVECEXP (pat, 0, i);
01150 switch (GET_CODE (sub))
01151 {
01152 case USE:
01153 case CLOBBER:
01154 break;
01155
01156 case SET:
01157
01158
01159
01160
01161
01162
01163
01164
01165 if (!set_verified)
01166 {
01167 if (find_reg_note (insn, REG_UNUSED, SET_DEST (set))
01168 && !side_effects_p (set))
01169 set = NULL;
01170 else
01171 set_verified = 1;
01172 }
01173 if (!set)
01174 set = sub, set_verified = 0;
01175 else if (!find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
01176 || side_effects_p (sub))
01177 return NULL_RTX;
01178 break;
01179
01180 default:
01181 return NULL_RTX;
01182 }
01183 }
01184 }
01185 return set;
01186 }
01187
01188
01189
01190
01191 int
01192 multiple_sets (insn)
01193 rtx insn;
01194 {
01195 int found;
01196 int i;
01197
01198
01199 if (! INSN_P (insn))
01200 return 0;
01201
01202
01203 if (GET_CODE (PATTERN (insn)) == PARALLEL)
01204 {
01205 for (i = 0, found = 0; i < XVECLEN (PATTERN (insn), 0); i++)
01206 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
01207 {
01208
01209 if (found)
01210 return 1;
01211 else
01212 found = 1;
01213 }
01214 }
01215
01216
01217 return 0;
01218 }
01219
01220
01221
01222
01223 int
01224 set_noop_p (set)
01225 rtx set;
01226 {
01227 rtx src = SET_SRC (set);
01228 rtx dst = SET_DEST (set);
01229
01230 if (side_effects_p (src) || side_effects_p (dst))
01231 return 0;
01232
01233 if (GET_CODE (dst) == MEM && GET_CODE (src) == MEM)
01234 return rtx_equal_p (dst, src);
01235
01236 if (dst == pc_rtx && src == pc_rtx)
01237 return 1;
01238
01239 if (GET_CODE (dst) == SIGN_EXTRACT
01240 || GET_CODE (dst) == ZERO_EXTRACT)
01241 return rtx_equal_p (XEXP (dst, 0), src)
01242 && ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx;
01243
01244 if (GET_CODE (dst) == STRICT_LOW_PART)
01245 dst = XEXP (dst, 0);
01246
01247 if (GET_CODE (src) == SUBREG && GET_CODE (dst) == SUBREG)
01248 {
01249 if (SUBREG_BYTE (src) != SUBREG_BYTE (dst))
01250 return 0;
01251 src = SUBREG_REG (src);
01252 dst = SUBREG_REG (dst);
01253 }
01254
01255 return (GET_CODE (src) == REG && GET_CODE (dst) == REG
01256 && REGNO (src) == REGNO (dst));
01257 }
01258
01259
01260
01261
01262 int
01263 noop_move_p (insn)
01264 rtx insn;
01265 {
01266 rtx pat = PATTERN (insn);
01267
01268 if (INSN_CODE (insn) == NOOP_MOVE_INSN_CODE)
01269 return 1;
01270
01271
01272 if (find_reg_note (insn, REG_EQUAL, NULL_RTX))
01273 return 0;
01274
01275
01276
01277 if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
01278 return 0;
01279
01280 if (GET_CODE (pat) == SET && set_noop_p (pat))
01281 return 1;
01282
01283 if (GET_CODE (pat) == PARALLEL)
01284 {
01285 int i;
01286
01287
01288 for (i = 0; i < XVECLEN (pat, 0); i++)
01289 {
01290 rtx tem = XVECEXP (pat, 0, i);
01291
01292 if (GET_CODE (tem) == USE
01293 || GET_CODE (tem) == CLOBBER)
01294 continue;
01295
01296 if (GET_CODE (tem) != SET || ! set_noop_p (tem))
01297 return 0;
01298 }
01299
01300 return 1;
01301 }
01302 return 0;
01303 }
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313 rtx
01314 find_last_value (x, pinsn, valid_to, allow_hwreg)
01315 rtx x;
01316 rtx *pinsn;
01317 rtx valid_to;
01318 int allow_hwreg;
01319 {
01320 rtx p;
01321
01322 for (p = PREV_INSN (*pinsn); p && GET_CODE (p) != CODE_LABEL;
01323 p = PREV_INSN (p))
01324 if (INSN_P (p))
01325 {
01326 rtx set = single_set (p);
01327 rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX);
01328
01329 if (set && rtx_equal_p (x, SET_DEST (set)))
01330 {
01331 rtx src = SET_SRC (set);
01332
01333 if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
01334 src = XEXP (note, 0);
01335
01336 if ((valid_to == NULL_RTX
01337 || ! modified_between_p (src, PREV_INSN (p), valid_to))
01338
01339
01340 && (! (GET_CODE (src) == REG
01341 && REGNO (src) < FIRST_PSEUDO_REGISTER) || allow_hwreg))
01342 {
01343 *pinsn = p;
01344 return src;
01345 }
01346 }
01347
01348
01349 if (reg_set_p (x, p))
01350 break;
01351 }
01352
01353 return x;
01354 }
01355
01356
01357
01358
01359
01360
01361
01362
01363 int
01364 refers_to_regno_p (regno, endregno, x, loc)
01365 unsigned int regno, endregno;
01366 rtx x;
01367 rtx *loc;
01368 {
01369 int i;
01370 unsigned int x_regno;
01371 RTX_CODE code;
01372 const char *fmt;
01373
01374 repeat:
01375
01376
01377 if (x == 0)
01378 return 0;
01379
01380 code = GET_CODE (x);
01381
01382 switch (code)
01383 {
01384 case REG:
01385 x_regno = REGNO (x);
01386
01387
01388
01389
01390 if ((x_regno == STACK_POINTER_REGNUM
01391 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
01392 || x_regno == ARG_POINTER_REGNUM
01393 #endif
01394 || x_regno == FRAME_POINTER_REGNUM)
01395 && regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER)
01396 return 1;
01397
01398 return (endregno > x_regno
01399 && regno < x_regno + (x_regno < FIRST_PSEUDO_REGISTER
01400 ? HARD_REGNO_NREGS (x_regno, GET_MODE (x))
01401 : 1));
01402
01403 case SUBREG:
01404
01405
01406 if (GET_CODE (SUBREG_REG (x)) == REG
01407 && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
01408 {
01409 unsigned int inner_regno = subreg_regno (x);
01410 unsigned int inner_endregno
01411 = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
01412 ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
01413
01414 return endregno > inner_regno && regno < inner_endregno;
01415 }
01416 break;
01417
01418 case CLOBBER:
01419 case SET:
01420 if (&SET_DEST (x) != loc
01421
01422
01423
01424 && ((GET_CODE (SET_DEST (x)) == SUBREG
01425 && loc != &SUBREG_REG (SET_DEST (x))
01426 && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
01427 && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
01428 && refers_to_regno_p (regno, endregno,
01429 SUBREG_REG (SET_DEST (x)), loc))
01430 || (GET_CODE (SET_DEST (x)) != REG
01431 && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))))
01432 return 1;
01433
01434 if (code == CLOBBER || loc == &SET_SRC (x))
01435 return 0;
01436 x = SET_SRC (x);
01437 goto repeat;
01438
01439 default:
01440 break;
01441 }
01442
01443
01444
01445 fmt = GET_RTX_FORMAT (code);
01446 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
01447 {
01448 if (fmt[i] == 'e' && loc != &XEXP (x, i))
01449 {
01450 if (i == 0)
01451 {
01452 x = XEXP (x, 0);
01453 goto repeat;
01454 }
01455 else
01456 if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc))
01457 return 1;
01458 }
01459 else if (fmt[i] == 'E')
01460 {
01461 int j;
01462 for (j = XVECLEN (x, i) - 1; j >=0; j--)
01463 if (loc != &XVECEXP (x, i, j)
01464 && refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))
01465 return 1;
01466 }
01467 }
01468 return 0;
01469 }
01470
01471
01472
01473
01474
01475
01476
01477 int
01478 reg_overlap_mentioned_p (x, in)
01479 rtx x, in;
01480 {
01481 unsigned int regno, endregno;
01482
01483
01484 if (GET_CODE (x) == STRICT_LOW_PART
01485 || GET_CODE (x) == ZERO_EXTRACT
01486 || GET_CODE (x) == SIGN_EXTRACT)
01487 x = XEXP (x, 0);
01488
01489
01490 if (CONSTANT_P (x) || CONSTANT_P (in))
01491 return 0;
01492
01493 switch (GET_CODE (x))
01494 {
01495 case SUBREG:
01496 regno = REGNO (SUBREG_REG (x));
01497 if (regno < FIRST_PSEUDO_REGISTER)
01498 regno = subreg_regno (x);
01499 goto do_reg;
01500
01501 case REG:
01502 regno = REGNO (x);
01503 do_reg:
01504 endregno = regno + (regno < FIRST_PSEUDO_REGISTER
01505 ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
01506 return refers_to_regno_p (regno, endregno, in, (rtx*) 0);
01507
01508 case MEM:
01509 {
01510 const char *fmt;
01511 int i;
01512
01513 if (GET_CODE (in) == MEM)
01514 return 1;
01515
01516 fmt = GET_RTX_FORMAT (GET_CODE (in));
01517 for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
01518 if (fmt[i] == 'e' && reg_overlap_mentioned_p (x, XEXP (in, i)))
01519 return 1;
01520
01521 return 0;
01522 }
01523
01524 case SCRATCH:
01525 case PC:
01526 case CC0:
01527 return reg_mentioned_p (x, in);
01528
01529 case PARALLEL:
01530 {
01531 int i;
01532
01533
01534 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
01535 if (XEXP (XVECEXP (x, 0, i), 0) != 0
01536 && reg_overlap_mentioned_p (XEXP (XVECEXP (x, 0, i), 0), in))
01537 return 1;
01538 return 0;
01539 }
01540
01541 default:
01542 break;
01543 }
01544
01545 abort ();
01546 }
01547
01548
01549
01550
01551
01552
01553
01554 rtx
01555 reg_set_last (x, insn)
01556 rtx x;
01557 rtx insn;
01558 {
01559 rtx orig_insn = insn;
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569 for (;
01570 insn && GET_CODE (insn) != CODE_LABEL
01571 && ! (GET_CODE (insn) == CALL_INSN
01572 && REGNO (x) <= FIRST_PSEUDO_REGISTER);
01573 insn = PREV_INSN (insn))
01574 if (INSN_P (insn))
01575 {
01576 rtx set = set_of (x, insn);
01577
01578 if (set)
01579 {
01580 rtx last_value;
01581 if (GET_CODE (set) != SET || SET_DEST (set) != x)
01582 return 0;
01583 last_value = SET_SRC (x);
01584 if (CONSTANT_P (last_value)
01585 || ((GET_CODE (last_value) == REG
01586 || GET_CODE (last_value) == SUBREG)
01587 && ! reg_set_between_p (last_value,
01588 insn, orig_insn)))
01589 return last_value;
01590 else
01591 return 0;
01592 }
01593 }
01594
01595 return 0;
01596 }
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607 void
01608 note_stores (x, fun, data)
01609 rtx x;
01610 void (*fun) PARAMS ((rtx, rtx, void *));
01611 void *data;
01612 {
01613 int i;
01614
01615 if (GET_CODE (x) == COND_EXEC)
01616 x = COND_EXEC_CODE (x);
01617
01618 if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
01619 {
01620 rtx dest = SET_DEST (x);
01621
01622 while ((GET_CODE (dest) == SUBREG
01623 && (GET_CODE (SUBREG_REG (dest)) != REG
01624 || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
01625 || GET_CODE (dest) == ZERO_EXTRACT
01626 || GET_CODE (dest) == SIGN_EXTRACT
01627 || GET_CODE (dest) == STRICT_LOW_PART)
01628 dest = XEXP (dest, 0);
01629
01630
01631
01632 if (GET_CODE (dest) == PARALLEL)
01633 {
01634 for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
01635 if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
01636 (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data);
01637 }
01638 else
01639 (*fun) (dest, x, data);
01640 }
01641
01642 else if (GET_CODE (x) == PARALLEL)
01643 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
01644 note_stores (XVECEXP (x, 0, i), fun, data);
01645 }
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656 void
01657 note_uses (pbody, fun, data)
01658 rtx *pbody;
01659 void (*fun) PARAMS ((rtx *, void *));
01660 void *data;
01661 {
01662 rtx body = *pbody;
01663 int i;
01664
01665 switch (GET_CODE (body))
01666 {
01667 case COND_EXEC:
01668 (*fun) (&COND_EXEC_TEST (body), data);
01669 note_uses (&COND_EXEC_CODE (body), fun, data);
01670 return;
01671
01672 case PARALLEL:
01673 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
01674 note_uses (&XVECEXP (body, 0, i), fun, data);
01675 return;
01676
01677 case USE:
01678 (*fun) (&XEXP (body, 0), data);
01679 return;
01680
01681 case ASM_OPERANDS:
01682 for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--)
01683 (*fun) (&ASM_OPERANDS_INPUT (body, i), data);
01684 return;
01685
01686 case TRAP_IF:
01687 (*fun) (&TRAP_CONDITION (body), data);
01688 return;
01689
01690 case PREFETCH:
01691 (*fun) (&XEXP (body, 0), data);
01692 return;
01693
01694 case UNSPEC:
01695 case UNSPEC_VOLATILE:
01696 for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
01697 (*fun) (&XVECEXP (body, 0, i), data);
01698 return;
01699
01700 case CLOBBER:
01701 if (GET_CODE (XEXP (body, 0)) == MEM)
01702 (*fun) (&XEXP (XEXP (body, 0), 0), data);
01703 return;
01704
01705 case SET:
01706 {
01707 rtx dest = SET_DEST (body);
01708
01709
01710
01711 (*fun) (&SET_SRC (body), data);
01712
01713 if (GET_CODE (dest) == ZERO_EXTRACT)
01714 {
01715 (*fun) (&XEXP (dest, 1), data);
01716 (*fun) (&XEXP (dest, 2), data);
01717 }
01718
01719 while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART)
01720 dest = XEXP (dest, 0);
01721
01722 if (GET_CODE (dest) == MEM)
01723 (*fun) (&XEXP (dest, 0), data);
01724 }
01725 return;
01726
01727 default:
01728
01729 (*fun) (pbody, data);
01730 return;
01731 }
01732 }
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751 int
01752 dead_or_set_p (insn, x)
01753 rtx insn;
01754 rtx x;
01755 {
01756 unsigned int regno, last_regno;
01757 unsigned int i;
01758
01759
01760 if (GET_CODE (x) == CC0)
01761 return 1;
01762
01763 if (GET_CODE (x) != REG)
01764 abort ();
01765
01766 regno = REGNO (x);
01767 last_regno = (regno >= FIRST_PSEUDO_REGISTER ? regno
01768 : regno + HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1);
01769
01770 for (i = regno; i <= last_regno; i++)
01771 if (! dead_or_set_regno_p (insn, i))
01772 return 0;
01773
01774 return 1;
01775 }
01776
01777
01778
01779
01780 int
01781 dead_or_set_regno_p (insn, test_regno)
01782 rtx insn;
01783 unsigned int test_regno;
01784 {
01785 unsigned int regno, endregno;
01786 rtx pattern;
01787
01788
01789 if (find_regno_note (insn, REG_DEAD, test_regno))
01790 return 1;
01791
01792 if (GET_CODE (insn) == CALL_INSN
01793 && find_regno_fusage (insn, CLOBBER, test_regno))
01794 return 1;
01795
01796 pattern = PATTERN (insn);
01797
01798 if (GET_CODE (pattern) == COND_EXEC)
01799 pattern = COND_EXEC_CODE (pattern);
01800
01801 if (GET_CODE (pattern) == SET)
01802 {
01803 rtx dest = SET_DEST (pattern);
01804
01805
01806
01807
01808 if (GET_CODE (dest) == SUBREG
01809 && (((GET_MODE_SIZE (GET_MODE (dest))
01810 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
01811 == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
01812 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
01813 dest = SUBREG_REG (dest);
01814
01815 if (GET_CODE (dest) != REG)
01816 return 0;
01817
01818 regno = REGNO (dest);
01819 endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
01820 : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));
01821
01822 return (test_regno >= regno && test_regno < endregno);
01823 }
01824 else if (GET_CODE (pattern) == PARALLEL)
01825 {
01826 int i;
01827
01828 for (i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
01829 {
01830 rtx body = XVECEXP (pattern, 0, i);
01831
01832 if (GET_CODE (body) == COND_EXEC)
01833 body = COND_EXEC_CODE (body);
01834
01835 if (GET_CODE (body) == SET || GET_CODE (body) == CLOBBER)
01836 {
01837 rtx dest = SET_DEST (body);
01838
01839 if (GET_CODE (dest) == SUBREG
01840 && (((GET_MODE_SIZE (GET_MODE (dest))
01841 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
01842 == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
01843 + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
01844 dest = SUBREG_REG (dest);
01845
01846 if (GET_CODE (dest) != REG)
01847 continue;
01848
01849 regno = REGNO (dest);
01850 endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
01851 : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));
01852
01853 if (test_regno >= regno && test_regno < endregno)
01854 return 1;
01855 }
01856 }
01857 }
01858
01859 return 0;
01860 }
01861
01862
01863
01864
01865 rtx
01866 find_reg_note (insn, kind, datum)
01867 rtx insn;
01868 enum reg_note kind;
01869 rtx datum;
01870 {
01871 rtx link;
01872
01873
01874 if (! INSN_P (insn))
01875 return 0;
01876
01877 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
01878 if (REG_NOTE_KIND (link) == kind
01879 && (datum == 0 || datum == XEXP (link, 0)))
01880 return link;
01881 return 0;
01882 }
01883
01884
01885
01886
01887
01888
01889 rtx
01890 find_regno_note (insn, kind, regno)
01891 rtx insn;
01892 enum reg_note kind;
01893 unsigned int regno;
01894 {
01895 rtx link;
01896
01897
01898 if (! INSN_P (insn))
01899 return 0;
01900
01901 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
01902 if (REG_NOTE_KIND (link) == kind
01903
01904
01905 && GET_CODE (XEXP (link, 0)) == REG
01906 && REGNO (XEXP (link, 0)) <= regno
01907 && ((REGNO (XEXP (link, 0))
01908 + (REGNO (XEXP (link, 0)) >= FIRST_PSEUDO_REGISTER ? 1
01909 : HARD_REGNO_NREGS (REGNO (XEXP (link, 0)),
01910 GET_MODE (XEXP (link, 0)))))
01911 > regno))
01912 return link;
01913 return 0;
01914 }
01915
01916
01917
01918
01919 rtx
01920 find_reg_equal_equiv_note (insn)
01921 rtx insn;
01922 {
01923 rtx note;
01924
01925 if (single_set (insn) == 0)
01926 return 0;
01927 else if ((note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
01928 return note;
01929 else
01930 return find_reg_note (insn, REG_EQUAL, NULL_RTX);
01931 }
01932
01933
01934
01935
01936 int
01937 find_reg_fusage (insn, code, datum)
01938 rtx insn;
01939 enum rtx_code code;
01940 rtx datum;
01941 {
01942
01943
01944 if (GET_CODE (insn) != CALL_INSN)
01945 return 0;
01946
01947 if (! datum)
01948 abort ();
01949
01950 if (GET_CODE (datum) != REG)
01951 {
01952 rtx link;
01953
01954 for (link = CALL_INSN_FUNCTION_USAGE (insn);
01955 link;
01956 link = XEXP (link, 1))
01957 if (GET_CODE (XEXP (link, 0)) == code
01958 && rtx_equal_p (datum, XEXP (XEXP (link, 0), 0)))
01959 return 1;
01960 }
01961 else
01962 {
01963 unsigned int regno = REGNO (datum);
01964
01965
01966
01967
01968 if (regno < FIRST_PSEUDO_REGISTER)
01969 {
01970 unsigned int end_regno
01971 = regno + HARD_REGNO_NREGS (regno, GET_MODE (datum));
01972 unsigned int i;
01973
01974 for (i = regno; i < end_regno; i++)
01975 if (find_regno_fusage (insn, code, i))
01976 return 1;
01977 }
01978 }
01979
01980 return 0;
01981 }
01982
01983
01984
01985
01986 int
01987 find_regno_fusage (insn, code, regno)
01988 rtx insn;
01989 enum rtx_code code;
01990 unsigned int regno;
01991 {
01992 rtx link;
01993
01994
01995
01996
01997 if (regno >= FIRST_PSEUDO_REGISTER
01998 || GET_CODE (insn) != CALL_INSN )
01999 return 0;
02000
02001 for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
02002 {
02003 unsigned int regnote;
02004 rtx op, reg;
02005
02006 if (GET_CODE (op = XEXP (link, 0)) == code
02007 && GET_CODE (reg = XEXP (op, 0)) == REG
02008 && (regnote = REGNO (reg)) <= regno
02009 && regnote + HARD_REGNO_NREGS (regnote, GET_MODE (reg)) > regno)
02010 return 1;
02011 }
02012
02013 return 0;
02014 }
02015
02016
02017
02018 int
02019 pure_call_p (insn)
02020 rtx insn;
02021 {
02022 rtx link;
02023
02024 if (GET_CODE (insn) != CALL_INSN || ! CONST_OR_PURE_CALL_P (insn))
02025 return 0;
02026
02027
02028 for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
02029 {
02030 rtx u, m;
02031
02032 if (GET_CODE (u = XEXP (link, 0)) == USE
02033 && GET_CODE (m = XEXP (u, 0)) == MEM && GET_MODE (m) == BLKmode
02034 && GET_CODE (XEXP (m, 0)) == SCRATCH)
02035 return 1;
02036 }
02037
02038 return 0;
02039 }
02040
02041
02042
02043 void
02044 remove_note (insn, note)
02045 rtx insn;
02046 rtx note;
02047 {
02048 rtx link;
02049
02050 if (note == NULL_RTX)
02051 return;
02052
02053 if (REG_NOTES (insn) == note)
02054 {
02055 REG_NOTES (insn) = XEXP (note, 1);
02056 return;
02057 }
02058
02059 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
02060 if (XEXP (link, 1) == note)
02061 {
02062 XEXP (link, 1) = XEXP (note, 1);
02063 return;
02064 }
02065
02066 abort ();
02067 }
02068
02069
02070
02071
02072
02073 int
02074 in_expr_list_p (listp, node)
02075 rtx listp;
02076 rtx node;
02077 {
02078 rtx x;
02079
02080 for (x = listp; x; x = XEXP (x, 1))
02081 if (node == XEXP (x, 0))
02082 return 1;
02083
02084 return 0;
02085 }
02086
02087
02088
02089
02090
02091
02092 void
02093 remove_node_from_expr_list (node, listp)
02094 rtx node;
02095 rtx *listp;
02096 {
02097 rtx temp = *listp;
02098 rtx prev = NULL_RTX;
02099
02100 while (temp)
02101 {
02102 if (node == XEXP (temp, 0))
02103 {
02104
02105 if (prev)
02106 XEXP (prev, 1) = XEXP (temp, 1);
02107 else
02108 *listp = XEXP (temp, 1);
02109
02110 return;
02111 }
02112
02113 prev = temp;
02114 temp = XEXP (temp, 1);
02115 }
02116 }
02117
02118
02119
02120
02121
02122
02123 int
02124 volatile_insn_p (x)
02125 rtx x;
02126 {
02127 RTX_CODE code;
02128
02129 code = GET_CODE (x);
02130 switch (code)
02131 {
02132 case LABEL_REF:
02133 case SYMBOL_REF:
02134 case CONST_INT:
02135 case CONST:
02136 case CONST_DOUBLE:
02137 case CONST_VECTOR:
02138 case CC0:
02139 case PC:
02140 case REG:
02141 case SCRATCH:
02142 case CLOBBER:
02143 case ADDR_VEC:
02144 case ADDR_DIFF_VEC:
02145 case CALL:
02146 case MEM:
02147 return 0;
02148
02149 case UNSPEC_VOLATILE:
02150
02151 return 1;
02152
02153 case ASM_INPUT:
02154 case ASM_OPERANDS:
02155 if (MEM_VOLATILE_P (x))
02156 return 1;
02157
02158 default:
02159 break;
02160 }
02161
02162
02163
02164 {
02165 const char *fmt = GET_RTX_FORMAT (code);
02166 int i;
02167
02168 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02169 {
02170 if (fmt[i] == 'e')
02171 {
02172 if (volatile_insn_p (XEXP (x, i)))
02173 return 1;
02174 }
02175 else if (fmt[i] == 'E')
02176 {
02177 int j;
02178 for (j = 0; j < XVECLEN (x, i); j++)
02179 if (volatile_insn_p (XVECEXP (x, i, j)))
02180 return 1;
02181 }
02182 }
02183 }
02184 return 0;
02185 }
02186
02187
02188
02189
02190 int
02191 volatile_refs_p (x)
02192 rtx x;
02193 {
02194 RTX_CODE code;
02195
02196 code = GET_CODE (x);
02197 switch (code)
02198 {
02199 case LABEL_REF:
02200 case SYMBOL_REF:
02201 case CONST_INT:
02202 case CONST:
02203 case CONST_DOUBLE:
02204 case CONST_VECTOR:
02205 case CC0:
02206 case PC:
02207 case REG:
02208 case SCRATCH:
02209 case CLOBBER:
02210 case ADDR_VEC:
02211 case ADDR_DIFF_VEC:
02212 return 0;
02213
02214 case UNSPEC_VOLATILE:
02215 return 1;
02216
02217 case MEM:
02218 case ASM_INPUT:
02219 case ASM_OPERANDS:
02220 if (MEM_VOLATILE_P (x))
02221 return 1;
02222
02223 default:
02224 break;
02225 }
02226
02227
02228
02229 {
02230 const char *fmt = GET_RTX_FORMAT (code);
02231 int i;
02232
02233 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02234 {
02235 if (fmt[i] == 'e')
02236 {
02237 if (volatile_refs_p (XEXP (x, i)))
02238 return 1;
02239 }
02240 else if (fmt[i] == 'E')
02241 {
02242 int j;
02243 for (j = 0; j < XVECLEN (x, i); j++)
02244 if (volatile_refs_p (XVECEXP (x, i, j)))
02245 return 1;
02246 }
02247 }
02248 }
02249 return 0;
02250 }
02251
02252
02253
02254
02255 int
02256 side_effects_p (x)
02257 rtx x;
02258 {
02259 RTX_CODE code;
02260
02261 code = GET_CODE (x);
02262 switch (code)
02263 {
02264 case LABEL_REF:
02265 case SYMBOL_REF:
02266 case CONST_INT:
02267 case CONST:
02268 case CONST_DOUBLE:
02269 case CONST_VECTOR:
02270 case CC0:
02271 case PC:
02272 case REG:
02273 case SCRATCH:
02274 case ADDR_VEC:
02275 case ADDR_DIFF_VEC:
02276 return 0;
02277
02278 case CLOBBER:
02279
02280
02281
02282 return (GET_MODE (x) != VOIDmode);
02283
02284 case PRE_INC:
02285 case PRE_DEC:
02286 case POST_INC:
02287 case POST_DEC:
02288 case PRE_MODIFY:
02289 case POST_MODIFY:
02290 case CALL:
02291 case UNSPEC_VOLATILE:
02292
02293 return 1;
02294
02295 case MEM:
02296 case ASM_INPUT:
02297 case ASM_OPERANDS:
02298 if (MEM_VOLATILE_P (x))
02299 return 1;
02300
02301 default:
02302 break;
02303 }
02304
02305
02306
02307 {
02308 const char *fmt = GET_RTX_FORMAT (code);
02309 int i;
02310
02311 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02312 {
02313 if (fmt[i] == 'e')
02314 {
02315 if (side_effects_p (XEXP (x, i)))
02316 return 1;
02317 }
02318 else if (fmt[i] == 'E')
02319 {
02320 int j;
02321 for (j = 0; j < XVECLEN (x, i); j++)
02322 if (side_effects_p (XVECEXP (x, i, j)))
02323 return 1;
02324 }
02325 }
02326 }
02327 return 0;
02328 }
02329
02330
02331
02332 int
02333 may_trap_p (x)
02334 rtx x;
02335 {
02336 int i;
02337 enum rtx_code code;
02338 const char *fmt;
02339
02340 if (x == 0)
02341 return 0;
02342 code = GET_CODE (x);
02343 switch (code)
02344 {
02345
02346 case CONST_INT:
02347 case CONST_DOUBLE:
02348 case CONST_VECTOR:
02349 case SYMBOL_REF:
02350 case LABEL_REF:
02351 case CONST:
02352 case PC:
02353 case CC0:
02354 case REG:
02355 case SCRATCH:
02356 return 0;
02357
02358 case ASM_INPUT:
02359 case UNSPEC_VOLATILE:
02360 case TRAP_IF:
02361 return 1;
02362
02363 case ASM_OPERANDS:
02364 return MEM_VOLATILE_P (x);
02365
02366
02367 case MEM:
02368 if (MEM_NOTRAP_P (x))
02369 return 0;
02370 return rtx_addr_can_trap_p (XEXP (x, 0));
02371
02372
02373 case DIV:
02374 case MOD:
02375 case UDIV:
02376 case UMOD:
02377 if (HONOR_SNANS (GET_MODE (x)))
02378 return 1;
02379 if (! CONSTANT_P (XEXP (x, 1))
02380 || (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
02381 && flag_trapping_math))
02382 return 1;
02383
02384
02385 if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)
02386 return 1;
02387 break;
02388
02389 case EXPR_LIST:
02390
02391
02392 return 1;
02393
02394 case GE:
02395 case GT:
02396 case LE:
02397 case LT:
02398 case COMPARE:
02399
02400 if (!flag_trapping_math)
02401 break;
02402
02403
02404
02405
02406 if (HONOR_NANS (GET_MODE (x)))
02407 return 1;
02408
02409
02410 if (HONOR_NANS (GET_MODE (XEXP (x, 0)))
02411 || HONOR_NANS (GET_MODE (XEXP (x, 1))))
02412 return 1;
02413 break;
02414
02415 case EQ:
02416 case NE:
02417 if (HONOR_SNANS (GET_MODE (x)))
02418 return 1;
02419
02420 if (HONOR_SNANS (GET_MODE (XEXP (x, 0)))
02421 || HONOR_SNANS (GET_MODE (XEXP (x, 1))))
02422 return 1;
02423 break;
02424
02425 case FIX:
02426
02427 if (flag_trapping_math && HONOR_NANS (GET_MODE (XEXP (x, 0))))
02428 return 1;
02429 break;
02430
02431 case NEG:
02432 case ABS:
02433
02434 break;
02435
02436 default:
02437
02438 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
02439 && flag_trapping_math)
02440 return 1;
02441 }
02442
02443 fmt = GET_RTX_FORMAT (code);
02444 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02445 {
02446 if (fmt[i] == 'e')
02447 {
02448 if (may_trap_p (XEXP (x, i)))
02449 return 1;
02450 }
02451 else if (fmt[i] == 'E')
02452 {
02453 int j;
02454 for (j = 0; j < XVECLEN (x, i); j++)
02455 if (may_trap_p (XVECEXP (x, i, j)))
02456 return 1;
02457 }
02458 }
02459 return 0;
02460 }
02461
02462
02463
02464
02465 int
02466 inequality_comparisons_p (x)
02467 rtx x;
02468 {
02469 const char *fmt;
02470 int len, i;
02471 enum rtx_code code = GET_CODE (x);
02472
02473 switch (code)
02474 {
02475 case REG:
02476 case SCRATCH:
02477 case PC:
02478 case CC0:
02479 case CONST_INT:
02480 case CONST_DOUBLE:
02481 case CONST_VECTOR:
02482 case CONST:
02483 case LABEL_REF:
02484 case SYMBOL_REF:
02485 return 0;
02486
02487 case LT:
02488 case LTU:
02489 case GT:
02490 case GTU:
02491 case LE:
02492 case LEU:
02493 case GE:
02494 case GEU:
02495 return 1;
02496
02497 default:
02498 break;
02499 }
02500
02501 len = GET_RTX_LENGTH (code);
02502 fmt = GET_RTX_FORMAT (code);
02503
02504 for (i = 0; i < len; i++)
02505 {
02506 if (fmt[i] == 'e')
02507 {
02508 if (inequality_comparisons_p (XEXP (x, i)))
02509 return 1;
02510 }
02511 else if (fmt[i] == 'E')
02512 {
02513 int j;
02514 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
02515 if (inequality_comparisons_p (XVECEXP (x, i, j)))
02516 return 1;
02517 }
02518 }
02519
02520 return 0;
02521 }
02522
02523
02524
02525
02526
02527
02528
02529 rtx
02530 replace_rtx (x, from, to)
02531 rtx x, from, to;
02532 {
02533 int i, j;
02534 const char *fmt;
02535
02536
02537
02538 if (x != 0 && GET_CODE (x) == CONST_DOUBLE)
02539 return x;
02540
02541 if (x == from)
02542 return to;
02543
02544
02545 if (x == 0)
02546 return 0;
02547
02548 if (GET_CODE (x) == SUBREG)
02549 {
02550 rtx new = replace_rtx (SUBREG_REG (x), from, to);
02551
02552 if (GET_CODE (new) == CONST_INT)
02553 {
02554 x = simplify_subreg (GET_MODE (x), new,
02555 GET_MODE (SUBREG_REG (x)),
02556 SUBREG_BYTE (x));
02557 if (! x)
02558 abort ();
02559 }
02560 else
02561 SUBREG_REG (x) = new;
02562
02563 return x;
02564 }
02565 else if (GET_CODE (x) == ZERO_EXTEND)
02566 {
02567 rtx new = replace_rtx (XEXP (x, 0), from, to);
02568
02569 if (GET_CODE (new) == CONST_INT)
02570 {
02571 x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
02572 new, GET_MODE (XEXP (x, 0)));
02573 if (! x)
02574 abort ();
02575 }
02576 else
02577 XEXP (x, 0) = new;
02578
02579 return x;
02580 }
02581
02582 fmt = GET_RTX_FORMAT (GET_CODE (x));
02583 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
02584 {
02585 if (fmt[i] == 'e')
02586 XEXP (x, i) = replace_rtx (XEXP (x, i), from, to);
02587 else if (fmt[i] == 'E')
02588 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
02589 XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), from, to);
02590 }
02591
02592 return x;
02593 }
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607 rtx
02608 replace_regs (x, reg_map, nregs, replace_dest)
02609 rtx x;
02610 rtx *reg_map;
02611 unsigned int nregs;
02612 int replace_dest;
02613 {
02614 enum rtx_code code;
02615 int i;
02616 const char *fmt;
02617
02618 if (x == 0)
02619 return x;
02620
02621 code = GET_CODE (x);
02622 switch (code)
02623 {
02624 case SCRATCH:
02625 case PC:
02626 case CC0:
02627 case CONST_INT:
02628 case CONST_DOUBLE:
02629 case CONST_VECTOR:
02630 case CONST:
02631 case SYMBOL_REF:
02632 case LABEL_REF:
02633 return x;
02634
02635 case REG:
02636
02637 if (REGNO (x) < nregs && reg_map[REGNO (x)] != 0)
02638 {
02639
02640
02641
02642 if (GET_CODE (reg_map[REGNO (x)]) == SUBREG)
02643 return copy_rtx (reg_map[REGNO (x)]);
02644 return reg_map[REGNO (x)];
02645 }
02646 return x;
02647
02648 case SUBREG:
02649
02650 if (GET_CODE (SUBREG_REG (x)) == REG && REGNO (SUBREG_REG (x)) < nregs
02651 && reg_map[REGNO (SUBREG_REG (x))] != 0
02652 && GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG)
02653 {
02654 rtx map_val = reg_map[REGNO (SUBREG_REG (x))];
02655 return simplify_gen_subreg (GET_MODE (x), map_val,
02656 GET_MODE (SUBREG_REG (x)),
02657 SUBREG_BYTE (x));
02658 }
02659 break;
02660
02661 case SET:
02662 if (replace_dest)
02663 SET_DEST (x) = replace_regs (SET_DEST (x), reg_map, nregs, 0);
02664
02665 else if (GET_CODE (SET_DEST (x)) == MEM
02666 || GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
02667
02668
02669
02670 XEXP (SET_DEST (x), 0) = replace_regs (XEXP (SET_DEST (x), 0),
02671 reg_map, nregs, 0);
02672 else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
02673
02674 break;
02675
02676 SET_SRC (x) = replace_regs (SET_SRC (x), reg_map, nregs, 0);
02677 return x;
02678
02679 default:
02680 break;
02681 }
02682
02683 fmt = GET_RTX_FORMAT (code);
02684 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02685 {
02686 if (fmt[i] == 'e')
02687 XEXP (x, i) = replace_regs (XEXP (x, i), reg_map, nregs, replace_dest);
02688 else if (fmt[i] == 'E')
02689 {
02690 int j;
02691 for (j = 0; j < XVECLEN (x, i); j++)
02692 XVECEXP (x, i, j) = replace_regs (XVECEXP (x, i, j), reg_map,
02693 nregs, replace_dest);
02694 }
02695 }
02696 return x;
02697 }
02698
02699
02700
02701
02702
02703 static int
02704 computed_jump_p_1 (x)
02705 rtx x;
02706 {
02707 enum rtx_code code = GET_CODE (x);
02708 int i, j;
02709 const char *fmt;
02710
02711 switch (code)
02712 {
02713 case LABEL_REF:
02714 case PC:
02715 return 0;
02716
02717 case CONST:
02718 case CONST_INT:
02719 case CONST_DOUBLE:
02720 case CONST_VECTOR:
02721 case SYMBOL_REF:
02722 case REG:
02723 return 1;
02724
02725 case MEM:
02726 return ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
02727 && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
02728
02729 case IF_THEN_ELSE:
02730 return (computed_jump_p_1 (XEXP (x, 1))
02731 || computed_jump_p_1 (XEXP (x, 2)));
02732
02733 default:
02734 break;
02735 }
02736
02737 fmt = GET_RTX_FORMAT (code);
02738 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
02739 {
02740 if (fmt[i] == 'e'
02741 && computed_jump_p_1 (XEXP (x, i)))
02742 return 1;
02743
02744 else if (fmt[i] == 'E')
02745 for (j = 0; j < XVECLEN (x, i); j++)
02746 if (computed_jump_p_1 (XVECEXP (x, i, j)))
02747 return 1;
02748 }
02749
02750 return 0;
02751 }
02752
02753
02754
02755
02756
02757
02758 int
02759 computed_jump_p (insn)
02760 rtx insn;
02761 {
02762 int i;
02763 if (GET_CODE (insn) == JUMP_INSN)
02764 {
02765 rtx pat = PATTERN (insn);
02766
02767 if (find_reg_note (insn, REG_LABEL, NULL_RTX))
02768 return 0;
02769 else if (GET_CODE (pat) == PARALLEL)
02770 {
02771 int len = XVECLEN (pat, 0);
02772 int has_use_labelref = 0;
02773
02774 for (i = len - 1; i >= 0; i--)
02775 if (GET_CODE (XVECEXP (pat, 0, i)) == USE
02776 && (GET_CODE (XEXP (XVECEXP (pat, 0, i), 0))
02777 == LABEL_REF))
02778 has_use_labelref = 1;
02779
02780 if (! has_use_labelref)
02781 for (i = len - 1; i >= 0; i--)
02782 if (GET_CODE (XVECEXP (pat, 0, i)) == SET
02783 && SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx
02784 && computed_jump_p_1 (SET_SRC (XVECEXP (pat, 0, i))))
02785 return 1;
02786 }
02787 else if (GET_CODE (pat) == SET
02788 && SET_DEST (pat) == pc_rtx
02789 && computed_jump_p_1 (SET_SRC (pat)))
02790 return 1;
02791 }
02792 return 0;
02793 }
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808 int
02809 for_each_rtx (x, f, data)
02810 rtx *x;
02811 rtx_function f;
02812 void *data;
02813 {
02814 int result;
02815 int length;
02816 const char *format;
02817 int i;
02818
02819
02820 result = (*f) (x, data);
02821 if (result == -1)
02822
02823 return 0;
02824 else if (result != 0)
02825
02826 return result;
02827
02828 if (*x == NULL_RTX)
02829
02830 return 0;
02831
02832 length = GET_RTX_LENGTH (GET_CODE (*x));
02833 format = GET_RTX_FORMAT (GET_CODE (*x));
02834
02835 for (i = 0; i < length; ++i)
02836 {
02837 switch (format[i])
02838 {
02839 case 'e':
02840 result = for_each_rtx (&XEXP (*x, i), f, data);
02841 if (result != 0)
02842 return result;
02843 break;
02844
02845 case 'V':
02846 case 'E':
02847 if (XVEC (*x, i) != 0)
02848 {
02849 int j;
02850 for (j = 0; j < XVECLEN (*x, i); ++j)
02851 {
02852 result = for_each_rtx (&XVECEXP (*x, i, j), f, data);
02853 if (result != 0)
02854 return result;
02855 }
02856 }
02857 break;
02858
02859 default:
02860
02861 break;
02862 }
02863
02864 }
02865
02866 return 0;
02867 }
02868
02869
02870
02871
02872 rtx
02873 regno_use_in (regno, x)
02874 unsigned int regno;
02875 rtx x;
02876 {
02877 const char *fmt;
02878 int i, j;
02879 rtx tem;
02880
02881 if (GET_CODE (x) == REG && REGNO (x) == regno)
02882 return x;
02883
02884 fmt = GET_RTX_FORMAT (GET_CODE (x));
02885 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
02886 {
02887 if (fmt[i] == 'e')
02888 {
02889 if ((tem = regno_use_in (regno, XEXP (x, i))))
02890 return tem;
02891 }
02892 else if (fmt[i] == 'E')
02893 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
02894 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
02895 return tem;
02896 }
02897
02898 return NULL_RTX;
02899 }
02900
02901
02902
02903
02904
02905
02906
02907 int
02908 commutative_operand_precedence (op)
02909 rtx op;
02910 {
02911
02912 if (GET_CODE (op) == CONST_INT)
02913 return -5;
02914 if (GET_CODE (op) == CONST_DOUBLE)
02915 return -4;
02916 if (CONSTANT_P (op))
02917 return -3;
02918
02919
02920 if (GET_CODE (op) == SUBREG
02921 && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op))) == 'o')
02922 return -2;
02923
02924
02925
02926
02927 if (GET_CODE (op) == NEG || GET_CODE (op) == NOT
02928 || GET_CODE (op) == MULT || GET_CODE (op) == PLUS
02929 || GET_CODE (op) == MINUS)
02930 return 2;
02931
02932
02933
02934 if (GET_RTX_CLASS (GET_CODE (op)) == 'o')
02935 return -1;
02936 return 0;
02937 }
02938
02939
02940
02941
02942 int
02943 swap_commutative_operands_p (x, y)
02944 rtx x, y;
02945 {
02946 return (commutative_operand_precedence (x)
02947 < commutative_operand_precedence (y));
02948 }
02949
02950
02951
02952 int
02953 auto_inc_p (x)
02954 rtx x;
02955 {
02956 switch (GET_CODE (x))
02957 {
02958 case PRE_INC:
02959 case POST_INC:
02960 case PRE_DEC:
02961 case POST_DEC:
02962 case PRE_MODIFY:
02963 case POST_MODIFY:
02964
02965 if (XEXP (x, 0) != stack_pointer_rtx)
02966 return 1;
02967 default:
02968 break;
02969 }
02970 return 0;
02971 }
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983 int
02984 insns_safe_to_move_p (from, to, new_to)
02985 rtx from;
02986 rtx to;
02987 rtx *new_to;
02988 {
02989 int eh_region_count = 0;
02990 int past_to_p = 0;
02991 rtx r = from;
02992
02993
02994
02995 if (new_to)
02996 *new_to = to;
02997
02998 while (r)
02999 {
03000 if (GET_CODE (r) == NOTE)
03001 {
03002 switch (NOTE_LINE_NUMBER (r))
03003 {
03004 case NOTE_INSN_EH_REGION_BEG:
03005 ++eh_region_count;
03006 break;
03007
03008 case NOTE_INSN_EH_REGION_END:
03009 if (eh_region_count == 0)
03010
03011
03012
03013 return 0;
03014
03015 --eh_region_count;
03016 break;
03017
03018 default:
03019 break;
03020 }
03021 }
03022 else if (past_to_p)
03023
03024
03025 return 0;
03026
03027 if (r == to)
03028 {
03029 if (!new_to)
03030
03031
03032 return eh_region_count == 0;
03033
03034 past_to_p = 1;
03035 }
03036
03037
03038
03039 if (past_to_p && eh_region_count == 0)
03040 {
03041 *new_to = r;
03042 return 1;
03043 }
03044
03045
03046 r = NEXT_INSN (r);
03047 }
03048
03049 return 0;
03050 }
03051
03052
03053 int
03054 loc_mentioned_in_p (loc, in)
03055 rtx *loc, in;
03056 {
03057 enum rtx_code code = GET_CODE (in);
03058 const char *fmt = GET_RTX_FORMAT (code);
03059 int i, j;
03060
03061 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
03062 {
03063 if (loc == &in->fld[i].rtx)
03064 return 1;
03065 if (fmt[i] == 'e')
03066 {
03067 if (loc_mentioned_in_p (loc, XEXP (in, i)))
03068 return 1;
03069 }
03070 else if (fmt[i] == 'E')
03071 for (j = XVECLEN (in, i) - 1; j >= 0; j--)
03072 if (loc_mentioned_in_p (loc, XVECEXP (in, i, j)))
03073 return 1;
03074 }
03075 return 0;
03076 }
03077
03078
03079
03080
03081 unsigned int
03082 subreg_lsb (x)
03083 rtx x;
03084 {
03085 enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
03086 enum machine_mode mode = GET_MODE (x);
03087 unsigned int bitpos;
03088 unsigned int byte;
03089 unsigned int word;
03090
03091
03092 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (inner_mode))
03093 return 0;
03094
03095 if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
03096
03097
03098 if ((SUBREG_BYTE (x) % UNITS_PER_WORD
03099 + GET_MODE_SIZE (mode)) > UNITS_PER_WORD
03100 && (SUBREG_BYTE (x) % UNITS_PER_WORD
03101 || GET_MODE_SIZE (mode) % UNITS_PER_WORD))
03102 abort ();
03103
03104 if (WORDS_BIG_ENDIAN)
03105 word = (GET_MODE_SIZE (inner_mode)
03106 - (SUBREG_BYTE (x) + GET_MODE_SIZE (mode))) / UNITS_PER_WORD;
03107 else
03108 word = SUBREG_BYTE (x) / UNITS_PER_WORD;
03109 bitpos = word * BITS_PER_WORD;
03110
03111 if (BYTES_BIG_ENDIAN)
03112 byte = (GET_MODE_SIZE (inner_mode)
03113 - (SUBREG_BYTE (x) + GET_MODE_SIZE (mode))) % UNITS_PER_WORD;
03114 else
03115 byte = SUBREG_BYTE (x) % UNITS_PER_WORD;
03116 bitpos += byte * BITS_PER_UNIT;
03117
03118 return bitpos;
03119 }
03120
03121
03122
03123
03124
03125
03126
03127 unsigned int
03128 subreg_regno_offset (xregno, xmode, offset, ymode)
03129 unsigned int xregno;
03130 enum machine_mode xmode;
03131 unsigned int offset;
03132 enum machine_mode ymode;
03133 {
03134 int nregs_xmode, nregs_ymode;
03135 int mode_multiple, nregs_multiple;
03136 int y_offset;
03137
03138 if (xregno >= FIRST_PSEUDO_REGISTER)
03139 abort ();
03140
03141 nregs_xmode = HARD_REGNO_NREGS (xregno, xmode);
03142 nregs_ymode = HARD_REGNO_NREGS (xregno, ymode);
03143
03144
03145
03146
03147 if (offset == 0
03148 && nregs_ymode > nregs_xmode
03149 && (GET_MODE_SIZE (ymode) > UNITS_PER_WORD
03150 ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
03151 return nregs_xmode - nregs_ymode;
03152
03153 if (offset == 0 || nregs_xmode == nregs_ymode)
03154 return 0;
03155
03156
03157 mode_multiple = GET_MODE_SIZE (xmode) / GET_MODE_SIZE (ymode);
03158 if (mode_multiple == 0)
03159 abort ();
03160
03161 y_offset = offset / GET_MODE_SIZE (ymode);
03162 nregs_multiple = nregs_xmode / nregs_ymode;
03163 return (y_offset / (mode_multiple / nregs_multiple)) * nregs_ymode;
03164 }
03165
03166
03167
03168
03169
03170
03171
03172
03173 bool
03174 subreg_offset_representable_p (xregno, xmode, offset, ymode)
03175 unsigned int xregno;
03176 enum machine_mode xmode;
03177 unsigned int offset;
03178 enum machine_mode ymode;
03179 {
03180 int nregs_xmode, nregs_ymode;
03181 int mode_multiple, nregs_multiple;
03182 int y_offset;
03183
03184 if (xregno >= FIRST_PSEUDO_REGISTER)
03185 abort ();
03186
03187 nregs_xmode = HARD_REGNO_NREGS (xregno, xmode);
03188 nregs_ymode = HARD_REGNO_NREGS (xregno, ymode);
03189
03190
03191 if (offset == 0
03192 && nregs_ymode > nregs_xmode
03193 && (GET_MODE_SIZE (ymode) > UNITS_PER_WORD
03194 ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
03195 return true;
03196
03197
03198 if (offset == subreg_lowpart_offset (ymode, xmode))
03199 return true;
03200
03201 #ifdef ENABLE_CHECKING
03202
03203
03204
03205 if (GET_MODE_SIZE (xmode) % GET_MODE_SIZE (ymode)
03206 || GET_MODE_SIZE (ymode) % nregs_ymode
03207 || nregs_xmode % nregs_ymode)
03208 abort ();
03209 #endif
03210
03211
03212
03213
03214 offset -= subreg_lowpart_offset (ymode,
03215 mode_for_size (GET_MODE_BITSIZE (xmode)
03216 / nregs_xmode,
03217 MODE_INT, 0));
03218
03219
03220 mode_multiple = GET_MODE_SIZE (xmode) / GET_MODE_SIZE (ymode);
03221 if (mode_multiple == 0)
03222 abort ();
03223
03224 y_offset = offset / GET_MODE_SIZE (ymode);
03225 nregs_multiple = nregs_xmode / nregs_ymode;
03226 #ifdef ENABLE_CHECKING
03227 if (offset % GET_MODE_SIZE (ymode)
03228 || mode_multiple % nregs_multiple)
03229 abort ();
03230 #endif
03231 return (!(y_offset % (mode_multiple / nregs_multiple)));
03232 }
03233
03234
03235 unsigned int
03236 subreg_regno (x)
03237 rtx x;
03238 {
03239 unsigned int ret;
03240 rtx subreg = SUBREG_REG (x);
03241 int regno = REGNO (subreg);
03242
03243 ret = regno + subreg_regno_offset (regno,
03244 GET_MODE (subreg),
03245 SUBREG_BYTE (x),
03246 GET_MODE (x));
03247 return ret;
03248
03249 }
03250 struct parms_set_data
03251 {
03252 int nregs;
03253 HARD_REG_SET regs;
03254 };
03255
03256
03257 static void
03258 parms_set (x, pat, data)
03259 rtx x, pat ATTRIBUTE_UNUSED;
03260 void *data;
03261 {
03262 struct parms_set_data *d = data;
03263 if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
03264 && TEST_HARD_REG_BIT (d->regs, REGNO (x)))
03265 {
03266 CLEAR_HARD_REG_BIT (d->regs, REGNO (x));
03267 d->nregs--;
03268 }
03269 }
03270
03271
03272
03273 rtx
03274 find_first_parameter_load (call_insn, boundary)
03275 rtx call_insn, boundary;
03276 {
03277 struct parms_set_data parm;
03278 rtx p, before;
03279
03280
03281
03282
03283 CLEAR_HARD_REG_SET (parm.regs);
03284 parm.nregs = 0;
03285 for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
03286 if (GET_CODE (XEXP (p, 0)) == USE
03287 && GET_CODE (XEXP (XEXP (p, 0), 0)) == REG)
03288 {
03289 if (REGNO (XEXP (XEXP (p, 0), 0)) >= FIRST_PSEUDO_REGISTER)
03290 abort ();
03291
03292
03293
03294 if (!FUNCTION_ARG_REGNO_P (REGNO (XEXP (XEXP (p, 0), 0))))
03295 continue;
03296
03297 SET_HARD_REG_BIT (parm.regs, REGNO (XEXP (XEXP (p, 0), 0)));
03298 parm.nregs++;
03299 }
03300 before = call_insn;
03301
03302
03303 while (parm.nregs && before != boundary)
03304 {
03305 before = PREV_INSN (before);
03306
03307
03308
03309 if (GET_CODE (before) == CALL_INSN)
03310 break;
03311
03312
03313
03314
03315
03316 if (GET_CODE (before) == CODE_LABEL)
03317 {
03318 if (before != boundary)
03319 abort ();
03320 break;
03321 }
03322
03323 if (INSN_P (before))
03324 note_stores (PATTERN (before), parms_set, &parm);
03325 }
03326 return before;
03327 }
03328
03329
03330
03331
03332 bool
03333 keep_with_call_p (insn)
03334 rtx insn;
03335 {
03336 rtx set;
03337
03338 if (INSN_P (insn) && (set = single_set (insn)) != NULL)
03339 {
03340 if (GET_CODE (SET_DEST (set)) == REG
03341 && REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
03342 && fixed_regs[REGNO (SET_DEST (set))]
03343 && general_operand (SET_SRC (set), VOIDmode))
03344 return true;
03345 if (GET_CODE (SET_SRC (set)) == REG
03346 && FUNCTION_VALUE_REGNO_P (REGNO (SET_SRC (set)))
03347 && GET_CODE (SET_DEST (set)) == REG
03348 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
03349 return true;
03350
03351
03352
03353 if (SET_DEST (set) == stack_pointer_rtx)
03354 {
03355 rtx i2 = next_nonnote_insn (insn);
03356 if (i2 && keep_with_call_p (i2))
03357 return true;
03358 }
03359 }
03360 return false;
03361 }
03362
03363
03364
03365
03366
03367 static bool
03368 hoist_test_store (x, val, live)
03369 rtx x, val;
03370 regset live;
03371 {
03372 if (GET_CODE (x) == SCRATCH)
03373 return true;
03374
03375 if (rtx_equal_p (x, val))
03376 return true;
03377
03378
03379
03380
03381
03382 if (GET_CODE (x) == SUBREG && rtx_equal_p (SUBREG_REG (x), val))
03383 {
03384 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))) > UNITS_PER_WORD
03385 && GET_MODE_BITSIZE (GET_MODE (x)) <
03386 GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))))
03387 return false;
03388 return true;
03389 }
03390 if (GET_CODE (x) == SUBREG)
03391 x = SUBREG_REG (x);
03392
03393
03394
03395
03396 if (!REG_P (x))
03397 return false;
03398
03399
03400
03401
03402
03403
03404 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
03405 {
03406 int regno = REGNO (x);
03407 int n = HARD_REGNO_NREGS (regno, GET_MODE (x));
03408
03409 if (!live)
03410 return false;
03411 if (REGNO_REG_SET_P (live, regno))
03412 return false;
03413 while (--n > 0)
03414 if (REGNO_REG_SET_P (live, regno + n))
03415 return false;
03416 }
03417 return true;
03418 }
03419
03420
03421
03422
03423
03424
03425 bool
03426 can_hoist_insn_p (insn, val, live)
03427 rtx insn, val;
03428 regset live;
03429 {
03430 rtx pat = PATTERN (insn);
03431 int i;
03432
03433
03434
03435 if (!single_set (insn))
03436 return false;
03437
03438
03439 if (GET_CODE (insn) == CALL_INSN)
03440 return false;
03441
03442
03443 if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
03444 return false;
03445 switch (GET_CODE (pat))
03446 {
03447 case SET:
03448 if (!hoist_test_store (SET_DEST (pat), val, live))
03449 return false;
03450 break;
03451 case USE:
03452
03453 return false;
03454 break;
03455 case CLOBBER:
03456 if (!hoist_test_store (XEXP (pat, 0), val, live))
03457 return false;
03458 break;
03459 case PARALLEL:
03460 for (i = 0; i < XVECLEN (pat, 0); i++)
03461 {
03462 rtx x = XVECEXP (pat, 0, i);
03463 switch (GET_CODE (x))
03464 {
03465 case SET:
03466 if (!hoist_test_store (SET_DEST (x), val, live))
03467 return false;
03468 break;
03469 case USE:
03470
03471
03472
03473 return false;
03474 break;
03475 case CLOBBER:
03476 if (!hoist_test_store (SET_DEST (x), val, live))
03477 return false;
03478 break;
03479 default:
03480 break;
03481 }
03482 }
03483 break;
03484 default:
03485 abort ();
03486 }
03487 return true;
03488 }
03489
03490
03491
03492
03493
03494 static void
03495 hoist_update_store (insn, xp, val, new)
03496 rtx insn, *xp, val, new;
03497 {
03498 rtx x = *xp;
03499
03500 if (GET_CODE (x) == SCRATCH)
03501 return;
03502
03503 if (GET_CODE (x) == SUBREG && SUBREG_REG (x) == val)
03504 validate_change (insn, xp,
03505 simplify_gen_subreg (GET_MODE (x), new, GET_MODE (new),
03506 SUBREG_BYTE (x)), 1);
03507 if (rtx_equal_p (x, val))
03508 {
03509 validate_change (insn, xp, new, 1);
03510 return;
03511 }
03512 if (GET_CODE (x) == SUBREG)
03513 {
03514 xp = &SUBREG_REG (x);
03515 x = *xp;
03516 }
03517
03518 if (!REG_P (x))
03519 abort ();
03520
03521
03522
03523 if (REGNO (x) >= FIRST_PSEUDO_REGISTER)
03524 validate_change (insn, xp, gen_reg_rtx (GET_MODE (x)), 1);
03525 REG_NOTES (insn)
03526 = alloc_EXPR_LIST (REG_UNUSED, *xp, REG_NOTES (insn));
03527 }
03528
03529
03530
03531
03532 rtx
03533 hoist_insn_after (insn, after, val, new)
03534 rtx insn, after, val, new;
03535 {
03536 rtx pat;
03537 int i;
03538 rtx note;
03539
03540 insn = emit_copy_of_insn_after (insn, after);
03541 pat = PATTERN (insn);
03542
03543
03544 while ((note = find_reg_note (insn, REG_UNUSED, NULL_RTX)))
03545 remove_note (insn, note);
03546
03547
03548
03549
03550 while ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)))
03551 remove_note (insn, note);
03552 while ((note = find_reg_note (insn, REG_EQUIV, NULL_RTX)))
03553 remove_note (insn, note);
03554
03555
03556
03557 while ((note = find_reg_note (insn, REG_DEAD, NULL_RTX)))
03558 remove_note (insn, note);
03559 switch (GET_CODE (pat))
03560 {
03561 case SET:
03562 hoist_update_store (insn, &SET_DEST (pat), val, new);
03563 break;
03564 case USE:
03565 break;
03566 case CLOBBER:
03567 hoist_update_store (insn, &XEXP (pat, 0), val, new);
03568 break;
03569 case PARALLEL:
03570 for (i = 0; i < XVECLEN (pat, 0); i++)
03571 {
03572 rtx x = XVECEXP (pat, 0, i);
03573 switch (GET_CODE (x))
03574 {
03575 case SET:
03576 hoist_update_store (insn, &SET_DEST (x), val, new);
03577 break;
03578 case USE:
03579 break;
03580 case CLOBBER:
03581 hoist_update_store (insn, &SET_DEST (x), val, new);
03582 break;
03583 default:
03584 break;
03585 }
03586 }
03587 break;
03588 default:
03589 abort ();
03590 }
03591 if (!apply_change_group ())
03592 abort ();
03593
03594 return insn;
03595 }
03596
03597 rtx
03598 hoist_insn_to_edge (insn, e, val, new)
03599 rtx insn, val, new;
03600 edge e;
03601 {
03602 rtx new_insn;
03603
03604
03605
03606 if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e))
03607 abort ();
03608
03609
03610
03611 if (e->insns == NULL_RTX)
03612 {
03613 start_sequence ();
03614 emit_note (NULL, NOTE_INSN_DELETED);
03615 }
03616 else
03617 push_to_sequence (e->insns);
03618
03619 new_insn = hoist_insn_after (insn, get_last_insn (), val, new);
03620
03621 e->insns = get_insns ();
03622 end_sequence ();
03623 return new_insn;
03624 }