|
|
1.1 root 1: /* Optimize by combining instructions for GNU compiler. 1.1.1.2 ! root 2: Copyright (C) 1987, 1988 Free Software Foundation, Inc. 1.1 root 3: 4: This file is part of GNU CC. 5: 6: GNU CC is distributed in the hope that it will be useful, 7: but WITHOUT ANY WARRANTY. No author or distributor 8: accepts responsibility to anyone for the consequences of using it 9: or for whether it serves any particular purpose or works at all, 10: unless he says so in writing. Refer to the GNU CC General Public 11: License for full details. 12: 13: Everyone is granted permission to copy, modify and redistribute 14: GNU CC, but only under the conditions described in the 15: GNU CC General Public License. A copy of this license is 16: supposed to have been given to you along with GNU CC so you 17: can know your rights and responsibilities. It should be in a 18: file named COPYING. Among other things, the copyright notice 19: and this notice must be preserved on all copies. */ 20: 21: 22: /* This module is essentially the "combiner" phase of the U. of Arizona 23: Portable Optimizer, but redone to work on our list-structured 24: representation for RTL instead of their string representation. 25: 26: The LOG_LINKS of each insn identify the most recent assignment 27: to each REG used in the insn. It is a list of previous insns, 28: each of which contains a SET for a REG that is used in this insn 29: and not used or set in between. LOG_LINKs never cross basic blocks. 30: They were set up by the preceding pass (lifetime analysis). 31: 32: We try to combine each pair of insns joined by a logical link. 33: We also try to combine triples of insns A, B and C when 34: C has a link back to B and B has a link back to A. 35: 36: LOG_LINKS does not have links for use of the CC0. They don't 37: need to, because the insn that sets the CC0 is always immediately 38: before the insn that tests it. So we always regard a branch 39: insn as having a logical link to the preceding insn. 40: 41: We check (with use_crosses_set_p) to avoid combining in such a way 42: as to move a computation to a place where its value would be different. 43: 44: Combination is done by mathematically substituting the previous 45: insn(s) values for the regs they set into the expressions in 46: the later insns that refer to these regs. If the result is a valid insn 47: for our target machine, according to the machine description, 48: we install it, delete the earlier insns, and update the data flow 49: information (LOG_LINKS and REG_NOTES) for what we did. 50: 51: To simplify substitution, we combine only when the earlier insn(s) 52: consist of only a single assignment. To simplify updating afterward, 53: we never combine when a subroutine call appears in the middle. 54: 55: Since we do not represent assignments to CC0 explicitly except when that 56: is all an insn does, there is no LOG_LINKS entry in an insn that uses 57: the condition code for the insn that set the condition code. 58: Fortunately, these two insns must be consecutive. 59: Therefore, every JUMP_INSN is taken to have an implicit logical link 60: to the preceding insn. This is not quite right, since non-jumps can 61: also use the condition code; but in practice such insns would not 62: combine anyway. */ 63: 64: #include "config.h" 65: #include "rtl.h" 1.1.1.2 ! root 66: #include "flags.h" 1.1 root 67: #include "regs.h" 68: #include "basic-block.h" 69: #include "insn-config.h" 70: #include "recog.h" 71: 72: #define max(A,B) ((A) > (B) ? (A) : (B)) 73: #define min(A,B) ((A) < (B) ? (A) : (B)) 74: 1.1.1.2 ! root 75: /* It is not safe to use ordinary gen_lowpart in combine. ! 76: Use gen_lowpart_for_combine instead. See comments there. */ ! 77: #define gen_lowpart dont_use_gen_lowpart_you_dummy ! 78: 1.1 root 79: /* Number of attempts to combine instructions in this function. */ 80: 81: static int combine_attempts; 82: 83: /* Number of attempts that got as far as substitution in this function. */ 84: 85: static int combine_merges; 86: 87: /* Number of instructions combined with added SETs in this function. */ 88: 89: static int combine_extras; 90: 91: /* Number of instructions combined in this function. */ 92: 93: static int combine_successes; 94: 95: /* Totals over entire compilation. */ 96: 97: static int total_attempts, total_merges, total_extras, total_successes; 98: 99: 100: /* Vector mapping INSN_UIDs to cuids. 101: The cuids are like uids but increase monononically always. 102: Combine always uses cuids so that it can compare them. 103: But actually renumbering the uids, which we used to do, 104: proves to be a bad idea because it makes it hard to compare 105: the dumps produced by earlier passes with those from later passes. */ 106: 107: static short *uid_cuid; 108: 109: /* Get the cuid of an insn. */ 110: 111: #define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)]) 112: 113: 114: /* Record last point of death of (hard or pseudo) register n. */ 115: 116: static rtx *reg_last_death; 117: 118: /* Record last point of modification of (hard or pseudo) register n. */ 119: 120: static rtx *reg_last_set; 121: 122: /* Record the cuid of the last insn that invalidated memory 123: (anything that writes memory, and subroutine calls). */ 124: 125: static int mem_last_set; 126: 127: /* Record the cuid of the last CALL_INSN 128: so we can tell whether a potential combination crosses any calls. */ 129: 130: static int last_call_cuid; 131: 132: /* When `subst' is called, this is the insn that is being modified 133: (by combining in a previous insn). The PATTERN of this insn 134: is still the old pattern partially modified and it should not be 135: looked at, but this may be used to examine the successors of the insn 136: to judge whether a simplification is valid. */ 137: 138: static rtx subst_insn; 139: 140: /* Record one modification to rtl structure 141: to be undone by storing old_contents into *where. */ 142: 143: struct undo 144: { 145: rtx *where; 146: rtx old_contents; 147: }; 148: 149: /* Record a bunch of changes to be undone, up to MAX_UNDO of them. 150: num_undo says how many are currently recorded. 151: storage is nonzero if we must undo the allocation of new storage. 152: The value of storage is what to pass to obfree. */ 153: 154: #define MAX_UNDO 10 155: 156: struct undobuf 157: { 158: int num_undo; 159: char *storage; 160: struct undo undo[MAX_UNDO]; 161: }; 162: 163: static struct undobuf undobuf; 164: 1.1.1.2 ! root 165: /* Number of times the pseudo being substituted for ! 166: was found and replaced. */ ! 167: ! 168: static int n_occurrences; ! 169: 1.1 root 170: static void move_deaths (); 171: static void remove_death (); 172: static void record_dead_and_set_regs (); 173: int regno_dead_p (); 174: static int use_crosses_set_p (); 175: static rtx subst (); 176: static void undo_all (); 1.1.1.2 ! root 177: static void copy_substitutions (); 1.1 root 178: static void add_links (); 179: static void add_incs (); 1.1.1.2 ! root 180: static int insn_has_inc_p (); 1.1 root 181: static int adjacent_insns_p (); 182: static rtx simplify_and_const_int (); 183: static rtx gen_lowpart_for_combine (); 184: static void simplify_set_cc0_and (); 185: 186: /* Main entry point for combiner. F is the first insn of the function. 187: NREGS is the first unused pseudo-reg number. */ 188: 189: void 190: combine_instructions (f, nregs) 191: rtx f; 192: int nregs; 193: { 194: register rtx insn; 195: register int i; 196: register rtx links, nextlinks; 197: rtx prev; 198: 199: combine_attempts = 0; 200: combine_merges = 0; 201: combine_extras = 0; 202: combine_successes = 0; 203: 204: reg_last_death = (rtx *) alloca (nregs * sizeof (rtx)); 205: reg_last_set = (rtx *) alloca (nregs * sizeof (rtx)); 206: bzero (reg_last_death, nregs * sizeof (rtx)); 207: bzero (reg_last_set, nregs * sizeof (rtx)); 208: 209: init_recog (); 210: 211: /* Compute maximum uid value so uid_cuid can be allocated. */ 212: 213: for (insn = f, i = 0; insn; insn = NEXT_INSN (insn)) 214: if (INSN_UID (insn) > i) 215: i = INSN_UID (insn); 216: 217: uid_cuid = (short *) alloca ((i + 1) * sizeof (short)); 218: 219: /* Compute the mapping from uids to cuids. 220: Cuids are numbers assigned to insns, like uids, 221: except that cuids increase monotonically through the code. */ 222: 223: for (insn = f, i = 0; insn; insn = NEXT_INSN (insn)) 224: INSN_CUID (insn) = ++i; 225: 226: /* Now scan all the insns in forward order. */ 227: 228: last_call_cuid = 0; 229: mem_last_set = 0; 230: prev = 0; 231: 232: for (insn = f; insn; insn = NEXT_INSN (insn)) 233: { 234: if (GET_CODE (insn) == INSN 235: || GET_CODE (insn) == CALL_INSN 236: || GET_CODE (insn) == JUMP_INSN) 237: { 238: retry: 239: /* Try this insn with each insn it links back to. */ 240: 241: for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 242: if (try_combine (insn, XEXP (links, 0), 0)) 243: goto retry; 244: 245: /* Try each sequence of three linked insns ending with this one. */ 246: 247: for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 248: if (GET_CODE (XEXP (links, 0)) != NOTE) 249: for (nextlinks = LOG_LINKS (XEXP (links, 0)); nextlinks; 250: nextlinks = XEXP (nextlinks, 1)) 251: if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0))) 252: goto retry; 253: 254: /* Try to combine a jump insn that uses CC0 255: with a preceding insn that sets CC0, and maybe with its 256: logical predecessor as well. 257: This is how we make decrement-and-branch insns. 258: We need this special code because data flow connections 259: via CC0 do not get entered in LOG_LINKS. */ 260: 261: if (GET_CODE (insn) == JUMP_INSN 262: && prev != 0 263: && GET_CODE (prev) == INSN 264: && GET_CODE (PATTERN (prev)) == SET 265: && GET_CODE (SET_DEST (PATTERN (prev))) == CC0) 266: { 267: if (try_combine (insn, prev, 0)) 268: goto retry; 269: 270: if (GET_CODE (prev) != NOTE) 271: for (nextlinks = LOG_LINKS (prev); nextlinks; 272: nextlinks = XEXP (nextlinks, 1)) 273: if (try_combine (insn, prev, XEXP (nextlinks, 0))) 274: goto retry; 275: } 276: #if 0 277: /* Turned off because on 68020 it takes four insns to make 278: something like (a[b / 32] & (1 << (31 - (b % 32)))) != 0 279: that could actually be optimized, and that's an unlikely piece of code. */ 280: /* If an insn gets or sets a bit field, try combining it 281: with two different insns whose results it uses. */ 282: if (GET_CODE (insn) == INSN 283: && GET_CODE (PATTERN (insn)) == SET 284: && (GET_CODE (SET_DEST (PATTERN (insn))) == ZERO_EXTRACT 285: || GET_CODE (SET_DEST (PATTERN (insn))) == SIGN_EXTRACT 286: || GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTRACT 287: || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTRACT)) 288: { 289: for (links = LOG_LINKS (insn); links; links = XEXP (links, 1)) 290: if (GET_CODE (XEXP (links, 0)) != NOTE) 291: for (nextlinks = XEXP (links, 1); nextlinks; 292: nextlinks = XEXP (nextlinks, 1)) 293: if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0))) 294: goto retry; 295: } 296: #endif 297: record_dead_and_set_regs (insn); 298: prev = insn; 299: } 300: else if (GET_CODE (insn) != NOTE) 301: prev = 0; 302: } 303: total_attempts += combine_attempts; 304: total_merges += combine_merges; 305: total_extras += combine_extras; 306: total_successes += combine_successes; 307: } 308: 309: /* Try to combine the insns I1 and I2 into I3. 310: Here I1 appears earlier than I2, which is earlier than I3. 311: I1 can be zero; then we combine just I2 into I3. 312: 313: Return 1 if successful; if that happens, I1 and I2 are pseudo-deleted 314: by turning them into NOTEs, and I3 is modified. 315: Return 0 if the combination does not work. Then nothing is changed. */ 316: 317: static int 318: try_combine (i3, i2, i1) 319: register rtx i3, i2, i1; 320: { 321: register rtx newpat; 322: int added_sets_1 = 0; 323: int added_sets_2 = 0; 324: int total_sets; 325: int i2_is_used; 326: register rtx link; 327: int insn_code_number; 328: int recog_flags = 0; 329: rtx i2dest, i2src; 330: rtx i1dest, i1src; 1.1.1.2 ! root 331: int maxreg; 1.1 root 332: 333: combine_attempts++; 334: 335: /* Don't combine with something already used up by combination. */ 336: 337: if (GET_CODE (i2) == NOTE 338: || (i1 && GET_CODE (i1) == NOTE)) 339: return 0; 340: 341: /* Don't combine across a CALL_INSN, because that would possibly 342: change whether the life span of some REGs crosses calls or not, 343: and it is a pain to update that information. */ 344: 345: if (INSN_CUID (i2) < last_call_cuid 346: || (i1 && INSN_CUID (i1) < last_call_cuid)) 347: return 0; 348: 349: /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0. 350: That REG must be either set or dead by the final instruction 351: (so that we can safely forget about setting it). 352: Also test use_crosses_set_p to make sure that the value 353: that is to be substituted for the register 354: does not use any registers whose values alter in between. 355: Do not try combining with moves from one register to another 356: since it is better to let them be tied by register allocation. 1.1.1.2 ! root 357: (There is a switch to permit such combination; except the insns ! 358: that copy a function value into another register are never combined ! 359: because moving that too far away from the function call could cause ! 360: something else to be stored in that register in the interim.) 1.1 root 361: 362: A set of a SUBREG is considered as if it were a set from 363: SUBREG. Thus, (SET (SUBREG:X (REG:Y...)) (something:X...)) 364: is handled by substituting (SUBREG:Y (something:X...)) for (REG:Y...). */ 365: 366: if (GET_CODE (PATTERN (i2)) != SET) 367: return 0; 368: i2dest = SET_DEST (PATTERN (i2)); 369: i2src = SET_SRC (PATTERN (i2)); 370: if (GET_CODE (i2dest) == SUBREG) 371: { 372: i2dest = SUBREG_REG (i2dest); 373: i2src = gen_rtx (SUBREG, GET_MODE (i2dest), i2src, 0); 374: } 375: if (GET_CODE (i2dest) != CC0 376: && (GET_CODE (i2dest) != REG 1.1.1.2 ! root 377: || (GET_CODE (i2src) == REG ! 378: && (!flag_combine_regs ! 379: || FUNCTION_VALUE_REGNO_P (REGNO (i2src)))) ! 380: || GET_CODE (i2src) == CALL 1.1 root 381: || use_crosses_set_p (i2src, INSN_CUID (i2)))) 382: return 0; 383: 384: if (i1 != 0) 385: { 386: if (GET_CODE (PATTERN (i1)) != SET) 387: return 0; 388: i1dest = SET_DEST (PATTERN (i1)); 389: i1src = SET_SRC (PATTERN (i1)); 390: if (GET_CODE (i1dest) == SUBREG) 391: { 392: i1dest = SUBREG_REG (i1dest); 393: i1src = gen_rtx (SUBREG, GET_MODE (i1dest), i1src, 0); 394: } 395: if (GET_CODE (i1dest) != CC0 396: && (GET_CODE (i1dest) != REG 1.1.1.2 ! root 397: || (GET_CODE (i1src) == REG ! 398: && (!flag_combine_regs ! 399: || FUNCTION_VALUE_REGNO_P (REGNO (i1src)))) ! 400: || GET_CODE (i1src) == CALL 1.1 root 401: || use_crosses_set_p (i1src, INSN_CUID (i1)))) 402: return 0; 403: } 404: 405: /* If I1 or I2 contains an autoincrement or autodecrement, 406: make sure that register is not used between there and I3. 407: Also insist that I3 not be a jump; if it were one 408: and the incremented register were spilled, we would lose. */ 1.1.1.2 ! root 409: if ((link = find_reg_note (i2, REG_INC, 0)) != 0 ! 410: && (GET_CODE (i3) == JUMP_INSN ! 411: || reg_used_between_p (XEXP (link, 0), i2, i3))) ! 412: return 0; 1.1 root 413: 1.1.1.2 ! root 414: if (i1 && (link = find_reg_note (i1, REG_INC, 0)) != 0 ! 415: && (GET_CODE (i3) == JUMP_INSN ! 416: || reg_used_between_p (XEXP (link, 0), i1, i3))) ! 417: return 0; 1.1 root 418: 419: /* See if the SETs in i1 or i2 need to be kept around in the merged 420: instruction: whenever the value set there is still needed past i3. */ 421: added_sets_2 = (GET_CODE (i2dest) != CC0 422: && ! dead_or_set_p (i3, i2dest)); 423: if (i1) 424: added_sets_1 = ! (dead_or_set_p (i3, i1dest) 425: || dead_or_set_p (i2, i1dest)); 426: 427: combine_merges++; 428: 429: undobuf.num_undo = 0; 430: undobuf.storage = 0; 431: 432: /* Substitute in the latest insn for the regs set by the earlier ones. */ 433: 1.1.1.2 ! root 434: maxreg = max_reg_num (); ! 435: 1.1 root 436: subst_insn = i3; 1.1.1.2 ! root 437: n_occurrences = 0; /* `subst' counts here */ ! 438: 1.1 root 439: newpat = subst (PATTERN (i3), i2dest, i2src); 440: /* Record whether i2's body now appears within i3's body. */ 1.1.1.2 ! root 441: i2_is_used = n_occurrences; 1.1 root 442: 443: if (i1) 1.1.1.2 ! root 444: { ! 445: n_occurrences = 0; ! 446: newpat = subst (newpat, i1dest, i1src); ! 447: } 1.1 root 448: 449: if (GET_CODE (PATTERN (i3)) == SET 450: && SET_DEST (PATTERN (i3)) == cc0_rtx 1.1.1.2 ! root 451: && (GET_CODE (SET_SRC (PATTERN (i3))) == AND ! 452: || GET_CODE (SET_SRC (PATTERN (i3))) == LSHIFTRT) 1.1 root 453: && next_insn_tests_no_inequality (i3)) 454: simplify_set_cc0_and (i3); 455: 1.1.1.2 ! root 456: if (max_reg_num () != maxreg) ! 457: abort (); ! 458: 1.1 root 459: /* If the actions of the earler insns must be kept 460: in addition to substituting them into the latest one, 461: we must make a new PARALLEL for the latest insn 462: to hold additional the SETs. */ 463: 464: if (added_sets_1 || added_sets_2) 465: { 466: combine_extras++; 467: 468: /* Arrange to free later what we allocate now 469: if we don't accept this combination. */ 470: if (!undobuf.storage) 471: undobuf.storage = (char *) oballoc (0); 472: 473: if (GET_CODE (newpat) == PARALLEL) 474: { 1.1.1.2 ! root 475: rtvec old = XVEC (newpat, 0); 1.1 root 476: total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2; 1.1.1.2 ! root 477: newpat = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (total_sets)); ! 478: bcopy (&old->elem[0], &XVECEXP (newpat, 0, 0), ! 479: sizeof (old->elem[0]) * old->num_elem); 1.1 root 480: } 481: else 482: { 1.1.1.2 ! root 483: rtx old = newpat; 1.1 root 484: total_sets = 1 + added_sets_1 + added_sets_2; 1.1.1.2 ! root 485: newpat = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (total_sets)); ! 486: XVECEXP (newpat, 0, 0) = old; 1.1 root 487: } 488: if (added_sets_1) 489: { 490: XVECEXP (newpat, 0, --total_sets) = PATTERN (i1); 491: } 492: if (added_sets_2) 493: { 494: /* If there is no I1, use I2's body as is. */ 495: if (i1 == 0 496: /* If I2 was stuck into I3, then anything within it has 497: already had I1 substituted into it when that was done to I3. */ 498: || i2_is_used) 499: { 500: XVECEXP (newpat, 0, --total_sets) = PATTERN (i2); 501: } 502: else 503: XVECEXP (newpat, 0, --total_sets) 504: = subst (PATTERN (i2), i1dest, i1src); 505: } 506: } 507: 1.1.1.2 ! root 508: /* Fail if an autoincrement side-effect has been duplicated. */ ! 509: if ((i2_is_used > 1 && find_reg_note (i2, REG_INC, 0) != 0) ! 510: || (i1 != 0 && n_occurrences > 1 && find_reg_note (i1, REG_INC, 0) != 0)) ! 511: { ! 512: undo_all (); ! 513: return 0; ! 514: } ! 515: 1.1 root 516: /* Is the result of combination a valid instruction? */ 517: insn_code_number = recog (newpat, i3); 518: 519: if (insn_code_number >= 0) 520: { 521: /* Yes. Install it. */ 522: register int regno; 523: INSN_CODE (i3) = insn_code_number; 524: PATTERN (i3) = newpat; 1.1.1.2 ! root 525: /* If anything was substituted more than once, ! 526: copy it to avoid invalid shared rtl structure. */ ! 527: copy_substitutions (); ! 528: /* The data flowing into I2 now flows into I3. ! 529: But we cannot always move all of I2's LOG_LINKS into I3, ! 530: since they must go to a setting of a REG from the ! 531: first use following. If I2 was the first use following a set, ! 532: I3 is now a use, but it is not the first use ! 533: if some instruction between I2 and I3 is also a use. ! 534: Here, for simplicity, we move all the links only if ! 535: there are no real insns between I2 and I3. ! 536: Otherwise, we move only links that correspond to regs ! 537: that used to die in I2. They are always safe to move. */ ! 538: add_links (i3, i2, adjacent_insns_p (i2, i3)); 1.1 root 539: /* Most REGs that previously died in I2 now die in I3. */ 540: move_deaths (i2src, INSN_CUID (i2), i3); 541: if (GET_CODE (i2dest) == REG) 542: { 543: /* If the reg formerly set in I2 died only once and that was in I3, 544: zero its use count so it won't make `reload' do any work. */ 545: regno = REGNO (i2dest); 546: if (! added_sets_2) 1.1.1.2 ! root 547: { ! 548: reg_n_sets[regno]--; ! 549: /* Used to check && regno_dead_p (regno, i3) also here. */ ! 550: if (reg_n_sets[regno] == 0 ! 551: && ! (basic_block_live_at_start[0][regno / HOST_BITS_PER_INT] ! 552: & (1 << (regno % HOST_BITS_PER_INT)))) ! 553: reg_n_refs[regno] = 0; ! 554: } 1.1 root 555: /* If a ref to REGNO was substituted into I3 from I2, 556: then it still dies there if it previously did. 557: Otherwise either REGNO never did die in I3 so remove_death is safe 558: or this entire life of REGNO is gone so remove its death. */ 559: if (!added_sets_2 560: && ! reg_mentioned_p (i2dest, PATTERN (i3))) 561: remove_death (regno, i3); 562: } 563: /* Any registers previously autoincremented in I2 564: are now incremented in I3. */ 565: add_incs (i3, REG_NOTES (i2)); 566: if (i1) 567: { 568: /* Likewise, merge the info from I1 and get rid of it. */ 1.1.1.2 ! root 569: add_links (i3, i1, ! 570: adjacent_insns_p (i1, i2) && adjacent_insns_p (i2, i3)); 1.1 root 571: move_deaths (i1src, INSN_CUID (i1), i3); 572: if (GET_CODE (i1dest) == REG) 573: { 574: regno = REGNO (i1dest); 575: if (! added_sets_1) 1.1.1.2 ! root 576: { ! 577: reg_n_sets[regno]--; ! 578: /* Used to also check && regno_dead_p (regno, i3) here. */ ! 579: ! 580: if (reg_n_sets[regno] == 0 ! 581: && ! (basic_block_live_at_start[0][regno / HOST_BITS_PER_INT] ! 582: & (1 << (regno % HOST_BITS_PER_INT)))) ! 583: ! 584: reg_n_refs[regno] = 0; ! 585: } 1.1 root 586: /* If a ref to REGNO was substituted into I3 from I1, 587: then it still dies there if it previously did. 588: Else either REGNO never did die in I3 so remove_death is safe 589: or this entire life of REGNO is gone so remove its death. */ 590: if (! added_sets_1 591: && ! reg_mentioned_p (i1dest, PATTERN (i3))) 592: remove_death (regno, i3); 593: } 594: add_incs (i3, REG_NOTES (i1)); 595: LOG_LINKS (i1) = 0; 596: PUT_CODE (i1, NOTE); 597: NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED; 598: NOTE_SOURCE_FILE (i1) = 0; 599: } 1.1.1.2 ! root 600: /* Get rid of I2. */ ! 601: LOG_LINKS (i2) = 0; ! 602: PUT_CODE (i2, NOTE); ! 603: NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED; ! 604: NOTE_SOURCE_FILE (i2) = 0; 1.1 root 605: 606: combine_successes++; 607: return 1; 608: } 609: 610: /* Failure: change I3 back the way it was. */ 611: undo_all (); 612: 613: return 0; 614: } 615: 616: /* Undo all the modifications recorded in undobuf. */ 617: 618: static void 619: undo_all () 620: { 621: register int i; 622: if (undobuf.num_undo > MAX_UNDO) 623: undobuf.num_undo = MAX_UNDO; 624: for (i = undobuf.num_undo - 1; i >= 0; i--) 625: *undobuf.undo[i].where = undobuf.undo[i].old_contents; 626: if (undobuf.storage) 627: obfree (undobuf.storage); 628: undobuf.num_undo = 0; 629: undobuf.storage = 0; 630: } 631: 1.1.1.2 ! root 632: /* If this insn had more than one substitution, ! 633: copy all but one, so that no invalid shared substructure is introduced. */ ! 634: ! 635: static void ! 636: copy_substitutions () ! 637: { ! 638: register int i; ! 639: if (undobuf.num_undo > 1) ! 640: { ! 641: for (i = undobuf.num_undo - 1; i >= 1; i--) ! 642: *undobuf.undo[i].where = copy_rtx (*undobuf.undo[i].where); ! 643: } ! 644: } ! 645: 1.1 root 646: /* Throughout X, replace FROM with TO, and return the result. 647: The result is TO if X is FROM; 648: otherwise the result is X, but its contents may have been modified. 649: If they were modified, a record was made in undobuf so that 650: undo_all will (among other things) return X to its original state. 651: 652: If the number of changes necessary is too much to record to undo, 653: the excess changes are not made, so the result is invalid. 654: The changes already made can still be undone. 655: undobuf.num_undo is incremented for such changes, so by testing that 1.1.1.2 ! root 656: the caller can tell whether the result is valid. ! 657: ! 658: `n_occurrences' is incremented each time FROM is replaced. */ 1.1 root 659: 660: static rtx 661: subst (x, from, to) 662: register rtx x, from, to; 663: { 664: register char *fmt; 665: register int len, i; 666: register enum rtx_code code; 1.1.1.2 ! root 667: char was_replaced[2]; 1.1 root 668: 1.1.1.2 ! root 669: #define SUBST(INTO, NEWVAL) \ ! 670: do { if (undobuf.num_undo < MAX_UNDO) \ ! 671: { \ ! 672: undobuf.undo[undobuf.num_undo].where = &INTO; \ ! 673: undobuf.undo[undobuf.num_undo].old_contents = INTO; \ ! 674: INTO = NEWVAL; \ ! 675: } \ ! 676: undobuf.num_undo++; } while (0) ! 677: ! 678: /* FAKE_EXTEND_SAFE_P (MODE, FROM) is 1 if (subreg:MODE FROM 0) is a safe ! 679: replacement for (zero_extend:MODE FROM) or (sign_extend:MODE FROM). ! 680: If it is 0, that cannot be done because it might cause a badly aligned ! 681: memory reference. */ ! 682: ! 683: #ifndef STRICT_ALIGNMENT ! 684: #define FAKE_EXTEND_SAFE_P(MODE, FROM) \ ! 685: (GET_CODE (FROM) == REG || \ ! 686: (GET_CODE (FROM) == MEM \ ! 687: && offsetable_address_p ((MODE), XEXP ((FROM), 0)) \ ! 688: && ! mode_dependent_address_p ((XEXP ((FROM), 0))))) ! 689: #else ! 690: #define FAKE_EXTEND_SAFE_P(MODE, FROM) (GET_CODE (FROM) == REG) ! 691: #endif 1.1 root 692: 693: if (x == from) 694: return to; 695: 1.1.1.2 ! root 696: /* It is possible to have a subexpression appear twice in the insn. ! 697: Suppose that FROM is a register that appears within TO. ! 698: Then, after that subexpression has been scanned once by `subst', ! 699: the second time it is scanned, TO may be found. If we were ! 700: to scan TO here, we would find FROM within it and create a ! 701: self-referent rtl structure which is completely wrong. */ ! 702: if (x == to) ! 703: return to; ! 704: 1.1 root 705: code = GET_CODE (x); 706: 707: /* A little bit of algebraic simplification here. */ 708: switch (code) 709: { 710: /* This case has no effect except to speed things up. */ 711: case REG: 712: case CONST_INT: 713: case CONST: 714: case SYMBOL_REF: 715: case LABEL_REF: 716: case PC: 717: case CC0: 718: return x; 1.1.1.2 ! root 719: } ! 720: ! 721: was_replaced[0] = 0; ! 722: was_replaced[1] = 0; ! 723: ! 724: len = GET_RTX_LENGTH (code); ! 725: fmt = GET_RTX_FORMAT (code); ! 726: ! 727: /* Don't replace FROM where it is being stored in rather than used. */ ! 728: if (code == SET && SET_DEST (x) == from) ! 729: fmt = "ie"; ! 730: if (code == SET && GET_CODE (SET_DEST (x)) == SUBREG ! 731: && SUBREG_REG (SET_DEST (x)) == from) ! 732: fmt = "ie"; ! 733: ! 734: for (i = 0; i < len; i++) ! 735: { ! 736: if (fmt[i] == 'E') ! 737: { ! 738: register int j; ! 739: for (j = XVECLEN (x, i) - 1; j >= 0; j--) ! 740: { ! 741: register rtx new; ! 742: if (XVECEXP (x, i, j) == from) ! 743: new = to, n_occurrences++; ! 744: else ! 745: new = subst (XVECEXP (x, i, j), from, to); ! 746: if (new != XVECEXP (x, i, j)) ! 747: SUBST (XVECEXP (x, i, j), new); ! 748: } ! 749: } ! 750: else if (fmt[i] == 'e') ! 751: { ! 752: register rtx new; ! 753: ! 754: if (XEXP (x, i) == from) ! 755: { ! 756: new = to; ! 757: n_occurrences++; ! 758: if (i < 2) ! 759: was_replaced[i] = 1; ! 760: } ! 761: else ! 762: new = subst (XEXP (x, i), from, to); ! 763: ! 764: if (new != XEXP (x, i)) ! 765: SUBST (XEXP (x, i), new); ! 766: } ! 767: } ! 768: ! 769: /* A little bit of algebraic simplification here. */ ! 770: switch (code) ! 771: { ! 772: case SUBREG: ! 773: /* Changing mode twice with SUBREG => just change it once, ! 774: or not at all if changing back to starting mode. */ ! 775: if (SUBREG_REG (x) == to ! 776: && GET_CODE (to) == SUBREG ! 777: && SUBREG_WORD (x) == 0 ! 778: && SUBREG_WORD (to) == 0) ! 779: { ! 780: if (GET_MODE (x) == GET_MODE (SUBREG_REG (to))) ! 781: return SUBREG_REG (to); ! 782: SUBST (SUBREG_REG (x), SUBREG_REG (to)); ! 783: } ! 784: break; 1.1 root 785: 786: case NOT: 787: case NEG: 788: /* Don't let substitution introduce double-negatives. */ 1.1.1.2 ! root 789: if (was_replaced[0] 1.1 root 790: && GET_CODE (to) == code) 791: return XEXP (to, 0); 792: break; 793: 1.1.1.2 ! root 794: case FLOAT_TRUNCATE: ! 795: /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */ ! 796: if (was_replaced[0] ! 797: && GET_CODE (to) == FLOAT_EXTEND ! 798: && GET_MODE (XEXP (to, 0)) == GET_MODE (x)) ! 799: return XEXP (to, 0); ! 800: break; ! 801: 1.1 root 802: case PLUS: 803: /* In (plus <foo> (ashift <bar> <n>)) 804: change the shift to a multiply so we can recognize 805: scaled indexed addresses. */ 1.1.1.2 ! root 806: if ((was_replaced[0] ! 807: || was_replaced[1]) 1.1 root 808: && GET_CODE (to) == ASHIFT 1.1.1.2 ! root 809: && GET_CODE (XEXP (to, 1)) == CONST_INT ! 810: && INTVAL (XEXP (to, 1)) < HOST_BITS_PER_INT) ! 811: { ! 812: rtx temp; ! 813: if (!undobuf.storage) ! 814: undobuf.storage = (char *) oballoc (0); ! 815: temp = gen_rtx (MULT, GET_MODE (to), ! 816: XEXP (to, 0), ! 817: gen_rtx (CONST_INT, VOIDmode, ! 818: 1 << INTVAL (XEXP (to, 1)))); ! 819: if (was_replaced[0]) ! 820: SUBST (XEXP (x, 0), temp); ! 821: else ! 822: SUBST (XEXP (x, 1), temp); ! 823: } ! 824: /* (plus X (neg Y)) becomes (minus X Y). */ ! 825: if (GET_CODE (XEXP (x, 1)) == NEG) ! 826: { ! 827: if (!undobuf.storage) ! 828: undobuf.storage = (char *) oballoc (0); ! 829: return gen_rtx (MINUS, GET_MODE (x), ! 830: XEXP (x, 0), XEXP (XEXP (x, 1), 0)); ! 831: } ! 832: /* (plus (neg X) Y) becomes (minus Y X). */ ! 833: if (GET_CODE (XEXP (x, 0)) == NEG) 1.1 root 834: { 835: if (!undobuf.storage) 836: undobuf.storage = (char *) oballoc (0); 1.1.1.2 ! root 837: return gen_rtx (MINUS, GET_MODE (x), ! 838: XEXP (x, 1), XEXP (XEXP (x, 0), 0)); ! 839: } ! 840: /* (plus (plus x c1) c2) => (plus x c1+c2) */ ! 841: if (GET_CODE (XEXP (x, 1)) == CONST_INT ! 842: && GET_CODE (XEXP (x, 0)) == PLUS ! 843: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT) ! 844: { ! 845: int sum = (INTVAL (XEXP (x, 1)) ! 846: + INTVAL (XEXP (XEXP (x, 0), 1))); ! 847: if (sum == 0) ! 848: return XEXP (XEXP (x, 0), 0); ! 849: if (!undobuf.storage) ! 850: undobuf.storage = (char *) oballoc (0); ! 851: SUBST (XEXP (x, 1), gen_rtx (CONST_INT, VOIDmode, sum)); ! 852: SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0)); ! 853: break; 1.1 root 854: } 855: /* If we have something (putative index) being added to a sum, 856: associate it so that any constant term is outermost. 857: That's because that's the way indexed addresses are 858: now supposed to appear. */ 1.1.1.2 ! root 859: if (((was_replaced[0] && GET_CODE (XEXP (x, 1)) == PLUS) ! 860: || (was_replaced[1] && GET_CODE (XEXP (x, 0)) == PLUS)) 1.1 root 861: || 1.1.1.2 ! root 862: ((was_replaced[0] || was_replaced[1]) ! 863: && GET_CODE (to) == PLUS)) 1.1 root 864: { 865: rtx offset = 0, base, index; 1.1.1.2 ! root 866: if (GET_CODE (to) != PLUS) 1.1 root 867: { 1.1.1.2 ! root 868: index = to; ! 869: base = was_replaced[0] ? XEXP (x, 1) : XEXP (x, 0); 1.1 root 870: } 871: else 872: { 1.1.1.2 ! root 873: index = was_replaced[0] ? XEXP (x, 1) : XEXP (x, 0); ! 874: base = to; 1.1 root 875: } 876: if (CONSTANT_ADDRESS_P (XEXP (base, 0))) 877: { 878: offset = XEXP (base, 0); 879: base = XEXP (base, 1); 880: } 881: else if (CONSTANT_ADDRESS_P (XEXP (base, 1))) 882: { 883: offset = XEXP (base, 1); 884: base = XEXP (base, 0); 885: } 886: if (offset != 0) 887: { 888: if (!undobuf.storage) 889: undobuf.storage = (char *) oballoc (0); 1.1.1.2 ! root 890: if (GET_CODE (offset) == CONST_INT) ! 891: return plus_constant (gen_rtx (PLUS, GET_MODE (index), ! 892: base, index), ! 893: INTVAL (offset)); ! 894: if (GET_CODE (index) == CONST_INT) ! 895: return plus_constant (gen_rtx (PLUS, GET_MODE (offset), ! 896: base, offset), ! 897: INTVAL (index)); ! 898: return gen_rtx (PLUS, GET_MODE (index), 1.1 root 899: gen_rtx (PLUS, GET_MODE (index), 1.1.1.2 ! root 900: base, index), ! 901: offset); 1.1 root 902: } 903: } 904: break; 905: 906: case MINUS: 907: /* Can simplify (minus:VOIDmode (zero/sign_extend FOO) CONST) 908: (which is a compare instruction, not a subtract instruction) 909: to (minus FOO CONST) if CONST fits in FOO's mode 910: and we are only testing equality. 911: In fact, this is valid for zero_extend if what follows is an 912: unsigned comparison, and for sign_extend with a signed comparison. */ 913: if (GET_MODE (x) == VOIDmode 1.1.1.2 ! root 914: && was_replaced[0] 1.1 root 915: && (GET_CODE (to) == ZERO_EXTEND || GET_CODE (to) == SIGN_EXTEND) 916: && next_insn_tests_no_inequality (subst_insn) 917: && GET_CODE (XEXP (x, 1)) == CONST_INT 1.1.1.2 ! root 918: /* This is overly cautious by one bit, but saves worrying about ! 919: whether it is zero-extension or sign extension. */ 1.1 root 920: && ((unsigned) INTVAL (XEXP (x, 1)) 1.1.1.2 ! root 921: < (1 << (GET_MODE_BITSIZE (GET_MODE (XEXP (to, 0))) - 1)))) ! 922: SUBST (XEXP (x, 0), XEXP (to, 0)); 1.1 root 923: break; 924: 925: case EQ: 926: case NE: 927: /* If comparing a subreg against zero, discard the subreg. */ 1.1.1.2 ! root 928: if (was_replaced[0] 1.1 root 929: && GET_CODE (to) == SUBREG 930: && SUBREG_WORD (to) == 0 931: && XEXP (x, 1) == const0_rtx) 1.1.1.2 ! root 932: SUBST (XEXP (x, 0), SUBREG_REG (to)); 1.1 root 933: 934: /* If comparing a ZERO_EXTRACT against zero, 935: canonicalize to a SIGN_EXTRACT, 936: since the two are equivalent here. */ 1.1.1.2 ! root 937: if (was_replaced[0] ! 938: && GET_CODE (to) == ZERO_EXTRACT 1.1 root 939: && XEXP (x, 1) == const0_rtx) 940: { 941: if (!undobuf.storage) 942: undobuf.storage = (char *) oballoc (0); 1.1.1.2 ! root 943: SUBST (XEXP (x, 0), ! 944: gen_rtx (SIGN_EXTRACT, GET_MODE (to), ! 945: XEXP (to, 0), XEXP (to, 1), ! 946: XEXP (to, 2))); 1.1 root 947: } 948: /* If we are putting (ASHIFT 1 x) into (EQ (AND ... y) 0), 949: arrange to return (EQ (SIGN_EXTRACT y 1 x) 0), 950: which is what jump-on-bit instructions are written with. */ 951: else if (XEXP (x, 1) == const0_rtx 952: && GET_CODE (XEXP (x, 0)) == AND 1.1.1.2 ! root 953: && (XEXP (XEXP (x, 0), 0) == to ! 954: || XEXP (XEXP (x, 0), 1) == to) ! 955: && GET_CODE (to) == ASHIFT ! 956: && XEXP (to, 0) == const1_rtx) 1.1 root 957: { 958: register rtx y = XEXP (XEXP (x, 0), 1.1.1.2 ! root 959: XEXP (XEXP (x, 0), 0) == to); 1.1 root 960: if (!undobuf.storage) 961: undobuf.storage = (char *) oballoc (0); 1.1.1.2 ! root 962: SUBST (XEXP (x, 0), ! 963: gen_rtx (SIGN_EXTRACT, GET_MODE (to), ! 964: y, ! 965: const1_rtx, XEXP (to, 1))); 1.1 root 966: } 967: 968: break; 969: 970: case ZERO_EXTEND: 1.1.1.2 ! root 971: if (was_replaced[0] 1.1 root 972: && GET_CODE (to) == ZERO_EXTEND) 1.1.1.2 ! root 973: SUBST (XEXP (x, 0), XEXP (to, 0)); 1.1 root 974: /* Zero-extending the result of an and with a constant can be done 975: with a wider and. */ 1.1.1.2 ! root 976: if (was_replaced[0] 1.1 root 977: && GET_CODE (to) == AND 978: && GET_CODE (XEXP (to, 1)) == CONST_INT 1.1.1.2 ! root 979: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0)) 1.1 root 980: /* Avoid getting wrong result if the constant has high bits set 981: that are irrelevant in the narrow mode where it is being used. */ 1.1.1.2 ! root 982: && 0 == (INTVAL (XEXP (to, 1)) ! 983: & ~ GET_MODE_MASK (GET_MODE (to)))) 1.1 root 984: { 985: if (!undobuf.storage) 986: undobuf.storage = (char *) oballoc (0); 987: return gen_rtx (AND, GET_MODE (x), 1.1.1.2 ! root 988: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)), 1.1 root 989: XEXP (to, 1)); 1.1.1.2 ! root 990: } ! 991: /* Change (zero_extend:M (subreg:N (zero_extract:M ...) 0)) ! 992: to (zero_extract:M ...) if the field extracted fits in mode N. */ ! 993: if (GET_CODE (XEXP (x, 0)) == SUBREG ! 994: && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTRACT ! 995: && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT ! 996: && (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)) ! 997: <= GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))))) ! 998: { ! 999: return XEXP (XEXP (x, 0), 0); ! 1000: } 1.1 root 1001: break; 1002: 1003: case SIGN_EXTEND: 1.1.1.2 ! root 1004: if (was_replaced[0] 1.1 root 1005: && GET_CODE (to) == SIGN_EXTEND) 1.1.1.2 ! root 1006: SUBST (XEXP (x, 0), XEXP (to, 0)); 1.1 root 1007: /* Sign-extending the result of an and with a constant can be done 1008: with a wider and, provided the high bit of the constant is 0. */ 1.1.1.2 ! root 1009: if (was_replaced[0] 1.1 root 1010: && GET_CODE (to) == AND 1011: && GET_CODE (XEXP (to, 1)) == CONST_INT 1.1.1.2 ! root 1012: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0)) 1.1 root 1013: && ((INTVAL (XEXP (to, 1)) 1.1.1.2 ! root 1014: & (-1 << (GET_MODE_BITSIZE (GET_MODE (to)) - 1))) 1.1 root 1015: == 0)) 1016: { 1017: if (!undobuf.storage) 1018: undobuf.storage = (char *) oballoc (0); 1019: return gen_rtx (AND, GET_MODE (x), 1.1.1.2 ! root 1020: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)), 1.1 root 1021: XEXP (to, 1)); 1022: } 1023: break; 1024: 1025: case SET: 1.1.1.2 ! root 1026: /* In (set (zero-extract <x> <n> <y>) (and <foo> <(2**n-1) | anything>)) 1.1 root 1027: the `and' can be deleted. This can happen when storing a bit 1.1.1.2 ! root 1028: that came from a set-flag insn followed by masking to one bit. */ 1.1 root 1029: if (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT 1.1.1.2 ! root 1030: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT ! 1031: && was_replaced[1] 1.1 root 1032: && GET_CODE (to) == AND 1.1.1.2 ! root 1033: && GET_CODE (XEXP (to, 1)) == CONST_INT ! 1034: && 0 == (((1 << INTVAL (XEXP (XEXP (x, 0), 1))) - 1) ! 1035: & ~ INTVAL (XEXP (to, 1)))) 1.1 root 1036: { 1.1.1.2 ! root 1037: SUBST (XEXP (x, 1), XEXP (to, 0)); ! 1038: } ! 1039: /* In (set (zero-extract <x> <n> <y>) ! 1040: (subreg (and <foo> <(2**n-1) | anything>))) ! 1041: the `and' can be deleted. */ ! 1042: if (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT ! 1043: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT ! 1044: && GET_CODE (XEXP (x, 1)) == SUBREG ! 1045: && SUBREG_WORD (XEXP (x, 1)) == 0 ! 1046: && GET_CODE (SUBREG_REG (XEXP (x, 1))) == AND ! 1047: && GET_CODE (XEXP (SUBREG_REG (XEXP (x, 1)), 1)) == CONST_INT ! 1048: && 0 == (((1 << INTVAL (XEXP (XEXP (x, 0), 1))) - 1) ! 1049: & ~ INTVAL (XEXP (SUBREG_REG (XEXP (x, 1)), 1)))) ! 1050: { ! 1051: SUBST (SUBREG_REG (XEXP (x, 1)), XEXP (SUBREG_REG (XEXP (x, 1)), 0)); ! 1052: } ! 1053: /* (set (zero_extract ...) (and/or/xor (zero_extract ...) const)), ! 1054: if both zero_extracts have the byte size and position, ! 1055: can be changed to avoid the byte extracts. */ ! 1056: if ((GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT ! 1057: || GET_CODE (XEXP (x, 0)) == SIGN_EXTRACT) ! 1058: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT ! 1059: && (GET_CODE (XEXP (x, 1)) == AND ! 1060: || GET_CODE (XEXP (x, 1)) == IOR ! 1061: || GET_CODE (XEXP (x, 1)) == XOR) ! 1062: && (GET_CODE (XEXP (XEXP (x, 1), 0)) == ZERO_EXTRACT ! 1063: || GET_CODE (XEXP (XEXP (x, 1), 0)) == SIGN_EXTRACT) ! 1064: && rtx_equal_p (XEXP (XEXP (XEXP (x, 1), 0), 1), ! 1065: XEXP (XEXP (x, 0), 1)) ! 1066: && rtx_equal_p (XEXP (XEXP (XEXP (x, 1), 0), 2), ! 1067: XEXP (XEXP (x, 0), 2)) ! 1068: && GET_CODE (XEXP (XEXP (x, 1), 0)) == GET_CODE (XEXP (x, 0)) ! 1069: && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT) ! 1070: { ! 1071: #ifdef BITS_BIG_ENDIAN ! 1072: int shiftcount ! 1073: = GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0))) ! 1074: - INTVAL (XEXP (XEXP (x, 0), 1)) - INTVAL (XEXP (XEXP (x, 0), 2)); ! 1075: #else ! 1076: int shiftcount ! 1077: = INTVAL (XEXP (XEXP (x, 0), 2)); ! 1078: #endif ! 1079: if (!undobuf.storage) ! 1080: undobuf.storage = (char *) oballoc (0); ! 1081: return ! 1082: gen_rtx (SET, VOIDmode, ! 1083: XEXP (XEXP (x, 0), 0), ! 1084: gen_rtx (GET_CODE (XEXP (x, 1)), ! 1085: GET_MODE (XEXP (XEXP (x, 0), 0)), ! 1086: XEXP (XEXP (XEXP (x, 1), 0), 0), ! 1087: gen_rtx (CONST_INT, VOIDmode, ! 1088: (INTVAL (XEXP (XEXP (x, 1), 1)) ! 1089: << shiftcount) ! 1090: + (GET_CODE (XEXP (x, 1)) == AND ! 1091: ? (1 << shiftcount) - 1 ! 1092: : 0)))); ! 1093: } 1.1 root 1094: break; 1095: 1096: case AND: 1097: if (GET_CODE (XEXP (x, 1)) == CONST_INT) 1098: { 1.1.1.2 ! root 1099: rtx tem = simplify_and_const_int (x, to); 1.1 root 1100: if (tem) 1101: return tem; 1102: } 1103: break; 1104: 1105: case FLOAT: 1106: /* (float (sign_extend <X>)) = (float <X>). */ 1.1.1.2 ! root 1107: if (was_replaced[0] 1.1 root 1108: && GET_CODE (to) == SIGN_EXTEND) 1.1.1.2 ! root 1109: SUBST (XEXP (x, 0), XEXP (to, 0)); 1.1 root 1110: break; 1111: 1112: case ZERO_EXTRACT: 1.1.1.2 ! root 1113: /* (ZERO_EXTRACT (TRUNCATE x)...) ! 1114: can become (ZERO_EXTRACT x ...). */ ! 1115: if (was_replaced[0] ! 1116: && GET_CODE (to) == TRUNCATE) ! 1117: { ! 1118: #ifdef BITS_BIG_ENDIAN ! 1119: if (GET_CODE (XEXP (x, 2)) == CONST_INT) ! 1120: { ! 1121: if (!undobuf.storage) ! 1122: undobuf.storage = (char *) oballoc (0); ! 1123: /* On a big-endian machine, must increment the bit-number ! 1124: since sign bit is farther away in the pre-truncated value. */ ! 1125: return gen_rtx (ZERO_EXTRACT, GET_MODE (x), ! 1126: XEXP (to, 0), ! 1127: XEXP (x, 1), ! 1128: gen_rtx (CONST_INT, VOIDmode, ! 1129: (INTVAL (XEXP (x, 2)) ! 1130: + GET_MODE_BITSIZE (GET_MODE (XEXP (to, 0))) ! 1131: - GET_MODE_BITSIZE (GET_MODE (to))))); ! 1132: } ! 1133: #else ! 1134: SUBST (XEXP (x, 0), XEXP (to, 0)); ! 1135: #endif ! 1136: } 1.1 root 1137: /* Extracting a single bit from the result of a shift: 1138: see which bit it was before the shift and extract that directly. */ 1.1.1.2 ! root 1139: if (was_replaced[0] 1.1 root 1140: && (GET_CODE (to) == ASHIFTRT || GET_CODE (to) == LSHIFTRT 1141: || GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT) 1142: && GET_CODE (XEXP (to, 1)) == CONST_INT 1143: && XEXP (x, 1) == const1_rtx 1144: && GET_CODE (XEXP (x, 2)) == CONST_INT) 1145: { 1146: int shift = INTVAL (XEXP (to, 1)); 1147: int newpos; 1148: if (GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT) 1149: shift = - shift; 1150: #ifdef BITS_BIG_ENDIAN 1151: shift = - shift; 1152: #endif 1153: newpos = INTVAL (XEXP (x, 2)) + shift; 1154: if (newpos >= 0 && 1.1.1.2 ! root 1155: newpos < GET_MODE_BITSIZE (GET_MODE (to))) 1.1 root 1156: { 1157: if (!undobuf.storage) 1158: undobuf.storage = (char *) oballoc (0); 1159: return gen_rtx (ZERO_EXTRACT, GET_MODE (x), 1160: XEXP (to, 0), const1_rtx, 1161: gen_rtx (CONST_INT, VOIDmode, newpos)); 1162: } 1163: } 1164: break; 1165: 1166: case LSHIFTRT: 1167: case ASHIFTRT: 1168: case ROTATE: 1169: case ROTATERT: 1170: #ifdef SHIFT_COUNT_TRUNCATED 1171: /* (lshift <X> (sign_extend <Y>)) = (lshift <X> <Y>) (most machines). 1172: True for all kinds of shifts and also for zero_extend. */ 1.1.1.2 ! root 1173: if (was_replaced[1] 1.1 root 1174: && (GET_CODE (to) == SIGN_EXTEND 1.1.1.2 ! root 1175: || GET_CODE (to) == ZERO_EXTEND) ! 1176: && FAKE_EXTEND_SAFE_P (GET_MODE (to), XEXP (to, 0))) 1.1 root 1177: { 1178: if (!undobuf.storage) 1179: undobuf.storage = (char *) oballoc (0); 1.1.1.2 ! root 1180: SUBST (XEXP (x, 1), ! 1181: /* This is a perverse SUBREG, wider than its base. */ ! 1182: gen_lowpart_for_combine (GET_MODE (to), XEXP (to, 0))); 1.1 root 1183: } 1184: #endif 1185: /* Two shifts in a row of same kind 1186: in same direction with constant counts 1187: may be combined. */ 1.1.1.2 ! root 1188: if (was_replaced[0] 1.1 root 1189: && GET_CODE (to) == GET_CODE (x) 1190: && GET_CODE (XEXP (x, 1)) == CONST_INT 1191: && GET_CODE (XEXP (to, 1)) == CONST_INT 1192: && INTVAL (XEXP (to, 1)) > 0 1193: && INTVAL (XEXP (x, 1)) > 0 1194: && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (to, 1)) 1.1.1.2 ! root 1195: < GET_MODE_BITSIZE (GET_MODE (x)))) 1.1 root 1196: { 1197: if (!undobuf.storage) 1198: undobuf.storage = (char *) oballoc (0); 1199: return gen_rtx (GET_CODE (x), GET_MODE (x), 1200: XEXP (to, 0), 1201: gen_rtx (CONST_INT, VOIDmode, 1202: INTVAL (XEXP (x, 1)) 1203: + INTVAL (XEXP (to, 1)))); 1204: } 1205: break; 1206: 1207: case LSHIFT: 1208: case ASHIFT: 1209: #ifdef SHIFT_COUNT_TRUNCATED 1210: /* (lshift <X> (sign_extend <Y>)) = (lshift <X> <Y>) (most machines). 1211: True for all kinds of shifts and also for zero_extend. */ 1.1.1.2 ! root 1212: if (was_replaced[1] 1.1 root 1213: && (GET_CODE (to) == SIGN_EXTEND 1214: || GET_CODE (to) == ZERO_EXTEND)) 1215: { 1216: if (!undobuf.storage) 1217: undobuf.storage = (char *) oballoc (0); 1.1.1.2 ! root 1218: SUBST (XEXP (x, 1), gen_rtx (SUBREG, GET_MODE (to), XEXP (to, 0), 0)); 1.1 root 1219: } 1220: #endif 1221: /* (lshift (and (lshiftrt <foo> <X>) <Y>) <X>) 1222: happens copying between bit fields in similar structures. 1223: It can be replaced by one and instruction. 1224: It does not matter whether the shifts are logical or arithmetic. */ 1225: if (GET_CODE (XEXP (x, 0)) == AND 1226: && GET_CODE (XEXP (x, 1)) == CONST_INT 1227: && INTVAL (XEXP (x, 1)) > 0 1228: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT 1.1.1.2 ! root 1229: && XEXP (XEXP (x, 0), 0) == to 1.1 root 1230: && (GET_CODE (to) == LSHIFTRT 1231: || GET_CODE (to) == ASHIFTRT) 1232: #if 0 1233: /* I now believe this restriction is unnecessary. 1234: The outer shift will discard those bits in any case, right? */ 1235: 1236: /* If inner shift is arithmetic, either it shifts left or 1237: the bits it shifts the sign into are zeroed by the and. */ 1238: && (INTVAL (XEXP (x, 1)) < 0 1239: || ((unsigned) INTVAL (XEXP (XEXP (x, 0), 1)) 1240: < 1 << (GET_MODE_BITSIZE (GET_MODE (x)) 1241: - INTVAL (XEXP (x, 0))))) 1242: #endif 1243: && GET_CODE (XEXP (to, 1)) == CONST_INT 1244: && INTVAL (XEXP (x, 1)) == INTVAL (XEXP (to, 1))) 1245: { 1246: if (!undobuf.storage) 1247: undobuf.storage = (char *) oballoc (0); 1248: /* The constant in the new `and' is <Y> << <X> 1249: but clear out all bits that don't belong in our mode. */ 1250: return gen_rtx (AND, GET_MODE (x), XEXP (to, 0), 1251: gen_rtx (CONST_INT, VOIDmode, 1252: (GET_MODE_MASK (GET_MODE (x)) 1253: & ((GET_MODE_MASK (GET_MODE (x)) 1254: & INTVAL (XEXP (XEXP (x, 0), 1))) 1255: << INTVAL (XEXP (x, 1)))))); 1256: } 1257: /* Two shifts in a row in same direction with constant counts 1258: may be combined. */ 1.1.1.2 ! root 1259: if (was_replaced[0] 1.1 root 1260: && (GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT) 1261: && GET_CODE (XEXP (x, 1)) == CONST_INT 1262: && GET_CODE (XEXP (to, 1)) == CONST_INT 1263: && INTVAL (XEXP (to, 1)) > 0 1264: && INTVAL (XEXP (x, 1)) > 0 1265: && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (to, 1)) 1.1.1.2 ! root 1266: < GET_MODE_BITSIZE (GET_MODE (x)))) 1.1 root 1267: { 1268: if (!undobuf.storage) 1269: undobuf.storage = (char *) oballoc (0); 1270: return gen_rtx (GET_CODE (x), GET_MODE (x), 1271: XEXP (to, 0), 1272: gen_rtx (CONST_INT, VOIDmode, 1273: INTVAL (XEXP (x, 1)) 1274: + INTVAL (XEXP (to, 1)))); 1275: } 1276: /* (ashift (ashiftrt <foo> <X>) <X>) 1277: (or, on some machines, (ashift (ashift <foo> <-X>) <X>) instead) 1278: happens if you divide by 2**N and then multiply by 2**N. 1279: It can be replaced by one `and' instruction. 1280: It does not matter whether the shifts are logical or arithmetic. */ 1281: if (GET_CODE (XEXP (x, 1)) == CONST_INT 1282: && INTVAL (XEXP (x, 1)) > 0 1.1.1.2 ! root 1283: && was_replaced[0] 1.1 root 1284: && (((GET_CODE (to) == LSHIFTRT || GET_CODE (to) == ASHIFTRT) 1285: && GET_CODE (XEXP (to, 1)) == CONST_INT 1286: && INTVAL (XEXP (x, 1)) == INTVAL (XEXP (to, 1))) 1287: || 1288: ((GET_CODE (to) == LSHIFT || GET_CODE (to) == ASHIFT) 1289: && GET_CODE (XEXP (to, 1)) == CONST_INT 1290: && INTVAL (XEXP (x, 1)) == - INTVAL (XEXP (to, 1))))) 1291: { 1292: if (!undobuf.storage) 1293: undobuf.storage = (char *) oballoc (0); 1.1.1.2 ! root 1294: /* The constant in the new `and' is -1 << <X> 1.1 root 1295: but clear out all bits that don't belong in our mode. */ 1296: return gen_rtx (AND, GET_MODE (x), XEXP (to, 0), 1297: gen_rtx (CONST_INT, VOIDmode, 1298: (GET_MODE_MASK (GET_MODE (x)) 1299: & (GET_MODE_MASK (GET_MODE (x)) 1300: << INTVAL (XEXP (x, 1)))))); 1301: } 1302: 1303: } 1304: 1305: return x; 1306: } 1307: 1308: /* This is the AND case of the function subst. */ 1309: 1310: static rtx 1.1.1.2 ! root 1311: simplify_and_const_int (x, to) ! 1312: rtx x, to; 1.1 root 1313: { 1314: register rtx varop = XEXP (x, 0); 1315: register int constop = INTVAL (XEXP (x, 1)); 1316: 1317: /* (and (subreg (and <foo> <constant>) 0) <constant>) 1318: results from an andsi followed by an andqi, 1319: which happens frequently when storing bit-fields 1320: on something whose result comes from an andsi. */ 1321: if (GET_CODE (varop) == SUBREG 1.1.1.2 ! root 1322: && XEXP (varop, 0) == to 1.1 root 1323: && subreg_lowpart_p (varop) 1324: && GET_CODE (to) == AND 1325: && GET_CODE (XEXP (to, 1)) == CONST_INT 1326: /* Verify that the result of the outer `and' 1327: is not affected by any bits not defined in the inner `and'. 1328: True if the outer mode is narrower, or if the outer constant 1329: masks to zero all the bits that the inner mode doesn't have. */ 1.1.1.2 ! root 1330: && (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (GET_MODE (to)) ! 1331: || (constop & ~ GET_MODE_MASK (GET_MODE (to))) == 0)) 1.1 root 1332: { 1333: if (!undobuf.storage) 1334: undobuf.storage = (char *) oballoc (0); 1335: return gen_rtx (AND, GET_MODE (x), 1.1.1.2 ! root 1336: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)), 1.1 root 1337: gen_rtx (CONST_INT, VOIDmode, 1338: constop 1339: /* Remember that the bits outside that mode 1340: are not being changed, so the effect 1341: is as if they were all 1. */ 1342: & INTVAL (XEXP (to, 1)))); 1343: } 1.1.1.2 ! root 1344: /* (and:SI (zero_extract:SI ...) <constant>) ! 1345: results from an andsi following a byte-fetch on risc machines. ! 1346: When the constant includes all bits extracted, eliminate the `and'. */ ! 1347: if (GET_CODE (varop) == ZERO_EXTRACT ! 1348: && GET_CODE (XEXP (varop, 1)) == CONST_INT ! 1349: /* The `and' must not clear any bits that the extract can give. */ ! 1350: && (~ constop & ((1 << INTVAL (XEXP (varop, 1))) - 1)) == 0) ! 1351: return varop; 1.1 root 1352: /* (and (zero_extend <foo>) <constant>) 1353: often results from storing in a bit-field something 1354: that was calculated as a short. Replace with a single `and' 1355: in whose constant all bits not in <foo>'s mode are zero. */ 1.1.1.2 ! root 1356: if (varop == to ! 1357: && GET_CODE (to) == ZERO_EXTEND ! 1358: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0))) 1.1 root 1359: { 1360: if (!undobuf.storage) 1361: undobuf.storage = (char *) oballoc (0); 1362: return gen_rtx (AND, GET_MODE (x), 1.1.1.2 ! root 1363: /* This is a perverse SUBREG, wider than its base. */ ! 1364: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)), 1.1 root 1365: gen_rtx (CONST_INT, VOIDmode, 1.1.1.2 ! root 1366: constop & GET_MODE_MASK (GET_MODE (XEXP (to, 0))))); 1.1 root 1367: } 1368: /* (and (sign_extend <foo>) <constant>) 1369: can be replaced with (and (subreg <foo>) <constant>) 1370: if <constant> is narrower than <foo>'s mode, 1371: or with (zero_extend <foo>) if <constant> is a mask for that mode. */ 1.1.1.2 ! root 1372: if (varop == to 1.1 root 1373: && GET_CODE (to) == SIGN_EXTEND 1.1.1.2 ! root 1374: && ((unsigned) constop <= GET_MODE_MASK (GET_MODE (XEXP (to, 0)))) ! 1375: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0))) 1.1 root 1376: { 1377: if (!undobuf.storage) 1378: undobuf.storage = (char *) oballoc (0); 1.1.1.2 ! root 1379: if (constop == GET_MODE_MASK (GET_MODE (XEXP (to, 0)))) 1.1 root 1380: return gen_rtx (ZERO_EXTEND, GET_MODE (x), XEXP (to, 0)); 1381: return gen_rtx (AND, GET_MODE (x), 1.1.1.2 ! root 1382: /* This is a perverse SUBREG, wider than its base. */ ! 1383: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)), 1.1 root 1384: XEXP (x, 1)); 1385: } 1386: /* (and (and <foo> <constant>) <constant>) 1387: comes from two and instructions in a row. */ 1.1.1.2 ! root 1388: if (varop == to 1.1 root 1389: && GET_CODE (to) == AND 1390: && GET_CODE (XEXP (to, 1)) == CONST_INT) 1391: { 1392: if (!undobuf.storage) 1393: undobuf.storage = (char *) oballoc (0); 1394: return gen_rtx (AND, GET_MODE (x), 1395: XEXP (to, 0), 1396: gen_rtx (CONST_INT, VOIDmode, 1397: constop 1398: & INTVAL (XEXP (to, 1)))); 1399: } 1400: /* (and (ashiftrt (ashift FOO N) N) CONST) 1401: may be simplified to (and FOO CONST) if CONST masks off the bits 1402: changed by the two shifts. */ 1403: if (GET_CODE (varop) == ASHIFTRT 1404: && GET_CODE (XEXP (varop, 1)) == CONST_INT 1.1.1.2 ! root 1405: && XEXP (varop, 0) == to 1.1 root 1406: && GET_CODE (to) == ASHIFT 1407: && GET_CODE (XEXP (to, 1)) == CONST_INT 1408: && INTVAL (XEXP (varop, 1)) == INTVAL (XEXP (to, 1)) 1409: && ((unsigned) constop >> INTVAL (XEXP (varop, 1))) == 0) 1410: { 1411: if (!undobuf.storage) 1412: undobuf.storage = (char *) oballoc (0); 1413: /* If CONST is a mask for the low byte, 1414: change this into a zero-extend instruction 1415: from just the low byte of FOO. */ 1.1.1.2 ! root 1416: if (constop == GET_MODE_MASK (QImode)) 1.1 root 1417: { 1418: rtx temp = gen_lowpart_for_combine (QImode, XEXP (to, 0)); 1.1.1.2 ! root 1419: if (GET_CODE (temp) != CLOBBER) 1.1 root 1420: return gen_rtx (ZERO_EXTEND, GET_MODE (x), temp); 1421: } 1422: return gen_rtx (AND, GET_MODE (x), 1423: XEXP (to, 0), XEXP (x, 1)); 1424: } 1.1.1.2 ! root 1425: /* (and x const) may be converted to (zero_extend (subreg x 0)). */ ! 1426: if (constop == GET_MODE_MASK (QImode)) ! 1427: { ! 1428: if (!undobuf.storage) ! 1429: undobuf.storage = (char *) oballoc (0); ! 1430: return gen_rtx (ZERO_EXTEND, GET_MODE (x), ! 1431: gen_rtx (SUBREG, QImode, varop, 0)); ! 1432: } ! 1433: if (constop == GET_MODE_MASK (HImode)) ! 1434: { ! 1435: if (!undobuf.storage) ! 1436: undobuf.storage = (char *) oballoc (0); ! 1437: return gen_rtx (ZERO_EXTEND, GET_MODE (x), ! 1438: gen_rtx (SUBREG, HImode, varop, 0)); ! 1439: } 1.1 root 1440: /* No simplification applies. */ 1441: return 0; 1442: } 1443: 1444: /* Like gen_lowpart but for use by combine. In combine it is not possible 1445: to create any new pseudoregs. However, it is safe to create 1446: invalid memory addresses, because combine will try to recognize 1447: them and all they will do is make the combine attempt fail. 1448: 1.1.1.2 ! root 1449: If for some reason this cannot do its job, an rtx ! 1450: (clobber (const_int 0)) is returned. ! 1451: An insn containing that will not be recognized. */ ! 1452: ! 1453: #undef gen_lowpart 1.1 root 1454: 1455: static rtx 1456: gen_lowpart_for_combine (mode, x) 1457: enum machine_mode mode; 1458: register rtx x; 1459: { 1460: if (GET_CODE (x) == SUBREG || GET_CODE (x) == REG) 1461: return gen_lowpart (mode, x); 1.1.1.2 ! root 1462: if (GET_MODE (x) == mode || x->volatil) ! 1463: return gen_rtx (CLOBBER, VOIDmode, const0_rtx); 1.1 root 1464: if (GET_CODE (x) == MEM) 1465: { 1466: register int offset = 0; 1467: #ifdef WORDS_BIG_ENDIAN 1468: offset = (max (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) 1469: - max (GET_MODE_SIZE (mode), UNITS_PER_WORD)); 1470: #endif 1471: #ifdef BYTES_BIG_ENDIAN 1.1.1.2 ! root 1472: /* Adjust the address so that the address-after-the-data ! 1473: is unchanged. */ ! 1474: offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (mode)) ! 1475: - min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))); 1.1 root 1476: #endif 1477: return gen_rtx (MEM, mode, plus_constant (XEXP (x, 0), 1478: offset)); 1479: } 1480: else 1.1.1.2 ! root 1481: return gen_rtx (CLOBBER, VOIDmode, const0_rtx); 1.1 root 1482: } 1483: 1484: /* After substitution, if the resulting pattern looks like 1.1.1.2 ! root 1485: (set (cc0) (and ...)) or (set (cc0) (lshiftrt ...)), ! 1486: this function is called to simplify the 1.1 root 1487: pattern into a bit-field operation if possible. */ 1488: 1489: static void 1490: simplify_set_cc0_and (insn) 1491: rtx insn; 1492: { 1493: register rtx value = XEXP (PATTERN (insn), 1); 1494: register rtx op0 = XEXP (value, 0); 1495: register rtx op1 = XEXP (value, 1); 1496: int offset = 0; 1497: rtx var = 0; 1498: rtx bitnum = 0; 1499: int temp; 1500: int unit; 1.1.1.2 ! root 1501: rtx newpat; ! 1502: ! 1503: if (GET_CODE (value) == AND) ! 1504: { ! 1505: op0 = XEXP (value, 0); ! 1506: op1 = XEXP (value, 1); ! 1507: } ! 1508: else if (GET_CODE (value) == LSHIFTRT) ! 1509: { ! 1510: /* If there is no AND, but there is a shift that discards ! 1511: all but the sign bit, we can pretend that the shift result ! 1512: is ANDed with 1. Otherwise we cannot handle just a shift. */ ! 1513: if (GET_CODE (XEXP (value, 1)) == CONST_INT ! 1514: && (INTVAL (XEXP (value, 1)) ! 1515: == GET_MODE_BITSIZE (GET_MODE (value)) - 1)) ! 1516: { ! 1517: op0 = value; ! 1518: op1 = const1_rtx; ! 1519: } ! 1520: else ! 1521: return; ! 1522: } ! 1523: else ! 1524: abort (); 1.1 root 1525: 1526: /* Look for a constant power of 2 or a shifted 1 1527: on either side of the AND. Set VAR to the other side. 1528: Set BITNUM to the shift count of the 1 (as an rtx). 1529: Or, if bit number is constant, set OFFSET to the bit number. */ 1530: 1531: switch (GET_CODE (op0)) 1532: { 1533: case CONST_INT: 1534: temp = exact_log2 (INTVAL (op0)); 1535: if (temp < 0) 1536: return; 1537: offset = temp; 1538: var = op1; 1539: break; 1540: 1541: case ASHIFT: 1542: case LSHIFT: 1543: if (XEXP (op0, 0) == const1_rtx) 1544: { 1545: bitnum = XEXP (op0, 1); 1546: var = op1; 1547: } 1548: } 1549: if (var == 0) 1550: switch (GET_CODE (op1)) 1551: { 1552: case CONST_INT: 1553: temp = exact_log2 (INTVAL (op1)); 1554: if (temp < 0) 1555: return; 1556: offset = temp; 1557: var = op0; 1558: break; 1559: 1560: case ASHIFT: 1561: case LSHIFT: 1562: if (XEXP (op1, 0) == const1_rtx) 1563: { 1564: bitnum = XEXP (op1, 1); 1565: var = op0; 1566: } 1567: } 1568: 1569: /* If VAR is 0, we didn't find something recognizable. */ 1570: if (var == 0) 1571: return; 1572: 1573: if (!undobuf.storage) 1574: undobuf.storage = (char *) oballoc (0); 1575: 1576: /* If the bit position is currently exactly 0, 1577: extract a right-shift from the variable portion. */ 1578: if (offset == 0 1579: && (GET_CODE (var) == ASHIFTRT || GET_CODE (var) == LSHIFTRT)) 1580: { 1581: bitnum = XEXP (var, 1); 1582: var = XEXP (var, 0); 1583: } 1584: 1.1.1.2 ! root 1585: if (GET_CODE (var) == SUBREG && SUBREG_WORD (var) == 0) ! 1586: var = SUBREG_REG (var); ! 1587: ! 1588: /* Note that BITNUM and OFFSET are always little-endian thru here ! 1589: even on a big-endian machine. */ ! 1590: 1.1 root 1591: #ifdef BITS_BIG_ENDIAN 1.1.1.2 ! root 1592: unit = GET_MODE_BITSIZE (GET_MODE (var)) - 1; 1.1 root 1593: 1594: if (bitnum != 0) 1595: bitnum = gen_rtx (MINUS, SImode, 1596: gen_rtx (CONST_INT, VOIDmode, unit), bitnum); 1597: else 1598: offset = unit - offset; 1599: #endif 1600: 1601: if (bitnum == 0) 1602: bitnum = gen_rtx (CONST_INT, VOIDmode, offset); 1603: 1.1.1.2 ! root 1604: newpat = gen_rtx (SET, VOIDmode, cc0_rtx, ! 1605: gen_rtx (ZERO_EXTRACT, VOIDmode, var, const1_rtx, bitnum)); ! 1606: if (recog (newpat, insn) >= 0) 1.1 root 1607: { 1.1.1.2 ! root 1608: if (undobuf.num_undo < MAX_UNDO) ! 1609: { ! 1610: undobuf.undo[undobuf.num_undo].where = &XEXP (PATTERN (insn), 1); ! 1611: undobuf.undo[undobuf.num_undo].old_contents = value; ! 1612: XEXP (PATTERN (insn), 1) = XEXP (newpat, 1); ! 1613: } ! 1614: undobuf.num_undo++; 1.1 root 1615: } 1616: } 1617: 1618: /* Update the records of when each REG was most recently set or killed 1619: for the things done by INSN. This is the last thing done in processing 1620: INSN in the combiner loop. 1621: 1622: We update reg_last_set, reg_last_death, and also the similar information 1623: mem_last_set (which insn most recently modified memory) 1624: and last_call_cuid (which insn was the most recent subroutine call). */ 1625: 1626: static void 1627: record_dead_and_set_regs (insn) 1628: rtx insn; 1629: { 1630: register rtx link; 1631: for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 1632: { 1.1.1.2 ! root 1633: if (REG_NOTE_KIND (link) == REG_DEAD) 1.1 root 1634: reg_last_death[REGNO (XEXP (link, 0))] = insn; 1.1.1.2 ! root 1635: else if (REG_NOTE_KIND (link) == REG_INC) 1.1 root 1636: reg_last_set[REGNO (XEXP (link, 0))] = insn; 1637: } 1638: 1639: if (GET_CODE (insn) == CALL_INSN) 1640: last_call_cuid = mem_last_set = INSN_CUID (insn); 1641: 1642: if (GET_CODE (PATTERN (insn)) == PARALLEL) 1643: { 1644: register int i; 1645: for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) 1646: { 1647: register rtx elt = XVECEXP (PATTERN (insn), 0, i); 1648: register enum rtx_code code = GET_CODE (elt); 1649: if (code == SET || code == CLOBBER) 1650: { 1651: if (GET_CODE (XEXP (elt, 0)) == REG) 1652: reg_last_set[REGNO (XEXP (elt, 0))] = insn; 1.1.1.2 ! root 1653: if (GET_CODE (XEXP (elt, 0)) == SUBREG ! 1654: && GET_CODE (SUBREG_REG (XEXP (elt, 0))) == REG) ! 1655: reg_last_set[REGNO (SUBREG_REG (XEXP (elt, 0)))] = insn; 1.1 root 1656: else if (GET_CODE (XEXP (elt, 0)) == MEM) 1657: mem_last_set = INSN_CUID (insn); 1658: } 1659: } 1660: } 1661: else if (GET_CODE (PATTERN (insn)) == SET 1662: || GET_CODE (PATTERN (insn)) == CLOBBER) 1663: { 1664: register rtx x = XEXP (PATTERN (insn), 0); 1665: if (GET_CODE (x) == REG) 1666: reg_last_set[REGNO (x)] = insn; 1.1.1.2 ! root 1667: if (GET_CODE (x) == SUBREG ! 1668: && GET_CODE (SUBREG_REG (x)) == REG) ! 1669: reg_last_set[REGNO (SUBREG_REG (x))] = insn; 1.1 root 1670: else if (GET_CODE (x) == MEM) 1671: mem_last_set = INSN_CUID (insn); 1672: } 1673: } 1674: 1675: /* Return nonzero if expression X refers to a REG or to memory 1676: that is set in an instruction more recent than FROM_CUID. */ 1677: 1678: static int 1679: use_crosses_set_p (x, from_cuid) 1680: register rtx x; 1681: int from_cuid; 1682: { 1683: register char *fmt; 1684: register int i; 1685: register enum rtx_code code = GET_CODE (x); 1686: 1687: if (code == REG) 1688: { 1689: register int regno = REGNO (x); 1690: return (reg_last_set[regno] 1691: && INSN_CUID (reg_last_set[regno]) > from_cuid); 1692: } 1693: 1694: if (code == MEM && mem_last_set > from_cuid) 1695: return 1; 1696: 1697: fmt = GET_RTX_FORMAT (code); 1698: 1699: for (i = GET_RTX_LENGTH (code); i >= 0; i--) 1700: { 1701: if (fmt[i] == 'E') 1702: { 1703: register int j; 1704: for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1705: if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid)) 1706: return 1; 1707: } 1708: else if (fmt[i] == 'e' 1709: && use_crosses_set_p (XEXP (x, i), from_cuid)) 1710: return 1; 1711: } 1712: return 0; 1713: } 1714: 1715: /* Return nonzero if reg REGNO is marked as dying in INSN. */ 1716: 1717: int 1718: regno_dead_p (regno, insn) 1719: int regno; 1720: rtx insn; 1721: { 1722: register rtx link; 1723: 1724: for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 1.1.1.2 ! root 1725: if ((REG_NOTE_KIND (link) == REG_DEAD ! 1726: || REG_NOTE_KIND (link) == REG_INC) ! 1727: && REGNO (XEXP (link, 0)) == regno) 1.1 root 1728: return 1; 1729: 1730: return 0; 1731: } 1732: 1733: /* Remove register number REGNO from the dead registers list of INSN. */ 1734: 1735: static void 1736: remove_death (regno, insn) 1737: int regno; 1738: rtx insn; 1739: { 1740: register rtx link, next; 1741: while ((link = REG_NOTES (insn)) 1.1.1.2 ! root 1742: && REG_NOTE_KIND (link) == REG_DEAD ! 1743: && REGNO (XEXP (link, 0)) == regno) 1.1 root 1744: REG_NOTES (insn) = XEXP (link, 1); 1745: 1746: if (link) 1747: while (next = XEXP (link, 1)) 1748: { 1.1.1.2 ! root 1749: if (REG_NOTE_KIND (next) == REG_DEAD ! 1750: && REGNO (XEXP (next, 0)) == regno) 1.1 root 1751: XEXP (link, 1) = XEXP (next, 1); 1752: else 1753: link = next; 1754: } 1755: } 1756: 1757: /* Return nonzero if J is the first insn following I, 1758: not counting labels, line numbers, etc. 1759: We assume that J follows I. */ 1760: 1761: static int 1762: adjacent_insns_p (i, j) 1763: rtx i, j; 1764: { 1765: register rtx insn; 1766: for (insn = NEXT_INSN (i); insn != j; insn = NEXT_INSN (insn)) 1767: if (GET_CODE (insn) == INSN 1768: || GET_CODE (insn) == CALL_INSN 1769: || GET_CODE (insn) == JUMP_INSN) 1770: return 0; 1771: return 1; 1772: } 1773: 1.1.1.2 ! root 1774: /* Concatenate the list of logical links of OINSN 1.1 root 1775: into INSN's list of logical links. 1.1.1.2 ! root 1776: Modifies OINSN destructively. ! 1777: ! 1778: If ALL_LINKS is nonzero, move all the links that OINSN has. ! 1779: Otherwise, move only those that point to insns that set regs ! 1780: that die in the insn OINSN. ! 1781: Other links are clobbered so that they are no longer effective. */ 1.1 root 1782: 1783: static void 1.1.1.2 ! root 1784: add_links (insn, oinsn, all_links) ! 1785: rtx insn, oinsn; ! 1786: int all_links; 1.1 root 1787: { 1.1.1.2 ! root 1788: register rtx links = LOG_LINKS (oinsn); ! 1789: if (! all_links) ! 1790: { ! 1791: rtx tail; ! 1792: for (tail = links; tail; tail = XEXP (tail, 1)) ! 1793: { ! 1794: rtx target = XEXP (tail, 0); ! 1795: if (GET_CODE (target) != INSN ! 1796: || GET_CODE (PATTERN (target)) != SET ! 1797: || GET_CODE (SET_DEST (PATTERN (target))) != REG ! 1798: || ! dead_or_set_p (oinsn, SET_DEST (PATTERN (target)))) ! 1799: /* OINSN is going to become a NOTE ! 1800: so a link pointing there will have no effect. */ ! 1801: XEXP (tail, 0) = oinsn; ! 1802: } ! 1803: } 1.1 root 1804: if (LOG_LINKS (insn) == 0) 1805: LOG_LINKS (insn) = links; 1806: else 1807: { 1808: register rtx next, prev = LOG_LINKS (insn); 1809: while (next = XEXP (prev, 1)) 1810: prev = next; 1811: XEXP (prev, 1) = links; 1812: } 1813: } 1814: 1815: /* Concatenate the any elements of the list of reg-notes INCS 1816: which are of type REG_INC 1817: into INSN's list of reg-notes. */ 1818: 1819: static void 1820: add_incs (insn, incs) 1821: rtx insn, incs; 1822: { 1823: register rtx tail; 1824: 1825: for (tail = incs; tail; tail = XEXP (tail, 1)) 1.1.1.2 ! root 1826: if (REG_NOTE_KIND (tail) == REG_INC) 1.1 root 1827: REG_NOTES (insn) 1828: = gen_rtx (EXPR_LIST, REG_INC, XEXP (tail, 0), REG_NOTES (insn)); 1829: } 1830: 1831: /* For each register (hardware or pseudo) used within expression X, 1832: if its death is in an instruction with cuid 1833: between FROM_CUID (inclusive) and TO_INSN (exclusive), 1834: mark it as dead in TO_INSN instead. 1835: 1836: This is done when X is being merged by combination into TO_INSN. */ 1837: 1838: static void 1839: move_deaths (x, from_cuid, to_insn) 1840: rtx x; 1841: int from_cuid; 1842: rtx to_insn; 1843: { 1844: register char *fmt; 1845: register int len, i; 1846: register enum rtx_code code = GET_CODE (x); 1847: 1848: if (code == REG) 1849: { 1850: register rtx where_dead = reg_last_death[REGNO (x)]; 1851: 1852: if (where_dead && INSN_CUID (where_dead) >= from_cuid 1853: && INSN_CUID (where_dead) < INSN_CUID (to_insn)) 1854: { 1855: remove_death (REGNO (x), reg_last_death[REGNO (x)]); 1856: if (! dead_or_set_p (to_insn, x)) 1857: REG_NOTES (to_insn) 1858: = gen_rtx (EXPR_LIST, REG_DEAD, x, REG_NOTES (to_insn)); 1859: } 1860: return; 1861: } 1862: 1863: len = GET_RTX_LENGTH (code); 1864: fmt = GET_RTX_FORMAT (code); 1865: 1866: for (i = 0; i < len; i++) 1867: { 1868: if (fmt[i] == 'E') 1869: { 1870: register int j; 1871: for (j = XVECLEN (x, i) - 1; j >= 0; j--) 1872: move_deaths (XVECEXP (x, i, j), from_cuid, to_insn); 1873: } 1874: else if (fmt[i] == 'e') 1875: move_deaths (XEXP (x, i), from_cuid, to_insn); 1876: } 1877: } 1878: 1.1.1.2 ! root 1879: void 1.1 root 1880: dump_combine_stats (file) 1881: char *file; 1882: { 1883: fprintf 1884: (file, 1885: ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n" 1886: , combine_attempts, combine_merges, combine_extras, combine_successes); 1887: } 1888: 1.1.1.2 ! root 1889: void 1.1 root 1890: dump_combine_total_stats (file) 1891: char *file; 1892: { 1893: fprintf 1894: (file, 1895: "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n", 1896: total_attempts, total_merges, total_extras, total_successes); 1897: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.