From 2c07f13b2bccf42a860e5d3634e77fb6a264fa54 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 29 Nov 2003 02:13:43 +0100 Subject: [PATCH] emit-rtl.c (set_used_flags): New. * emit-rtl.c (set_used_flags): New. (verify_rtx_sharing, verify_rtl_sharing): New. (unshare_all_rtl_1): Rename to.... (unshare_all_rtl_in_chain): ... this one; make static. (copy_rtx_if_shared): LABEL_REF chan be shared. * ifcvt.c (unshare_ifcvt_sequence): New. (noce_try_move, noce_try_store_flag, noce_try_store_flag_constants, noce_try_addcc, noce_try_addcc, noce_try_store_flag_mask, noce_try_cmove, noce_try_store_flag_mask, noce_try_minmax, noce_try_abs, noce_process_if_block, find_cond_trap * rtl.h (verify_rtl_sharing, set_used_flags, unshare_all_rtl_in_chain): Declare. From-SVN: r74030 --- gcc/ChangeLog | 19 ++++- gcc/emit-rtl.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++- gcc/ifcvt.c | 40 ++++++++-- gcc/rtl.h | 3 + 4 files changed, 248 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1fecf91eeb2..920f03b47e4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2003-11-28 Jan Hubicka + + * emit-rtl.c (set_used_flags): New. + (verify_rtx_sharing, verify_rtl_sharing): New. + (unshare_all_rtl_1): Rename to.... + (unshare_all_rtl_in_chain): ... this one; make static. + (copy_rtx_if_shared): LABEL_REF chan be shared. + * ifcvt.c (unshare_ifcvt_sequence): New. + (noce_try_move, noce_try_store_flag, noce_try_store_flag_constants, + noce_try_addcc, noce_try_addcc, noce_try_store_flag_mask, + noce_try_cmove, noce_try_store_flag_mask, noce_try_minmax, + noce_try_abs, noce_process_if_block, find_cond_trap + * rtl.h (verify_rtl_sharing, set_used_flags, unshare_all_rtl_in_chain): + Declare. + 2003-11-28 Kazu Hirata * config/h8300/h8300.md: Fix a comment typo. @@ -204,8 +219,8 @@ 2003-11-24 Jan Hubicka - * fold-const.c (fold): Do not return early when optimizing COMPONENT_REF - and constant. + * fold-const.c (fold): Do not return early when optimizing + COMPONENT_REF and constant. 2003-11-24 Kazu Hirata diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index a528641a6f9..0f7e677e3ef 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -180,7 +180,6 @@ static rtx make_jump_insn_raw (rtx); static rtx make_call_insn_raw (rtx); static rtx find_line_note (rtx); static rtx change_address_1 (rtx, enum machine_mode, rtx, int); -static void unshare_all_rtl_1 (rtx); static void unshare_all_decls (tree); static void reset_used_decls (tree); static void mark_label_nuses (rtx); @@ -2450,7 +2449,7 @@ unshare_all_rtl (tree fndecl, rtx insn) unshare_all_decls (DECL_INITIAL (fndecl)); /* Unshare just about everything else. */ - unshare_all_rtl_1 (insn); + unshare_all_rtl_in_chain (insn); /* Make sure the addresses of stack slots found outside the insn chain (such as, in DECL_RTL of a variable) are not shared @@ -2492,11 +2491,138 @@ unshare_all_rtl_again (rtx insn) unshare_all_rtl (cfun->decl, insn); } +/* Check that ORIG is not marked when it should not be and mark ORIG as in use, + Recursively does the same for subexpressions. */ + +static void +verify_rtx_sharing (rtx orig, rtx insn) +{ + rtx x = orig; + int i; + enum rtx_code code; + const char *format_ptr; + + if (x == 0) + return; + + code = GET_CODE (x); + + /* These types may be freely shared. */ + + switch (code) + { + case REG: + case QUEUED: + case CONST_INT: + case CONST_DOUBLE: + case CONST_VECTOR: + case SYMBOL_REF: + case LABEL_REF: + case CODE_LABEL: + case PC: + case CC0: + case SCRATCH: + /* SCRATCH must be shared because they represent distinct values. */ + return; + + case CONST: + /* CONST can be shared if it contains a SYMBOL_REF. If it contains + a LABEL_REF, it isn't sharable. */ + if (GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT) + return; + break; + + case MEM: + /* A MEM is allowed to be shared if its address is constant. */ + if (CONSTANT_ADDRESS_P (XEXP (x, 0)) + || reload_completed || reload_in_progress) + return; + + break; + + default: + break; + } + + /* This rtx may not be shared. If it has already been seen, + replace it with a copy of itself. */ + + if (RTX_FLAG (x, used)) + { + error ("Invalid rtl sharing found in the insn"); + debug_rtx (insn); + error ("Shared rtx"); + debug_rtx (x); + abort (); + } + RTX_FLAG (x, used) = 1; + + /* Now scan the subexpressions recursively. */ + + format_ptr = GET_RTX_FORMAT (code); + + for (i = 0; i < GET_RTX_LENGTH (code); i++) + { + switch (*format_ptr++) + { + case 'e': + verify_rtx_sharing (XEXP (x, i), insn); + break; + + case 'E': + if (XVEC (x, i) != NULL) + { + int j; + int len = XVECLEN (x, i); + + for (j = 0; j < len; j++) + { + /* We allow sharing of ASM_OPERANDS inside single instruction. */ + if (j && GET_CODE (XVECEXP (x, i, j)) == SET + && GET_CODE (SET_SRC (XVECEXP (x, i, j))) == ASM_OPERANDS) + verify_rtx_sharing (SET_DEST (XVECEXP (x, i, j)), insn); + else + verify_rtx_sharing (XVECEXP (x, i, j), insn); + } + } + break; + } + } + return; +} + +/* Go through all the RTL insn bodies and chec that there is no inexpected + sharing in between the subexpressions. */ + +void +verify_rtl_sharing (void) +{ + rtx p; + + for (p = get_insns (); p; p = NEXT_INSN (p)) + if (INSN_P (p)) + { + reset_used_flags (PATTERN (p)); + reset_used_flags (REG_NOTES (p)); + reset_used_flags (LOG_LINKS (p)); + } + + for (p = get_insns (); p; p = NEXT_INSN (p)) + if (INSN_P (p)) + { + verify_rtx_sharing (PATTERN (p), p); + verify_rtx_sharing (REG_NOTES (p), p); + verify_rtx_sharing (LOG_LINKS (p), p); + } +} + /* Go through all the RTL insn bodies and copy any invalid shared structure. Assumes the mark bits are cleared at entry. */ -static void -unshare_all_rtl_1 (rtx insn) +void +unshare_all_rtl_in_chain (rtx insn) { for (; insn; insn = NEXT_INSN (insn)) if (INSN_P (insn)) @@ -2668,6 +2794,7 @@ copy_rtx_if_shared (rtx orig) case CONST_DOUBLE: case CONST_VECTOR: case SYMBOL_REF: + case LABEL_REF: case CODE_LABEL: case PC: case CC0: @@ -2804,6 +2931,69 @@ reset_used_flags (rtx x) } } } + +/* Set all the USED bits in X to allow copy_rtx_if_shared to be used + to look for shared sub-parts. */ + +void +set_used_flags (rtx x) +{ + int i, j; + enum rtx_code code; + const char *format_ptr; + + if (x == 0) + return; + + code = GET_CODE (x); + + /* These types may be freely shared so we needn't do any resetting + for them. */ + + switch (code) + { + case REG: + case QUEUED: + case CONST_INT: + case CONST_DOUBLE: + case CONST_VECTOR: + case SYMBOL_REF: + case CODE_LABEL: + case PC: + case CC0: + return; + + case INSN: + case JUMP_INSN: + case CALL_INSN: + case NOTE: + case LABEL_REF: + case BARRIER: + /* The chain of insns is not being copied. */ + return; + + default: + break; + } + + RTX_FLAG (x, used) = 1; + + format_ptr = GET_RTX_FORMAT (code); + for (i = 0; i < GET_RTX_LENGTH (code); i++) + { + switch (*format_ptr++) + { + case 'e': + set_used_flags (XEXP (x, i)); + break; + + case 'E': + for (j = 0; j < XVECLEN (x, i); j++) + set_used_flags (XVECEXP (x, i, j)); + break; + } + } +} /* Copy X if necessary so that it won't be altered by changes in OTHER. Return X or the rtx for the pseudo reg the value of X was copied into. diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index f7fddf98764..29f3f008f7f 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -700,6 +700,16 @@ noce_emit_move_insn (rtx x, rtx y) GET_MODE_BITSIZE (inmode)); } +/* Unshare sequence SEQ produced by if conversion. We care to mark + all arguments that may be shared with outer instruction stream. */ +static void +unshare_ifcvt_sequence (struct noce_if_info *if_info, rtx seq) +{ + set_used_flags (if_info->x); + set_used_flags (if_info->cond); + unshare_all_rtl_in_chain (seq); +} + /* Convert "if (a != b) x = a; else x = b" into "x = a" and "if (a == b) x = a; else x = b" into "x = b". */ @@ -734,6 +744,7 @@ noce_try_move (struct noce_if_info *if_info) start_sequence (); noce_emit_move_insn (if_info->x, y); seq = get_insns (); + unshare_ifcvt_sequence (if_info, seq); end_sequence (); emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a)); @@ -777,6 +788,7 @@ noce_try_store_flag (struct noce_if_info *if_info) noce_emit_move_insn (if_info->x, target); seq = get_insns (); + unshare_ifcvt_sequence (if_info, seq); end_sequence (); emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a)); @@ -907,6 +919,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info) noce_emit_move_insn (if_info->x, target); seq = get_insns (); + unshare_ifcvt_sequence (if_info, seq); end_sequence (); if (seq_contains_jump (seq)) @@ -944,9 +957,11 @@ noce_try_addcc (struct noce_if_info *if_info) { start_sequence (); target = emit_conditional_add (if_info->x, code, - XEXP (cond, 0), XEXP (cond, 1), + XEXP (cond, 0), + XEXP (cond, 1), VOIDmode, - if_info->b, XEXP (if_info->a, 1), + if_info->b, + XEXP (if_info->a, 1), GET_MODE (if_info->x), (code == LTU || code == GEU || code == LEU || code == GTU)); @@ -956,6 +971,7 @@ noce_try_addcc (struct noce_if_info *if_info) noce_emit_move_insn (if_info->x, target); seq = get_insns (); + unshare_ifcvt_sequence (if_info, seq); end_sequence (); emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a)); @@ -994,6 +1010,7 @@ noce_try_addcc (struct noce_if_info *if_info) noce_emit_move_insn (if_info->x, target); seq = get_insns (); + unshare_ifcvt_sequence (if_info, seq); end_sequence (); if (seq_contains_jump (seq)) @@ -1037,7 +1054,8 @@ noce_try_store_flag_mask (struct noce_if_info *if_info) reversep, -1); if (target) target = expand_simple_binop (GET_MODE (if_info->x), AND, - if_info->x, target, if_info->x, 0, + if_info->x, + target, if_info->x, 0, OPTAB_WIDEN); if (target) @@ -1046,6 +1064,7 @@ noce_try_store_flag_mask (struct noce_if_info *if_info) noce_emit_move_insn (if_info->x, target); seq = get_insns (); + unshare_ifcvt_sequence (if_info, seq); end_sequence (); if (seq_contains_jump (seq)) @@ -1143,6 +1162,7 @@ noce_try_cmove (struct noce_if_info *if_info) noce_emit_move_insn (if_info->x, target); seq = get_insns (); + unshare_ifcvt_sequence (if_info, seq); end_sequence (); emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a)); @@ -1260,7 +1280,9 @@ noce_try_cmove_arith (struct noce_if_info *if_info) if (is_mem) { tmp = gen_reg_rtx (GET_MODE (b)); - tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, b)); + tmp = emit_insn (gen_rtx_SET (VOIDmode, + tmp, + b)); } else if (! insn_b) goto end_seq_and_fail; @@ -1305,6 +1327,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info) noce_emit_move_insn (x, target); tmp = get_insns (); + unshare_ifcvt_sequence (if_info, tmp); end_sequence (); emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR (if_info->insn_a)); return TRUE; @@ -1550,6 +1573,7 @@ noce_try_minmax (struct noce_if_info *if_info) noce_emit_move_insn (if_info->x, target); seq = get_insns (); + unshare_ifcvt_sequence (if_info, seq); end_sequence (); if (seq_contains_jump (seq)) @@ -1667,6 +1691,7 @@ noce_try_abs (struct noce_if_info *if_info) noce_emit_move_insn (if_info->x, target); seq = get_insns (); + unshare_ifcvt_sequence (if_info, seq); end_sequence (); if (seq_contains_jump (seq)) @@ -1988,8 +2013,10 @@ noce_process_if_block (struct ce_if_block * ce_info) if (orig_x != x) { start_sequence (); - noce_emit_move_insn (copy_rtx (orig_x), x); + noce_emit_move_insn (orig_x, x); insn_b = get_insns (); + set_used_flags (orig_x); + unshare_all_rtl_in_chain (insn_b); end_sequence (); emit_insn_after_setloc (insn_b, test_bb->end, INSN_LOCATOR (insn_a)); @@ -2585,7 +2612,8 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) } /* Attempt to generate the conditional trap. */ - seq = gen_cond_trap (code, XEXP (cond, 0), XEXP (cond, 1), + seq = gen_cond_trap (code, XEXP (cond, 0), + XEXP (cond, 1), TRAP_CODE (PATTERN (trap))); if (seq == NULL) return FALSE; diff --git a/gcc/rtl.h b/gcc/rtl.h index 33027e68f0e..44fd9652025 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2036,6 +2036,7 @@ extern void delete_insns_since (rtx); extern void mark_reg_pointer (rtx, int); extern void mark_user_reg (rtx); extern void reset_used_flags (rtx); +extern void set_used_flags (rtx); extern void reorder_insns (rtx, rtx, rtx); extern void reorder_insns_nobb (rtx, rtx, rtx); extern int get_max_uid (void); @@ -2051,6 +2052,8 @@ extern void set_new_first_and_last_insn (rtx, rtx); extern void set_new_first_and_last_label_num (int, int); extern void set_new_last_label_num (int); extern void unshare_all_rtl_again (rtx); +extern void unshare_all_rtl_in_chain (rtx); +extern void verify_rtl_sharing (void); extern void set_first_insn (rtx); extern void set_last_insn (rtx); extern void link_cc0_insns (rtx); -- 2.30.2