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