|
|
1.1 root 1: /* Optimize jump instructions, for GNU compiler. 1.1.1.4 ! root 2: Copyright (C) 1987, 1988, 1989, 1991, 1992 Free Software Foundation, Inc. 1.1 root 3: 4: This file is part of GNU CC. 5: 6: GNU CC is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU CC is distributed in the hope that it will be useful, 12: but WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14: GNU General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU CC; see the file COPYING. If not, write to 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19: 20: 21: /* This is the jump-optimization pass of the compiler. 22: It is run two or three times: once before cse, sometimes once after cse, 23: and once after reload (before final). 24: 25: jump_optimize deletes unreachable code and labels that are not used. 26: It also deletes jumps that jump to the following insn, 27: and simplifies jumps around unconditional jumps and jumps 28: to unconditional jumps. 29: 30: Each CODE_LABEL has a count of the times it is used 31: stored in the LABEL_NUSES internal field, and each JUMP_INSN 32: has one label that it refers to stored in the 33: JUMP_LABEL internal field. With this we can detect labels that 34: become unused because of the deletion of all the jumps that 35: formerly used them. The JUMP_LABEL info is sometimes looked 36: at by later passes. 37: 38: Optionally, cross-jumping can be done. Currently it is done 39: only the last time (when after reload and before final). 40: In fact, the code for cross-jumping now assumes that register 41: allocation has been done, since it uses `rtx_renumbered_equal_p'. 42: 43: Jump optimization is done after cse when cse's constant-propagation 44: causes jumps to become unconditional or to be deleted. 45: 46: Unreachable loops are not detected here, because the labels 47: have references and the insns appear reachable from the labels. 48: find_basic_blocks in flow.c finds and deletes such loops. 49: 50: The subroutines delete_insn, redirect_jump, and invert_jump are used 51: from other passes as well. */ 52: 53: #include "config.h" 54: #include "rtl.h" 55: #include "flags.h" 56: #include "hard-reg-set.h" 57: #include "regs.h" 58: #include "expr.h" 59: #include "insn-config.h" 60: #include "insn-flags.h" 61: #include "real.h" 62: 63: /* ??? Eventually must record somehow the labels used by jumps 64: from nested functions. */ 65: /* Pre-record the next or previous real insn for each label? 66: No, this pass is very fast anyway. */ 67: /* Condense consecutive labels? 68: This would make life analysis faster, maybe. */ 69: /* Optimize jump y; x: ... y: jumpif... x? 70: Don't know if it is worth bothering with. */ 71: /* Optimize two cases of conditional jump to conditional jump? 72: This can never delete any instruction or make anything dead, 73: or even change what is live at any point. 74: So perhaps let combiner do it. */ 75: 76: /* Vector indexed by uid. 77: For each CODE_LABEL, index by its uid to get first unconditional jump 78: that jumps to the label. 79: For each JUMP_INSN, index by its uid to get the next unconditional jump 80: that jumps to the same label. 81: Element 0 is the start of a chain of all return insns. 82: (It is safe to use element 0 because insn uid 0 is not used. */ 83: 84: static rtx *jump_chain; 85: 86: /* List of labels referred to from initializers. 87: These can never be deleted. */ 88: rtx forced_labels; 89: 90: /* Maximum index in jump_chain. */ 91: 92: static int max_jump_chain; 93: 94: /* Set nonzero by jump_optimize if control can fall through 95: to the end of the function. */ 96: int can_reach_end; 97: 98: /* Indicates whether death notes are significant in cross jump analysis. 99: Normally they are not significant, because of A and B jump to C, 100: and R dies in A, it must die in B. But this might not be true after 101: stack register conversion, and we must compare death notes in that 102: case. */ 103: 104: static int cross_jump_death_matters = 0; 105: 106: static int duplicate_loop_exit_test (); 107: void redirect_tablejump (); 108: static int delete_labelref_insn (); 109: static void mark_jump_label (); 110: void delete_jump (); 1.1.1.4 ! root 111: void delete_computation (); 1.1 root 112: static void delete_from_jump_chain (); 113: static int tension_vector_labels (); 114: static void find_cross_jump (); 115: static void do_cross_jump (); 116: static int jump_back_p (); 1.1.1.4 ! root 117: ! 118: extern rtx gen_jump (); 1.1 root 119: 120: /* Delete no-op jumps and optimize jumps to jumps 121: and jumps around jumps. 122: Delete unused labels and unreachable code. 123: 124: If CROSS_JUMP is 1, detect matching code 125: before a jump and its destination and unify them. 126: If CROSS_JUMP is 2, do cross-jumping, but pay attention to death notes. 127: 128: If NOOP_MOVES is nonzero, delete no-op move insns. 129: 130: If AFTER_REGSCAN is nonzero, then this jump pass is being run immediately 131: after regscan, and it is safe to use regno_first_uid and regno_last_uid. 132: 133: If `optimize' is zero, don't change any code, 134: just determine whether control drops off the end of the function. 135: This case occurs when we have -W and not -O. 136: It works because `delete_insn' checks the value of `optimize' 137: and refrains from actually deleting when that is 0. */ 138: 139: void 140: jump_optimize (f, cross_jump, noop_moves, after_regscan) 141: rtx f; 142: int cross_jump; 143: int noop_moves; 144: int after_regscan; 145: { 1.1.1.4 ! root 146: register rtx insn, next; 1.1 root 147: int changed; 148: int first = 1; 149: int max_uid = 0; 150: rtx last_insn; 151: 152: cross_jump_death_matters = (cross_jump == 2); 153: 154: /* Initialize LABEL_NUSES and JUMP_LABEL fields. */ 155: 156: for (insn = f; insn; insn = NEXT_INSN (insn)) 157: { 158: if (GET_CODE (insn) == CODE_LABEL) 159: LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0); 160: else if (GET_CODE (insn) == JUMP_INSN) 161: JUMP_LABEL (insn) = 0; 162: if (INSN_UID (insn) > max_uid) 163: max_uid = INSN_UID (insn); 164: } 165: 166: max_uid++; 167: 168: /* Delete insns following barriers, up to next label. */ 169: 170: for (insn = f; insn;) 171: { 172: if (GET_CODE (insn) == BARRIER) 173: { 174: insn = NEXT_INSN (insn); 175: while (insn != 0 && GET_CODE (insn) != CODE_LABEL) 176: { 177: if (GET_CODE (insn) == NOTE 178: && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END) 179: insn = NEXT_INSN (insn); 180: else 181: insn = delete_insn (insn); 182: } 183: /* INSN is now the code_label. */ 184: } 185: else 186: insn = NEXT_INSN (insn); 187: } 188: 189: /* Leave some extra room for labels and duplicate exit test insns 190: we make. */ 191: max_jump_chain = max_uid * 14 / 10; 192: jump_chain = (rtx *) alloca (max_jump_chain * sizeof (rtx)); 193: bzero (jump_chain, max_jump_chain * sizeof (rtx)); 194: 195: /* Mark the label each jump jumps to. 196: Combine consecutive labels, and count uses of labels. 197: 198: For each label, make a chain (using `jump_chain') 199: of all the *unconditional* jumps that jump to it; 200: also make a chain of all returns. */ 201: 202: for (insn = f; insn; insn = NEXT_INSN (insn)) 203: if ((GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == INSN 204: || GET_CODE (insn) == CALL_INSN) 205: && ! INSN_DELETED_P (insn)) 206: { 207: mark_jump_label (PATTERN (insn), insn, cross_jump); 208: if (GET_CODE (insn) == JUMP_INSN) 209: { 210: if (JUMP_LABEL (insn) != 0 && simplejump_p (insn)) 211: { 212: jump_chain[INSN_UID (insn)] 213: = jump_chain[INSN_UID (JUMP_LABEL (insn))]; 214: jump_chain[INSN_UID (JUMP_LABEL (insn))] = insn; 215: } 216: if (GET_CODE (PATTERN (insn)) == RETURN) 217: { 218: jump_chain[INSN_UID (insn)] = jump_chain[0]; 219: jump_chain[0] = insn; 220: } 221: } 222: } 223: 224: /* Keep track of labels used from static data; 225: they cannot ever be deleted. */ 226: 227: for (insn = forced_labels; insn; insn = XEXP (insn, 1)) 228: LABEL_NUSES (XEXP (insn, 0))++; 229: 230: /* Delete all labels already not referenced. 231: Also find the last insn. */ 232: 233: last_insn = 0; 234: for (insn = f; insn; ) 235: { 236: if (GET_CODE (insn) == CODE_LABEL && LABEL_NUSES (insn) == 0) 237: insn = delete_insn (insn); 238: else 239: { 240: last_insn = insn; 241: insn = NEXT_INSN (insn); 242: } 243: } 244: 245: if (!optimize) 246: { 247: /* See if there is still a NOTE_INSN_FUNCTION_END in this function. 248: If so record that this function can drop off the end. */ 249: 250: insn = last_insn; 251: { 252: int n_labels = 1; 253: while (insn 254: /* One label can follow the end-note: the return label. */ 255: && ((GET_CODE (insn) == CODE_LABEL && n_labels-- > 0) 256: /* Ordinary insns can follow it if returning a structure. */ 257: || GET_CODE (insn) == INSN 258: /* If machine uses explicit RETURN insns, no epilogue, 259: then one of them follows the note. */ 260: || (GET_CODE (insn) == JUMP_INSN 261: && GET_CODE (PATTERN (insn)) == RETURN) 262: /* Other kinds of notes can follow also. */ 263: || (GET_CODE (insn) == NOTE 264: && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END))) 265: insn = PREV_INSN (insn); 266: } 267: 268: /* Report if control can fall through at the end of the function. */ 269: if (insn && GET_CODE (insn) == NOTE 270: && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END 271: && ! INSN_DELETED_P (insn)) 272: can_reach_end = 1; 273: 274: /* Zero the "deleted" flag of all the "deleted" insns. */ 275: for (insn = f; insn; insn = NEXT_INSN (insn)) 276: INSN_DELETED_P (insn) = 0; 277: return; 278: } 279: 280: #ifdef HAVE_return 281: if (HAVE_return) 282: { 283: /* If we fall through to the epilogue, see if we can insert a RETURN insn 284: in front of it. If the machine allows it at this point (we might be 285: after reload for a leaf routine), it will improve optimization for it 286: to be there. */ 287: insn = get_last_insn (); 288: while (insn && GET_CODE (insn) == NOTE) 289: insn = PREV_INSN (insn); 290: 291: if (insn && GET_CODE (insn) != BARRIER) 292: { 293: emit_jump_insn (gen_return ()); 294: emit_barrier (); 295: } 296: } 297: #endif 298: 299: if (noop_moves) 300: for (insn = f; insn; ) 301: { 1.1.1.4 ! root 302: next = NEXT_INSN (insn); 1.1 root 303: 304: if (GET_CODE (insn) == INSN) 305: { 306: register rtx body = PATTERN (insn); 307: 308: /* Combine stack_adjusts with following push_insns. */ 309: #ifdef PUSH_ROUNDING 310: if (GET_CODE (body) == SET 311: && SET_DEST (body) == stack_pointer_rtx 312: && GET_CODE (SET_SRC (body)) == PLUS 313: && XEXP (SET_SRC (body), 0) == stack_pointer_rtx 314: && GET_CODE (XEXP (SET_SRC (body), 1)) == CONST_INT 315: && INTVAL (XEXP (SET_SRC (body), 1)) > 0) 316: { 317: rtx p; 318: rtx stack_adjust_insn = insn; 319: int stack_adjust_amount = INTVAL (XEXP (SET_SRC (body), 1)); 320: int total_pushed = 0; 321: int pushes = 0; 322: 323: /* Find all successive push insns. */ 324: p = insn; 325: /* Don't convert more than three pushes; 326: that starts adding too many displaced addresses 327: and the whole thing starts becoming a losing 328: proposition. */ 329: while (pushes < 3) 330: { 331: rtx pbody, dest; 332: p = next_nonnote_insn (p); 333: if (p == 0 || GET_CODE (p) != INSN) 334: break; 335: pbody = PATTERN (p); 336: if (GET_CODE (pbody) != SET) 337: break; 338: dest = SET_DEST (pbody); 339: /* Allow a no-op move between the adjust and the push. */ 340: if (GET_CODE (dest) == REG 341: && GET_CODE (SET_SRC (pbody)) == REG 342: && REGNO (dest) == REGNO (SET_SRC (pbody))) 343: continue; 344: if (! (GET_CODE (dest) == MEM 345: && GET_CODE (XEXP (dest, 0)) == POST_INC 346: && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)) 347: break; 348: pushes++; 349: if (total_pushed + GET_MODE_SIZE (SET_DEST (pbody)) 350: > stack_adjust_amount) 351: break; 352: total_pushed += GET_MODE_SIZE (SET_DEST (pbody)); 353: } 354: 355: /* Discard the amount pushed from the stack adjust; 356: maybe eliminate it entirely. */ 357: if (total_pushed >= stack_adjust_amount) 358: { 359: delete_insn (stack_adjust_insn); 360: total_pushed = stack_adjust_amount; 361: } 362: else 363: XEXP (SET_SRC (PATTERN (stack_adjust_insn)), 1) 1.1.1.4 ! root 364: = GEN_INT (stack_adjust_amount - total_pushed); 1.1 root 365: 366: /* Change the appropriate push insns to ordinary stores. */ 367: p = insn; 368: while (total_pushed > 0) 369: { 370: rtx pbody, dest; 371: p = next_nonnote_insn (p); 372: if (GET_CODE (p) != INSN) 373: break; 374: pbody = PATTERN (p); 375: if (GET_CODE (pbody) == SET) 376: break; 377: dest = SET_DEST (pbody); 378: if (! (GET_CODE (dest) == MEM 379: && GET_CODE (XEXP (dest, 0)) == POST_INC 380: && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)) 381: break; 382: total_pushed -= GET_MODE_SIZE (SET_DEST (pbody)); 383: /* If this push doesn't fully fit in the space 384: of the stack adjust that we deleted, 385: make another stack adjust here for what we 386: didn't use up. There should be peepholes 387: to recognize the resulting sequence of insns. */ 388: if (total_pushed < 0) 389: { 390: emit_insn_before (gen_add2_insn (stack_pointer_rtx, 1.1.1.4 ! root 391: GEN_INT (- total_pushed)), 1.1 root 392: p); 393: break; 394: } 395: XEXP (dest, 0) 396: = plus_constant (stack_pointer_rtx, total_pushed); 397: } 398: } 399: #endif 400: 401: /* Detect and delete no-op move instructions 402: resulting from not allocating a parameter in a register. */ 403: 404: if (GET_CODE (body) == SET 405: && (SET_DEST (body) == SET_SRC (body) 406: || (GET_CODE (SET_DEST (body)) == MEM 407: && GET_CODE (SET_SRC (body)) == MEM 408: && rtx_equal_p (SET_SRC (body), SET_DEST (body)))) 409: && ! (GET_CODE (SET_DEST (body)) == MEM 410: && MEM_VOLATILE_P (SET_DEST (body))) 411: && ! (GET_CODE (SET_SRC (body)) == MEM 412: && MEM_VOLATILE_P (SET_SRC (body)))) 413: delete_insn (insn); 414: 415: /* Detect and ignore no-op move instructions 416: resulting from smart or fortuitous register allocation. */ 417: 418: else if (GET_CODE (body) == SET) 419: { 420: int sreg = true_regnum (SET_SRC (body)); 421: int dreg = true_regnum (SET_DEST (body)); 422: 423: if (sreg == dreg && sreg >= 0) 424: delete_insn (insn); 425: else if (sreg >= 0 && dreg >= 0) 426: { 427: rtx trial; 1.1.1.4 ! root 428: rtx tem = find_equiv_reg (NULL_RTX, insn, 0, ! 429: sreg, NULL_PTR, dreg, 1.1 root 430: GET_MODE (SET_SRC (body))); 431: 432: #ifdef PRESERVE_DEATH_INFO_REGNO_P 433: /* Deleting insn could lose a death-note for SREG or DREG 434: so don't do it if final needs accurate death-notes. */ 435: if (! PRESERVE_DEATH_INFO_REGNO_P (sreg) 436: && ! PRESERVE_DEATH_INFO_REGNO_P (dreg)) 437: #endif 438: { 439: /* DREG may have been the target of a REG_DEAD note in 440: the insn which makes INSN redundant. If so, reorg 441: would still think it is dead. So search for such a 442: note and delete it if we find it. */ 443: for (trial = prev_nonnote_insn (insn); 444: trial && GET_CODE (trial) != CODE_LABEL; 445: trial = prev_nonnote_insn (trial)) 446: if (find_regno_note (trial, REG_DEAD, dreg)) 447: { 448: remove_death (dreg, trial); 449: break; 450: } 451: 452: if (tem != 0 453: && GET_MODE (tem) == GET_MODE (SET_DEST (body))) 454: delete_insn (insn); 455: } 456: } 457: else if (dreg >= 0 && CONSTANT_P (SET_SRC (body)) 1.1.1.4 ! root 458: && find_equiv_reg (SET_SRC (body), insn, 0, dreg, ! 459: NULL_PTR, 0, ! 460: GET_MODE (SET_DEST (body)))) 1.1 root 461: { 462: /* This handles the case where we have two consecutive 463: assignments of the same constant to pseudos that didn't 464: get a hard reg. Each SET from the constant will be 465: converted into a SET of the spill register and an 466: output reload will be made following it. This produces 467: two loads of the same constant into the same spill 468: register. */ 469: 470: rtx in_insn = insn; 471: 472: /* Look back for a death note for the first reg. 473: If there is one, it is no longer accurate. */ 474: while (in_insn && GET_CODE (in_insn) != CODE_LABEL) 475: { 476: if ((GET_CODE (in_insn) == INSN 477: || GET_CODE (in_insn) == JUMP_INSN) 478: && find_regno_note (in_insn, REG_DEAD, dreg)) 479: { 480: remove_death (dreg, in_insn); 481: break; 482: } 483: in_insn = PREV_INSN (in_insn); 484: } 485: 486: /* Delete the second load of the value. */ 487: delete_insn (insn); 488: } 489: } 490: else if (GET_CODE (body) == PARALLEL) 491: { 492: /* If each part is a set between two identical registers or 493: a USE or CLOBBER, delete the insn. */ 494: int i, sreg, dreg; 495: rtx tem; 496: 497: for (i = XVECLEN (body, 0) - 1; i >= 0; i--) 498: { 499: tem = XVECEXP (body, 0, i); 500: if (GET_CODE (tem) == USE || GET_CODE (tem) == CLOBBER) 501: continue; 502: 503: if (GET_CODE (tem) != SET 504: || (sreg = true_regnum (SET_SRC (tem))) < 0 505: || (dreg = true_regnum (SET_DEST (tem))) < 0 506: || dreg != sreg) 507: break; 508: } 509: 510: if (i < 0) 511: delete_insn (insn); 512: } 513: #if !BYTES_BIG_ENDIAN /* Not worth the hair to detect this 514: in the big-endian case. */ 515: /* Also delete insns to store bit fields if they are no-ops. */ 516: else if (GET_CODE (body) == SET 517: && GET_CODE (SET_DEST (body)) == ZERO_EXTRACT 518: && XEXP (SET_DEST (body), 2) == const0_rtx 519: && XEXP (SET_DEST (body), 0) == SET_SRC (body) 520: && ! (GET_CODE (SET_SRC (body)) == MEM 521: && MEM_VOLATILE_P (SET_SRC (body)))) 522: delete_insn (insn); 523: #endif /* not BYTES_BIG_ENDIAN */ 524: } 525: insn = next; 526: } 527: 1.1.1.4 ! root 528: /* If we haven't yet gotten to reload and we have just run regscan, ! 529: delete any insn that sets a register that isn't used elsewhere. ! 530: This helps some of the optimizations below by having less insns ! 531: being jumped around. */ ! 532: ! 533: if (! reload_completed && after_regscan) ! 534: for (insn = f; insn; insn = next) ! 535: { ! 536: rtx set = single_set (insn); ! 537: ! 538: next = NEXT_INSN (insn); ! 539: ! 540: if (set && GET_CODE (SET_DEST (set)) == REG ! 541: && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER ! 542: && regno_first_uid[REGNO (SET_DEST (set))] == INSN_UID (insn) ! 543: && regno_last_uid[REGNO (SET_DEST (set))] == INSN_UID (insn) ! 544: && ! side_effects_p (SET_SRC (set))) ! 545: delete_insn (insn); ! 546: } ! 547: 1.1 root 548: /* Now iterate optimizing jumps until nothing changes over one pass. */ 549: changed = 1; 550: while (changed) 551: { 552: changed = 0; 553: 554: for (insn = f; insn; insn = next) 555: { 556: rtx reallabelprev; 1.1.1.4 ! root 557: rtx temp, temp1, temp2, temp3, temp4, temp5, temp6; 1.1 root 558: rtx nlabel; 1.1.1.4 ! root 559: int this_is_simplejump, this_is_condjump, reversep; 1.1 root 560: #if 0 561: /* If NOT the first iteration, if this is the last jump pass 562: (just before final), do the special peephole optimizations. 563: Avoiding the first iteration gives ordinary jump opts 564: a chance to work before peephole opts. */ 565: 566: if (reload_completed && !first && !flag_no_peephole) 567: if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN) 568: peephole (insn); 569: #endif 570: 571: /* That could have deleted some insns after INSN, so check now 572: what the following insn is. */ 573: 574: next = NEXT_INSN (insn); 575: 576: /* See if this is a NOTE_INSN_LOOP_BEG followed by an unconditional 577: jump. Try to optimize by duplicating the loop exit test if so. 578: This is only safe immediately after regscan, because it uses 579: the values of regno_first_uid and regno_last_uid. */ 580: if (after_regscan && GET_CODE (insn) == NOTE 581: && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG 582: && (temp1 = next_nonnote_insn (insn)) != 0 583: && simplejump_p (temp1)) 584: { 585: temp = PREV_INSN (insn); 586: if (duplicate_loop_exit_test (insn)) 587: { 588: changed = 1; 589: next = NEXT_INSN (temp); 590: continue; 591: } 592: } 593: 594: if (GET_CODE (insn) != JUMP_INSN) 595: continue; 596: 597: this_is_simplejump = simplejump_p (insn); 598: this_is_condjump = condjump_p (insn); 599: 600: /* Tension the labels in dispatch tables. */ 601: 602: if (GET_CODE (PATTERN (insn)) == ADDR_VEC) 603: changed |= tension_vector_labels (PATTERN (insn), 0); 604: if (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) 605: changed |= tension_vector_labels (PATTERN (insn), 1); 606: 607: /* If a dispatch table always goes to the same place, 608: get rid of it and replace the insn that uses it. */ 609: 610: if (GET_CODE (PATTERN (insn)) == ADDR_VEC 611: || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC) 612: { 613: int i; 614: rtx pat = PATTERN (insn); 615: int diff_vec_p = GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC; 616: int len = XVECLEN (pat, diff_vec_p); 617: rtx dispatch = prev_real_insn (insn); 618: 619: for (i = 0; i < len; i++) 620: if (XEXP (XVECEXP (pat, diff_vec_p, i), 0) 621: != XEXP (XVECEXP (pat, diff_vec_p, 0), 0)) 622: break; 623: if (i == len 1.1.1.4 ! root 624: && dispatch != 0 1.1 root 625: && GET_CODE (dispatch) == JUMP_INSN 626: && JUMP_LABEL (dispatch) != 0 627: /* Don't mess with a casesi insn. */ 628: && !(GET_CODE (PATTERN (dispatch)) == SET 629: && (GET_CODE (SET_SRC (PATTERN (dispatch))) 630: == IF_THEN_ELSE)) 631: && next_real_insn (JUMP_LABEL (dispatch)) == insn) 632: { 633: redirect_tablejump (dispatch, 634: XEXP (XVECEXP (pat, diff_vec_p, 0), 0)); 635: changed = 1; 636: } 637: } 638: 639: reallabelprev = prev_active_insn (JUMP_LABEL (insn)); 640: 641: /* If a jump references the end of the function, try to turn 642: it into a RETURN insn, possibly a conditional one. */ 643: if (JUMP_LABEL (insn) 644: && next_active_insn (JUMP_LABEL (insn)) == 0) 1.1.1.4 ! root 645: changed |= redirect_jump (insn, NULL_RTX); 1.1 root 646: 647: /* Detect jump to following insn. */ 648: if (reallabelprev == insn && condjump_p (insn)) 649: { 650: delete_jump (insn); 651: changed = 1; 652: continue; 653: } 654: 1.1.1.2 root 655: /* If we have an unconditional jump preceded by a USE, try to put 1.1 root 656: the USE before the target and jump there. This simplifies many 657: of the optimizations below since we don't have to worry about 658: dealing with these USE insns. We only do this if the label 659: being branch to already has the identical USE or if code 660: never falls through to that label. */ 661: 662: if (this_is_simplejump 663: && (temp = prev_nonnote_insn (insn)) != 0 664: && GET_CODE (temp) == INSN && GET_CODE (PATTERN (temp)) == USE 665: && (temp1 = prev_nonnote_insn (JUMP_LABEL (insn))) != 0 666: && (GET_CODE (temp1) == BARRIER 667: || (GET_CODE (temp1) == INSN 668: && rtx_equal_p (PATTERN (temp), PATTERN (temp1))))) 669: { 670: if (GET_CODE (temp1) == BARRIER) 671: { 1.1.1.4 ! root 672: emit_insn_after (PATTERN (temp), temp1); 1.1 root 673: temp1 = NEXT_INSN (temp1); 674: } 675: 1.1.1.4 ! root 676: delete_insn (temp); 1.1 root 677: redirect_jump (insn, get_label_before (temp1)); 678: reallabelprev = prev_real_insn (temp1); 679: changed = 1; 680: } 681: 682: /* Simplify if (...) x = a; else x = b; by converting it 683: to x = b; if (...) x = a; 684: if B is sufficiently simple, the test doesn't involve X, 685: and nothing in the test modifies B or X. 686: 687: If we have small register classes, we also can't do this if X 688: is a hard register. 689: 690: If the "x = b;" insn has any REG_NOTES, we don't do this because 691: of the possibility that we are running after CSE and there is a 692: REG_EQUAL note that is only valid if the branch has already been 693: taken. If we move the insn with the REG_EQUAL note, we may 694: fold the comparison to always be false in a later CSE pass. 695: (We could also delete the REG_NOTES when moving the insn, but it 696: seems simpler to not move it.) An exception is that we can move 697: the insn if the only note is a REG_EQUAL or REG_EQUIV whose 698: value is the same as "b". 699: 700: INSN is the branch over the `else' part. 701: 702: We set: 703: 1.1.1.2 root 704: TEMP to the jump insn preceding "x = a;" 1.1 root 705: TEMP1 to X 706: TEMP2 to the insn that sets "x = b;" 1.1.1.4 ! root 707: TEMP3 to the insn that sets "x = a;" ! 708: TEMP4 to the set of "x = b"; */ 1.1 root 709: 710: if (this_is_simplejump 711: && (temp3 = prev_active_insn (insn)) != 0 712: && GET_CODE (temp3) == INSN 1.1.1.4 ! root 713: && (temp4 = single_set (temp3)) != 0 ! 714: && GET_CODE (temp1 = SET_DEST (temp4)) == REG 1.1 root 715: #ifdef SMALL_REGISTER_CLASSES 716: && REGNO (temp1) >= FIRST_PSEUDO_REGISTER 717: #endif 718: && (temp2 = next_active_insn (insn)) != 0 719: && GET_CODE (temp2) == INSN 1.1.1.4 ! root 720: && (temp4 = single_set (temp2)) != 0 ! 721: && rtx_equal_p (SET_DEST (temp4), temp1) ! 722: && (GET_CODE (SET_SRC (temp4)) == REG ! 723: || GET_CODE (SET_SRC (temp4)) == SUBREG ! 724: || CONSTANT_P (SET_SRC (temp4))) 1.1 root 725: && (REG_NOTES (temp2) == 0 726: || ((REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUAL 727: || REG_NOTE_KIND (REG_NOTES (temp2)) == REG_EQUIV) 728: && XEXP (REG_NOTES (temp2), 1) == 0 729: && rtx_equal_p (XEXP (REG_NOTES (temp2), 0), 1.1.1.4 ! root 730: SET_SRC (temp4)))) 1.1 root 731: && (temp = prev_active_insn (temp3)) != 0 732: && condjump_p (temp) && ! simplejump_p (temp) 733: /* TEMP must skip over the "x = a;" insn */ 734: && prev_real_insn (JUMP_LABEL (temp)) == insn 735: && no_labels_between_p (insn, JUMP_LABEL (temp)) 736: /* There must be no other entries to the "x = b;" insn. */ 737: && no_labels_between_p (JUMP_LABEL (temp), temp2) 738: /* INSN must either branch to the insn after TEMP2 or the insn 739: after TEMP2 must branch to the same place as INSN. */ 740: && (reallabelprev == temp2 1.1.1.4 ! root 741: || ((temp5 = next_active_insn (temp2)) != 0 ! 742: && simplejump_p (temp5) ! 743: && JUMP_LABEL (temp5) == JUMP_LABEL (insn)))) 1.1 root 744: { 745: /* The test expression, X, may be a complicated test with 746: multiple branches. See if we can find all the uses of 747: the label that TEMP branches to without hitting a CALL_INSN 748: or a jump to somewhere else. */ 749: rtx target = JUMP_LABEL (temp); 750: int nuses = LABEL_NUSES (target); 751: rtx p, q; 752: 753: /* Set P to the first jump insn that goes around "x = a;". */ 754: for (p = temp; nuses && p; p = prev_nonnote_insn (p)) 755: { 756: if (GET_CODE (p) == JUMP_INSN) 757: { 758: if (condjump_p (p) && ! simplejump_p (p) 759: && JUMP_LABEL (p) == target) 760: { 761: nuses--; 762: if (nuses == 0) 763: break; 764: } 765: else 766: break; 767: } 768: else if (GET_CODE (p) == CALL_INSN) 769: break; 770: } 771: 772: #ifdef HAVE_cc0 773: /* We cannot insert anything between a set of cc and its use 774: so if P uses cc0, we must back up to the previous insn. */ 775: q = prev_nonnote_insn (p); 776: if (q && GET_RTX_CLASS (GET_CODE (q)) == 'i' 777: && sets_cc0_p (PATTERN (q))) 778: p = q; 779: #endif 780: 781: if (p) 782: p = PREV_INSN (p); 783: 784: /* If we found all the uses and there was no data conflict, we 785: can move the assignment unless we can branch into the middle 786: from somewhere. */ 787: if (nuses == 0 && p 788: && no_labels_between_p (p, insn) 789: && ! reg_referenced_between_p (temp1, p, NEXT_INSN (temp3)) 790: && ! reg_set_between_p (temp1, p, temp3) 1.1.1.4 ! root 791: && (GET_CODE (SET_SRC (temp4)) == CONST_INT ! 792: || ! reg_set_between_p (SET_SRC (temp4), p, temp2))) 1.1 root 793: { 1.1.1.4 ! root 794: emit_insn_after_with_line_notes (PATTERN (temp2), p, temp2); ! 795: delete_insn (temp2); 1.1 root 796: 797: /* Set NEXT to an insn that we know won't go away. */ 798: next = next_active_insn (insn); 799: 800: /* Delete the jump around the set. Note that we must do 801: this before we redirect the test jumps so that it won't 802: delete the code immediately following the assignment 803: we moved (which might be a jump). */ 804: 805: delete_insn (insn); 806: 807: /* We either have two consecutive labels or a jump to 808: a jump, so adjust all the JUMP_INSNs to branch to where 809: INSN branches to. */ 810: for (p = NEXT_INSN (p); p != next; p = NEXT_INSN (p)) 811: if (GET_CODE (p) == JUMP_INSN) 812: redirect_jump (p, target); 813: 814: changed = 1; 815: continue; 816: } 817: } 818: 1.1.1.4 ! root 819: #ifndef HAVE_cc0 ! 820: /* If we have if (...) x = exp; and branches are expensive, ! 821: EXP is a single insn, does not have any side effects, cannot ! 822: trap, and is not too costly, convert this to ! 823: t = exp; if (...) x = t; ! 824: ! 825: Don't do this when we have CC0 because it is unlikely to help ! 826: and we'd need to worry about where to place the new insn and ! 827: the potential for conflicts. We also can't do this when we have ! 828: notes on the insn for the same reason as above. ! 829: ! 830: We set: ! 831: ! 832: TEMP to the "x = exp;" insn. ! 833: TEMP1 to the single set in the "x = exp; insn. ! 834: TEMP2 to "x". */ ! 835: ! 836: if (! reload_completed ! 837: && this_is_condjump && ! this_is_simplejump ! 838: && BRANCH_COST >= 3 ! 839: && (temp = next_nonnote_insn (insn)) != 0 ! 840: && GET_CODE (temp) == INSN ! 841: && REG_NOTES (temp) == 0 ! 842: && (reallabelprev == temp ! 843: || ((temp2 = next_active_insn (temp)) != 0 ! 844: && simplejump_p (temp2) ! 845: && JUMP_LABEL (temp2) == JUMP_LABEL (insn))) ! 846: && (temp1 = single_set (temp)) != 0 ! 847: && (temp2 = SET_DEST (temp1), GET_CODE (temp2) == REG) ! 848: && GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT ! 849: #ifdef SMALL_REGISTER_CLASSES ! 850: && REGNO (temp2) >= FIRST_PSEUDO_REGISTER ! 851: #endif ! 852: && GET_CODE (SET_SRC (temp1)) != REG ! 853: && GET_CODE (SET_SRC (temp1)) != SUBREG ! 854: && GET_CODE (SET_SRC (temp1)) != CONST_INT ! 855: && ! side_effects_p (SET_SRC (temp1)) ! 856: && ! may_trap_p (SET_SRC (temp1)) ! 857: && rtx_cost (SET_SRC (temp1)) < 10) ! 858: { ! 859: rtx new = gen_reg_rtx (GET_MODE (temp2)); ! 860: ! 861: if (validate_change (temp, &SET_DEST (temp1), new, 0)) ! 862: { ! 863: next = emit_insn_after (gen_move_insn (temp2, new), insn); ! 864: emit_insn_after_with_line_notes (PATTERN (temp), ! 865: PREV_INSN (insn), temp); ! 866: delete_insn (temp); ! 867: } ! 868: } ! 869: ! 870: /* Similarly, if it takes two insns to compute EXP but they ! 871: have the same destination. Here TEMP3 will be the second ! 872: insn and TEMP4 the SET from that insn. */ ! 873: ! 874: if (! reload_completed ! 875: && this_is_condjump && ! this_is_simplejump ! 876: && BRANCH_COST >= 4 ! 877: && (temp = next_nonnote_insn (insn)) != 0 ! 878: && GET_CODE (temp) == INSN ! 879: && REG_NOTES (temp) == 0 ! 880: && (temp3 = next_nonnote_insn (temp)) != 0 ! 881: && GET_CODE (temp3) == INSN ! 882: && REG_NOTES (temp3) == 0 ! 883: && (reallabelprev == temp3 ! 884: || ((temp2 = next_active_insn (temp3)) != 0 ! 885: && simplejump_p (temp2) ! 886: && JUMP_LABEL (temp2) == JUMP_LABEL (insn))) ! 887: && (temp1 = single_set (temp)) != 0 ! 888: && (temp2 = SET_DEST (temp1), GET_CODE (temp2) == REG) ! 889: && GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT ! 890: #ifdef SMALL_REGISTER_CLASSES ! 891: && REGNO (temp2) >= FIRST_PSEUDO_REGISTER ! 892: #endif ! 893: && ! side_effects_p (SET_SRC (temp1)) ! 894: && ! may_trap_p (SET_SRC (temp1)) ! 895: && rtx_cost (SET_SRC (temp1)) < 10 ! 896: && (temp4 = single_set (temp3)) != 0 ! 897: && rtx_equal_p (SET_DEST (temp4), temp2) ! 898: && ! side_effects_p (SET_SRC (temp4)) ! 899: && ! may_trap_p (SET_SRC (temp4)) ! 900: && rtx_cost (SET_SRC (temp4)) < 10) ! 901: { ! 902: rtx new = gen_reg_rtx (GET_MODE (temp2)); ! 903: ! 904: if (validate_change (temp, &SET_DEST (temp1), new, 0)) ! 905: { ! 906: next = emit_insn_after (gen_move_insn (temp2, new), insn); ! 907: emit_insn_after_with_line_notes (PATTERN (temp), ! 908: PREV_INSN (insn), temp); ! 909: emit_insn_after_with_line_notes ! 910: (replace_rtx (PATTERN (temp3), temp2, new), ! 911: PREV_INSN (insn), temp3); ! 912: delete_insn (temp); ! 913: delete_insn (temp3); ! 914: } ! 915: } ! 916: ! 917: /* Finally, handle the case where two insns are used to ! 918: compute EXP but a temporary register is used. Here we must ! 919: ensure that the temporary register is not used anywhere else. */ ! 920: ! 921: if (! reload_completed ! 922: && after_regscan ! 923: && this_is_condjump && ! this_is_simplejump ! 924: && BRANCH_COST >= 4 ! 925: && (temp = next_nonnote_insn (insn)) != 0 ! 926: && GET_CODE (temp) == INSN ! 927: && REG_NOTES (temp) == 0 ! 928: && (temp3 = next_nonnote_insn (temp)) != 0 ! 929: && GET_CODE (temp3) == INSN ! 930: && REG_NOTES (temp3) == 0 ! 931: && (reallabelprev == temp3 ! 932: || ((temp2 = next_active_insn (temp3)) != 0 ! 933: && simplejump_p (temp2) ! 934: && JUMP_LABEL (temp2) == JUMP_LABEL (insn))) ! 935: && (temp1 = single_set (temp)) != 0 ! 936: && (temp5 = SET_DEST (temp1), GET_CODE (temp5) == REG) ! 937: && REGNO (temp5) >= FIRST_PSEUDO_REGISTER ! 938: && regno_first_uid[REGNO (temp5)] == INSN_UID (temp) ! 939: && regno_last_uid[REGNO (temp5)] == INSN_UID (temp3) ! 940: && ! side_effects_p (SET_SRC (temp1)) ! 941: && ! may_trap_p (SET_SRC (temp1)) ! 942: && rtx_cost (SET_SRC (temp1)) < 10 ! 943: && (temp4 = single_set (temp3)) != 0 ! 944: && (temp2 = SET_DEST (temp4), GET_CODE (temp2) == REG) ! 945: && GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT ! 946: #ifdef SMALL_REGISTER_CLASSES ! 947: && REGNO (temp2) >= FIRST_PSEUDO_REGISTER ! 948: #endif ! 949: && rtx_equal_p (SET_DEST (temp4), temp2) ! 950: && ! side_effects_p (SET_SRC (temp4)) ! 951: && ! may_trap_p (SET_SRC (temp4)) ! 952: && rtx_cost (SET_SRC (temp4)) < 10) ! 953: { ! 954: rtx new = gen_reg_rtx (GET_MODE (temp2)); ! 955: ! 956: if (validate_change (temp3, &SET_DEST (temp4), new, 0)) ! 957: { ! 958: next = emit_insn_after (gen_move_insn (temp2, new), insn); ! 959: emit_insn_after_with_line_notes (PATTERN (temp), ! 960: PREV_INSN (insn), temp); ! 961: emit_insn_after_with_line_notes (PATTERN (temp3), ! 962: PREV_INSN (insn), temp3); ! 963: delete_insn (temp); ! 964: delete_insn (temp3); ! 965: } ! 966: } ! 967: #endif /* HAVE_cc0 */ ! 968: ! 969: /* We deal with four cases: ! 970: ! 971: 1) x = a; if (...) x = b; and either A or B is zero, ! 972: 2) if (...) x = 0; and jumps are expensive, ! 973: 3) x = a; if (...) x = b; and A and B are constants where all the ! 974: set bits in A are also set in B and jumps are expensive, and ! 975: 4) x = a; if (...) x = b; and A and B non-zero, and jumps are ! 976: more expensive. ! 977: 5) if (...) x = b; if jumps are even more expensive. ! 978: ! 979: In each of these try to use a store-flag insn to avoid the jump. ! 980: (If the jump would be faster, the machine should not have ! 981: defined the scc insns!). These cases are often made by the ! 982: previous optimization. 1.1 root 983: 984: INSN here is the jump around the store. We set: 985: 986: TEMP to the "x = b;" insn. 987: TEMP1 to X. 988: TEMP2 to B (const0_rtx in the second case). 989: TEMP3 to A (X in the second case). 990: TEMP4 to the condition being tested. 991: TEMP5 to the earliest insn used to find the condition. */ 992: 993: if (/* We can't do this after reload has completed. */ 994: ! reload_completed 995: && this_is_condjump && ! this_is_simplejump 996: /* Set TEMP to the "x = b;" insn. */ 997: && (temp = next_nonnote_insn (insn)) != 0 998: && GET_CODE (temp) == INSN 999: && GET_CODE (PATTERN (temp)) == SET 1000: && GET_CODE (temp1 = SET_DEST (PATTERN (temp))) == REG 1001: #ifdef SMALL_REGISTER_CLASSES 1002: && REGNO (temp1) >= FIRST_PSEUDO_REGISTER 1003: #endif 1004: && GET_MODE_CLASS (GET_MODE (temp1)) == MODE_INT 1005: && (GET_CODE (temp2 = SET_SRC (PATTERN (temp))) == REG 1.1.1.4 ! root 1006: || GET_CODE (temp2) == SUBREG 1.1 root 1007: || GET_CODE (temp2) == CONST_INT) 1.1.1.4 ! root 1008: /* Allow either form, but prefer the former if both apply. ! 1009: There is no point in using the old value of TEMP1 if ! 1010: it is a register, since cse will alias them. It can ! 1011: lose if the old value were a hard register since CSE ! 1012: won't replace hard registers. */ 1.1 root 1013: && (((temp3 = reg_set_last (temp1, insn)) != 0 1.1.1.4 ! root 1014: && GET_CODE (temp3) == CONST_INT) 1.1 root 1015: /* Make the latter case look like x = x; if (...) x = 0; */ 1.1.1.4 ! root 1016: || (temp3 = temp1, ! 1017: ((BRANCH_COST >= 2 ! 1018: && temp2 == const0_rtx) ! 1019: || BRANCH_COST >= 3))) 1.1 root 1020: /* INSN must either branch to the insn after TEMP or the insn 1021: after TEMP must branch to the same place as INSN. */ 1022: && (reallabelprev == temp 1023: || ((temp4 = next_active_insn (temp)) != 0 1024: && simplejump_p (temp4) 1025: && JUMP_LABEL (temp4) == JUMP_LABEL (insn))) 1026: && (temp4 = get_condition (insn, &temp5)) != 0 1.1.1.4 ! root 1027: /* We must be comparing objects whose modes imply the size. ! 1028: We could handle BLKmode if (1) emit_store_flag could ! 1029: and (2) we could find the size reliably. */ ! 1030: && GET_MODE (XEXP (temp4, 0)) != BLKmode ! 1031: ! 1032: /* If B is zero, OK; if A is zero, can only do (1) if we ! 1033: can reverse the condition. See if (3) applies possibly ! 1034: by reversing the condition. Prefer reversing to (4) when ! 1035: branches are very expensive. */ ! 1036: && ((reversep = 0, temp2 == const0_rtx) 1.1 root 1037: || (temp3 == const0_rtx 1.1.1.4 ! root 1038: && (reversep = can_reverse_comparison_p (temp4, insn))) ! 1039: || (BRANCH_COST >= 2 ! 1040: && GET_CODE (temp2) == CONST_INT ! 1041: && GET_CODE (temp3) == CONST_INT ! 1042: && ((INTVAL (temp2) & INTVAL (temp3)) == INTVAL (temp2) ! 1043: || ((INTVAL (temp2) & INTVAL (temp3)) == INTVAL (temp3) ! 1044: && (reversep = can_reverse_comparison_p (temp4, ! 1045: insn))))) ! 1046: || BRANCH_COST >= 3) ! 1047: #ifdef HAVE_cc0 ! 1048: /* If the previous insn sets CC0 and something else, we can't ! 1049: do this since we are going to delete that insn. */ ! 1050: ! 1051: && ! ((temp6 = prev_nonnote_insn (insn)) != 0 ! 1052: && GET_CODE (temp6) == INSN ! 1053: && (sets_cc0_p (PATTERN (temp6)) == -1 ! 1054: || (sets_cc0_p (PATTERN (temp6)) == 1 ! 1055: && FIND_REG_INC_NOTE (temp6, NULL_RTX)))) ! 1056: #endif ! 1057: ) 1.1 root 1058: { 1059: enum rtx_code code = GET_CODE (temp4); 1.1.1.4 ! root 1060: rtx uval, cval, var = temp1; 1.1 root 1061: int normalizep; 1062: rtx target; 1063: 1064: /* If necessary, reverse the condition. */ 1.1.1.4 ! root 1065: if (reversep) ! 1066: code = reverse_condition (code), uval = temp2, cval = temp3; ! 1067: else ! 1068: uval = temp3, cval = temp2; 1.1 root 1069: 1070: /* See if we can do this with a store-flag insn. */ 1071: start_sequence (); 1072: 1.1.1.4 ! root 1073: /* If CVAL is non-zero, normalize to -1. Otherwise, ! 1074: if UVAL is the constant 1, it is best to just compute ! 1075: the result directly. If UVAL is constant and STORE_FLAG_VALUE 1.1 root 1076: includes all of its bits, it is best to compute the flag 1.1.1.4 ! root 1077: value unnormalized and `and' it with UVAL. Otherwise, ! 1078: normalize to -1 and `and' with UVAL. */ ! 1079: normalizep = (cval != const0_rtx ? -1 ! 1080: : (uval == const1_rtx ? 1 ! 1081: : (GET_CODE (uval) == CONST_INT ! 1082: && (INTVAL (uval) & ~STORE_FLAG_VALUE) == 0) ! 1083: ? 0 : -1)); 1.1 root 1084: 1085: /* We will be putting the store-flag insn immediately in 1086: front of the comparison that was originally being done, 1087: so we know all the variables in TEMP4 will be valid. 1088: However, this might be in front of the assignment of 1089: A to VAR. If it is, it would clobber the store-flag 1090: we will be emitting. 1091: 1092: Therefore, emit into a temporary which will be copied to 1093: VAR immediately after TEMP. */ 1094: 1095: target = emit_store_flag (gen_reg_rtx (GET_MODE (var)), code, 1096: XEXP (temp4, 0), XEXP (temp4, 1), 1097: VOIDmode, 1098: (code == LTU || code == LEU 1099: || code == GEU || code == GTU), 1100: normalizep); 1101: if (target) 1102: { 1.1.1.4 ! root 1103: rtx before = insn; 1.1 root 1104: rtx seq; 1105: 1.1.1.4 ! root 1106: /* Put the store-flag insns in front of the first insn ! 1107: used to compute the condition to ensure that we ! 1108: use the same values of them as the current ! 1109: comparison. However, the remainder of the insns we ! 1110: generate will be placed directly in front of the ! 1111: jump insn, in case any of the pseudos we use ! 1112: are modified earlier. */ ! 1113: ! 1114: seq = get_insns (); ! 1115: end_sequence (); ! 1116: ! 1117: emit_insns_before (seq, temp5); ! 1118: ! 1119: start_sequence (); ! 1120: ! 1121: /* Both CVAL and UVAL are non-zero. */ ! 1122: if (cval != const0_rtx && uval != const0_rtx) ! 1123: { ! 1124: rtx tem1, tem2; ! 1125: ! 1126: tem1 = expand_and (uval, target, NULL_RTX); ! 1127: if (GET_CODE (cval) == CONST_INT ! 1128: && GET_CODE (uval) == CONST_INT ! 1129: && (INTVAL (cval) & INTVAL (uval)) == INTVAL (cval)) ! 1130: tem2 = cval; ! 1131: else ! 1132: { ! 1133: tem2 = expand_unop (GET_MODE (var), one_cmpl_optab, ! 1134: target, NULL_RTX, 0); ! 1135: tem2 = expand_and (cval, tem2, ! 1136: (GET_CODE (tem2) == REG ! 1137: ? tem2 : 0)); ! 1138: } ! 1139: ! 1140: /* If we usually make new pseudos, do so here. This ! 1141: turns out to help machines that have conditional ! 1142: move insns. */ ! 1143: ! 1144: if (flag_expensive_optimizations) ! 1145: target = 0; ! 1146: ! 1147: target = expand_binop (GET_MODE (var), ior_optab, ! 1148: tem1, tem2, target, ! 1149: 1, OPTAB_WIDEN); ! 1150: } ! 1151: else if (normalizep != 1) ! 1152: target = expand_and (uval, target, 1.1 root 1153: (GET_CODE (target) == REG 1.1.1.4 ! root 1154: && ! preserve_subexpressions_p () ! 1155: ? target : NULL_RTX)); ! 1156: ! 1157: emit_move_insn (var, target); ! 1158: seq = get_insns (); 1.1 root 1159: end_sequence (); 1.1.1.4 ! root 1160: 1.1 root 1161: #ifdef HAVE_cc0 1.1.1.4 ! root 1162: /* If INSN uses CC0, we must not separate it from the ! 1163: insn that sets cc0. */ ! 1164: ! 1165: if (reg_mentioned_p (cc0_rtx, PATTERN (before))) ! 1166: before = prev_nonnote_insn (before); 1.1 root 1167: #endif 1.1.1.4 ! root 1168: ! 1169: emit_insns_before (seq, before); ! 1170: ! 1171: delete_insn (temp); ! 1172: next = NEXT_INSN (insn); ! 1173: ! 1174: delete_jump (insn); 1.1 root 1175: changed = 1; 1176: continue; 1177: } 1178: else 1179: end_sequence (); 1180: } 1181: 1182: /* If branches are expensive, convert 1183: if (foo) bar++; to bar += (foo != 0); 1184: and similarly for "bar--;" 1185: 1186: INSN is the conditional branch around the arithmetic. We set: 1187: 1188: TEMP is the arithmetic insn. 1.1.1.3 root 1189: TEMP1 is the SET doing the arithmetic. 1.1 root 1190: TEMP2 is the operand being incremented or decremented. 1191: TEMP3 to the condition being tested. 1192: TEMP4 to the earliest insn used to find the condition. */ 1193: 1194: if (BRANCH_COST >= 2 1195: && ! reload_completed 1196: && this_is_condjump && ! this_is_simplejump 1197: && (temp = next_nonnote_insn (insn)) != 0 1198: && (temp1 = single_set (temp)) != 0 1199: && (temp2 = SET_DEST (temp1), 1200: GET_MODE_CLASS (GET_MODE (temp2)) == MODE_INT) 1201: && GET_CODE (SET_SRC (temp1)) == PLUS 1202: && (XEXP (SET_SRC (temp1), 1) == const1_rtx 1203: || XEXP (SET_SRC (temp1), 1) == constm1_rtx) 1204: && rtx_equal_p (temp2, XEXP (SET_SRC (temp1), 0)) 1205: /* INSN must either branch to the insn after TEMP or the insn 1206: after TEMP must branch to the same place as INSN. */ 1207: && (reallabelprev == temp 1208: || ((temp3 = next_active_insn (temp)) != 0 1209: && simplejump_p (temp3) 1210: && JUMP_LABEL (temp3) == JUMP_LABEL (insn))) 1211: && (temp3 = get_condition (insn, &temp4)) != 0 1.1.1.4 ! root 1212: /* We must be comparing objects whose modes imply the size. ! 1213: We could handle BLKmode if (1) emit_store_flag could ! 1214: and (2) we could find the size reliably. */ ! 1215: && GET_MODE (XEXP (temp3, 0)) != BLKmode 1.1 root 1216: && can_reverse_comparison_p (temp3, insn)) 1217: { 1.1.1.3 root 1218: rtx temp6, target = 0, seq, init_insn = 0, init = temp2; 1.1 root 1219: enum rtx_code code = reverse_condition (GET_CODE (temp3)); 1220: 1221: start_sequence (); 1222: 1.1.1.3 root 1223: /* It must be the case that TEMP2 is not modified in the range 1224: [TEMP4, INSN). The one exception we make is if the insn 1225: before INSN sets TEMP2 to something which is also unchanged 1226: in that range. In that case, we can move the initialization 1227: into our sequence. */ 1228: 1229: if ((temp5 = prev_active_insn (insn)) != 0 1230: && GET_CODE (temp5) == INSN 1231: && (temp6 = single_set (temp5)) != 0 1232: && rtx_equal_p (temp2, SET_DEST (temp6)) 1233: && (CONSTANT_P (SET_SRC (temp6)) 1234: || GET_CODE (SET_SRC (temp6)) == REG 1235: || GET_CODE (SET_SRC (temp6)) == SUBREG)) 1236: { 1237: emit_insn (PATTERN (temp5)); 1238: init_insn = temp5; 1239: init = SET_SRC (temp6); 1240: } 1241: 1242: if (CONSTANT_P (init) 1243: || ! reg_set_between_p (init, PREV_INSN (temp4), insn)) 1244: target = emit_store_flag (gen_reg_rtx (GET_MODE (temp2)), code, 1245: XEXP (temp3, 0), XEXP (temp3, 1), 1246: VOIDmode, 1247: (code == LTU || code == LEU 1248: || code == GTU || code == GEU), 1); 1.1 root 1249: 1250: /* If we can do the store-flag, do the addition or 1251: subtraction. */ 1252: 1253: if (target) 1254: target = expand_binop (GET_MODE (temp2), 1255: (XEXP (SET_SRC (temp1), 1) == const1_rtx 1256: ? add_optab : sub_optab), 1257: temp2, target, temp2, OPTAB_WIDEN); 1258: 1259: if (target != 0) 1260: { 1261: /* Put the result back in temp2 in case it isn't already. 1262: Then replace the jump, possible a CC0-setting insn in 1263: front of the jump, and TEMP, with the sequence we have 1264: made. */ 1265: 1266: if (target != temp2) 1267: emit_move_insn (temp2, target); 1268: 1269: seq = get_insns (); 1270: end_sequence (); 1271: 1272: emit_insns_before (seq, temp4); 1273: delete_insn (temp); 1.1.1.3 root 1274: 1275: if (init_insn) 1276: delete_insn (init_insn); 1277: 1.1 root 1278: next = NEXT_INSN (insn); 1279: #ifdef HAVE_cc0 1280: delete_insn (prev_nonnote_insn (insn)); 1281: #endif 1282: delete_insn (insn); 1283: changed = 1; 1284: continue; 1285: } 1286: else 1287: end_sequence (); 1288: } 1289: 1290: /* Simplify if (...) x = 1; else {...} if (x) ... 1291: We recognize this case scanning backwards as well. 1292: 1293: TEMP is the assignment to x; 1294: TEMP1 is the label at the head of the second if. */ 1295: /* ?? This should call get_condition to find the values being 1296: compared, instead of looking for a COMPARE insn when HAVE_cc0 1297: is not defined. This would allow it to work on the m88k. */ 1298: /* ?? This optimization is only safe before cse is run if HAVE_cc0 1299: is not defined and the condition is tested by a separate compare 1300: insn. This is because the code below assumes that the result 1301: of the compare dies in the following branch. 1302: 1303: Not only that, but there might be other insns between the 1304: compare and branch whose results are live. Those insns need 1305: to be executed. 1306: 1307: A way to fix this is to move the insns at JUMP_LABEL (insn) 1308: to before INSN. If we are running before flow, they will 1309: be deleted if they aren't needed. But this doesn't work 1310: well after flow. 1311: 1312: This is really a special-case of jump threading, anyway. The 1313: right thing to do is to replace this and jump threading with 1314: much simpler code in cse. 1315: 1316: This code has been turned off in the non-cc0 case in the 1317: meantime. */ 1318: 1319: #ifdef HAVE_cc0 1320: else if (this_is_simplejump 1321: /* Safe to skip USE and CLOBBER insns here 1322: since they will not be deleted. */ 1323: && (temp = prev_active_insn (insn)) 1324: && no_labels_between_p (temp, insn) 1325: && GET_CODE (temp) == INSN 1326: && GET_CODE (PATTERN (temp)) == SET 1327: && GET_CODE (SET_DEST (PATTERN (temp))) == REG 1328: && CONSTANT_P (SET_SRC (PATTERN (temp))) 1329: && (temp1 = next_active_insn (JUMP_LABEL (insn))) 1330: /* If we find that the next value tested is `x' 1331: (TEMP1 is the insn where this happens), win. */ 1332: && GET_CODE (temp1) == INSN 1333: && GET_CODE (PATTERN (temp1)) == SET 1334: #ifdef HAVE_cc0 1335: /* Does temp1 `tst' the value of x? */ 1336: && SET_SRC (PATTERN (temp1)) == SET_DEST (PATTERN (temp)) 1337: && SET_DEST (PATTERN (temp1)) == cc0_rtx 1338: && (temp1 = next_nonnote_insn (temp1)) 1339: #else 1340: /* Does temp1 compare the value of x against zero? */ 1341: && GET_CODE (SET_SRC (PATTERN (temp1))) == COMPARE 1342: && XEXP (SET_SRC (PATTERN (temp1)), 1) == const0_rtx 1343: && (XEXP (SET_SRC (PATTERN (temp1)), 0) 1344: == SET_DEST (PATTERN (temp))) 1345: && GET_CODE (SET_DEST (PATTERN (temp1))) == REG 1346: && (temp1 = find_next_ref (SET_DEST (PATTERN (temp1)), temp1)) 1347: #endif 1348: && condjump_p (temp1)) 1349: { 1350: /* Get the if_then_else from the condjump. */ 1351: rtx choice = SET_SRC (PATTERN (temp1)); 1352: if (GET_CODE (choice) == IF_THEN_ELSE) 1353: { 1354: enum rtx_code code = GET_CODE (XEXP (choice, 0)); 1355: rtx val = SET_SRC (PATTERN (temp)); 1356: rtx cond 1357: = simplify_relational_operation (code, GET_MODE (SET_DEST (PATTERN (temp))), 1358: val, const0_rtx); 1359: rtx ultimate; 1360: 1361: if (cond == const_true_rtx) 1362: ultimate = XEXP (choice, 1); 1363: else if (cond == const0_rtx) 1364: ultimate = XEXP (choice, 2); 1365: else 1366: ultimate = 0; 1367: 1368: if (ultimate == pc_rtx) 1369: ultimate = get_label_after (temp1); 1370: else if (ultimate && GET_CODE (ultimate) != RETURN) 1371: ultimate = XEXP (ultimate, 0); 1372: 1373: if (ultimate) 1374: changed |= redirect_jump (insn, ultimate); 1375: } 1376: } 1377: #endif 1378: 1379: #if 0 1380: /* @@ This needs a bit of work before it will be right. 1381: 1382: Any type of comparison can be accepted for the first and 1383: second compare. When rewriting the first jump, we must 1384: compute the what conditions can reach label3, and use the 1385: appropriate code. We can not simply reverse/swap the code 1386: of the first jump. In some cases, the second jump must be 1387: rewritten also. 1388: 1389: For example, 1390: < == converts to > == 1391: < != converts to == > 1392: etc. 1393: 1394: If the code is written to only accept an '==' test for the second 1395: compare, then all that needs to be done is to swap the condition 1396: of the first branch. 1397: 1398: It is questionable whether we want this optimization anyways, 1399: since if the user wrote code like this because he/she knew that 1.1.1.3 root 1400: the jump to label1 is taken most of the time, then rewriting 1.1 root 1401: this gives slower code. */ 1402: /* @@ This should call get_condition to find the values being 1403: compared, instead of looking for a COMPARE insn when HAVE_cc0 1404: is not defined. This would allow it to work on the m88k. */ 1405: /* @@ This optimization is only safe before cse is run if HAVE_cc0 1406: is not defined and the condition is tested by a separate compare 1407: insn. This is because the code below assumes that the result 1408: of the compare dies in the following branch. */ 1409: 1410: /* Simplify test a ~= b 1411: condjump label1; 1412: test a == b 1413: condjump label2; 1414: jump label3; 1415: label1: 1416: 1417: rewriting as 1418: test a ~~= b 1419: condjump label3 1420: test a == b 1421: condjump label2 1422: label1: 1423: 1424: where ~= is an inequality, e.g. >, and ~~= is the swapped 1425: inequality, e.g. <. 1426: 1427: We recognize this case scanning backwards. 1428: 1429: TEMP is the conditional jump to `label2'; 1430: TEMP1 is the test for `a == b'; 1431: TEMP2 is the conditional jump to `label1'; 1432: TEMP3 is the test for `a ~= b'. */ 1433: else if (this_is_simplejump 1434: && (temp = prev_active_insn (insn)) 1435: && no_labels_between_p (temp, insn) 1436: && condjump_p (temp) 1437: && (temp1 = prev_active_insn (temp)) 1438: && no_labels_between_p (temp1, temp) 1439: && GET_CODE (temp1) == INSN 1440: && GET_CODE (PATTERN (temp1)) == SET 1441: #ifdef HAVE_cc0 1442: && sets_cc0_p (PATTERN (temp1)) == 1 1443: #else 1444: && GET_CODE (SET_SRC (PATTERN (temp1))) == COMPARE 1445: && GET_CODE (SET_DEST (PATTERN (temp1))) == REG 1446: && (temp == find_next_ref (SET_DEST (PATTERN (temp1)), temp1)) 1447: #endif 1448: && (temp2 = prev_active_insn (temp1)) 1449: && no_labels_between_p (temp2, temp1) 1450: && condjump_p (temp2) 1451: && JUMP_LABEL (temp2) == next_nonnote_insn (NEXT_INSN (insn)) 1452: && (temp3 = prev_active_insn (temp2)) 1453: && no_labels_between_p (temp3, temp2) 1454: && GET_CODE (PATTERN (temp3)) == SET 1455: && rtx_equal_p (SET_DEST (PATTERN (temp3)), 1456: SET_DEST (PATTERN (temp1))) 1457: && rtx_equal_p (SET_SRC (PATTERN (temp1)), 1458: SET_SRC (PATTERN (temp3))) 1459: && ! inequality_comparisons_p (PATTERN (temp)) 1460: && inequality_comparisons_p (PATTERN (temp2))) 1461: { 1462: rtx fallthrough_label = JUMP_LABEL (temp2); 1463: 1464: ++LABEL_NUSES (fallthrough_label); 1465: if (swap_jump (temp2, JUMP_LABEL (insn))) 1466: { 1467: delete_insn (insn); 1468: changed = 1; 1469: } 1470: 1471: if (--LABEL_NUSES (fallthrough_label) == 0) 1472: delete_insn (fallthrough_label); 1473: } 1474: #endif 1475: /* Simplify if (...) {... x = 1;} if (x) ... 1476: 1477: We recognize this case backwards. 1478: 1479: TEMP is the test of `x'; 1480: TEMP1 is the assignment to `x' at the end of the 1481: previous statement. */ 1482: /* @@ This should call get_condition to find the values being 1483: compared, instead of looking for a COMPARE insn when HAVE_cc0 1484: is not defined. This would allow it to work on the m88k. */ 1485: /* @@ This optimization is only safe before cse is run if HAVE_cc0 1486: is not defined and the condition is tested by a separate compare 1487: insn. This is because the code below assumes that the result 1488: of the compare dies in the following branch. */ 1489: 1490: /* ??? This has to be turned off. The problem is that the 1491: unconditional jump might indirectly end up branching to the 1492: label between TEMP1 and TEMP. We can't detect this, in general, 1493: since it may become a jump to there after further optimizations. 1494: If that jump is done, it will be deleted, so we will retry 1495: this optimization in the next pass, thus an infinite loop. 1496: 1497: The present code prevents this by putting the jump after the 1498: label, but this is not logically correct. */ 1499: #if 0 1500: else if (this_is_condjump 1501: /* Safe to skip USE and CLOBBER insns here 1502: since they will not be deleted. */ 1503: && (temp = prev_active_insn (insn)) 1504: && no_labels_between_p (temp, insn) 1505: && GET_CODE (temp) == INSN 1506: && GET_CODE (PATTERN (temp)) == SET 1507: #ifdef HAVE_cc0 1508: && sets_cc0_p (PATTERN (temp)) == 1 1509: && GET_CODE (SET_SRC (PATTERN (temp))) == REG 1510: #else 1511: /* Temp must be a compare insn, we can not accept a register 1512: to register move here, since it may not be simply a 1513: tst insn. */ 1514: && GET_CODE (SET_SRC (PATTERN (temp))) == COMPARE 1515: && XEXP (SET_SRC (PATTERN (temp)), 1) == const0_rtx 1516: && GET_CODE (XEXP (SET_SRC (PATTERN (temp)), 0)) == REG 1517: && GET_CODE (SET_DEST (PATTERN (temp))) == REG 1518: && insn == find_next_ref (SET_DEST (PATTERN (temp)), temp) 1519: #endif 1520: /* May skip USE or CLOBBER insns here 1521: for checking for opportunity, since we 1522: take care of them later. */ 1523: && (temp1 = prev_active_insn (temp)) 1524: && GET_CODE (temp1) == INSN 1525: && GET_CODE (PATTERN (temp1)) == SET 1526: #ifdef HAVE_cc0 1527: && SET_SRC (PATTERN (temp)) == SET_DEST (PATTERN (temp1)) 1528: #else 1529: && (XEXP (SET_SRC (PATTERN (temp)), 0) 1530: == SET_DEST (PATTERN (temp1))) 1531: #endif 1532: && CONSTANT_P (SET_SRC (PATTERN (temp1))) 1533: /* If this isn't true, cse will do the job. */ 1534: && ! no_labels_between_p (temp1, temp)) 1535: { 1536: /* Get the if_then_else from the condjump. */ 1537: rtx choice = SET_SRC (PATTERN (insn)); 1538: if (GET_CODE (choice) == IF_THEN_ELSE 1539: && (GET_CODE (XEXP (choice, 0)) == EQ 1540: || GET_CODE (XEXP (choice, 0)) == NE)) 1541: { 1542: int want_nonzero = (GET_CODE (XEXP (choice, 0)) == NE); 1543: rtx last_insn; 1544: rtx ultimate; 1545: rtx p; 1546: 1547: /* Get the place that condjump will jump to 1548: if it is reached from here. */ 1549: if ((SET_SRC (PATTERN (temp1)) != const0_rtx) 1550: == want_nonzero) 1551: ultimate = XEXP (choice, 1); 1552: else 1553: ultimate = XEXP (choice, 2); 1554: /* Get it as a CODE_LABEL. */ 1555: if (ultimate == pc_rtx) 1556: ultimate = get_label_after (insn); 1557: else 1558: /* Get the label out of the LABEL_REF. */ 1559: ultimate = XEXP (ultimate, 0); 1560: 1561: /* Insert the jump immediately before TEMP, specifically 1562: after the label that is between TEMP1 and TEMP. */ 1563: last_insn = PREV_INSN (temp); 1564: 1565: /* If we would be branching to the next insn, the jump 1566: would immediately be deleted and the re-inserted in 1567: a subsequent pass over the code. So don't do anything 1568: in that case. */ 1569: if (next_active_insn (last_insn) 1570: != next_active_insn (ultimate)) 1571: { 1572: emit_barrier_after (last_insn); 1573: p = emit_jump_insn_after (gen_jump (ultimate), 1574: last_insn); 1575: JUMP_LABEL (p) = ultimate; 1576: ++LABEL_NUSES (ultimate); 1577: if (INSN_UID (ultimate) < max_jump_chain 1578: && INSN_CODE (p) < max_jump_chain) 1579: { 1580: jump_chain[INSN_UID (p)] 1581: = jump_chain[INSN_UID (ultimate)]; 1582: jump_chain[INSN_UID (ultimate)] = p; 1583: } 1584: changed = 1; 1585: continue; 1586: } 1587: } 1588: } 1589: #endif 1590: /* Detect a conditional jump going to the same place 1591: as an immediately following unconditional jump. */ 1592: else if (this_is_condjump 1593: && (temp = next_active_insn (insn)) != 0 1594: && simplejump_p (temp) 1595: && (next_active_insn (JUMP_LABEL (insn)) 1596: == next_active_insn (JUMP_LABEL (temp)))) 1597: { 1598: delete_jump (insn); 1599: changed = 1; 1600: continue; 1601: } 1602: /* Detect a conditional jump jumping over an unconditional jump. */ 1603: 1604: else if (this_is_condjump && ! this_is_simplejump 1605: && reallabelprev != 0 1606: && GET_CODE (reallabelprev) == JUMP_INSN 1607: && prev_active_insn (reallabelprev) == insn 1608: && no_labels_between_p (insn, reallabelprev) 1609: && simplejump_p (reallabelprev)) 1610: { 1611: /* When we invert the unconditional jump, we will be 1612: decrementing the usage count of its old label. 1613: Make sure that we don't delete it now because that 1614: might cause the following code to be deleted. */ 1615: rtx prev_uses = prev_nonnote_insn (reallabelprev); 1616: rtx prev_label = JUMP_LABEL (insn); 1617: 1618: ++LABEL_NUSES (prev_label); 1619: 1620: if (invert_jump (insn, JUMP_LABEL (reallabelprev))) 1621: { 1622: /* It is very likely that if there are USE insns before 1623: this jump, they hold REG_DEAD notes. These REG_DEAD 1624: notes are no longer valid due to this optimization, 1625: and will cause the life-analysis that following passes 1626: (notably delayed-branch scheduling) to think that 1627: these registers are dead when they are not. 1628: 1629: To prevent this trouble, we just remove the USE insns 1630: from the insn chain. */ 1631: 1632: while (prev_uses && GET_CODE (prev_uses) == INSN 1633: && GET_CODE (PATTERN (prev_uses)) == USE) 1634: { 1635: rtx useless = prev_uses; 1636: prev_uses = prev_nonnote_insn (prev_uses); 1637: delete_insn (useless); 1638: } 1639: 1640: delete_insn (reallabelprev); 1641: next = insn; 1642: changed = 1; 1643: } 1644: 1645: /* We can now safely delete the label if it is unreferenced 1646: since the delete_insn above has deleted the BARRIER. */ 1647: if (--LABEL_NUSES (prev_label) == 0) 1648: delete_insn (prev_label); 1649: continue; 1650: } 1651: else 1652: { 1653: /* Detect a jump to a jump. */ 1654: 1655: nlabel = follow_jumps (JUMP_LABEL (insn)); 1656: if (nlabel != JUMP_LABEL (insn) 1657: && redirect_jump (insn, nlabel)) 1658: { 1659: changed = 1; 1660: next = insn; 1661: } 1662: 1663: /* Look for if (foo) bar; else break; */ 1664: /* The insns look like this: 1665: insn = condjump label1; 1666: ...range1 (some insns)... 1667: jump label2; 1668: label1: 1669: ...range2 (some insns)... 1670: jump somewhere unconditionally 1671: label2: */ 1672: { 1673: rtx label1 = next_label (insn); 1674: rtx range1end = label1 ? prev_active_insn (label1) : 0; 1675: /* Don't do this optimization on the first round, so that 1676: jump-around-a-jump gets simplified before we ask here 1677: whether a jump is unconditional. 1678: 1679: Also don't do it when we are called after reload since 1680: it will confuse reorg. */ 1681: if (! first 1682: && (reload_completed ? ! flag_delayed_branch : 1) 1683: /* Make sure INSN is something we can invert. */ 1684: && condjump_p (insn) 1685: && label1 != 0 1686: && JUMP_LABEL (insn) == label1 1687: && LABEL_NUSES (label1) == 1 1688: && GET_CODE (range1end) == JUMP_INSN 1689: && simplejump_p (range1end)) 1690: { 1691: rtx label2 = next_label (label1); 1692: rtx range2end = label2 ? prev_active_insn (label2) : 0; 1693: if (range1end != range2end 1694: && JUMP_LABEL (range1end) == label2 1695: && GET_CODE (range2end) == JUMP_INSN 1696: && GET_CODE (NEXT_INSN (range2end)) == BARRIER 1697: /* Invert the jump condition, so we 1698: still execute the same insns in each case. */ 1699: && invert_jump (insn, label1)) 1700: { 1701: rtx range1beg = next_active_insn (insn); 1702: rtx range2beg = next_active_insn (label1); 1703: rtx range1after, range2after; 1704: rtx range1before, range2before; 1705: 1.1.1.2 root 1706: /* Include in each range any line number before it. */ 1707: while (PREV_INSN (range1beg) 1708: && GET_CODE (PREV_INSN (range1beg)) == NOTE 1709: && NOTE_LINE_NUMBER (PREV_INSN (range1beg)) > 0) 1710: range1beg = PREV_INSN (range1beg); 1711: 1712: while (PREV_INSN (range2beg) 1713: && GET_CODE (PREV_INSN (range2beg)) == NOTE 1714: && NOTE_LINE_NUMBER (PREV_INSN (range2beg)) > 0) 1715: range2beg = PREV_INSN (range2beg); 1716: 1.1 root 1717: /* Don't move NOTEs for blocks or loops; shift them 1718: outside the ranges, where they'll stay put. */ 1.1.1.3 root 1719: range1beg = squeeze_notes (range1beg, range1end); 1720: range2beg = squeeze_notes (range2beg, range2end); 1.1 root 1721: 1722: /* Get current surrounds of the 2 ranges. */ 1723: range1before = PREV_INSN (range1beg); 1724: range2before = PREV_INSN (range2beg); 1725: range1after = NEXT_INSN (range1end); 1726: range2after = NEXT_INSN (range2end); 1727: 1728: /* Splice range2 where range1 was. */ 1729: NEXT_INSN (range1before) = range2beg; 1730: PREV_INSN (range2beg) = range1before; 1731: NEXT_INSN (range2end) = range1after; 1732: PREV_INSN (range1after) = range2end; 1733: /* Splice range1 where range2 was. */ 1734: NEXT_INSN (range2before) = range1beg; 1735: PREV_INSN (range1beg) = range2before; 1736: NEXT_INSN (range1end) = range2after; 1737: PREV_INSN (range2after) = range1end; 1738: changed = 1; 1739: continue; 1740: } 1741: } 1742: } 1743: 1744: /* Now that the jump has been tensioned, 1745: try cross jumping: check for identical code 1746: before the jump and before its target label. */ 1747: 1748: /* First, cross jumping of conditional jumps: */ 1749: 1750: if (cross_jump && condjump_p (insn)) 1751: { 1752: rtx newjpos, newlpos; 1753: rtx x = prev_real_insn (JUMP_LABEL (insn)); 1754: 1755: /* A conditional jump may be crossjumped 1756: only if the place it jumps to follows 1757: an opposing jump that comes back here. */ 1758: 1759: if (x != 0 && ! jump_back_p (x, insn)) 1760: /* We have no opposing jump; 1761: cannot cross jump this insn. */ 1762: x = 0; 1763: 1764: newjpos = 0; 1765: /* TARGET is nonzero if it is ok to cross jump 1766: to code before TARGET. If so, see if matches. */ 1767: if (x != 0) 1768: find_cross_jump (insn, x, 2, 1769: &newjpos, &newlpos); 1770: 1771: if (newjpos != 0) 1772: { 1773: do_cross_jump (insn, newjpos, newlpos); 1774: /* Make the old conditional jump 1775: into an unconditional one. */ 1776: SET_SRC (PATTERN (insn)) 1777: = gen_rtx (LABEL_REF, VOIDmode, JUMP_LABEL (insn)); 1778: INSN_CODE (insn) = -1; 1779: emit_barrier_after (insn); 1780: /* Add to jump_chain unless this is a new label 1781: whose UID is too large. */ 1782: if (INSN_UID (JUMP_LABEL (insn)) < max_jump_chain) 1783: { 1784: jump_chain[INSN_UID (insn)] 1785: = jump_chain[INSN_UID (JUMP_LABEL (insn))]; 1786: jump_chain[INSN_UID (JUMP_LABEL (insn))] = insn; 1787: } 1788: changed = 1; 1789: next = insn; 1790: } 1791: } 1792: 1793: /* Cross jumping of unconditional jumps: 1794: a few differences. */ 1795: 1796: if (cross_jump && simplejump_p (insn)) 1797: { 1798: rtx newjpos, newlpos; 1799: rtx target; 1800: 1801: newjpos = 0; 1802: 1803: /* TARGET is nonzero if it is ok to cross jump 1804: to code before TARGET. If so, see if matches. */ 1805: find_cross_jump (insn, JUMP_LABEL (insn), 1, 1806: &newjpos, &newlpos); 1807: 1808: /* If cannot cross jump to code before the label, 1809: see if we can cross jump to another jump to 1810: the same label. */ 1811: /* Try each other jump to this label. */ 1812: if (INSN_UID (JUMP_LABEL (insn)) < max_uid) 1813: for (target = jump_chain[INSN_UID (JUMP_LABEL (insn))]; 1814: target != 0 && newjpos == 0; 1815: target = jump_chain[INSN_UID (target)]) 1816: if (target != insn 1817: && JUMP_LABEL (target) == JUMP_LABEL (insn) 1818: /* Ignore TARGET if it's deleted. */ 1819: && ! INSN_DELETED_P (target)) 1820: find_cross_jump (insn, target, 2, 1821: &newjpos, &newlpos); 1822: 1823: if (newjpos != 0) 1824: { 1825: do_cross_jump (insn, newjpos, newlpos); 1826: changed = 1; 1827: next = insn; 1828: } 1829: } 1830: 1831: /* This code was dead in the previous jump.c! */ 1832: if (cross_jump && GET_CODE (PATTERN (insn)) == RETURN) 1833: { 1834: /* Return insns all "jump to the same place" 1835: so we can cross-jump between any two of them. */ 1836: 1837: rtx newjpos, newlpos, target; 1838: 1839: newjpos = 0; 1840: 1841: /* If cannot cross jump to code before the label, 1842: see if we can cross jump to another jump to 1843: the same label. */ 1844: /* Try each other jump to this label. */ 1845: for (target = jump_chain[0]; 1846: target != 0 && newjpos == 0; 1847: target = jump_chain[INSN_UID (target)]) 1848: if (target != insn 1849: && ! INSN_DELETED_P (target) 1850: && GET_CODE (PATTERN (target)) == RETURN) 1851: find_cross_jump (insn, target, 2, 1852: &newjpos, &newlpos); 1853: 1854: if (newjpos != 0) 1855: { 1856: do_cross_jump (insn, newjpos, newlpos); 1857: changed = 1; 1858: next = insn; 1859: } 1860: } 1861: } 1862: } 1863: 1864: first = 0; 1865: } 1866: 1867: /* Delete extraneous line number notes. 1868: Note that two consecutive notes for different lines are not really 1869: extraneous. There should be some indication where that line belonged, 1870: even if it became empty. */ 1871: 1872: { 1873: rtx last_note = 0; 1874: 1875: for (insn = f; insn; insn = NEXT_INSN (insn)) 1876: if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) >= 0) 1877: { 1878: /* Delete this note if it is identical to previous note. */ 1879: if (last_note 1880: && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last_note) 1881: && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last_note)) 1882: { 1883: delete_insn (insn); 1884: continue; 1885: } 1886: 1887: last_note = insn; 1888: } 1889: } 1890: 1891: /* See if there is still a NOTE_INSN_FUNCTION_END in this function. 1892: If so, delete it, and record that this function can drop off the end. */ 1893: 1894: insn = last_insn; 1895: { 1896: int n_labels = 1; 1897: while (insn 1898: /* One label can follow the end-note: the return label. */ 1899: && ((GET_CODE (insn) == CODE_LABEL && n_labels-- > 0) 1900: /* Ordinary insns can follow it if returning a structure. */ 1901: || GET_CODE (insn) == INSN 1902: /* If machine uses explicit RETURN insns, no epilogue, 1903: then one of them follows the note. */ 1904: || (GET_CODE (insn) == JUMP_INSN 1905: && GET_CODE (PATTERN (insn)) == RETURN) 1906: /* Other kinds of notes can follow also. */ 1907: || (GET_CODE (insn) == NOTE 1908: && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END))) 1909: insn = PREV_INSN (insn); 1910: } 1911: 1912: /* Report if control can fall through at the end of the function. */ 1913: if (insn && GET_CODE (insn) == NOTE 1914: && NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END) 1915: { 1916: can_reach_end = 1; 1917: delete_insn (insn); 1918: } 1919: 1920: /* Show JUMP_CHAIN no longer valid. */ 1921: jump_chain = 0; 1922: } 1923: 1924: /* LOOP_START is a NOTE_INSN_LOOP_BEG note that is followed by an unconditional 1925: jump. Assume that this unconditional jump is to the exit test code. If 1926: the code is sufficiently simple, make a copy of it before INSN, 1927: followed by a jump to the exit of the loop. Then delete the unconditional 1928: jump after INSN. 1929: 1930: Note that it is possible we can get confused here if the jump immediately 1931: after the loop start branches outside the loop but within an outer loop. 1932: If we are near the exit of that loop, we will copy its exit test. This 1933: will not generate incorrect code, but could suppress some optimizations. 1934: However, such cases are degenerate loops anyway. 1935: 1936: Return 1 if we made the change, else 0. 1937: 1938: This is only safe immediately after a regscan pass because it uses the 1939: values of regno_first_uid and regno_last_uid. */ 1940: 1941: static int 1942: duplicate_loop_exit_test (loop_start) 1943: rtx loop_start; 1944: { 1945: rtx insn, set, p; 1946: rtx copy, link; 1947: int num_insns = 0; 1948: rtx exitcode = NEXT_INSN (JUMP_LABEL (next_nonnote_insn (loop_start))); 1949: rtx lastexit; 1950: int max_reg = max_reg_num (); 1951: rtx *reg_map = 0; 1952: 1953: /* Scan the exit code. We do not perform this optimization if any insn: 1954: 1955: is a CALL_INSN 1956: is a CODE_LABEL 1957: has a REG_RETVAL or REG_LIBCALL note (hard to adjust) 1958: is a NOTE_INSN_LOOP_BEG because this means we have a nested loop 1959: is a NOTE_INSN_BLOCK_{BEG,END} because duplicating these notes 1960: are not valid 1961: 1962: Also, don't do this if the exit code is more than 20 insns. */ 1963: 1964: for (insn = exitcode; 1965: insn 1966: && ! (GET_CODE (insn) == NOTE 1967: && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END); 1968: insn = NEXT_INSN (insn)) 1969: { 1970: switch (GET_CODE (insn)) 1971: { 1972: case CODE_LABEL: 1973: case CALL_INSN: 1974: return 0; 1975: case NOTE: 1976: if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG 1977: || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG 1978: || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END) 1979: return 0; 1980: break; 1981: case JUMP_INSN: 1982: case INSN: 1983: if (++num_insns > 20 1.1.1.4 ! root 1984: || find_reg_note (insn, REG_RETVAL, NULL_RTX) ! 1985: || find_reg_note (insn, REG_LIBCALL, NULL_RTX)) 1.1 root 1986: return 0; 1987: break; 1988: } 1989: } 1990: 1991: /* Unless INSN is zero, we can do the optimization. */ 1992: if (insn == 0) 1993: return 0; 1994: 1995: lastexit = insn; 1996: 1997: /* See if any insn sets a register only used in the loop exit code and 1998: not a user variable. If so, replace it with a new register. */ 1999: for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn)) 2000: if (GET_CODE (insn) == INSN 2001: && (set = single_set (insn)) != 0 2002: && GET_CODE (SET_DEST (set)) == REG 2003: && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER 2004: && regno_first_uid[REGNO (SET_DEST (set))] == INSN_UID (insn)) 2005: { 2006: for (p = NEXT_INSN (insn); p != lastexit; p = NEXT_INSN (p)) 2007: if (regno_last_uid[REGNO (SET_DEST (set))] == INSN_UID (p)) 2008: break; 2009: 2010: if (p != lastexit) 2011: { 2012: /* We can do the replacement. Allocate reg_map if this is the 2013: first replacement we found. */ 2014: if (reg_map == 0) 2015: { 2016: reg_map = (rtx *) alloca (max_reg * sizeof (rtx)); 2017: bzero (reg_map, max_reg * sizeof (rtx)); 2018: } 2019: 2020: REG_LOOP_TEST_P (SET_DEST (set)) = 1; 2021: 2022: reg_map[REGNO (SET_DEST (set))] 2023: = gen_reg_rtx (GET_MODE (SET_DEST (set))); 2024: } 2025: } 2026: 2027: /* Now copy each insn. */ 2028: for (insn = exitcode; insn != lastexit; insn = NEXT_INSN (insn)) 2029: switch (GET_CODE (insn)) 2030: { 2031: case BARRIER: 2032: copy = emit_barrier_before (loop_start); 2033: break; 2034: case NOTE: 2035: /* Only copy line-number notes. */ 2036: if (NOTE_LINE_NUMBER (insn) >= 0) 2037: { 2038: copy = emit_note_before (NOTE_LINE_NUMBER (insn), loop_start); 2039: NOTE_SOURCE_FILE (copy) = NOTE_SOURCE_FILE (insn); 2040: } 2041: break; 2042: 2043: case INSN: 2044: copy = emit_insn_before (copy_rtx (PATTERN (insn)), loop_start); 2045: if (reg_map) 2046: replace_regs (PATTERN (copy), reg_map, max_reg, 1); 2047: 2048: mark_jump_label (PATTERN (copy), copy, 0); 2049: 2050: /* Copy all REG_NOTES except REG_LABEL since mark_jump_label will 2051: make them. */ 2052: for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) 2053: if (REG_NOTE_KIND (link) != REG_LABEL) 2054: REG_NOTES (copy) 2055: = copy_rtx (gen_rtx (EXPR_LIST, REG_NOTE_KIND (link), 2056: XEXP (link, 0), REG_NOTES (copy))); 2057: if (reg_map && REG_NOTES (copy)) 2058: replace_regs (REG_NOTES (copy), reg_map, max_reg, 1); 2059: break; 2060: 2061: case JUMP_INSN: 2062: copy = emit_jump_insn_before (copy_rtx (PATTERN (insn)), loop_start); 2063: if (reg_map) 2064: replace_regs (PATTERN (copy), reg_map, max_reg, 1); 2065: mark_jump_label (PATTERN (copy), copy, 0); 2066: if (REG_NOTES (insn)) 2067: { 2068: REG_NOTES (copy) = copy_rtx (REG_NOTES (insn)); 2069: if (reg_map) 2070: replace_regs (REG_NOTES (copy), reg_map, max_reg, 1); 2071: } 2072: 2073: /* If this is a simple jump, add it to the jump chain. */ 2074: 2075: if (INSN_UID (copy) < max_jump_chain && JUMP_LABEL (copy) 2076: && simplejump_p (copy)) 2077: { 2078: jump_chain[INSN_UID (copy)] 2079: = jump_chain[INSN_UID (JUMP_LABEL (copy))]; 2080: jump_chain[INSN_UID (JUMP_LABEL (copy))] = copy; 2081: } 2082: break; 2083: 2084: default: 2085: abort (); 2086: } 2087: 2088: /* Now clean up by emitting a jump to the end label and deleting the jump 2089: at the start of the loop. */ 2090: if (GET_CODE (copy) != BARRIER) 2091: { 2092: copy = emit_jump_insn_before (gen_jump (get_label_after (insn)), 2093: loop_start); 2094: mark_jump_label (PATTERN (copy), copy, 0); 2095: if (INSN_UID (copy) < max_jump_chain 2096: && INSN_UID (JUMP_LABEL (copy)) < max_jump_chain) 2097: { 2098: jump_chain[INSN_UID (copy)] 2099: = jump_chain[INSN_UID (JUMP_LABEL (copy))]; 2100: jump_chain[INSN_UID (JUMP_LABEL (copy))] = copy; 2101: } 2102: emit_barrier_before (loop_start); 2103: } 2104: 2105: delete_insn (next_nonnote_insn (loop_start)); 2106: 2107: /* Mark the exit code as the virtual top of the converted loop. */ 2108: emit_note_before (NOTE_INSN_LOOP_VTOP, exitcode); 2109: 2110: return 1; 2111: } 2112: 2113: /* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, and 1.1.1.3 root 2114: loop-end notes between START and END out before START. Assume that 2115: END is not such a note. START may be such a note. Returns the value 2116: of the new starting insn, which may be different if the original start 2117: was such a note. */ 1.1 root 2118: 1.1.1.3 root 2119: rtx 1.1 root 2120: squeeze_notes (start, end) 2121: rtx start, end; 2122: { 2123: rtx insn; 2124: rtx next; 2125: 2126: for (insn = start; insn != end; insn = next) 2127: { 2128: next = NEXT_INSN (insn); 2129: if (GET_CODE (insn) == NOTE 2130: && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END 2131: || NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG 2132: || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG 2133: || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END 2134: || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT 2135: || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP)) 2136: { 1.1.1.3 root 2137: if (insn == start) 2138: start = next; 2139: else 2140: { 2141: rtx prev = PREV_INSN (insn); 2142: PREV_INSN (insn) = PREV_INSN (start); 2143: NEXT_INSN (insn) = start; 2144: NEXT_INSN (PREV_INSN (insn)) = insn; 2145: PREV_INSN (NEXT_INSN (insn)) = insn; 2146: NEXT_INSN (prev) = next; 2147: PREV_INSN (next) = prev; 2148: } 1.1 root 2149: } 2150: } 1.1.1.3 root 2151: 2152: return start; 1.1 root 2153: } 2154: 2155: /* Compare the instructions before insn E1 with those before E2 2156: to find an opportunity for cross jumping. 2157: (This means detecting identical sequences of insns followed by 2158: jumps to the same place, or followed by a label and a jump 2159: to that label, and replacing one with a jump to the other.) 2160: 2161: Assume E1 is a jump that jumps to label E2 2162: (that is not always true but it might as well be). 2163: Find the longest possible equivalent sequences 2164: and store the first insns of those sequences into *F1 and *F2. 2165: Store zero there if no equivalent preceding instructions are found. 2166: 2167: We give up if we find a label in stream 1. 2168: Actually we could transfer that label into stream 2. */ 2169: 2170: static void 2171: find_cross_jump (e1, e2, minimum, f1, f2) 2172: rtx e1, e2; 2173: int minimum; 2174: rtx *f1, *f2; 2175: { 2176: register rtx i1 = e1, i2 = e2; 2177: register rtx p1, p2; 2178: int lose = 0; 2179: 2180: rtx last1 = 0, last2 = 0; 2181: rtx afterlast1 = 0, afterlast2 = 0; 2182: rtx prev1; 2183: 2184: *f1 = 0; 2185: *f2 = 0; 2186: 2187: while (1) 2188: { 2189: i1 = prev_nonnote_insn (i1); 2190: 2191: i2 = PREV_INSN (i2); 2192: while (i2 && (GET_CODE (i2) == NOTE || GET_CODE (i2) == CODE_LABEL)) 2193: i2 = PREV_INSN (i2); 2194: 2195: if (i1 == 0) 2196: break; 2197: 2198: /* Don't allow the range of insns preceding E1 or E2 2199: to include the other (E2 or E1). */ 2200: if (i2 == e1 || i1 == e2) 2201: break; 2202: 2203: /* If we will get to this code by jumping, those jumps will be 2204: tensioned to go directly to the new label (before I2), 2205: so this cross-jumping won't cost extra. So reduce the minimum. */ 2206: if (GET_CODE (i1) == CODE_LABEL) 2207: { 2208: --minimum; 2209: break; 2210: } 2211: 2212: if (i2 == 0 || GET_CODE (i1) != GET_CODE (i2)) 2213: break; 2214: 2215: p1 = PATTERN (i1); 2216: p2 = PATTERN (i2); 2217: 2218: #ifdef STACK_REGS 2219: /* If cross_jump_death_matters is not 0, the insn's mode 2220: indicates whether or not the insn contains any stack-like 2221: regs. */ 2222: 2223: if (cross_jump_death_matters && GET_MODE (i1) == QImode) 2224: { 2225: /* If register stack conversion has already been done, then 2226: death notes must also be compared before it is certain that 2227: the two instruction streams match. */ 2228: 2229: rtx note; 2230: HARD_REG_SET i1_regset, i2_regset; 2231: 2232: CLEAR_HARD_REG_SET (i1_regset); 2233: CLEAR_HARD_REG_SET (i2_regset); 2234: 2235: for (note = REG_NOTES (i1); note; note = XEXP (note, 1)) 2236: if (REG_NOTE_KIND (note) == REG_DEAD 2237: && STACK_REG_P (XEXP (note, 0))) 2238: SET_HARD_REG_BIT (i1_regset, REGNO (XEXP (note, 0))); 2239: 2240: for (note = REG_NOTES (i2); note; note = XEXP (note, 1)) 2241: if (REG_NOTE_KIND (note) == REG_DEAD 2242: && STACK_REG_P (XEXP (note, 0))) 2243: SET_HARD_REG_BIT (i2_regset, REGNO (XEXP (note, 0))); 2244: 2245: GO_IF_HARD_REG_EQUAL (i1_regset, i2_regset, done); 2246: 2247: lose = 1; 2248: 2249: done: 2250: ; 2251: } 2252: #endif 2253: 2254: if (lose || GET_CODE (p1) != GET_CODE (p2) 2255: || ! rtx_renumbered_equal_p (p1, p2)) 2256: { 2257: /* The following code helps take care of G++ cleanups. */ 2258: rtx equiv1; 2259: rtx equiv2; 2260: 2261: if (!lose && GET_CODE (p1) == GET_CODE (p2) 1.1.1.4 ! root 2262: && ((equiv1 = find_reg_note (i1, REG_EQUAL, NULL_RTX)) != 0 ! 2263: || (equiv1 = find_reg_note (i1, REG_EQUIV, NULL_RTX)) != 0) ! 2264: && ((equiv2 = find_reg_note (i2, REG_EQUAL, NULL_RTX)) != 0 ! 2265: || (equiv2 = find_reg_note (i2, REG_EQUIV, NULL_RTX)) != 0) 1.1 root 2266: /* If the equivalences are not to a constant, they may 2267: reference pseudos that no longer exist, so we can't 2268: use them. */ 2269: && CONSTANT_P (XEXP (equiv1, 0)) 2270: && rtx_equal_p (XEXP (equiv1, 0), XEXP (equiv2, 0))) 2271: { 2272: rtx s1 = single_set (i1); 2273: rtx s2 = single_set (i2); 2274: if (s1 != 0 && s2 != 0 2275: && rtx_renumbered_equal_p (SET_DEST (s1), SET_DEST (s2))) 2276: { 2277: validate_change (i1, &SET_SRC (s1), XEXP (equiv1, 0), 1); 2278: validate_change (i2, &SET_SRC (s2), XEXP (equiv2, 0), 1); 2279: if (! rtx_renumbered_equal_p (p1, p2)) 2280: cancel_changes (0); 2281: else if (apply_change_group ()) 2282: goto win; 2283: } 2284: } 2285: 2286: /* Insns fail to match; cross jumping is limited to the following 2287: insns. */ 2288: 2289: #ifdef HAVE_cc0 2290: /* Don't allow the insn after a compare to be shared by 2291: cross-jumping unless the compare is also shared. 2292: Here, if either of these non-matching insns is a compare, 2293: exclude the following insn from possible cross-jumping. */ 2294: if (sets_cc0_p (p1) || sets_cc0_p (p2)) 2295: last1 = afterlast1, last2 = afterlast2, ++minimum; 2296: #endif 2297: 2298: /* If cross-jumping here will feed a jump-around-jump 2299: optimization, this jump won't cost extra, so reduce 2300: the minimum. */ 2301: if (GET_CODE (i1) == JUMP_INSN 2302: && JUMP_LABEL (i1) 2303: && prev_real_insn (JUMP_LABEL (i1)) == e1) 2304: --minimum; 2305: break; 2306: } 2307: 2308: win: 2309: if (GET_CODE (p1) != USE && GET_CODE (p1) != CLOBBER) 2310: { 2311: /* Ok, this insn is potentially includable in a cross-jump here. */ 2312: afterlast1 = last1, afterlast2 = last2; 2313: last1 = i1, last2 = i2, --minimum; 2314: } 2315: } 2316: 2317: /* We have to be careful that we do not cross-jump into the middle of 2318: USE-CALL_INSN-CLOBBER sequence. This sequence is used instead of 2319: putting the USE and CLOBBERs inside the CALL_INSN. The delay slot 2320: scheduler needs to know what registers are used and modified by the 2321: CALL_INSN and needs the adjacent USE and CLOBBERs to do so. 2322: 2323: ??? At some point we should probably change this so that these are 2324: part of the CALL_INSN. The way we are doing it now is a kludge that 2325: is now causing trouble. */ 2326: 2327: if (last1 != 0 && GET_CODE (last1) == CALL_INSN 2328: && (prev1 = prev_nonnote_insn (last1)) 2329: && GET_CODE (prev1) == INSN 2330: && GET_CODE (PATTERN (prev1)) == USE) 2331: { 2332: /* Remove this CALL_INSN from the range we can cross-jump. */ 2333: last1 = next_real_insn (last1); 2334: last2 = next_real_insn (last2); 2335: 2336: minimum++; 2337: } 2338: 2339: /* Skip past CLOBBERS since they may be right after a CALL_INSN. It 2340: isn't worth checking for the CALL_INSN. */ 2341: while (last1 != 0 && GET_CODE (PATTERN (last1)) == CLOBBER) 2342: last1 = next_real_insn (last1), last2 = next_real_insn (last2); 2343: 2344: if (minimum <= 0 && last1 != 0 && last1 != e1) 2345: *f1 = last1, *f2 = last2; 2346: } 2347: 2348: static void 2349: do_cross_jump (insn, newjpos, newlpos) 2350: rtx insn, newjpos, newlpos; 2351: { 2352: /* Find an existing label at this point 2353: or make a new one if there is none. */ 2354: register rtx label = get_label_before (newlpos); 2355: 2356: /* Make the same jump insn jump to the new point. */ 2357: if (GET_CODE (PATTERN (insn)) == RETURN) 2358: { 2359: /* Remove from jump chain of returns. */ 2360: delete_from_jump_chain (insn); 2361: /* Change the insn. */ 2362: PATTERN (insn) = gen_jump (label); 2363: INSN_CODE (insn) = -1; 2364: JUMP_LABEL (insn) = label; 2365: LABEL_NUSES (label)++; 2366: /* Add to new the jump chain. */ 2367: if (INSN_UID (label) < max_jump_chain 2368: && INSN_UID (insn) < max_jump_chain) 2369: { 2370: jump_chain[INSN_UID (insn)] = jump_chain[INSN_UID (label)]; 2371: jump_chain[INSN_UID (label)] = insn; 2372: } 2373: } 2374: else 2375: redirect_jump (insn, label); 2376: 2377: /* Delete the matching insns before the jump. Also, remove any REG_EQUAL 2378: or REG_EQUIV note in the NEWLPOS stream that isn't also present in 2379: the NEWJPOS stream. */ 2380: 2381: while (newjpos != insn) 2382: { 2383: rtx lnote; 2384: 2385: for (lnote = REG_NOTES (newlpos); lnote; lnote = XEXP (lnote, 1)) 2386: if ((REG_NOTE_KIND (lnote) == REG_EQUAL 2387: || REG_NOTE_KIND (lnote) == REG_EQUIV) 2388: && ! find_reg_note (newjpos, REG_EQUAL, XEXP (lnote, 0)) 2389: && ! find_reg_note (newjpos, REG_EQUIV, XEXP (lnote, 0))) 2390: remove_note (newlpos, lnote); 2391: 2392: delete_insn (newjpos); 2393: newjpos = next_real_insn (newjpos); 2394: newlpos = next_real_insn (newlpos); 2395: } 2396: } 2397: 2398: /* Return the label before INSN, or put a new label there. */ 2399: 2400: rtx 2401: get_label_before (insn) 2402: rtx insn; 2403: { 2404: rtx label; 2405: 2406: /* Find an existing label at this point 2407: or make a new one if there is none. */ 2408: label = prev_nonnote_insn (insn); 2409: 2410: if (label == 0 || GET_CODE (label) != CODE_LABEL) 2411: { 2412: rtx prev = PREV_INSN (insn); 2413: 1.1.1.3 root 2414: /* Don't put a label between a CALL_INSN and USE insns that precede 1.1 root 2415: it. */ 2416: 2417: if (GET_CODE (insn) == CALL_INSN 2418: || (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE 2419: && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN)) 2420: while (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == USE) 2421: prev = PREV_INSN (prev); 2422: 2423: label = gen_label_rtx (); 2424: emit_label_after (label, prev); 2425: LABEL_NUSES (label) = 0; 2426: } 2427: return label; 2428: } 2429: 2430: /* Return the label after INSN, or put a new label there. */ 2431: 2432: rtx 2433: get_label_after (insn) 2434: rtx insn; 2435: { 2436: rtx label; 2437: 2438: /* Find an existing label at this point 2439: or make a new one if there is none. */ 2440: label = next_nonnote_insn (insn); 2441: 2442: if (label == 0 || GET_CODE (label) != CODE_LABEL) 2443: { 2444: /* Don't put a label between a CALL_INSN and CLOBBER insns 2445: following it. */ 2446: 2447: if (GET_CODE (insn) == CALL_INSN 2448: || (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE 2449: && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN)) 2450: while (GET_CODE (NEXT_INSN (insn)) == INSN 2451: && GET_CODE (PATTERN (NEXT_INSN (insn))) == CLOBBER) 2452: insn = NEXT_INSN (insn); 2453: 2454: label = gen_label_rtx (); 2455: emit_label_after (label, insn); 2456: LABEL_NUSES (label) = 0; 2457: } 2458: return label; 2459: } 2460: 2461: /* Return 1 if INSN is a jump that jumps to right after TARGET 2462: only on the condition that TARGET itself would drop through. 2463: Assumes that TARGET is a conditional jump. */ 2464: 2465: static int 2466: jump_back_p (insn, target) 2467: rtx insn, target; 2468: { 2469: rtx cinsn, ctarget; 2470: enum rtx_code codei, codet; 2471: 2472: if (simplejump_p (insn) || ! condjump_p (insn) 2473: || simplejump_p (target) 2474: || target != prev_real_insn (JUMP_LABEL (insn))) 2475: return 0; 2476: 2477: cinsn = XEXP (SET_SRC (PATTERN (insn)), 0); 2478: ctarget = XEXP (SET_SRC (PATTERN (target)), 0); 2479: 2480: codei = GET_CODE (cinsn); 2481: codet = GET_CODE (ctarget); 2482: 2483: if (XEXP (SET_SRC (PATTERN (insn)), 1) == pc_rtx) 2484: { 2485: if (! can_reverse_comparison_p (cinsn, insn)) 2486: return 0; 2487: codei = reverse_condition (codei); 2488: } 2489: 2490: if (XEXP (SET_SRC (PATTERN (target)), 2) == pc_rtx) 2491: { 2492: if (! can_reverse_comparison_p (ctarget, target)) 2493: return 0; 2494: codet = reverse_condition (codet); 2495: } 2496: 2497: return (codei == codet 2498: && rtx_renumbered_equal_p (XEXP (cinsn, 0), XEXP (ctarget, 0)) 2499: && rtx_renumbered_equal_p (XEXP (cinsn, 1), XEXP (ctarget, 1))); 2500: } 2501: 2502: /* Given a comparison, COMPARISON, inside a conditional jump insn, INSN, 2503: return non-zero if it is safe to reverse this comparison. It is if our 2504: floating-point is not IEEE, if this is an NE or EQ comparison, or if 2505: this is known to be an integer comparison. */ 2506: 2507: int 2508: can_reverse_comparison_p (comparison, insn) 2509: rtx comparison; 2510: rtx insn; 2511: { 2512: rtx arg0; 2513: 2514: /* If this is not actually a comparison, we can't reverse it. */ 2515: if (GET_RTX_CLASS (GET_CODE (comparison)) != '<') 2516: return 0; 2517: 2518: if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT 2519: /* If this is an NE comparison, it is safe to reverse it to an EQ 2520: comparison and vice versa, even for floating point. If no operands 2521: are NaNs, the reversal is valid. If some operand is a NaN, EQ is 2522: always false and NE is always true, so the reversal is also valid. */ 2523: || GET_CODE (comparison) == NE 2524: || GET_CODE (comparison) == EQ) 2525: return 1; 2526: 2527: arg0 = XEXP (comparison, 0); 2528: 2529: /* Make sure ARG0 is one of the actual objects being compared. If we 2530: can't do this, we can't be sure the comparison can be reversed. 2531: 2532: Handle cc0 and a MODE_CC register. */ 2533: if ((GET_CODE (arg0) == REG && GET_MODE_CLASS (GET_MODE (arg0)) == MODE_CC) 2534: #ifdef HAVE_cc0 2535: || arg0 == cc0_rtx 2536: #endif 2537: ) 2538: { 2539: rtx prev = prev_nonnote_insn (insn); 2540: rtx set = single_set (prev); 2541: 2542: if (set == 0 || SET_DEST (set) != arg0) 2543: return 0; 2544: 2545: arg0 = SET_SRC (set); 2546: 2547: if (GET_CODE (arg0) == COMPARE) 2548: arg0 = XEXP (arg0, 0); 2549: } 2550: 2551: /* We can reverse this if ARG0 is a CONST_INT or if its mode is 2552: not VOIDmode and neither a MODE_CC nor MODE_FLOAT type. */ 2553: return (GET_CODE (arg0) == CONST_INT 2554: || (GET_MODE (arg0) != VOIDmode 2555: && GET_MODE_CLASS (GET_MODE (arg0)) != MODE_CC 2556: && GET_MODE_CLASS (GET_MODE (arg0)) != MODE_FLOAT)); 2557: } 2558: 2559: /* Given an rtx-code for a comparison, return the code 2560: for the negated comparison. 2561: WATCH OUT! reverse_condition is not safe to use on a jump 2562: that might be acting on the results of an IEEE floating point comparison, 2563: because of the special treatment of non-signaling nans in comparisons. 2564: Use can_reverse_comparison_p to be sure. */ 2565: 2566: enum rtx_code 2567: reverse_condition (code) 2568: enum rtx_code code; 2569: { 2570: switch (code) 2571: { 2572: case EQ: 2573: return NE; 2574: 2575: case NE: 2576: return EQ; 2577: 2578: case GT: 2579: return LE; 2580: 2581: case GE: 2582: return LT; 2583: 2584: case LT: 2585: return GE; 2586: 2587: case LE: 2588: return GT; 2589: 2590: case GTU: 2591: return LEU; 2592: 2593: case GEU: 2594: return LTU; 2595: 2596: case LTU: 2597: return GEU; 2598: 2599: case LEU: 2600: return GTU; 2601: 2602: default: 2603: abort (); 2604: return UNKNOWN; 2605: } 2606: } 2607: 2608: /* Similar, but return the code when two operands of a comparison are swapped. 2609: This IS safe for IEEE floating-point. */ 2610: 2611: enum rtx_code 2612: swap_condition (code) 2613: enum rtx_code code; 2614: { 2615: switch (code) 2616: { 2617: case EQ: 2618: case NE: 2619: return code; 2620: 2621: case GT: 2622: return LT; 2623: 2624: case GE: 2625: return LE; 2626: 2627: case LT: 2628: return GT; 2629: 2630: case LE: 2631: return GE; 2632: 2633: case GTU: 2634: return LTU; 2635: 2636: case GEU: 2637: return LEU; 2638: 2639: case LTU: 2640: return GTU; 2641: 2642: case LEU: 2643: return GEU; 2644: 2645: default: 2646: abort (); 2647: return UNKNOWN; 2648: } 2649: } 2650: 2651: /* Given a comparison CODE, return the corresponding unsigned comparison. 2652: If CODE is an equality comparison or already an unsigned comparison, 2653: CODE is returned. */ 2654: 2655: enum rtx_code 2656: unsigned_condition (code) 2657: enum rtx_code code; 2658: { 2659: switch (code) 2660: { 2661: case EQ: 2662: case NE: 2663: case GTU: 2664: case GEU: 2665: case LTU: 2666: case LEU: 2667: return code; 2668: 2669: case GT: 2670: return GTU; 2671: 2672: case GE: 2673: return GEU; 2674: 2675: case LT: 2676: return LTU; 2677: 2678: case LE: 2679: return LEU; 2680: 2681: default: 2682: abort (); 2683: } 2684: } 2685: 2686: /* Similarly, return the signed version of a comparison. */ 2687: 2688: enum rtx_code 2689: signed_condition (code) 2690: enum rtx_code code; 2691: { 2692: switch (code) 2693: { 2694: case EQ: 2695: case NE: 2696: case GT: 2697: case GE: 2698: case LT: 2699: case LE: 2700: return code; 2701: 2702: case GTU: 2703: return GT; 2704: 2705: case GEU: 2706: return GE; 2707: 2708: case LTU: 2709: return LT; 2710: 2711: case LEU: 2712: return LE; 2713: 2714: default: 2715: abort (); 2716: } 2717: } 2718: 2719: /* Return non-zero if CODE1 is more strict than CODE2, i.e., if the 2720: truth of CODE1 implies the truth of CODE2. */ 2721: 2722: int 2723: comparison_dominates_p (code1, code2) 2724: enum rtx_code code1, code2; 2725: { 2726: if (code1 == code2) 2727: return 1; 2728: 2729: switch (code1) 2730: { 2731: case EQ: 2732: if (code2 == LE || code2 == LEU || code2 == GE || code2 == GEU) 2733: return 1; 2734: break; 2735: 2736: case LT: 2737: if (code2 == LE) 2738: return 1; 2739: break; 2740: 2741: case GT: 2742: if (code2 == GE) 2743: return 1; 2744: break; 2745: 2746: case LTU: 2747: if (code2 == LEU) 2748: return 1; 2749: break; 2750: 2751: case GTU: 2752: if (code2 == GEU) 2753: return 1; 2754: break; 2755: } 2756: 2757: return 0; 2758: } 2759: 2760: /* Return 1 if INSN is an unconditional jump and nothing else. */ 2761: 2762: int 2763: simplejump_p (insn) 2764: rtx insn; 2765: { 2766: return (GET_CODE (insn) == JUMP_INSN 2767: && GET_CODE (PATTERN (insn)) == SET 2768: && GET_CODE (SET_DEST (PATTERN (insn))) == PC 2769: && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF); 2770: } 2771: 2772: /* Return nonzero if INSN is a (possibly) conditional jump 2773: and nothing more. */ 2774: 2775: int 2776: condjump_p (insn) 2777: rtx insn; 2778: { 2779: register rtx x = PATTERN (insn); 2780: if (GET_CODE (x) != SET) 2781: return 0; 2782: if (GET_CODE (SET_DEST (x)) != PC) 2783: return 0; 2784: if (GET_CODE (SET_SRC (x)) == LABEL_REF) 2785: return 1; 2786: if (GET_CODE (SET_SRC (x)) != IF_THEN_ELSE) 2787: return 0; 2788: if (XEXP (SET_SRC (x), 2) == pc_rtx 2789: && (GET_CODE (XEXP (SET_SRC (x), 1)) == LABEL_REF 2790: || GET_CODE (XEXP (SET_SRC (x), 1)) == RETURN)) 2791: return 1; 2792: if (XEXP (SET_SRC (x), 1) == pc_rtx 2793: && (GET_CODE (XEXP (SET_SRC (x), 2)) == LABEL_REF 2794: || GET_CODE (XEXP (SET_SRC (x), 2)) == RETURN)) 2795: return 1; 2796: return 0; 2797: } 2798: 2799: /* Return 1 if X is an RTX that does nothing but set the condition codes 2800: and CLOBBER or USE registers. 2801: Return -1 if X does explicitly set the condition codes, 2802: but also does other things. */ 2803: 2804: int 2805: sets_cc0_p (x) 2806: rtx x; 2807: { 2808: #ifdef HAVE_cc0 2809: if (GET_CODE (x) == SET && SET_DEST (x) == cc0_rtx) 2810: return 1; 2811: if (GET_CODE (x) == PARALLEL) 2812: { 2813: int i; 2814: int sets_cc0 = 0; 2815: int other_things = 0; 2816: for (i = XVECLEN (x, 0) - 1; i >= 0; i--) 2817: { 2818: if (GET_CODE (XVECEXP (x, 0, i)) == SET 2819: && SET_DEST (XVECEXP (x, 0, i)) == cc0_rtx) 2820: sets_cc0 = 1; 2821: else if (GET_CODE (XVECEXP (x, 0, i)) == SET) 2822: other_things = 1; 2823: } 2824: return ! sets_cc0 ? 0 : other_things ? -1 : 1; 2825: } 2826: return 0; 2827: #else 2828: abort (); 2829: #endif 2830: } 2831: 2832: /* Follow any unconditional jump at LABEL; 2833: return the ultimate label reached by any such chain of jumps. 2834: If LABEL is not followed by a jump, return LABEL. 2835: If the chain loops or we can't find end, return LABEL, 2836: since that tells caller to avoid changing the insn. 2837: 2838: If RELOAD_COMPLETED is 0, we do not chain across a NOTE_INSN_LOOP_BEG or 2839: a USE or CLOBBER. */ 2840: 2841: rtx 2842: follow_jumps (label) 2843: rtx label; 2844: { 2845: register rtx insn; 2846: register rtx next; 2847: register rtx value = label; 2848: register int depth; 2849: 2850: for (depth = 0; 2851: (depth < 10 2852: && (insn = next_active_insn (value)) != 0 2853: && GET_CODE (insn) == JUMP_INSN 2854: && (JUMP_LABEL (insn) != 0 || GET_CODE (PATTERN (insn)) == RETURN) 2855: && (next = NEXT_INSN (insn)) 2856: && GET_CODE (next) == BARRIER); 2857: depth++) 2858: { 2859: /* Don't chain through the insn that jumps into a loop 2860: from outside the loop, 2861: since that would create multiple loop entry jumps 2862: and prevent loop optimization. */ 2863: rtx tem; 2864: if (!reload_completed) 2865: for (tem = value; tem != insn; tem = NEXT_INSN (tem)) 2866: if (GET_CODE (tem) == NOTE 2867: && NOTE_LINE_NUMBER (tem) == NOTE_INSN_LOOP_BEG) 2868: return value; 2869: 2870: /* If we have found a cycle, make the insn jump to itself. */ 2871: if (JUMP_LABEL (insn) == label) 2872: return label; 2873: value = JUMP_LABEL (insn); 2874: } 2875: if (depth == 10) 2876: return label; 2877: return value; 2878: } 2879: 2880: /* Assuming that field IDX of X is a vector of label_refs, 2881: replace each of them by the ultimate label reached by it. 2882: Return nonzero if a change is made. 2883: If IGNORE_LOOPS is 0, we do not chain across a NOTE_INSN_LOOP_BEG. */ 2884: 2885: static int 2886: tension_vector_labels (x, idx) 2887: register rtx x; 2888: register int idx; 2889: { 2890: int changed = 0; 2891: register int i; 2892: for (i = XVECLEN (x, idx) - 1; i >= 0; i--) 2893: { 2894: register rtx olabel = XEXP (XVECEXP (x, idx, i), 0); 2895: register rtx nlabel = follow_jumps (olabel); 2896: if (nlabel && nlabel != olabel) 2897: { 2898: XEXP (XVECEXP (x, idx, i), 0) = nlabel; 2899: ++LABEL_NUSES (nlabel); 2900: if (--LABEL_NUSES (olabel) == 0) 2901: delete_insn (olabel); 2902: changed = 1; 2903: } 2904: } 2905: return changed; 2906: } 2907: 2908: /* Find all CODE_LABELs referred to in X, and increment their use counts. 2909: If INSN is a JUMP_INSN and there is at least one CODE_LABEL referenced 2910: in INSN, then store one of them in JUMP_LABEL (INSN). 2911: If INSN is an INSN or a CALL_INSN and there is at least one CODE_LABEL 2912: referenced in INSN, add a REG_LABEL note containing that label to INSN. 2913: Also, when there are consecutive labels, canonicalize on the last of them. 2914: 2915: Note that two labels separated by a loop-beginning note 2916: must be kept distinct if we have not yet done loop-optimization, 2917: because the gap between them is where loop-optimize 2918: will want to move invariant code to. CROSS_JUMP tells us 2919: that loop-optimization is done with. 2920: 2921: Once reload has completed (CROSS_JUMP non-zero), we need not consider 2922: two labels distinct if they are separated by only USE or CLOBBER insns. */ 2923: 2924: static void 2925: mark_jump_label (x, insn, cross_jump) 2926: register rtx x; 2927: rtx insn; 2928: int cross_jump; 2929: { 2930: register RTX_CODE code = GET_CODE (x); 2931: register int i; 2932: register char *fmt; 2933: 2934: switch (code) 2935: { 2936: case PC: 2937: case CC0: 2938: case REG: 2939: case SUBREG: 2940: case CONST_INT: 2941: case SYMBOL_REF: 2942: case CONST_DOUBLE: 2943: case CLOBBER: 2944: case CALL: 2945: return; 2946: 1.1.1.3 root 2947: case MEM: 2948: /* If this is a constant-pool reference, see if it is a label. */ 2949: if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF 2950: && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0))) 2951: mark_jump_label (get_pool_constant (XEXP (x, 0)), insn, cross_jump); 2952: break; 2953: 1.1 root 2954: case LABEL_REF: 2955: { 2956: register rtx label = XEXP (x, 0); 2957: register rtx next; 2958: if (GET_CODE (label) != CODE_LABEL) 2959: abort (); 1.1.1.4 ! root 2960: /* Ignore references to labels of containing functions. */ ! 2961: if (LABEL_REF_NONLOCAL_P (x)) ! 2962: break; 1.1 root 2963: /* If there are other labels following this one, 2964: replace it with the last of the consecutive labels. */ 2965: for (next = NEXT_INSN (label); next; next = NEXT_INSN (next)) 2966: { 2967: if (GET_CODE (next) == CODE_LABEL) 2968: label = next; 2969: else if (cross_jump && GET_CODE (next) == INSN 2970: && (GET_CODE (PATTERN (next)) == USE 2971: || GET_CODE (PATTERN (next)) == CLOBBER)) 2972: continue; 2973: else if (GET_CODE (next) != NOTE) 2974: break; 2975: else if (! cross_jump 2976: && (NOTE_LINE_NUMBER (next) == NOTE_INSN_LOOP_BEG 2977: || NOTE_LINE_NUMBER (next) == NOTE_INSN_FUNCTION_END)) 2978: break; 2979: } 2980: XEXP (x, 0) = label; 2981: ++LABEL_NUSES (label); 2982: if (insn) 2983: { 2984: if (GET_CODE (insn) == JUMP_INSN) 2985: JUMP_LABEL (insn) = label; 1.1.1.2 root 2986: else if (! find_reg_note (insn, REG_LABEL, label)) 1.1 root 2987: { 2988: rtx next = next_real_insn (label); 2989: /* Don't record labels that refer to dispatch tables. 2990: This is not necessary, since the tablejump 2991: references the same label. 2992: And if we did record them, flow.c would make worse code. */ 2993: if (next == 0 2994: || ! (GET_CODE (next) == JUMP_INSN 2995: && (GET_CODE (PATTERN (next)) == ADDR_VEC 2996: || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))) 1.1.1.4 ! root 2997: { ! 2998: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_LABEL, label, ! 2999: REG_NOTES (insn)); ! 3000: /* Record in the note whether label is nonlocal. */ ! 3001: LABEL_REF_NONLOCAL_P (REG_NOTES (insn)) ! 3002: = LABEL_REF_NONLOCAL_P (x); ! 3003: } 1.1 root 3004: } 3005: } 3006: return; 3007: } 3008: 3009: /* Do walk the labels in a vector, but not the first operand of an 3010: ADDR_DIFF_VEC. Don't set the JUMP_LABEL of a vector. */ 3011: case ADDR_VEC: 3012: case ADDR_DIFF_VEC: 3013: { 3014: int eltnum = code == ADDR_DIFF_VEC ? 1 : 0; 3015: 3016: for (i = 0; i < XVECLEN (x, eltnum); i++) 1.1.1.4 ! root 3017: mark_jump_label (XVECEXP (x, eltnum, i), NULL_RTX, cross_jump); 1.1 root 3018: return; 3019: } 3020: } 3021: 3022: fmt = GET_RTX_FORMAT (code); 3023: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 3024: { 3025: if (fmt[i] == 'e') 3026: mark_jump_label (XEXP (x, i), insn, cross_jump); 3027: else if (fmt[i] == 'E') 3028: { 3029: register int j; 3030: for (j = 0; j < XVECLEN (x, i); j++) 3031: mark_jump_label (XVECEXP (x, i, j), insn, cross_jump); 3032: } 3033: } 3034: } 3035: 3036: /* If all INSN does is set the pc, delete it, 3037: and delete the insn that set the condition codes for it 3038: if that's what the previous thing was. */ 3039: 3040: void 3041: delete_jump (insn) 3042: rtx insn; 3043: { 3044: register rtx x = PATTERN (insn); 3045: 3046: if (GET_CODE (x) == SET 3047: && GET_CODE (SET_DEST (x)) == PC) 3048: { 3049: #ifdef HAVE_cc0 1.1.1.4 ! root 3050: rtx prev = prev_nonnote_insn (insn); 1.1 root 3051: /* We assume that at this stage 3052: CC's are always set explicitly 3053: and always immediately before the jump that 3054: will use them. So if the previous insn 3055: exists to set the CC's, delete it 3056: (unless it performs auto-increments, etc.). */ 3057: if (prev && GET_CODE (prev) == INSN 3058: && sets_cc0_p (PATTERN (prev))) 3059: { 3060: if (sets_cc0_p (PATTERN (prev)) > 0 1.1.1.4 ! root 3061: && !FIND_REG_INC_NOTE (prev, NULL_RTX)) 1.1 root 3062: delete_insn (prev); 3063: else 3064: /* Otherwise, show that cc0 won't be used. */ 3065: REG_NOTES (prev) = gen_rtx (EXPR_LIST, REG_UNUSED, 3066: cc0_rtx, REG_NOTES (prev)); 3067: } 1.1.1.4 ! root 3068: #endif ! 3069: /* Now delete the jump insn itself. */ ! 3070: delete_computation (insn); ! 3071: } ! 3072: } 1.1 root 3073: 1.1.1.4 ! root 3074: /* Delete INSN and recursively delete insns that compute values used only ! 3075: by INSN. This uses the REG_DEAD notes computed during flow analysis. ! 3076: If we are running before flow.c, we need do nothing since flow.c will ! 3077: delete dead code. We also can't know if the registers being used are ! 3078: dead or not at this point. ! 3079: ! 3080: Otherwise, look at all our REG_DEAD notes. If a previous insn does ! 3081: nothing other than set a register that dies in this insn, we can delete ! 3082: that insn as well. */ 1.1 root 3083: 1.1.1.4 ! root 3084: void ! 3085: delete_computation (insn) ! 3086: rtx insn; ! 3087: { ! 3088: #ifndef HAVE_cc0 ! 3089: rtx note, next; 1.1 root 3090: 1.1.1.4 ! root 3091: for (note = REG_NOTES (insn); note; note = next) ! 3092: { ! 3093: rtx our_prev; 1.1 root 3094: 1.1.1.4 ! root 3095: next = XEXP (note, 1); 1.1 root 3096: 1.1.1.4 ! root 3097: if (REG_NOTE_KIND (note) != REG_DEAD ! 3098: /* Verify that the REG_NOTE is legitimate. */ ! 3099: || GET_CODE (XEXP (note, 0)) != REG) ! 3100: continue; 1.1 root 3101: 1.1.1.4 ! root 3102: for (our_prev = prev_nonnote_insn (insn); ! 3103: our_prev && GET_CODE (our_prev) == INSN; ! 3104: our_prev = prev_nonnote_insn (our_prev)) ! 3105: { ! 3106: /* If we reach a SEQUENCE, it is too complex to try to ! 3107: do anything with it, so give up. */ ! 3108: if (GET_CODE (PATTERN (our_prev)) == SEQUENCE) ! 3109: break; 1.1 root 3110: 1.1.1.4 ! root 3111: if (GET_CODE (PATTERN (our_prev)) == USE ! 3112: && GET_CODE (XEXP (PATTERN (our_prev), 0)) == INSN) ! 3113: /* reorg creates USEs that look like this. We leave them ! 3114: alone because reorg needs them for its own purposes. */ ! 3115: break; 1.1 root 3116: 1.1.1.4 ! root 3117: if (reg_set_p (XEXP (note, 0), PATTERN (our_prev))) ! 3118: { ! 3119: if (FIND_REG_INC_NOTE (our_prev, NULL_RTX)) ! 3120: break; 1.1 root 3121: 1.1.1.4 ! root 3122: if (GET_CODE (PATTERN (our_prev)) == PARALLEL) ! 3123: { ! 3124: /* If we find a SET of something else, we can't ! 3125: delete the insn. */ 1.1 root 3126: 1.1.1.4 ! root 3127: int i; 1.1 root 3128: 1.1.1.4 ! root 3129: for (i = 0; i < XVECLEN (PATTERN (our_prev), 0); i++) ! 3130: { ! 3131: rtx part = XVECEXP (PATTERN (our_prev), 0, i); 1.1 root 3132: 1.1.1.4 ! root 3133: if (GET_CODE (part) == SET ! 3134: && SET_DEST (part) != XEXP (note, 0)) ! 3135: break; ! 3136: } 1.1 root 3137: 1.1.1.4 ! root 3138: if (i == XVECLEN (PATTERN (our_prev), 0)) ! 3139: delete_computation (our_prev); ! 3140: } ! 3141: else if (GET_CODE (PATTERN (our_prev)) == SET ! 3142: && SET_DEST (PATTERN (our_prev)) == XEXP (note, 0)) ! 3143: delete_computation (our_prev); ! 3144: ! 3145: break; ! 3146: } ! 3147: ! 3148: /* If OUR_PREV references the register that dies here, it is an ! 3149: additional use. Hence any prior SET isn't dead. However, this ! 3150: insn becomes the new place for the REG_DEAD note. */ ! 3151: if (reg_overlap_mentioned_p (XEXP (note, 0), ! 3152: PATTERN (our_prev))) ! 3153: { ! 3154: XEXP (note, 1) = REG_NOTES (our_prev); ! 3155: REG_NOTES (our_prev) = note; ! 3156: break; ! 3157: } ! 3158: } 1.1 root 3159: } 1.1.1.4 ! root 3160: #endif /* Don't HAVE_cc0 */ ! 3161: delete_insn (insn); 1.1 root 3162: } 3163: 3164: /* Delete insn INSN from the chain of insns and update label ref counts. 3165: May delete some following insns as a consequence; may even delete 3166: a label elsewhere and insns that follow it. 3167: 3168: Returns the first insn after INSN that was not deleted. */ 3169: 3170: rtx 3171: delete_insn (insn) 3172: register rtx insn; 3173: { 3174: register rtx next = NEXT_INSN (insn); 3175: register rtx prev = PREV_INSN (insn); 1.1.1.4 ! root 3176: register int was_code_label = (GET_CODE (insn) == CODE_LABEL); ! 3177: register int dont_really_delete = 0; 1.1 root 3178: 3179: while (next && INSN_DELETED_P (next)) 3180: next = NEXT_INSN (next); 3181: 3182: /* This insn is already deleted => return first following nondeleted. */ 3183: if (INSN_DELETED_P (insn)) 3184: return next; 3185: 1.1.1.4 ! root 3186: /* Don't delete user-declared labels. Convert them to special NOTEs ! 3187: instead. */ ! 3188: if (was_code_label && LABEL_NAME (insn) != 0 ! 3189: && optimize && ! dont_really_delete) ! 3190: { ! 3191: PUT_CODE (insn, NOTE); ! 3192: NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED_LABEL; ! 3193: NOTE_SOURCE_FILE (insn) = 0; ! 3194: dont_really_delete = 1; ! 3195: } ! 3196: else ! 3197: /* Mark this insn as deleted. */ ! 3198: INSN_DELETED_P (insn) = 1; 1.1 root 3199: 3200: /* If this is an unconditional jump, delete it from the jump chain. */ 3201: if (simplejump_p (insn)) 3202: delete_from_jump_chain (insn); 3203: 3204: /* If instruction is followed by a barrier, 3205: delete the barrier too. */ 3206: 3207: if (next != 0 && GET_CODE (next) == BARRIER) 3208: { 3209: INSN_DELETED_P (next) = 1; 3210: next = NEXT_INSN (next); 3211: } 3212: 3213: /* Patch out INSN (and the barrier if any) */ 3214: 1.1.1.4 ! root 3215: if (optimize && ! dont_really_delete) 1.1 root 3216: { 3217: if (prev) 3218: { 3219: NEXT_INSN (prev) = next; 3220: if (GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SEQUENCE) 3221: NEXT_INSN (XVECEXP (PATTERN (prev), 0, 3222: XVECLEN (PATTERN (prev), 0) - 1)) = next; 3223: } 3224: 3225: if (next) 3226: { 3227: PREV_INSN (next) = prev; 3228: if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == SEQUENCE) 3229: PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = prev; 3230: } 3231: 3232: if (prev && NEXT_INSN (prev) == 0) 3233: set_last_insn (prev); 3234: } 3235: 3236: /* If deleting a jump, decrement the count of the label, 3237: and delete the label if it is now unused. */ 3238: 3239: if (GET_CODE (insn) == JUMP_INSN && JUMP_LABEL (insn)) 3240: if (--LABEL_NUSES (JUMP_LABEL (insn)) == 0) 3241: { 3242: /* This can delete NEXT or PREV, 3243: either directly if NEXT is JUMP_LABEL (INSN), 3244: or indirectly through more levels of jumps. */ 3245: delete_insn (JUMP_LABEL (insn)); 3246: /* I feel a little doubtful about this loop, 3247: but I see no clean and sure alternative way 3248: to find the first insn after INSN that is not now deleted. 3249: I hope this works. */ 3250: while (next && INSN_DELETED_P (next)) 3251: next = NEXT_INSN (next); 3252: return next; 3253: } 3254: 3255: while (prev && (INSN_DELETED_P (prev) || GET_CODE (prev) == NOTE)) 3256: prev = PREV_INSN (prev); 3257: 3258: /* If INSN was a label and a dispatch table follows it, 3259: delete the dispatch table. The tablejump must have gone already. 3260: It isn't useful to fall through into a table. */ 3261: 1.1.1.4 ! root 3262: if (was_code_label 1.1 root 3263: && NEXT_INSN (insn) != 0 3264: && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN 3265: && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC 3266: || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC)) 3267: next = delete_insn (NEXT_INSN (insn)); 3268: 3269: /* If INSN was a label, delete insns following it if now unreachable. */ 3270: 1.1.1.4 ! root 3271: if (was_code_label && prev && GET_CODE (prev) == BARRIER) 1.1 root 3272: { 3273: register RTX_CODE code; 3274: while (next != 0 3275: && ((code = GET_CODE (next)) == INSN 3276: || code == JUMP_INSN || code == CALL_INSN 1.1.1.3 root 3277: || code == NOTE 3278: || (code == CODE_LABEL && INSN_DELETED_P (next)))) 1.1 root 3279: { 3280: if (code == NOTE 3281: && NOTE_LINE_NUMBER (next) != NOTE_INSN_FUNCTION_END) 3282: next = NEXT_INSN (next); 1.1.1.3 root 3283: /* Keep going past other deleted labels to delete what follows. */ 3284: else if (code == CODE_LABEL && INSN_DELETED_P (next)) 3285: next = NEXT_INSN (next); 1.1 root 3286: else 3287: /* Note: if this deletes a jump, it can cause more 3288: deletion of unreachable code, after a different label. 3289: As long as the value from this recursive call is correct, 3290: this invocation functions correctly. */ 3291: next = delete_insn (next); 3292: } 3293: } 3294: 3295: return next; 3296: } 3297: 3298: /* Advance from INSN till reaching something not deleted 3299: then return that. May return INSN itself. */ 3300: 3301: rtx 3302: next_nondeleted_insn (insn) 3303: rtx insn; 3304: { 3305: while (INSN_DELETED_P (insn)) 3306: insn = NEXT_INSN (insn); 3307: return insn; 3308: } 3309: 3310: /* Delete a range of insns from FROM to TO, inclusive. 3311: This is for the sake of peephole optimization, so assume 3312: that whatever these insns do will still be done by a new 3313: peephole insn that will replace them. */ 3314: 3315: void 3316: delete_for_peephole (from, to) 3317: register rtx from, to; 3318: { 3319: register rtx insn = from; 3320: 3321: while (1) 3322: { 3323: register rtx next = NEXT_INSN (insn); 3324: register rtx prev = PREV_INSN (insn); 3325: 3326: if (GET_CODE (insn) != NOTE) 3327: { 3328: INSN_DELETED_P (insn) = 1; 3329: 3330: /* Patch this insn out of the chain. */ 3331: /* We don't do this all at once, because we 3332: must preserve all NOTEs. */ 3333: if (prev) 3334: NEXT_INSN (prev) = next; 3335: 3336: if (next) 3337: PREV_INSN (next) = prev; 3338: } 3339: 3340: if (insn == to) 3341: break; 3342: insn = next; 3343: } 3344: 3345: /* Note that if TO is an unconditional jump 3346: we *do not* delete the BARRIER that follows, 3347: since the peephole that replaces this sequence 3348: is also an unconditional jump in that case. */ 3349: } 3350: 3351: /* Invert the condition of the jump JUMP, and make it jump 3352: to label NLABEL instead of where it jumps now. */ 3353: 3354: int 3355: invert_jump (jump, nlabel) 3356: rtx jump, nlabel; 3357: { 3358: register rtx olabel = JUMP_LABEL (jump); 3359: 3360: /* We have to either invert the condition and change the label or 3361: do neither. Either operation could fail. We first try to invert 3362: the jump. If that succeeds, we try changing the label. If that fails, 3363: we invert the jump back to what it was. */ 3364: 3365: if (! invert_exp (PATTERN (jump), jump)) 3366: return 0; 3367: 3368: if (redirect_jump (jump, nlabel)) 3369: return 1; 3370: 3371: if (! invert_exp (PATTERN (jump), jump)) 3372: /* This should just be putting it back the way it was. */ 3373: abort (); 3374: 3375: return 0; 3376: } 3377: 3378: /* Invert the jump condition of rtx X contained in jump insn, INSN. 3379: 3380: Return 1 if we can do so, 0 if we cannot find a way to do so that 3381: matches a pattern. */ 3382: 1.1.1.4 ! root 3383: int 1.1 root 3384: invert_exp (x, insn) 3385: rtx x; 3386: rtx insn; 3387: { 3388: register RTX_CODE code; 3389: register int i; 3390: register char *fmt; 3391: 3392: code = GET_CODE (x); 3393: 3394: if (code == IF_THEN_ELSE) 3395: { 3396: register rtx comp = XEXP (x, 0); 3397: register rtx tem; 3398: 3399: /* We can do this in two ways: The preferable way, which can only 3400: be done if this is not an integer comparison, is to reverse 3401: the comparison code. Otherwise, swap the THEN-part and ELSE-part 3402: of the IF_THEN_ELSE. If we can't do either, fail. */ 3403: 3404: if (can_reverse_comparison_p (comp, insn) 3405: && validate_change (insn, &XEXP (x, 0), 3406: gen_rtx (reverse_condition (GET_CODE (comp)), 3407: GET_MODE (comp), XEXP (comp, 0), 3408: XEXP (comp, 1)), 0)) 3409: return 1; 3410: 3411: tem = XEXP (x, 1); 3412: validate_change (insn, &XEXP (x, 1), XEXP (x, 2), 1); 3413: validate_change (insn, &XEXP (x, 2), tem, 1); 3414: return apply_change_group (); 3415: } 3416: 3417: fmt = GET_RTX_FORMAT (code); 3418: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 3419: { 3420: if (fmt[i] == 'e') 3421: if (! invert_exp (XEXP (x, i), insn)) 3422: return 0; 3423: if (fmt[i] == 'E') 3424: { 3425: register int j; 3426: for (j = 0; j < XVECLEN (x, i); j++) 3427: if (!invert_exp (XVECEXP (x, i, j), insn)) 3428: return 0; 3429: } 3430: } 3431: 3432: return 1; 3433: } 3434: 3435: /* Make jump JUMP jump to label NLABEL instead of where it jumps now. 3436: If the old jump target label is unused as a result, 3437: it and the code following it may be deleted. 3438: 3439: If NLABEL is zero, we are to turn the jump into a (possibly conditional) 3440: RETURN insn. 3441: 3442: The return value will be 1 if the change was made, 0 if it wasn't (this 3443: can only occur for NLABEL == 0). */ 3444: 3445: int 3446: redirect_jump (jump, nlabel) 3447: rtx jump, nlabel; 3448: { 3449: register rtx olabel = JUMP_LABEL (jump); 3450: 3451: if (nlabel == olabel) 3452: return 1; 3453: 3454: if (! redirect_exp (&PATTERN (jump), olabel, nlabel, jump)) 3455: return 0; 3456: 3457: /* If this is an unconditional branch, delete it from the jump_chain of 3458: OLABEL and add it to the jump_chain of NLABEL (assuming both labels 3459: have UID's in range and JUMP_CHAIN is valid). */ 3460: if (jump_chain && (simplejump_p (jump) 3461: || GET_CODE (PATTERN (jump)) == RETURN)) 3462: { 3463: int label_index = nlabel ? INSN_UID (nlabel) : 0; 3464: 3465: delete_from_jump_chain (jump); 3466: if (label_index < max_jump_chain 3467: && INSN_UID (jump) < max_jump_chain) 3468: { 3469: jump_chain[INSN_UID (jump)] = jump_chain[label_index]; 3470: jump_chain[label_index] = jump; 3471: } 3472: } 3473: 3474: JUMP_LABEL (jump) = nlabel; 3475: if (nlabel) 3476: ++LABEL_NUSES (nlabel); 3477: 3478: if (olabel && --LABEL_NUSES (olabel) == 0) 3479: delete_insn (olabel); 3480: 3481: return 1; 3482: } 3483: 3484: /* Delete the instruction JUMP from any jump chain it might be on. */ 3485: 3486: static void 3487: delete_from_jump_chain (jump) 3488: rtx jump; 3489: { 3490: int index; 3491: rtx olabel = JUMP_LABEL (jump); 3492: 3493: /* Handle unconditional jumps. */ 3494: if (jump_chain && olabel != 0 3495: && INSN_UID (olabel) < max_jump_chain 3496: && simplejump_p (jump)) 3497: index = INSN_UID (olabel); 3498: /* Handle return insns. */ 3499: else if (jump_chain && GET_CODE (PATTERN (jump)) == RETURN) 3500: index = 0; 3501: else return; 3502: 3503: if (jump_chain[index] == jump) 3504: jump_chain[index] = jump_chain[INSN_UID (jump)]; 3505: else 3506: { 3507: rtx insn; 3508: 3509: for (insn = jump_chain[index]; 3510: insn != 0; 3511: insn = jump_chain[INSN_UID (insn)]) 3512: if (jump_chain[INSN_UID (insn)] == jump) 3513: { 3514: jump_chain[INSN_UID (insn)] = jump_chain[INSN_UID (jump)]; 3515: break; 3516: } 3517: } 3518: } 3519: 3520: /* If NLABEL is nonzero, throughout the rtx at LOC, 3521: alter (LABEL_REF OLABEL) to (LABEL_REF NLABEL). If OLABEL is 3522: zero, alter (RETURN) to (LABEL_REF NLABEL). 3523: 3524: If NLABEL is zero, alter (LABEL_REF OLABEL) to (RETURN) and check 3525: validity with validate_change. Convert (set (pc) (label_ref olabel)) 3526: to (return). 3527: 3528: Return 0 if we found a change we would like to make but it is invalid. 3529: Otherwise, return 1. */ 3530: 1.1.1.4 ! root 3531: int 1.1 root 3532: redirect_exp (loc, olabel, nlabel, insn) 3533: rtx *loc; 3534: rtx olabel, nlabel; 3535: rtx insn; 3536: { 3537: register rtx x = *loc; 3538: register RTX_CODE code = GET_CODE (x); 3539: register int i; 3540: register char *fmt; 3541: 3542: if (code == LABEL_REF) 3543: { 3544: if (XEXP (x, 0) == olabel) 3545: { 3546: if (nlabel) 3547: XEXP (x, 0) = nlabel; 3548: else 3549: return validate_change (insn, loc, gen_rtx (RETURN, VOIDmode), 0); 3550: return 1; 3551: } 3552: } 3553: else if (code == RETURN && olabel == 0) 3554: { 3555: x = gen_rtx (LABEL_REF, VOIDmode, nlabel); 3556: if (loc == &PATTERN (insn)) 3557: x = gen_rtx (SET, VOIDmode, pc_rtx, x); 3558: return validate_change (insn, loc, x, 0); 3559: } 3560: 3561: if (code == SET && nlabel == 0 && SET_DEST (x) == pc_rtx 3562: && GET_CODE (SET_SRC (x)) == LABEL_REF 3563: && XEXP (SET_SRC (x), 0) == olabel) 3564: return validate_change (insn, loc, gen_rtx (RETURN, VOIDmode), 0); 3565: 3566: fmt = GET_RTX_FORMAT (code); 3567: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 3568: { 3569: if (fmt[i] == 'e') 3570: if (! redirect_exp (&XEXP (x, i), olabel, nlabel, insn)) 3571: return 0; 3572: if (fmt[i] == 'E') 3573: { 3574: register int j; 3575: for (j = 0; j < XVECLEN (x, i); j++) 3576: if (! redirect_exp (&XVECEXP (x, i, j), olabel, nlabel, insn)) 3577: return 0; 3578: } 3579: } 3580: 3581: return 1; 3582: } 3583: 3584: /* Make jump JUMP jump to label NLABEL, assuming it used to be a tablejump. 3585: 3586: If the old jump target label (before the dispatch table) becomes unused, 3587: it and the dispatch table may be deleted. In that case, find the insn 1.1.1.3 root 3588: before the jump references that label and delete it and logical successors 1.1 root 3589: too. */ 3590: 3591: void 3592: redirect_tablejump (jump, nlabel) 3593: rtx jump, nlabel; 3594: { 3595: register rtx olabel = JUMP_LABEL (jump); 3596: 3597: /* Add this jump to the jump_chain of NLABEL. */ 3598: if (jump_chain && INSN_UID (nlabel) < max_jump_chain 3599: && INSN_UID (jump) < max_jump_chain) 3600: { 3601: jump_chain[INSN_UID (jump)] = jump_chain[INSN_UID (nlabel)]; 3602: jump_chain[INSN_UID (nlabel)] = jump; 3603: } 3604: 3605: PATTERN (jump) = gen_jump (nlabel); 3606: JUMP_LABEL (jump) = nlabel; 3607: ++LABEL_NUSES (nlabel); 3608: INSN_CODE (jump) = -1; 3609: 3610: if (--LABEL_NUSES (olabel) == 0) 3611: { 3612: delete_labelref_insn (jump, olabel, 0); 3613: delete_insn (olabel); 3614: } 3615: } 3616: 3617: /* Find the insn referencing LABEL that is a logical predecessor of INSN. 3618: If we found one, delete it and then delete this insn if DELETE_THIS is 3619: non-zero. Return non-zero if INSN or a predecessor references LABEL. */ 3620: 3621: static int 3622: delete_labelref_insn (insn, label, delete_this) 3623: rtx insn, label; 3624: int delete_this; 3625: { 3626: int deleted = 0; 3627: rtx link; 3628: 3629: if (GET_CODE (insn) != NOTE 3630: && reg_mentioned_p (label, PATTERN (insn))) 3631: { 3632: if (delete_this) 3633: { 3634: delete_insn (insn); 3635: deleted = 1; 3636: } 3637: else 3638: return 1; 3639: } 3640: 3641: for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) 3642: if (delete_labelref_insn (XEXP (link, 0), label, 1)) 3643: { 3644: if (delete_this) 3645: { 3646: delete_insn (insn); 3647: deleted = 1; 3648: } 3649: else 3650: return 1; 3651: } 3652: 3653: return deleted; 3654: } 3655: 3656: /* Like rtx_equal_p except that it considers two REGs as equal 3657: if they renumber to the same value. */ 3658: 3659: int 3660: rtx_renumbered_equal_p (x, y) 3661: rtx x, y; 3662: { 3663: register int i; 3664: register RTX_CODE code = GET_CODE (x); 3665: register char *fmt; 3666: 3667: if (x == y) 3668: return 1; 3669: if ((code == REG || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG)) 3670: && (GET_CODE (y) == REG || (GET_CODE (y) == SUBREG 3671: && GET_CODE (SUBREG_REG (y)) == REG))) 3672: { 3673: register int j; 3674: 3675: if (GET_MODE (x) != GET_MODE (y)) 3676: return 0; 3677: 3678: /* If we haven't done any renumbering, don't 3679: make any assumptions. */ 3680: if (reg_renumber == 0) 3681: return rtx_equal_p (x, y); 3682: 3683: if (code == SUBREG) 3684: { 3685: i = REGNO (SUBREG_REG (x)); 3686: if (reg_renumber[i] >= 0) 3687: i = reg_renumber[i]; 3688: i += SUBREG_WORD (x); 3689: } 3690: else 3691: { 3692: i = REGNO (x); 3693: if (reg_renumber[i] >= 0) 3694: i = reg_renumber[i]; 3695: } 3696: if (GET_CODE (y) == SUBREG) 3697: { 3698: j = REGNO (SUBREG_REG (y)); 3699: if (reg_renumber[j] >= 0) 3700: j = reg_renumber[j]; 3701: j += SUBREG_WORD (y); 3702: } 3703: else 3704: { 3705: j = REGNO (y); 3706: if (reg_renumber[j] >= 0) 3707: j = reg_renumber[j]; 3708: } 3709: return i == j; 3710: } 3711: /* Now we have disposed of all the cases 3712: in which different rtx codes can match. */ 3713: if (code != GET_CODE (y)) 3714: return 0; 3715: switch (code) 3716: { 3717: case PC: 3718: case CC0: 3719: case ADDR_VEC: 3720: case ADDR_DIFF_VEC: 3721: return 0; 3722: 3723: case CONST_INT: 3724: return XINT (x, 0) == XINT (y, 0); 3725: 3726: case LABEL_REF: 1.1.1.4 ! root 3727: /* We can't assume nonlocal labels have their following insns yet. */ ! 3728: if (LABEL_REF_NONLOCAL_P (x) || LABEL_REF_NONLOCAL_P (y)) ! 3729: return XEXP (x, 0) == XEXP (y, 0); 1.1 root 3730: /* Two label-refs are equivalent if they point at labels 3731: in the same position in the instruction stream. */ 3732: return (next_real_insn (XEXP (x, 0)) 3733: == next_real_insn (XEXP (y, 0))); 3734: 3735: case SYMBOL_REF: 3736: return XSTR (x, 0) == XSTR (y, 0); 3737: } 3738: 3739: /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. */ 3740: 3741: if (GET_MODE (x) != GET_MODE (y)) 3742: return 0; 3743: 3744: /* Compare the elements. If any pair of corresponding elements 3745: fail to match, return 0 for the whole things. */ 3746: 3747: fmt = GET_RTX_FORMAT (code); 3748: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 3749: { 3750: register int j; 3751: switch (fmt[i]) 3752: { 1.1.1.4 ! root 3753: case 'w': ! 3754: if (XWINT (x, i) != XWINT (y, i)) ! 3755: return 0; ! 3756: break; ! 3757: 1.1 root 3758: case 'i': 3759: if (XINT (x, i) != XINT (y, i)) 3760: return 0; 3761: break; 3762: 3763: case 's': 3764: if (strcmp (XSTR (x, i), XSTR (y, i))) 3765: return 0; 3766: break; 3767: 3768: case 'e': 3769: if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i))) 3770: return 0; 3771: break; 3772: 3773: case 'u': 3774: if (XEXP (x, i) != XEXP (y, i)) 3775: return 0; 3776: /* fall through. */ 3777: case '0': 3778: break; 3779: 3780: case 'E': 3781: if (XVECLEN (x, i) != XVECLEN (y, i)) 3782: return 0; 3783: for (j = XVECLEN (x, i) - 1; j >= 0; j--) 3784: if (!rtx_renumbered_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j))) 3785: return 0; 3786: break; 3787: 3788: default: 3789: abort (); 3790: } 3791: } 3792: return 1; 3793: } 3794: 3795: /* If X is a hard register or equivalent to one or a subregister of one, 3796: return the hard register number. If X is a pseudo register that was not 3797: assigned a hard register, return the pseudo register number. Otherwise, 3798: return -1. Any rtx is valid for X. */ 3799: 3800: int 3801: true_regnum (x) 3802: rtx x; 3803: { 3804: if (GET_CODE (x) == REG) 3805: { 3806: if (REGNO (x) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (x)] >= 0) 3807: return reg_renumber[REGNO (x)]; 3808: return REGNO (x); 3809: } 3810: if (GET_CODE (x) == SUBREG) 3811: { 3812: int base = true_regnum (SUBREG_REG (x)); 3813: if (base >= 0 && base < FIRST_PSEUDO_REGISTER) 3814: return SUBREG_WORD (x) + base; 3815: } 3816: return -1; 3817: } 3818: 3819: /* Optimize code of the form: 3820: 3821: for (x = a[i]; x; ...) 3822: ... 3823: for (x = a[i]; x; ...) 3824: ... 3825: foo: 3826: 3827: Loop optimize will change the above code into 3828: 3829: if (x = a[i]) 3830: for (;;) 3831: { ...; if (! (x = ...)) break; } 3832: if (x = a[i]) 3833: for (;;) 3834: { ...; if (! (x = ...)) break; } 3835: foo: 3836: 3837: In general, if the first test fails, the program can branch 3838: directly to `foo' and skip the second try which is doomed to fail. 3839: We run this after loop optimization and before flow analysis. */ 3840: 3841: /* When comparing the insn patterns, we track the fact that different 3842: pseudo-register numbers may have been used in each computation. 3843: The following array stores an equivalence -- same_regs[I] == J means 3844: that pseudo register I was used in the first set of tests in a context 3845: where J was used in the second set. We also count the number of such 3846: pending equivalences. If nonzero, the expressions really aren't the 3847: same. */ 3848: 3849: static short *same_regs; 3850: 3851: static int num_same_regs; 3852: 3853: /* Track any registers modified between the target of the first jump and 3854: the second jump. They never compare equal. */ 3855: 3856: static char *modified_regs; 3857: 3858: /* Record if memory was modified. */ 3859: 3860: static int modified_mem; 3861: 3862: /* Called via note_stores on each insn between the target of the first 3863: branch and the second branch. It marks any changed registers. */ 3864: 3865: static void 3866: mark_modified_reg (dest, x) 3867: rtx dest; 3868: rtx x; 3869: { 3870: int regno, i; 3871: 3872: if (GET_CODE (dest) == SUBREG) 3873: dest = SUBREG_REG (dest); 3874: 3875: if (GET_CODE (dest) == MEM) 3876: modified_mem = 1; 3877: 3878: if (GET_CODE (dest) != REG) 3879: return; 3880: 3881: regno = REGNO (dest); 3882: if (regno >= FIRST_PSEUDO_REGISTER) 3883: modified_regs[regno] = 1; 3884: else 3885: for (i = 0; i < HARD_REGNO_NREGS (regno, GET_MODE (dest)); i++) 3886: modified_regs[regno + i] = 1; 3887: } 3888: 3889: /* F is the first insn in the chain of insns. */ 3890: 3891: void 3892: thread_jumps (f, max_reg, verbose) 3893: rtx f; 3894: int max_reg; 3895: int verbose; 3896: { 3897: /* Basic algorithm is to find a conditional branch, 3898: the label it may branch to, and the branch after 3899: that label. If the two branches test the same condition, 3900: walk back from both branch paths until the insn patterns 3901: differ, or code labels are hit. If we make it back to 3902: the target of the first branch, then we know that the first branch 3903: will either always succeed or always fail depending on the relative 3904: senses of the two branches. So adjust the first branch accordingly 3905: in this case. */ 3906: 3907: rtx label, b1, b2, t1, t2; 3908: enum rtx_code code1, code2; 3909: rtx b1op0, b1op1, b2op0, b2op1; 3910: int changed = 1; 3911: int i; 3912: short *all_reset; 3913: 3914: /* Allocate register tables and quick-reset table. */ 3915: modified_regs = (char *) alloca (max_reg * sizeof (char)); 3916: same_regs = (short *) alloca (max_reg * sizeof (short)); 3917: all_reset = (short *) alloca (max_reg * sizeof (short)); 3918: for (i = 0; i < max_reg; i++) 3919: all_reset[i] = -1; 3920: 3921: while (changed) 3922: { 3923: changed = 0; 3924: 3925: for (b1 = f; b1; b1 = NEXT_INSN (b1)) 3926: { 3927: /* Get to a candidate branch insn. */ 3928: if (GET_CODE (b1) != JUMP_INSN 3929: || ! condjump_p (b1) || simplejump_p (b1) 3930: || JUMP_LABEL (b1) == 0) 3931: continue; 3932: 3933: bzero (modified_regs, max_reg * sizeof (char)); 3934: modified_mem = 0; 3935: 3936: bcopy (all_reset, same_regs, max_reg * sizeof (short)); 3937: num_same_regs = 0; 3938: 3939: label = JUMP_LABEL (b1); 3940: 3941: /* Look for a branch after the target. Record any registers and 3942: memory modified between the target and the branch. Stop when we 3943: get to a label since we can't know what was changed there. */ 3944: for (b2 = NEXT_INSN (label); b2; b2 = NEXT_INSN (b2)) 3945: { 3946: if (GET_CODE (b2) == CODE_LABEL) 3947: break; 3948: 3949: else if (GET_CODE (b2) == JUMP_INSN) 3950: { 3951: /* If this is an unconditional jump and is the only use of 3952: its target label, we can follow it. */ 3953: if (simplejump_p (b2) 3954: && JUMP_LABEL (b2) != 0 3955: && LABEL_NUSES (JUMP_LABEL (b2)) == 1) 3956: { 3957: b2 = JUMP_LABEL (b2); 3958: continue; 3959: } 3960: else 3961: break; 3962: } 3963: 3964: if (GET_CODE (b2) != CALL_INSN && GET_CODE (b2) != INSN) 3965: continue; 3966: 3967: if (GET_CODE (b2) == CALL_INSN) 3968: { 3969: modified_mem = 1; 3970: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 3971: if (call_used_regs[i] && ! fixed_regs[i] 3972: && i != STACK_POINTER_REGNUM 3973: && i != FRAME_POINTER_REGNUM 3974: && i != ARG_POINTER_REGNUM) 3975: modified_regs[i] = 1; 3976: } 3977: 3978: note_stores (PATTERN (b2), mark_modified_reg); 3979: } 3980: 3981: /* Check the next candidate branch insn from the label 3982: of the first. */ 3983: if (b2 == 0 3984: || GET_CODE (b2) != JUMP_INSN 3985: || b2 == b1 3986: || ! condjump_p (b2) 3987: || simplejump_p (b2)) 3988: continue; 3989: 3990: /* Get the comparison codes and operands, reversing the 3991: codes if appropriate. If we don't have comparison codes, 3992: we can't do anything. */ 3993: b1op0 = XEXP (XEXP (SET_SRC (PATTERN (b1)), 0), 0); 3994: b1op1 = XEXP (XEXP (SET_SRC (PATTERN (b1)), 0), 1); 3995: code1 = GET_CODE (XEXP (SET_SRC (PATTERN (b1)), 0)); 3996: if (XEXP (SET_SRC (PATTERN (b1)), 1) == pc_rtx) 3997: code1 = reverse_condition (code1); 3998: 3999: b2op0 = XEXP (XEXP (SET_SRC (PATTERN (b2)), 0), 0); 4000: b2op1 = XEXP (XEXP (SET_SRC (PATTERN (b2)), 0), 1); 4001: code2 = GET_CODE (XEXP (SET_SRC (PATTERN (b2)), 0)); 4002: if (XEXP (SET_SRC (PATTERN (b2)), 1) == pc_rtx) 4003: code2 = reverse_condition (code2); 4004: 4005: /* If they test the same things and knowing that B1 branches 4006: tells us whether or not B2 branches, check if we 4007: can thread the branch. */ 4008: if (rtx_equal_for_thread_p (b1op0, b2op0, b2) 4009: && rtx_equal_for_thread_p (b1op1, b2op1, b2) 4010: && (comparison_dominates_p (code1, code2) 4011: || comparison_dominates_p (code1, reverse_condition (code2)))) 4012: { 4013: t1 = prev_nonnote_insn (b1); 4014: t2 = prev_nonnote_insn (b2); 4015: 4016: while (t1 != 0 && t2 != 0) 4017: { 4018: if (t1 == 0 || t2 == 0) 4019: break; 4020: 4021: if (t2 == label) 4022: { 4023: /* We have reached the target of the first branch. 4024: If there are no pending register equivalents, 4025: we know that this branch will either always 4026: succeed (if the senses of the two branches are 4027: the same) or always fail (if not). */ 4028: rtx new_label; 4029: 4030: if (num_same_regs != 0) 4031: break; 4032: 4033: if (comparison_dominates_p (code1, code2)) 4034: new_label = JUMP_LABEL (b2); 4035: else 4036: new_label = get_label_after (b2); 4037: 4038: if (JUMP_LABEL (b1) != new_label 4039: && redirect_jump (b1, new_label)) 4040: changed = 1; 4041: break; 4042: } 4043: 4044: /* If either of these is not a normal insn (it might be 4045: a JUMP_INSN, CALL_INSN, or CODE_LABEL) we fail. (NOTEs 4046: have already been skipped above.) Similarly, fail 4047: if the insns are different. */ 4048: if (GET_CODE (t1) != INSN || GET_CODE (t2) != INSN 4049: || recog_memoized (t1) != recog_memoized (t2) 4050: || ! rtx_equal_for_thread_p (PATTERN (t1), 4051: PATTERN (t2), t2)) 4052: break; 4053: 4054: t1 = prev_nonnote_insn (t1); 4055: t2 = prev_nonnote_insn (t2); 4056: } 4057: } 4058: } 4059: } 4060: } 4061: 4062: /* This is like RTX_EQUAL_P except that it knows about our handling of 4063: possibly equivalent registers and knows to consider volatile and 4064: modified objects as not equal. 4065: 4066: YINSN is the insn containing Y. */ 4067: 4068: int 4069: rtx_equal_for_thread_p (x, y, yinsn) 4070: rtx x, y; 4071: rtx yinsn; 4072: { 4073: register int i; 4074: register int j; 4075: register enum rtx_code code; 4076: register char *fmt; 4077: 4078: code = GET_CODE (x); 4079: /* Rtx's of different codes cannot be equal. */ 4080: if (code != GET_CODE (y)) 4081: return 0; 4082: 4083: /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent. 4084: (REG:SI x) and (REG:HI x) are NOT equivalent. */ 4085: 4086: if (GET_MODE (x) != GET_MODE (y)) 4087: return 0; 4088: 4089: /* Handle special-cases first. */ 4090: switch (code) 4091: { 4092: case REG: 4093: if (REGNO (x) == REGNO (y) && ! modified_regs[REGNO (x)]) 4094: return 1; 4095: 4096: /* If neither is user variable or hard register, check for possible 4097: equivalence. */ 4098: if (REG_USERVAR_P (x) || REG_USERVAR_P (y) 4099: || REGNO (x) < FIRST_PSEUDO_REGISTER 4100: || REGNO (y) < FIRST_PSEUDO_REGISTER) 4101: return 0; 4102: 4103: if (same_regs[REGNO (x)] == -1) 4104: { 4105: same_regs[REGNO (x)] = REGNO (y); 4106: num_same_regs++; 4107: 4108: /* If this is the first time we are seeing a register on the `Y' 4109: side, see if it is the last use. If not, we can't thread the 4110: jump, so mark it as not equivalent. */ 4111: if (regno_last_uid[REGNO (y)] != INSN_UID (yinsn)) 4112: return 0; 4113: 4114: return 1; 4115: } 4116: else 4117: return (same_regs[REGNO (x)] == REGNO (y)); 4118: 4119: break; 4120: 4121: case MEM: 1.1.1.3 root 4122: /* If memory modified or either volatile, not equivalent. 1.1 root 4123: Else, check address. */ 4124: if (modified_mem || MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y)) 4125: return 0; 4126: 4127: return rtx_equal_for_thread_p (XEXP (x, 0), XEXP (y, 0), yinsn); 4128: 4129: case ASM_INPUT: 4130: if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y)) 4131: return 0; 4132: 4133: break; 4134: 4135: case SET: 4136: /* Cancel a pending `same_regs' if setting equivalenced registers. 4137: Then process source. */ 4138: if (GET_CODE (SET_DEST (x)) == REG 4139: && GET_CODE (SET_DEST (y)) == REG) 4140: { 4141: if (same_regs[REGNO (SET_DEST (x))] == REGNO (SET_DEST (y))) 4142: { 4143: same_regs[REGNO (SET_DEST (x))] = -1; 4144: num_same_regs--; 4145: } 4146: else if (REGNO (SET_DEST (x)) != REGNO (SET_DEST (y))) 4147: return 0; 4148: } 4149: else 4150: if (rtx_equal_for_thread_p (SET_DEST (x), SET_DEST (y), yinsn) == 0) 4151: return 0; 4152: 4153: return rtx_equal_for_thread_p (SET_SRC (x), SET_SRC (y), yinsn); 4154: 4155: case LABEL_REF: 4156: return XEXP (x, 0) == XEXP (y, 0); 4157: 4158: case SYMBOL_REF: 4159: return XSTR (x, 0) == XSTR (y, 0); 4160: } 4161: 4162: if (x == y) 4163: return 1; 4164: 4165: fmt = GET_RTX_FORMAT (code); 4166: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 4167: { 4168: switch (fmt[i]) 4169: { 1.1.1.4 ! root 4170: case 'w': ! 4171: if (XWINT (x, i) != XWINT (y, i)) ! 4172: return 0; ! 4173: break; ! 4174: 1.1 root 4175: case 'n': 4176: case 'i': 4177: if (XINT (x, i) != XINT (y, i)) 4178: return 0; 4179: break; 4180: 4181: case 'V': 4182: case 'E': 4183: /* Two vectors must have the same length. */ 4184: if (XVECLEN (x, i) != XVECLEN (y, i)) 4185: return 0; 4186: 4187: /* And the corresponding elements must match. */ 4188: for (j = 0; j < XVECLEN (x, i); j++) 4189: if (rtx_equal_for_thread_p (XVECEXP (x, i, j), 4190: XVECEXP (y, i, j), yinsn) == 0) 4191: return 0; 4192: break; 4193: 4194: case 'e': 4195: if (rtx_equal_for_thread_p (XEXP (x, i), XEXP (y, i), yinsn) == 0) 4196: return 0; 4197: break; 4198: 4199: case 'S': 4200: case 's': 4201: if (strcmp (XSTR (x, i), XSTR (y, i))) 4202: return 0; 4203: break; 4204: 4205: case 'u': 4206: /* These are just backpointers, so they don't matter. */ 4207: break; 4208: 4209: case '0': 4210: break; 4211: 4212: /* It is believed that rtx's at this level will never 4213: contain anything but integers and other rtx's, 4214: except for within LABEL_REFs and SYMBOL_REFs. */ 4215: default: 4216: abort (); 4217: } 4218: } 4219: return 1; 4220: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.