From 4a8cae8370a9c7ccaff2df5b552f52db51eb9f9b Mon Sep 17 00:00:00 2001 From: Steven Bosscher Date: Tue, 17 Jun 2008 05:57:04 +0000 Subject: [PATCH] Remove libcall notes. * see.c (see_analyse_one_def): Do not look for REG_LIBCALL and REG_RETVAL notes. (see_update_relevancy): Likewise. * fwprop.c (try_fwprop_subst): Likewise. * rtlanal.c (noop_move_p): Likewise. * builtins.c (expand_buitlin_mathfn): Don't try to add REG_EQUAL notes to non-existing libcall blocks. * cse.c (cse_insn): Change prototype. Don't update libcall notes. Remove orig_set. (cse_extended_basic_block): Don't track libcall and no-conflict notes. (dead_libcall_p): Remove. (delete_trivially_dead_insns): Don't use it. * web.c (union_defs): Remove comment about keeping nops. * gcse.c (hash_scan_insn): Don't take libcall pointers. (compute_hash_table_work): Don't track libcall notes. (do_local_cprop): Don't take libcall pointers. Don't update libcall notes. (adjust_libcall_notes): Deleted. (local_cprop_pass): Remove stack for nested libcalls (which shouldn't ever have existed in the first place). (replace_store_insn): Don't try to remove libcall notes. * lower-subreg.c (move_libcall_note, move_retval_note): Deleted. (resolve_reg_notes): Don't call them. (resolve_simple_move): Likewise. (decompose_multiword_subregs): Remove block handling REG_RETVAL notes. Don't remove REG_RETVAL notes. * emit-rtl.c (try_split): Don't update libcall notes. (emit_copy_of_insn_after): Dito. * cselib.c (cselib_current_insn_in_libcall): Remove. (cselib_process_insn): Don't set/clear it. (new_elt_loc_list): Don't record it. (cselib_init): Don't initialize it. * cselib.c (struct elt_loc_list): Remove in_libcall field. * loop-invariant.c (find_invariant_insn): Don't look for libcall notes. * sched-deps.c (sched_analyze_insn): Don't group libcall blocks. (sched_analyze): Don't set up deps->libcall_block_tail_insn. (init_deps): Don't initialize it. * sched-int.h (struct deps): Rremove libcall_block_tail_insn field. * combine.c (delete_noop_moves): Don't update libcall notes. (can_combine_p): Remove now pointless #if 0 block. (try_combine): Remove another obsolete #if 0 block. (distribute_notes): Don't distribute libcall notes. * reg-notes.def (REG_LIBCALL, REG_RETVAL): Remove. * dce.c (libcall_dead_p): Remove. (delete_unmarked_insns): Don't handle libcall blocks. (preserve_libcall_for_dce): Remove. (prescan_insns_for_dce): Don't special-case libcall block insns. * reload1 (reload): Don't handle libcall notes. * doc/rtl.texi (REG_LIBCALL, REG_RETVAL, REG_LIBCALL_ID): Remove documentation. From-SVN: r136861 --- gcc/ChangeLog | 54 +++++++++++++ gcc/builtins.c | 43 +--------- gcc/combine.c | 78 +----------------- gcc/cse.c | 186 +++++-------------------------------------- gcc/cselib.c | 11 --- gcc/cselib.h | 2 - gcc/dce.c | 152 +---------------------------------- gcc/doc/rtl.texi | 31 -------- gcc/emit-rtl.c | 39 +-------- gcc/fwprop.c | 7 +- gcc/gcse.c | 130 +++--------------------------- gcc/loop-invariant.c | 11 +-- gcc/lower-subreg.c | 94 ++-------------------- gcc/reg-notes.def | 16 +--- gcc/reload1.c | 9 +-- gcc/rtlanal.c | 5 -- gcc/sched-deps.c | 52 ------------ gcc/sched-int.h | 6 -- gcc/see.c | 12 +-- gcc/web.c | 4 +- 20 files changed, 109 insertions(+), 833 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8e205af3eac..91430aff4a0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,57 @@ +2008-06-17 Steven Bosscher + + * see.c (see_analyse_one_def): Do not look for REG_LIBCALL and + REG_RETVAL notes. + (see_update_relevancy): Likewise. + * fwprop.c (try_fwprop_subst): Likewise. + * rtlanal.c (noop_move_p): Likewise. + * builtins.c (expand_buitlin_mathfn): Don't try to add REG_EQUAL + notes to non-existing libcall blocks. + * cse.c (cse_insn): Change prototype. Don't update libcall notes. + Remove orig_set. + (cse_extended_basic_block): Don't track libcall and no-conflict notes. + (dead_libcall_p): Remove. + (delete_trivially_dead_insns): Don't use it. + * web.c (union_defs): Remove comment about keeping nops. + * gcse.c (hash_scan_insn): Don't take libcall pointers. + (compute_hash_table_work): Don't track libcall notes. + (do_local_cprop): Don't take libcall pointers. Don't update + libcall notes. + (adjust_libcall_notes): Deleted. + (local_cprop_pass): Remove stack for nested libcalls (which shouldn't + ever have existed in the first place). + (replace_store_insn): Don't try to remove libcall notes. + * lower-subreg.c (move_libcall_note, move_retval_note): Deleted. + (resolve_reg_notes): Don't call them. + (resolve_simple_move): Likewise. + (decompose_multiword_subregs): Remove block handling REG_RETVAL notes. + Don't remove REG_RETVAL notes. + * emit-rtl.c (try_split): Don't update libcall notes. + (emit_copy_of_insn_after): Dito. + * cselib.c (cselib_current_insn_in_libcall): Remove. + (cselib_process_insn): Don't set/clear it. + (new_elt_loc_list): Don't record it. + (cselib_init): Don't initialize it. + * cselib.c (struct elt_loc_list): Remove in_libcall field. + * loop-invariant.c (find_invariant_insn): Don't look for libcall + notes. + * sched-deps.c (sched_analyze_insn): Don't group libcall blocks. + (sched_analyze): Don't set up deps->libcall_block_tail_insn. + (init_deps): Don't initialize it. + * sched-int.h (struct deps): Rremove libcall_block_tail_insn field. + * combine.c (delete_noop_moves): Don't update libcall notes. + (can_combine_p): Remove now pointless #if 0 block. + (try_combine): Remove another obsolete #if 0 block. + (distribute_notes): Don't distribute libcall notes. + * reg-notes.def (REG_LIBCALL, REG_RETVAL): Remove. + * dce.c (libcall_dead_p): Remove. + (delete_unmarked_insns): Don't handle libcall blocks. + (preserve_libcall_for_dce): Remove. + (prescan_insns_for_dce): Don't special-case libcall block insns. + * reload1 (reload): Don't handle libcall notes. + * doc/rtl.texi (REG_LIBCALL, REG_RETVAL, REG_LIBCALL_ID): Remove + documentation. + 2008-06-16 Eric B. Weddington * config/avr/avr.c (avr_mcu_t): Add atmega32c1. diff --git a/gcc/builtins.c b/gcc/builtins.c index b3fc3041377..57d9379983b 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1945,48 +1945,7 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) before_call = get_last_insn (); - target = expand_call (exp, target, target == const0_rtx); - - /* If this is a sqrt operation and we don't care about errno, try to - attach a REG_EQUAL note with a SQRT rtx to the emitted libcall. - This allows the semantics of the libcall to be visible to the RTL - optimizers. */ - if (builtin_optab == sqrt_optab && !errno_set) - { - /* Search backwards through the insns emitted by expand_call looking - for the instruction with the REG_RETVAL note. */ - rtx last = get_last_insn (); - while (last != before_call) - { - if (find_reg_note (last, REG_RETVAL, NULL)) - { - rtx note = find_reg_note (last, REG_EQUAL, NULL); - /* Check that the REQ_EQUAL note is an EXPR_LIST with - two elements, i.e. symbol_ref(sqrt) and the operand. */ - if (note - && GET_CODE (note) == EXPR_LIST - && GET_CODE (XEXP (note, 0)) == EXPR_LIST - && XEXP (XEXP (note, 0), 1) != NULL_RTX - && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX) - { - rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0); - /* Check operand is a register with expected mode. */ - if (operand - && REG_P (operand) - && GET_MODE (operand) == mode) - { - /* Replace the REG_EQUAL note with a SQRT rtx. */ - rtx equiv = gen_rtx_SQRT (mode, operand); - set_unique_reg_note (last, REG_EQUAL, equiv); - } - } - break; - } - last = PREV_INSN (last); - } - } - - return target; + return expand_call (exp, target, target == const0_rtx); } /* Expand a call to the builtin binary math functions (pow and atan2). diff --git a/gcc/combine.c b/gcc/combine.c index c194d663ba3..79d96ed3763 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -882,23 +882,6 @@ delete_noop_moves (void) next = NEXT_INSN (insn); if (INSN_P (insn) && noop_move_p (insn)) { - rtx note; - - /* If we're about to remove the first insn of a libcall - then move the libcall note to the next real insn and - update the retval note. */ - if ((note = find_reg_note (insn, REG_LIBCALL, NULL_RTX)) - && XEXP (note, 0) != insn) - { - rtx new_libcall_insn = next_real_insn (insn); - rtx retval_note = find_reg_note (XEXP (note, 0), - REG_RETVAL, NULL_RTX); - REG_NOTES (new_libcall_insn) - = gen_rtx_INSN_LIST (REG_LIBCALL, XEXP (note, 0), - REG_NOTES (new_libcall_insn)); - XEXP (retval_note, 0) = new_libcall_insn; - } - if (dump_file) fprintf (dump_file, "deleting noop move %d\n", INSN_UID (insn)); @@ -1676,14 +1659,6 @@ can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ, || (succ && FIND_REG_INC_NOTE (succ, dest)) /* Don't substitute into a non-local goto, this confuses CFG. */ || (JUMP_P (i3) && find_reg_note (i3, REG_NON_LOCAL_GOTO, NULL_RTX)) -#if 0 - /* Don't combine the end of a libcall into anything. */ - /* ??? This gives worse code, and appears to be unnecessary, since no - pass after flow uses REG_LIBCALL/REG_RETVAL notes. Local-alloc does - use REG_RETVAL notes for noconflict blocks, but other code here - makes sure that those insns don't disappear. */ - || find_reg_note (insn, REG_RETVAL, NULL_RTX) -#endif /* Make sure that DEST is not used after SUCC but before I3. */ || (succ && ! all_adjacent && reg_used_between_p (dest, succ, i3)) @@ -2241,16 +2216,7 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p) if (cant_combine_insn_p (i3) || cant_combine_insn_p (i2) || (i1 && cant_combine_insn_p (i1)) - || likely_spilled_retval_p (i3) - /* We also can't do anything if I3 has a - REG_LIBCALL note since we don't want to disrupt the contiguity of a - libcall. */ -#if 0 - /* ??? This gives worse code, and appears to be unnecessary, since no - pass after flow uses REG_LIBCALL/REG_RETVAL notes. */ - || find_reg_note (i3, REG_LIBCALL, NULL_RTX) -#endif - ) + || likely_spilled_retval_p (i3)) return 0; combine_attempts++; @@ -12547,48 +12513,6 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2, to simply delete it. */ break; - case REG_RETVAL: - /* If the insn previously containing this note still exists, - put it back where it was. Otherwise move it to the previous - insn. Adjust the corresponding REG_LIBCALL note. */ - if (!NOTE_P (from_insn)) - place = from_insn; - else - { - tem = find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX); - place = prev_real_insn (from_insn); - if (tem && place) - XEXP (tem, 0) = place; - /* If we're deleting the last remaining instruction of a - libcall sequence, don't add the notes. */ - else if (XEXP (note, 0) == from_insn) - tem = place = 0; - /* Don't add the dangling REG_RETVAL note. */ - else if (! tem) - place = 0; - } - break; - - case REG_LIBCALL: - /* This is handled similarly to REG_RETVAL. */ - if (!NOTE_P (from_insn)) - place = from_insn; - else - { - tem = find_reg_note (XEXP (note, 0), REG_RETVAL, NULL_RTX); - place = next_real_insn (from_insn); - if (tem && place) - XEXP (tem, 0) = place; - /* If we're deleting the last remaining instruction of a - libcall sequence, don't add the notes. */ - else if (XEXP (note, 0) == from_insn) - tem = place = 0; - /* Don't add the dangling REG_LIBCALL note. */ - else if (! tem) - place = 0; - } - break; - case REG_DEAD: /* If we replaced the right hand side of FROM_INSN with a REG_EQUAL note, the original use of the dying register diff --git a/gcc/cse.c b/gcc/cse.c index 73eb1c6805b..02420f1a076 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -584,7 +584,7 @@ static rtx equiv_constant (rtx); static void record_jump_equiv (rtx, bool); static void record_jump_cond (enum rtx_code, enum machine_mode, rtx, rtx, int); -static void cse_insn (rtx, rtx); +static void cse_insn (rtx); static void cse_prescan_path (struct cse_basic_block_data *); static void invalidate_from_clobbers (rtx); static rtx cse_process_notes (rtx, rtx, bool *); @@ -599,7 +599,6 @@ static int check_dependence (rtx *, void *); static void flush_hash_table (void); static bool insn_live_p (rtx, int *); static bool set_live_p (rtx, rtx, int *); -static bool dead_libcall_p (rtx, int *); static int cse_change_cc_mode (rtx *, void *); static void cse_change_cc_mode_insn (rtx, rtx); static void cse_change_cc_mode_insns (rtx, rtx, rtx); @@ -3929,11 +3928,7 @@ record_jump_cond (enum rtx_code code, enum machine_mode mode, rtx op0, First simplify sources and addresses of all assignments in the instruction, using previously-computed equivalents values. Then install the new sources and destinations in the table - of available values. - - If LIBCALL_INSN is nonzero, don't record any equivalence made in - the insn. It means that INSN is inside libcall block. In this - case LIBCALL_INSN is the corresponding insn with REG_LIBCALL. */ + of available values. */ /* Data on one SET contained in the instruction. */ @@ -3962,8 +3957,6 @@ struct set ENUM_BITFIELD(machine_mode) mode : 8; /* A constant equivalent for SET_SRC, if any. */ rtx src_const; - /* Original SET_SRC value used for libcall notes. */ - rtx orig_src; /* Hash value of constant equivalent for SET_SRC. */ unsigned src_const_hash; /* Table entry for constant equivalent for SET_SRC, if any. */ @@ -3973,7 +3966,7 @@ struct set }; static void -cse_insn (rtx insn, rtx libcall_insn) +cse_insn (rtx insn) { rtx x = PATTERN (insn); int i; @@ -4170,7 +4163,6 @@ cse_insn (rtx insn, rtx libcall_insn) rtx src = SET_SRC (sets[i].rtl); rtx new = canon_reg (src, insn); - sets[i].orig_src = src; validate_change (insn, &SET_SRC (sets[i].rtl), new, 1); if (GET_CODE (dest) == ZERO_EXTRACT) @@ -4821,22 +4813,6 @@ cse_insn (rtx insn, rtx libcall_insn) { rtx new = canon_reg (SET_SRC (sets[i].rtl), insn); - /* If we just made a substitution inside a libcall, then we - need to make the same substitution in any notes attached - to the RETVAL insn. */ - if (libcall_insn - && (REG_P (sets[i].orig_src) - || GET_CODE (sets[i].orig_src) == SUBREG - || MEM_P (sets[i].orig_src))) - { - rtx note = find_reg_equal_equiv_note (libcall_insn); - if (note != 0) - XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), - sets[i].orig_src, - copy_rtx (new)); - df_notes_rescan (libcall_insn); - } - /* The result of apply_change_group can be ignored; see canon_reg. */ @@ -5175,27 +5151,19 @@ cse_insn (rtx insn, rtx libcall_insn) if (sets[i].src_elt == 0) { - /* Don't put a hard register source into the table if this is - the last insn of a libcall. In this case, we only need - to put src_eqv_elt in src_elt. */ - if (! find_reg_note (insn, REG_RETVAL, NULL_RTX)) - { - struct table_elt *elt; + struct table_elt *elt; - /* Note that these insert_regs calls cannot remove - any of the src_elt's, because they would have failed to - match if not still valid. */ - if (insert_regs (src, classp, 0)) - { - rehash_using_reg (src); - sets[i].src_hash = HASH (src, mode); - } - elt = insert (src, classp, sets[i].src_hash, mode); - elt->in_memory = sets[i].src_in_memory; - sets[i].src_elt = classp = elt; + /* Note that these insert_regs calls cannot remove + any of the src_elt's, because they would have failed to + match if not still valid. */ + if (insert_regs (src, classp, 0)) + { + rehash_using_reg (src); + sets[i].src_hash = HASH (src, mode); } - else - sets[i].src_elt = classp; + elt = insert (src, classp, sets[i].src_hash, mode); + elt->in_memory = sets[i].src_in_memory; + sets[i].src_elt = classp = elt; } if (sets[i].src_const && sets[i].src_const_elt == 0 && src != sets[i].src_const @@ -5392,11 +5360,6 @@ cse_insn (rtx insn, rtx libcall_insn) size of it, and can't be sure that other BLKmode values have the same or smaller size. */ || GET_MODE (dest) == BLKmode - /* Don't record values of destinations set inside a libcall block - since we might delete the libcall. Things should have been set - up so we won't want to reuse such a value, but we play it safe - here. */ - || libcall_insn /* If we didn't put a REG_EQUAL value or a source into the hash table, there is no point is recording DEST. */ || sets[i].src_elt == 0 @@ -5540,11 +5503,7 @@ cse_insn (rtx insn, rtx libcall_insn) then be used in the sequel and we may be changing a two-operand insn into a three-operand insn. - Also do not do this if we are operating on a copy of INSN. - - Also don't do this if INSN ends a libcall; this would cause an unrelated - register to be set in the middle of a libcall, and we then get bad code - if the libcall is deleted. */ + Also do not do this if we are operating on a copy of INSN. */ if (n_sets == 1 && sets[0].rtl && REG_P (SET_DEST (sets[0].rtl)) && NEXT_INSN (PREV_INSN (insn)) == insn @@ -5555,8 +5514,7 @@ cse_insn (rtx insn, rtx libcall_insn) int src_q = REG_QTY (REGNO (SET_SRC (sets[0].rtl))); struct qty_table_elem *src_ent = &qty_table[src_q]; - if ((src_ent->first_reg == REGNO (SET_DEST (sets[0].rtl))) - && ! find_reg_note (insn, REG_RETVAL, NULL_RTX)) + if (src_ent->first_reg == REGNO (SET_DEST (sets[0].rtl))) { /* Scan for the previous nonnote insn, but stop at a basic block boundary. */ @@ -5993,8 +5951,6 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data) { basic_block bb; rtx insn; - rtx libcall_insn = NULL_RTX; - int no_conflict = 0; bb = ebb_data->path[path_entry].bb; @@ -6043,39 +5999,8 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data) df_notes_rescan (insn); } - /* Track when we are inside in LIBCALL block. Inside such - a block we do not want to record destinations. The last - insn of a LIBCALL block is not considered to be part of - the block, since its destination is the result of the - block and hence should be recorded. */ - if (REG_NOTES (insn) != 0) - { - rtx p; + cse_insn (insn); - if ((p = find_reg_note (insn, REG_LIBCALL, NULL_RTX))) - libcall_insn = XEXP (p, 0); - else if (find_reg_note (insn, REG_RETVAL, NULL_RTX)) - { - /* Keep libcall_insn for the last SET insn of - a no-conflict block to prevent changing the - destination. */ - if (!no_conflict) - libcall_insn = NULL_RTX; - else - no_conflict = -1; - } - } - - cse_insn (insn, libcall_insn); - - /* If we kept libcall_insn for a no-conflict bock, - clear it here. */ - if (no_conflict == -1) - { - libcall_insn = NULL_RTX; - no_conflict = 0; - } - /* If we haven't already found an insn where we added a LABEL_REF, check this one. */ if (INSN_P (insn) && !recorded_label_ref @@ -6112,9 +6037,6 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data) } } - /* Make sure that libcalls don't span multiple basic blocks. */ - gcc_assert (libcall_insn == NULL_RTX); - /* With non-call exceptions, we are not always able to update the CFG properly inside cse_insn. So clean up possibly redundant EH edges here. */ @@ -6479,57 +6401,6 @@ insn_live_p (rtx insn, int *counts) return true; } -/* Return true if libcall is dead as a whole. */ - -static bool -dead_libcall_p (rtx insn, int *counts) -{ - rtx note, set, new; - - /* See if there's a REG_EQUAL note on this insn and try to - replace the source with the REG_EQUAL expression. - - We assume that insns with REG_RETVALs can only be reg->reg - copies at this point. */ - note = find_reg_note (insn, REG_EQUAL, NULL_RTX); - if (!note) - return false; - - set = single_set (insn); - if (!set) - return false; - - new = simplify_rtx (XEXP (note, 0)); - if (!new) - new = XEXP (note, 0); - - /* While changing insn, we must update the counts accordingly. */ - count_reg_usage (insn, counts, NULL_RTX, -1); - - if (validate_change (insn, &SET_SRC (set), new, 0)) - { - count_reg_usage (insn, counts, NULL_RTX, 1); - remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX)); - remove_note (insn, note); - return true; - } - - if (CONSTANT_P (new)) - { - new = force_const_mem (GET_MODE (SET_DEST (set)), new); - if (new && validate_change (insn, &SET_SRC (set), new, 0)) - { - count_reg_usage (insn, counts, NULL_RTX, 1); - remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX)); - remove_note (insn, note); - return true; - } - } - - count_reg_usage (insn, counts, NULL_RTX, 1); - return false; -} - /* Scan all the insns and delete any that are dead; i.e., they store a register that is never used or they copy a register to itself. @@ -6543,7 +6414,6 @@ delete_trivially_dead_insns (rtx insns, int nreg) { int *counts; rtx insn, prev; - int in_libcall = 0, dead_libcall = 0; int ndead = 0; timevar_push (TV_DELETE_TRIVIALLY_DEAD); @@ -6568,21 +6438,7 @@ delete_trivially_dead_insns (rtx insns, int nreg) if (!INSN_P (insn)) continue; - /* Don't delete any insns that are part of a libcall block unless - we can delete the whole libcall block. - - Flow or loop might get confused if we did that. Remember - that we are scanning backwards. */ - if (find_reg_note (insn, REG_RETVAL, NULL_RTX)) - { - in_libcall = 1; - live_insn = 1; - dead_libcall = dead_libcall_p (insn, counts); - } - else if (in_libcall) - live_insn = ! dead_libcall; - else - live_insn = insn_live_p (insn, counts); + live_insn = insn_live_p (insn, counts); /* If this is a dead insn, delete it and show registers in it aren't being used. */ @@ -6593,12 +6449,6 @@ delete_trivially_dead_insns (rtx insns, int nreg) delete_insn_and_edges (insn); ndead++; } - - if (in_libcall && find_reg_note (insn, REG_LIBCALL, NULL_RTX)) - { - in_libcall = 0; - dead_libcall = 0; - } } if (dump_file && ndead) diff --git a/gcc/cselib.c b/gcc/cselib.c index f45803e8e4d..69ad207f00a 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -78,7 +78,6 @@ static htab_t cselib_hash_table; /* This is a global so we don't have to pass this through every function. It is used in new_elt_loc_list to set SETTING_INSN. */ static rtx cselib_current_insn; -static bool cselib_current_insn_in_libcall; /* Every new unknown value gets a unique number. */ static unsigned int next_unknown_value; @@ -160,7 +159,6 @@ new_elt_loc_list (struct elt_loc_list *next, rtx loc) el->next = next; el->loc = loc; el->setting_insn = cselib_current_insn; - el->in_libcall = cselib_current_insn_in_libcall; return el; } @@ -1655,8 +1653,6 @@ cselib_process_insn (rtx insn) int i; rtx x; - if (find_reg_note (insn, REG_LIBCALL, NULL)) - cselib_current_insn_in_libcall = true; cselib_current_insn = insn; /* Forget everything at a CODE_LABEL, a volatile asm, or a setjmp. */ @@ -1667,16 +1663,12 @@ cselib_process_insn (rtx insn) && GET_CODE (PATTERN (insn)) == ASM_OPERANDS && MEM_VOLATILE_P (PATTERN (insn)))) { - if (find_reg_note (insn, REG_RETVAL, NULL)) - cselib_current_insn_in_libcall = false; cselib_clear_table (); return; } if (! INSN_P (insn)) { - if (find_reg_note (insn, REG_RETVAL, NULL)) - cselib_current_insn_in_libcall = false; cselib_current_insn = 0; return; } @@ -1719,8 +1711,6 @@ cselib_process_insn (rtx insn) if (GET_CODE (XEXP (x, 0)) == CLOBBER) cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0)); - if (find_reg_note (insn, REG_RETVAL, NULL)) - cselib_current_insn_in_libcall = false; cselib_current_insn = 0; if (n_useless_values > MAX_USELESS_VALUES @@ -1769,7 +1759,6 @@ cselib_init (bool record_memory) n_used_regs = 0; cselib_hash_table = htab_create (31, get_value_hash, entry_and_rtx_equal_p, NULL); - cselib_current_insn_in_libcall = false; } /* Called when the current user is done with cselib. */ diff --git a/gcc/cselib.h b/gcc/cselib.h index 0e4c6f211df..09c2006b843 100644 --- a/gcc/cselib.h +++ b/gcc/cselib.h @@ -47,8 +47,6 @@ struct elt_loc_list GTY(()) rtx loc; /* The insn that made the equivalence. */ rtx setting_insn; - /* True when setting insn is inside libcall. */ - bool in_libcall; }; /* A list of cselib_val structures. */ diff --git a/gcc/dce.c b/gcc/dce.c index 91cc9aa5c28..b75a8b1b113 100644 --- a/gcc/dce.c +++ b/gcc/dce.c @@ -214,62 +214,6 @@ mark_nonreg_stores (rtx body, rtx insn, bool fast) } -/* Return true if the entire libcall sequence starting at INSN is dead. - NOTE is the REG_LIBCALL note attached to INSN. - - A libcall sequence is a block of insns with no side-effects, i.e. - that is only used for its return value. The terminology derives - from that of a call, but a libcall sequence need not contain one. - It is only defined by a pair of REG_LIBCALL/REG_RETVAL notes. - - From a dataflow viewpoint, a libcall sequence has the property that - no UD chain can enter it from the outside. As a consequence, if a - libcall sequence has a dead return value, it is effectively dead. - This is both enforced by CSE (cse_extended_basic_block) and relied - upon by delete_trivially_dead_insns. - - However, in practice, the return value business is a tricky one and - only checking the liveness of the last insn is not sufficient to - decide whether the whole sequence is dead (e.g. PR middle-end/19551) - so we check the liveness of every insn starting from the call. */ - -static bool -libcall_dead_p (rtx insn, rtx note) -{ - rtx last = XEXP (note, 0); - - /* Find the call insn. */ - while (insn != last && !CALL_P (insn)) - insn = NEXT_INSN (insn); - - /* If there is none, do nothing special, since ordinary death handling - can understand these insns. */ - if (!CALL_P (insn)) - return false; - - /* If this is a call that returns a value via an invisible pointer, the - dataflow engine cannot see it so it has been marked unconditionally. - Skip it unless it has been made the last insn in the libcall, for - example by the combiner, in which case we're left with no easy way - of asserting its liveness. */ - if (!single_set (insn)) - { - if (insn == last) - return false; - insn = NEXT_INSN (insn); - } - - while (insn != NEXT_INSN (last)) - { - if (INSN_P (insn) && marked_insn_p (insn)) - return false; - insn = NEXT_INSN (insn); - } - - return true; -} - - /* Delete all REG_EQUAL notes of the registers INSN writes, to prevent bad dangling REG_EQUAL notes. */ @@ -316,29 +260,10 @@ delete_unmarked_insns (void) FOR_BB_INSNS_SAFE (bb, insn, next) if (INSN_P (insn)) { - rtx note = find_reg_note (insn, REG_LIBCALL, NULL_RTX); - /* Always delete no-op moves. */ if (noop_move_p (insn)) ; - /* Try to delete libcall sequences as a whole. */ - else if (note && libcall_dead_p (insn, note)) - { - rtx last = XEXP (note, 0); - - if (!dbg_cnt (dce)) - continue; - - if (dump_file) - fprintf (dump_file, "DCE: Deleting libcall %d-%d\n", - INSN_UID (insn), INSN_UID (last)); - - next = NEXT_INSN (last); - delete_insn_chain_and_edges (insn, last); - continue; - } - /* Otherwise rely only on the DCE algorithm. */ else if (marked_insn_p (insn)) continue; @@ -353,41 +278,6 @@ delete_unmarked_insns (void) for the destination regs in order to avoid dangling notes. */ delete_corresponding_reg_eq_notes (insn); - /* If we're about to delete the first insn of a libcall, then - move the REG_LIBCALL note to the next real insn and update - the REG_RETVAL note. */ - if (note && (XEXP (note, 0) != insn)) - { - rtx new_libcall_insn = next_real_insn (insn); - rtx retval_note = find_reg_note (XEXP (note, 0), - REG_RETVAL, NULL_RTX); - /* If the RETVAL and LIBCALL notes would land on the same - insn just remove them. */ - if (XEXP (note, 0) == new_libcall_insn) - remove_note (new_libcall_insn, retval_note); - else - { - REG_NOTES (new_libcall_insn) - = gen_rtx_INSN_LIST (REG_LIBCALL, XEXP (note, 0), - REG_NOTES (new_libcall_insn)); - XEXP (retval_note, 0) = new_libcall_insn; - } - } - - /* If the insn contains a REG_RETVAL note and is dead, but the - libcall as a whole is not dead, then we want to remove the - insn, but not the whole libcall sequence. However, we also - need to remove the dangling REG_LIBCALL note in order to - avoid mismatched notes. We could find a new location for - the REG_RETVAL note, but it hardly seems worth the effort. */ - note = find_reg_note (insn, REG_RETVAL, NULL_RTX); - if (note && (XEXP (note, 0) != insn)) - { - rtx libcall_note - = find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX); - remove_note (XEXP (note, 0), libcall_note); - } - /* If a pure or const call is deleted, this may make the cfg have unreachable blocks. We rememeber this and call delete_unreachable_blocks at the end. */ @@ -404,43 +294,6 @@ delete_unmarked_insns (void) } -/* Helper function for prescan_insns_for_dce: prescan the entire libcall - sequence starting at INSN and return the insn following the libcall. - NOTE is the REG_LIBCALL note attached to INSN. */ - -static rtx -prescan_libcall_for_dce (rtx insn, rtx note, bool fast) -{ - rtx last = XEXP (note, 0); - - /* A libcall is never necessary on its own but we need to mark the stores - to a non-register destination. */ - while (insn != last && !CALL_P (insn)) - { - if (INSN_P (insn)) - mark_nonreg_stores (PATTERN (insn), insn, fast); - insn = NEXT_INSN (insn); - } - - /* If this is a call that returns a value via an invisible pointer, the - dataflow engine cannot see it so it has to be marked unconditionally. */ - if (CALL_P (insn) && !single_set (insn)) - { - mark_insn (insn, fast); - insn = NEXT_INSN (insn); - } - - while (insn != NEXT_INSN (last)) - { - if (INSN_P (insn)) - mark_nonreg_stores (PATTERN (insn), insn, fast); - insn = NEXT_INSN (insn); - } - - return insn; -} - - /* Go through the instructions and mark those whose necessity is not dependent on inter-instruction information. Make sure all other instructions are not marked. */ @@ -458,10 +311,7 @@ prescan_insns_for_dce (bool fast) FOR_BB_INSNS_SAFE (bb, insn, next) if (INSN_P (insn)) { - rtx note = find_reg_note (insn, REG_LIBCALL, NULL_RTX); - if (note) - next = prescan_libcall_for_dce (insn, note, fast); - else if (deletable_insn_p (insn, fast)) + if (deletable_insn_p (insn, fast)) mark_nonreg_stores (PATTERN (insn), insn, fast); else mark_insn (insn, fast); diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 3191fc8e6a9..10e4999ca9f 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -3754,31 +3754,6 @@ insn has one of a pair of notes that points to a second insn, which has the inverse note pointing back to the first insn. @table @code -@findex REG_RETVAL -@item REG_RETVAL -This insn copies the value of a multi-insn sequence (for example, a -library call), and @var{op} is the first insn of the sequence (for a -library call, the first insn that was generated to set up the arguments -for the library call). - -Loop optimization uses this note to treat such a sequence as a single -operation for code motion purposes and flow analysis uses this note to -delete such sequences whose results are dead. - -A @code{REG_EQUAL} note will also usually be attached to this insn to -provide the expression being computed by the sequence. - -These notes will be deleted after reload, since they are no longer -accurate or useful. - -@findex REG_LIBCALL -@item REG_LIBCALL -This is the inverse of @code{REG_RETVAL}: it is placed on the first -insn of a multi-insn sequence, and it points to the last one. - -These notes are deleted after reload, since they are no longer useful or -accurate. - @findex REG_CC_SETTER @findex REG_CC_USER @item REG_CC_SETTER @@ -3836,12 +3811,6 @@ of the JUMP@. The format is a bitmask of ATTR_FLAG_* values. This is used on an RTX_FRAME_RELATED_P insn wherein the attached expression is used in place of the actual insn pattern. This is done in cases where the pattern is either complex or misleading. - -@findex REG_LIBCALL_ID -@item REG_LIBCALL_ID -This is used to specify that an insn is part of a libcall. Each libcall -in a function has a unique id, and all the insns that are part of that -libcall will have a REG_LIBCALL_ID note attached with the same ID. @end table For convenience, the machine mode in an @code{insn_list} or diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 0bacebcf9f8..d6929cf154b 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -3160,8 +3160,7 @@ try_split (rtx pat, rtx trial, int last) rtx before = PREV_INSN (trial); rtx after = NEXT_INSN (trial); int has_barrier = 0; - rtx tem, note_retval, note_libcall; - rtx note, seq; + rtx note, seq, tem; int probability; rtx insn_last, insn; int njumps = 0; @@ -3296,30 +3295,6 @@ try_split (rtx pat, rtx trial, int last) break; #endif - case REG_LIBCALL: - /* Relink the insns with REG_LIBCALL note and with REG_RETVAL note - after split. */ - REG_NOTES (insn_last) - = gen_rtx_INSN_LIST (REG_LIBCALL, - XEXP (note, 0), - REG_NOTES (insn_last)); - - note_retval = find_reg_note (XEXP (note, 0), REG_RETVAL, NULL); - XEXP (note_retval, 0) = insn_last; - break; - - case REG_RETVAL: - /* Relink the insns with REG_LIBCALL note and with REG_RETVAL note - after split. */ - REG_NOTES (insn_last) - = gen_rtx_INSN_LIST (REG_RETVAL, - XEXP (note, 0), - REG_NOTES (insn_last)); - - note_libcall = find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL); - XEXP (note_libcall, 0) = insn_last; - break; - default: break; } @@ -5501,8 +5476,7 @@ init_emit_once (int line_numbers) rtx emit_copy_of_insn_after (rtx insn, rtx after) { - rtx new; - rtx note1, note2, link; + rtx new, link; switch (GET_CODE (insn)) { @@ -5556,15 +5530,6 @@ emit_copy_of_insn_after (rtx insn, rtx after) XEXP (link, 0), REG_NOTES (new)); } - /* Fix the libcall sequences. */ - if ((note1 = find_reg_note (new, REG_RETVAL, NULL_RTX)) != NULL) - { - rtx p = new; - while ((note2 = find_reg_note (p, REG_LIBCALL, NULL_RTX)) == NULL) - p = PREV_INSN (p); - XEXP (note1, 0) = p; - XEXP (note2, 0) = new; - } INSN_CODE (new) = INSN_CODE (insn); return new; } diff --git a/gcc/fwprop.c b/gcc/fwprop.c index 93329875705..35bc230fa34 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -776,11 +776,8 @@ try_fwprop_subst (struct df_ref *use, rtx *loc, rtx new, rtx def_insn, bool set_ cancel_changes (0); /* Can also record a simplified value in a REG_EQUAL note, - making a new one if one does not already exist. - Don't do this if the insn has a REG_RETVAL note, because the - combined presence means that the REG_EQUAL note refers to the - (full) contents of the libcall value. */ - if (set_reg_equal && !find_reg_note (insn, REG_RETVAL, NULL_RTX)) + making a new one if one does not already exist. */ + if (set_reg_equal) { if (dump_file) fprintf (dump_file, " Setting REG_EQUAL note\n"); diff --git a/gcc/gcse.c b/gcc/gcse.c index c86f2af1e79..f7e42fb0641 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -519,7 +519,7 @@ static void free_reg_set_mem (void); static void record_one_set (int, rtx); static void record_set_info (rtx, const_rtx, void *); static void compute_sets (void); -static void hash_scan_insn (rtx, struct hash_table *, int); +static void hash_scan_insn (rtx, struct hash_table *); static void hash_scan_set (rtx, rtx, struct hash_table *); static void hash_scan_clobber (rtx, rtx, struct hash_table *); static void hash_scan_call (rtx, rtx, struct hash_table *); @@ -635,8 +635,7 @@ static void clear_modify_mem_tables (void); static void free_modify_mem_tables (void); static rtx gcse_emit_move_after (rtx, rtx, rtx); static void local_cprop_find_used_regs (rtx *, void *); -static bool do_local_cprop (rtx, rtx, bool, rtx*); -static bool adjust_libcall_notes (rtx, rtx, rtx, rtx*); +static bool do_local_cprop (rtx, rtx, bool); static void local_cprop_pass (bool); static bool is_too_expensive (const char *); @@ -1838,19 +1837,14 @@ hash_scan_call (rtx x ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED, are also in the PARALLEL. Later. If SET_P is nonzero, this is for the assignment hash table, - otherwise it is for the expression hash table. - If IN_LIBCALL_BLOCK nonzero, we are in a libcall block, and should - not record any expressions. */ + otherwise it is for the expression hash table. */ static void -hash_scan_insn (rtx insn, struct hash_table *table, int in_libcall_block) +hash_scan_insn (rtx insn, struct hash_table *table) { rtx pat = PATTERN (insn); int i; - if (in_libcall_block) - return; - /* Pick out the sets of INSN and for other forms of instructions record what's been modified. */ @@ -2063,7 +2057,6 @@ compute_hash_table_work (struct hash_table *table) { rtx insn; unsigned int regno; - int in_libcall_block; /* First pass over the instructions records information used to determine when registers and memory are first and last set. @@ -2094,18 +2087,9 @@ compute_hash_table_work (struct hash_table *table) BB_HEAD (current_bb), table); /* The next pass builds the hash table. */ - in_libcall_block = 0; FOR_BB_INSNS (current_bb, insn) if (INSN_P (insn)) - { - if (find_reg_note (insn, REG_LIBCALL, NULL_RTX)) - in_libcall_block = 1; - else if (table->set_p && find_reg_note (insn, REG_RETVAL, NULL_RTX)) - in_libcall_block = 0; - hash_scan_insn (insn, table, in_libcall_block); - if (!table->set_p && find_reg_note (insn, REG_RETVAL, NULL_RTX)) - in_libcall_block = 0; - } + hash_scan_insn (insn, table); } free (reg_avail_info); @@ -3077,11 +3061,11 @@ local_cprop_find_used_regs (rtx *xptr, void *data) find_used_regs (xptr, data); } -/* LIBCALL_SP is a zero-terminated array of insns at the end of a libcall; - their REG_EQUAL notes need updating. */ +/* Try to perform local const/copy propagation on X in INSN. + If ALTER_JUMPS is false, changing jump insns is not allowed. */ static bool -do_local_cprop (rtx x, rtx insn, bool alter_jumps, rtx *libcall_sp) +do_local_cprop (rtx x, rtx insn, bool alter_jumps) { rtx newreg = NULL, newcnst = NULL; @@ -3102,10 +3086,6 @@ do_local_cprop (rtx x, rtx insn, bool alter_jumps, rtx *libcall_sp) rtx this_rtx = l->loc; rtx note; - /* Don't CSE non-constant values out of libcall blocks. */ - if (l->in_libcall && ! CONSTANT_P (this_rtx)) - continue; - if (gcse_constant_p (this_rtx)) newcnst = this_rtx; if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER @@ -3120,16 +3100,6 @@ do_local_cprop (rtx x, rtx insn, bool alter_jumps, rtx *libcall_sp) } if (newcnst && constprop_register (insn, x, newcnst, alter_jumps)) { - /* If we find a case where we can't fix the retval REG_EQUAL notes - match the new register, we either have to abandon this replacement - or fix delete_trivially_dead_insns to preserve the setting insn, - or make it delete the REG_EQUAL note, and fix up all passes that - require the REG_EQUAL note there. */ - bool adjusted; - - adjusted = adjust_libcall_notes (x, newcnst, insn, libcall_sp); - gcc_assert (adjusted); - if (dump_file != NULL) { fprintf (dump_file, "LOCAL CONST-PROP: Replacing reg %d in ", @@ -3144,7 +3114,6 @@ do_local_cprop (rtx x, rtx insn, bool alter_jumps, rtx *libcall_sp) } else if (newreg && newreg != x && try_replace_reg (x, newreg, insn)) { - adjust_libcall_notes (x, newreg, insn, libcall_sp); if (dump_file != NULL) { fprintf (dump_file, @@ -3159,47 +3128,6 @@ do_local_cprop (rtx x, rtx insn, bool alter_jumps, rtx *libcall_sp) return false; } -/* LIBCALL_SP is a zero-terminated array of insns at the end of a libcall; - their REG_EQUAL notes need updating to reflect that OLDREG has been - replaced with NEWVAL in INSN. Return true if all substitutions could - be made. */ -static bool -adjust_libcall_notes (rtx oldreg, rtx newval, rtx insn, rtx *libcall_sp) -{ - rtx end; - - while ((end = *libcall_sp++)) - { - rtx note = find_reg_equal_equiv_note (end); - - if (! note) - continue; - - if (REG_P (newval)) - { - if (reg_set_between_p (newval, PREV_INSN (insn), end)) - { - do - { - note = find_reg_equal_equiv_note (end); - if (! note) - continue; - if (reg_mentioned_p (newval, XEXP (note, 0))) - return false; - } - while ((end = *libcall_sp++)); - return true; - } - } - XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), oldreg, newval); - df_notes_rescan (end); - insn = end; - } - return true; -} - -#define MAX_NESTED_LIBCALLS 9 - /* Do local const/copy propagation (i.e. within each basic block). If ALTER_JUMPS is true, allow propagating into jump insns, which could modify the CFG. */ @@ -3210,29 +3138,16 @@ local_cprop_pass (bool alter_jumps) basic_block bb; rtx insn; struct reg_use *reg_used; - rtx libcall_stack[MAX_NESTED_LIBCALLS + 1], *libcall_sp; bool changed = false; cselib_init (false); - libcall_sp = &libcall_stack[MAX_NESTED_LIBCALLS]; - *libcall_sp = 0; FOR_EACH_BB (bb) { FOR_BB_INSNS (bb, insn) { if (INSN_P (insn)) { - rtx note = find_reg_note (insn, REG_LIBCALL, NULL_RTX); - - if (note) - { - gcc_assert (libcall_sp != libcall_stack); - *--libcall_sp = XEXP (note, 0); - } - note = find_reg_note (insn, REG_RETVAL, NULL_RTX); - if (note) - libcall_sp++; - note = find_reg_equal_equiv_note (insn); + rtx note = find_reg_equal_equiv_note (insn); do { reg_use_count = 0; @@ -3244,8 +3159,7 @@ local_cprop_pass (bool alter_jumps) for (reg_used = ®_use_table[0]; reg_use_count > 0; reg_used++, reg_use_count--) { - if (do_local_cprop (reg_used->reg_rtx, insn, alter_jumps, - libcall_sp)) + if (do_local_cprop (reg_used->reg_rtx, insn, alter_jumps)) { changed = true; break; @@ -3259,10 +3173,8 @@ local_cprop_pass (bool alter_jumps) cselib_process_insn (insn); } - /* Forget everything at the end of a basic block. Make sure we are - not inside a libcall, they should never cross basic blocks. */ + /* Forget everything at the end of a basic block. */ cselib_clear_table (); - gcc_assert (libcall_sp == &libcall_stack[MAX_NESTED_LIBCALLS]); } cselib_finish (); @@ -6376,7 +6288,7 @@ remove_reachable_equiv_notes (basic_block bb, struct ls_expr *smexpr) static void replace_store_insn (rtx reg, rtx del, basic_block bb, struct ls_expr *smexpr) { - rtx insn, mem, note, set, ptr, pair; + rtx insn, mem, note, set, ptr; mem = smexpr->pattern; insn = gen_move_insn (reg, SET_SRC (single_set (del))); @@ -6388,25 +6300,9 @@ replace_store_insn (rtx reg, rtx del, basic_block bb, struct ls_expr *smexpr) break; } - /* Move the notes from the deleted insn to its replacement, and patch - up the LIBCALL notes. */ + /* Move the notes from the deleted insn to its replacement. */ REG_NOTES (insn) = REG_NOTES (del); - note = find_reg_note (insn, REG_RETVAL, NULL_RTX); - if (note) - { - pair = XEXP (note, 0); - note = find_reg_note (pair, REG_LIBCALL, NULL_RTX); - XEXP (note, 0) = insn; - } - note = find_reg_note (insn, REG_LIBCALL, NULL_RTX); - if (note) - { - pair = XEXP (note, 0); - note = find_reg_note (pair, REG_RETVAL, NULL_RTX); - XEXP (note, 0) = insn; - } - /* Emit the insn AFTER all the notes are transferred. This is cheaper since we avoid df rescanning for the note change. */ insn = emit_insn_after (insn, del); diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 384649d8515..66773075dd6 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -18,9 +18,9 @@ along with GCC; see the file COPYING3. If not see . */ /* This implements the loop invariant motion pass. It is very simple - (no calls, libcalls, etc.). This should be sufficient to cleanup things - like address arithmetics -- other more complicated invariants should be - eliminated on tree level either in tree-ssa-loop-im.c or in tree-ssa-pre.c. + (no calls, no loads/stores, etc.). This should be sufficient to cleanup + things like address arithmetics -- other more complicated invariants should + be eliminated on GIMPLE either in tree-ssa-loop-im.c or in tree-ssa-pre.c. We proceed loop by loop -- it is simpler than trying to handle things globally and should not lose much. First we inspect all sets inside loop @@ -795,11 +795,6 @@ find_invariant_insn (rtx insn, bool always_reached, bool always_executed) bool simple = true; struct invariant *inv; - /* Until we get rid of LIBCALLS. */ - if (find_reg_note (insn, REG_RETVAL, NULL_RTX) - || find_reg_note (insn, REG_LIBCALL, NULL_RTX)) - return; - #ifdef HAVE_cc0 /* We can't move a CC0 setter without the user. */ if (sets_cc0_p (insn)) diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index a9e7da998a4..67a95984fab 100644 --- a/gcc/lower-subreg.c +++ b/gcc/lower-subreg.c @@ -225,11 +225,9 @@ enum classify_move_insn { /* Not a simple move from one location to another. */ NOT_SIMPLE_MOVE, - /* A simple move from one pseudo-register to another with no - REG_RETVAL note. */ + /* A simple move from one pseudo-register to another. */ SIMPLE_PSEUDO_REG_MOVE, - /* A simple move involving a non-pseudo-register, or from one - pseudo-register to another with a REG_RETVAL note. */ + /* A simple move involving a non-pseudo-register. */ SIMPLE_MOVE }; @@ -304,10 +302,10 @@ find_decomposable_subregs (rtx *px, void *data) If this is not a simple copy from one location to another, then we can not decompose this register. If this is a simple - copy from one pseudo-register to another, with no REG_RETVAL - note, and the mode is right, then we mark the register as - decomposable. Otherwise we don't say anything about this - register--it could be decomposed, but whether that would be + copy from one pseudo-register to another, and the mode is right + then we mark the register as decomposable. + Otherwise we don't say anything about this register -- + it could be decomposed, but whether that would be profitable depends upon how it is used elsewhere. We only set bits in the bitmap for multi-word @@ -558,47 +556,6 @@ move_eh_region_note (rtx insn, rtx insns) } } -/* If there is a REG_LIBCALL note on OLD_START, move it to NEW_START, - and link the corresponding REG_RETVAL note to NEW_START. */ - -static void -move_libcall_note (rtx old_start, rtx new_start) -{ - rtx note0, note1, end; - - note0 = find_reg_note (old_start, REG_LIBCALL, NULL); - if (note0 == NULL_RTX) - return; - - remove_note (old_start, note0); - end = XEXP (note0, 0); - note1 = find_reg_note (end, REG_RETVAL, NULL); - - XEXP (note0, 1) = REG_NOTES (new_start); - REG_NOTES (new_start) = note0; - XEXP (note1, 0) = new_start; -} - -/* Remove any REG_RETVAL note, the corresponding REG_LIBCALL note, and - any markers for a no-conflict block. We have decomposed the - registers so the non-conflict is now obvious. */ - -static void -remove_retval_note (rtx insn1) -{ - rtx note0, insn0, note1; - - note1 = find_reg_note (insn1, REG_RETVAL, NULL); - if (note1 == NULL_RTX) - return; - - insn0 = XEXP (note1, 0); - note0 = find_reg_note (insn0, REG_LIBCALL, NULL); - - remove_note (insn0, note0); - remove_note (insn1, note1); -} - /* Resolve any decomposed registers which appear in register notes on INSN. */ @@ -612,10 +569,7 @@ resolve_reg_notes (rtx insn) { int old_count = num_validated_changes (); if (for_each_rtx (&XEXP (note, 0), resolve_subreg_use, NULL)) - { - remove_note (insn, note); - remove_retval_note (insn); - } + remove_note (insn, note); else if (old_count != num_validated_changes ()) df_notes_rescan (insn); @@ -870,8 +824,6 @@ resolve_simple_move (rtx set, rtx insn) emit_insn_before (insns, insn); - move_libcall_note (insn, insns); - remove_retval_note (insn); delete_insn (insn); return insns; @@ -1156,34 +1108,8 @@ decompose_multiword_subregs (void) cmi = NOT_SIMPLE_MOVE; else { - bool retval; - - retval = find_reg_note (insn, REG_RETVAL, NULL_RTX) != NULL_RTX; - - if (find_pseudo_copy (set) && !retval) + if (find_pseudo_copy (set)) cmi = SIMPLE_PSEUDO_REG_MOVE; - else if (retval - && REG_P (SET_SRC (set)) - && HARD_REGISTER_P (SET_SRC (set))) - { - rtx note; - - /* We don't want to decompose an assignment which - copies the value returned by a libcall to a - pseudo-register. Doing that will lose the RETVAL - note with no real gain. */ - cmi = NOT_SIMPLE_MOVE; - - /* If we have a RETVAL note, there should be an - EQUAL note. We don't want to decompose any - registers which that EQUAL note refers to - directly. If we do, we will no longer know the - value of the libcall. */ - note = find_reg_equal_equiv_note (insn); - if (note != NULL_RTX) - for_each_rtx (&XEXP (note, 0), find_decomposable_subregs, - &cmi); - } else cmi = SIMPLE_MOVE; } @@ -1277,8 +1203,6 @@ decompose_multiword_subregs (void) insn = resolve_simple_move (set, insn); if (insn != orig_insn) { - remove_retval_note (insn); - recog_memoized (insn); extract_insn (insn); @@ -1319,8 +1243,6 @@ decompose_multiword_subregs (void) i = apply_change_group (); gcc_assert (i); - - remove_retval_note (insn); } } } diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def index c9cc1c7819b..5a5325f01ae 100644 --- a/gcc/reg-notes.def +++ b/gcc/reg-notes.def @@ -52,23 +52,9 @@ REG_NOTE (EQUIV) /* Like REG_EQUIV except that the destination is only momentarily equal to the specified rtx. Therefore, it cannot be used for - substitution; but it can be used for cse. Together with a - REG_RETVAL note, it means that the insn sets the full contents of - the libcall value. */ + substitution; but it can be used for cse. */ REG_NOTE (EQUAL) -/* This insn copies the return-value of a library call out of the hard - reg for return values. This note is actually an INSN_LIST and it - points to the first insn involved in setting up arguments for the - call. flow.c uses this to delete the entire library call when its - result is dead. */ -REG_NOTE (RETVAL) - -/* The inverse of REG_RETVAL: it goes on the first insn of the library - call and points at the one that has the REG_RETVAL. This note is - also an INSN_LIST. */ -REG_NOTE (LIBCALL) - /* The register is always nonnegative during the containing loop. This is used in branches so that decrement and branch instructions terminating on zero can be matched. There must be an insn pattern diff --git a/gcc/reload1.c b/gcc/reload1.c index 7f413665747..48424abb68f 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1219,9 +1219,8 @@ reload (rtx first, int global) notes. Delete all CLOBBER insns, except those that refer to the return value and the special mem:BLK CLOBBERs added to prevent the scheduler from misarranging variable-array code, and simplify (subreg (reg)) - operands. Also remove all REG_RETVAL and REG_LIBCALL notes since they - are no longer useful or accurate. Strip and regenerate REG_INC notes - that may have been moved around. */ + operands. Strip and regenerate REG_INC notes that may have been moved + around. */ for (insn = first; insn; insn = NEXT_INSN (insn)) if (INSN_P (insn)) @@ -1274,9 +1273,7 @@ reload (rtx first, int global) { if (REG_NOTE_KIND (*pnote) == REG_DEAD || REG_NOTE_KIND (*pnote) == REG_UNUSED - || REG_NOTE_KIND (*pnote) == REG_INC - || REG_NOTE_KIND (*pnote) == REG_RETVAL - || REG_NOTE_KIND (*pnote) == REG_LIBCALL) + || REG_NOTE_KIND (*pnote) == REG_INC) *pnote = XEXP (*pnote, 1); else pnote = &XEXP (*pnote, 1); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index cf58c348489..56311d970e9 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -1123,11 +1123,6 @@ noop_move_p (const_rtx insn) if (find_reg_note (insn, REG_EQUAL, NULL_RTX)) return 0; - /* For now treat an insn with a REG_RETVAL note as a - special insn which should not be considered a no-op. */ - if (find_reg_note (insn, REG_RETVAL, NULL_RTX)) - return 0; - if (GET_CODE (pat) == SET && set_noop_p (pat)) return 1; diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index b62797f6a56..b8b3a4418df 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -2121,16 +2121,6 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn) reg_pending_barrier = NOT_A_BARRIER; } - /* If we are currently in a libcall scheduling group, then mark the - current insn as being in a scheduling group and that it can not - be moved into a different basic block. */ - - if (deps->libcall_block_tail_insn) - { - SCHED_GROUP_P (insn) = 1; - CANT_MOVE (insn) = 1; - } - /* If a post-call group is still open, see if it should remain so. This insn must be a simple move of a hard reg to a pseudo or vice-versa. @@ -2226,8 +2216,6 @@ sched_analyze (struct deps *deps, rtx head, rtx tail) } for (insn = head;; insn = NEXT_INSN (insn)) { - rtx link, end_seq, r0, set; - if (INSN_P (insn)) { /* And initialize deps_lists. */ @@ -2326,45 +2314,6 @@ sched_analyze (struct deps *deps, rtx head, rtx tail) if (current_sched_info->use_cselib) cselib_process_insn (insn); - /* Now that we have completed handling INSN, check and see if it is - a CLOBBER beginning a libcall block. If it is, record the - end of the libcall sequence. - - We want to schedule libcall blocks as a unit before reload. While - this restricts scheduling, it preserves the meaning of a libcall - block. - - As a side effect, we may get better code due to decreased register - pressure as well as less chance of a foreign insn appearing in - a libcall block. */ - if (!reload_completed - /* Note we may have nested libcall sequences. We only care about - the outermost libcall sequence. */ - && deps->libcall_block_tail_insn == 0 - /* The sequence must start with a clobber of a register. */ - && NONJUMP_INSN_P (insn) - && GET_CODE (PATTERN (insn)) == CLOBBER - && (r0 = XEXP (PATTERN (insn), 0), REG_P (r0)) - && REG_P (XEXP (PATTERN (insn), 0)) - /* The CLOBBER must also have a REG_LIBCALL note attached. */ - && (link = find_reg_note (insn, REG_LIBCALL, NULL_RTX)) != 0 - && (end_seq = XEXP (link, 0)) != 0 - /* The insn referenced by the REG_LIBCALL note must be a - simple nop copy with the same destination as the register - mentioned in the clobber. */ - && (set = single_set (end_seq)) != 0 - && SET_DEST (set) == r0 && SET_SRC (set) == r0 - /* And finally the insn referenced by the REG_LIBCALL must - also contain a REG_EQUAL note and a REG_RETVAL note. */ - && find_reg_note (end_seq, REG_EQUAL, NULL_RTX) != 0 - && find_reg_note (end_seq, REG_RETVAL, NULL_RTX) != 0) - deps->libcall_block_tail_insn = XEXP (link, 0); - - /* If we have reached the end of a libcall block, then close the - block. */ - if (deps->libcall_block_tail_insn == insn) - deps->libcall_block_tail_insn = 0; - if (insn == tail) { if (current_sched_info->use_cselib) @@ -2452,7 +2401,6 @@ init_deps (struct deps *deps) deps->last_function_call = 0; deps->sched_before_next_call = 0; deps->in_post_call_group_p = not_post_call; - deps->libcall_block_tail_insn = 0; } /* Free insn lists found in DEPS. */ diff --git a/gcc/sched-int.h b/gcc/sched-int.h index 60919f09c41..f2e39bf4fc3 100644 --- a/gcc/sched-int.h +++ b/gcc/sched-int.h @@ -307,12 +307,6 @@ struct deps the call. */ enum { not_post_call, post_call, post_call_initial } in_post_call_group_p; - /* Set to the tail insn of the outermost libcall block. - - When nonzero, we will mark each insn processed by sched_analyze_insn - with SCHED_GROUP_P to ensure libcalls are scheduled as a unit. */ - rtx libcall_block_tail_insn; - /* The maximum register number for the following arrays. Before reload this is max_reg_num; after reload it is FIRST_PSEUDO_REGISTER. */ int max_reg; diff --git a/gcc/see.c b/gcc/see.c index 6ea9f3ed25a..2d664e17cfb 100644 --- a/gcc/see.c +++ b/gcc/see.c @@ -3489,12 +3489,6 @@ see_analyze_one_def (rtx insn, enum machine_mode *source_mode, if (!reg_set_between_p (source_register, PREV_INSN (prev_insn), insn)) return NOT_RELEVANT; - if (find_reg_note (prev_insn, REG_LIBCALL, NULL_RTX)) - return NOT_RELEVANT; - - if (find_reg_note (prev_insn, REG_RETVAL, NULL_RTX)) - return NOT_RELEVANT; - /* If we can't use copy_rtx on the reference it can't be a reference. */ if (GET_CODE (PATTERN (prev_insn)) == PARALLEL && asm_noperands (PATTERN (prev_insn)) >= 0) @@ -3690,11 +3684,7 @@ see_update_relevancy (void) unsigned int uid = INSN_UID (insn); if (INSN_P (insn)) { - if (find_reg_note (insn, REG_LIBCALL, NULL_RTX) - || find_reg_note (insn, REG_RETVAL, NULL_RTX)) - et = NOT_RELEVANT; - else - et = RELEVANT_USE; + et = RELEVANT_USE; for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) { diff --git a/gcc/web.c b/gcc/web.c index ada150ed23d..84987df5e1f 100644 --- a/gcc/web.c +++ b/gcc/web.c @@ -152,9 +152,7 @@ union_defs (struct df_ref *use, struct web_entry *def_entry, eq_use_link++; } - /* Recognize trivial noop moves and attempt to keep them as noop. - While most of noop moves should be removed, we still keep some - of them at libcall boundaries and such. */ + /* Recognize trivial noop moves and attempt to keep them as noop. */ if (set && SET_SRC (set) == DF_REF_REG (use) -- 2.30.2