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