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