diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-12-22 23:41:17 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-12-22 23:41:17 +0000 |
commit | aa140b766aa5d0e312e662ca1f2351c7a7c8525a (patch) | |
tree | 167c47dc48087fc4f6a776d5c66088ff2c4fca0a /gcc/cselib.c | |
parent | ad0a178f65bb4cf3be066dcc451820d15687c213 (diff) | |
download | gcc-aa140b766aa5d0e312e662ca1f2351c7a7c8525a.tar.gz |
PR middle-end/31150
* dse.c (struct store_info): Add const_rhs field.
(clear_rhs_from_active_local_stores): Clear also const_rhs.
(record_store): Try also cselib_expand_value_rtx to get a constant.
(find_shift_sequence, get_stored_val): Use const_rhs instead of
rhs if worthwhile.
* cselib.c (cselib_record_sets): If !cselib_record_memory and
there is just one set from read-only MEM, look at REG_EQUAL or
REG_EQUIV note.
* dse.c (struct store_info): Add redundant_reason field.
(record_store): When storing the same constant as has been
stored by an earlier store, set redundant_reason field
to the earlier store's insn_info_t. Don't delete cannot_delete
insns.
(find_shift_sequence): Remove read_info argument, add read_mode
and require_cst arguments. Return early if require_cst and
constant wouldn't be returned.
(get_stored_val): New function.
(replace_read): Use it.
(scan_insn): Put even cannot_delete insns with exactly 1 store
into active_local_stores.
(dse_step1): Don't delete cannot_delete insns. Remove redundant
constant stores if contains_cselib_groups and earlier store storing
the same value hasn't been eliminated.
(dse_step6): Renamed to dse_step7. New function.
(dse_step7): Renamed from dse_step6.
(rest_of_handle_dse): Call dse_step6 and dse_step7 at the end.
* cselib.c (cselib_expand_value_rtx): Don't wrap CONST_INTs
into CONST unless really necessary. Handle SUBREG, unary,
ternary, bitfield and compares specially, to be able to simplify
operations on constants.
(expand_loc): Try to optimize LO_SUM.
* dse.c (get_call_args): New function.
(scan_insn): Don't handle BUILT_IN_BZERO. For memset, attempt
to get call arguments and if successful and both len and val are
constants, handle the call as (mem:BLK) (const_int) store.
* dse.c (struct store_info): Add is_large bool field, change
positions_needed into a union of a bitmask and bitmap + count.
(free_store_info): Free bitmap if is_large.
(set_usage_bits): Don't look at stores where
offset + width >= MAX_OFFSET.
(set_position_unneeded, set_all_positions_unneeded,
any_positions_needed_p, all_positions_needed_p): New static inline
functions.
(record_store): Handle BLKmode stores of CONST_INT, if
MEM_SIZE is set on the MEM. Use the new positions_needed
accessor inlines.
(replace_read): Handle reads from BLKmode CONST_INT stores.
(check_mem_read_rtx): Use all_positions_needed_p function.
(dse_step1): Free large positions_needed bitmaps and clear is_large.
* dse.c (struct store_info): Change begin and end types to
HOST_WIDE_INT.
* dse.c (record_store): Fix check for unused store.
* expr.c (block_clear_fn): No longer static.
* expr.h (block_clear_fn): Declare.
* dse.c (scan_insn): Memset and bzero can just read their
arguments.
* gcc.c-torture/execute/20081218-1.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142892 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cselib.c')
-rw-r--r-- | gcc/cselib.c | 130 |
1 files changed, 109 insertions, 21 deletions
diff --git a/gcc/cselib.c b/gcc/cselib.c index d50d0c44f17..945a4a118de 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -1,6 +1,7 @@ /* Common subexpression elimination library for GNU compiler. Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. This file is part of GCC. @@ -865,12 +866,18 @@ expand_loc (struct elt_loc_list *p, bitmap regs_active, int max_depth) continue; else if (!REG_P (p->loc)) { - rtx result; + rtx result, note; if (dump_file) { print_inline_rtx (dump_file, p->loc, 0); fprintf (dump_file, "\n"); } + if (GET_CODE (p->loc) == LO_SUM + && GET_CODE (XEXP (p->loc, 1)) == SYMBOL_REF + && p->setting_insn + && (note = find_reg_note (p->setting_insn, REG_EQUAL, NULL_RTX)) + && XEXP (note, 0) == XEXP (p->loc, 1)) + return XEXP (p->loc, 1); result = cselib_expand_value_rtx (p->loc, regs_active, max_depth - 1); if (result) return result; @@ -928,6 +935,7 @@ cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth) int i, j; RTX_CODE code; const char *format_ptr; + enum machine_mode mode; code = GET_CODE (orig); @@ -1007,25 +1015,30 @@ cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth) return orig; break; - - case VALUE: + case SUBREG: { - rtx result; - if (dump_file) - fprintf (dump_file, "expanding value %s into: ", GET_MODE_NAME (GET_MODE (orig))); - - result = expand_loc (CSELIB_VAL_PTR (orig)->locs, regs_active, max_depth); - if (result - && GET_CODE (result) == CONST_INT - && GET_MODE (orig) != VOIDmode) - { - result = gen_rtx_CONST (GET_MODE (orig), result); - if (dump_file) - fprintf (dump_file, " wrapping const_int result in const to preserve mode %s\n", - GET_MODE_NAME (GET_MODE (orig))); - } - return result; + rtx subreg = cselib_expand_value_rtx (SUBREG_REG (orig), regs_active, + max_depth - 1); + if (!subreg) + return NULL; + scopy = simplify_gen_subreg (GET_MODE (orig), subreg, + GET_MODE (SUBREG_REG (orig)), + SUBREG_BYTE (orig)); + if (scopy == NULL + || (GET_CODE (scopy) == SUBREG + && !REG_P (SUBREG_REG (scopy)) + && !MEM_P (SUBREG_REG (scopy)))) + return shallow_copy_rtx (orig); + return scopy; } + + case VALUE: + if (dump_file) + fprintf (dump_file, "expanding value %s into: ", + GET_MODE_NAME (GET_MODE (orig))); + + return expand_loc (CSELIB_VAL_PTR (orig)->locs, regs_active, max_depth); + default: break; } @@ -1036,9 +1049,9 @@ cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth) us to explicitly document why we are *not* copying a flag. */ copy = shallow_copy_rtx (orig); - format_ptr = GET_RTX_FORMAT (GET_CODE (copy)); + format_ptr = GET_RTX_FORMAT (code); - for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++) + for (i = 0; i < GET_RTX_LENGTH (code); i++) switch (*format_ptr++) { case 'e': @@ -1082,6 +1095,70 @@ cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth) gcc_unreachable (); } + mode = GET_MODE (copy); + /* If an operand has been simplified into CONST_INT, which doesn't + have a mode and the mode isn't derivable from whole rtx's mode, + try simplify_*_operation first with mode from original's operand + and as a fallback wrap CONST_INT into gen_rtx_CONST. */ + scopy = copy; + switch (GET_RTX_CLASS (code)) + { + case RTX_UNARY: + if (CONST_INT_P (XEXP (copy, 0)) + && GET_MODE (XEXP (orig, 0)) != VOIDmode) + { + scopy = simplify_unary_operation (code, mode, XEXP (copy, 0), + GET_MODE (XEXP (orig, 0))); + if (scopy) + return scopy; + } + break; + case RTX_COMM_ARITH: + case RTX_BIN_ARITH: + /* These expressions can derive operand modes from the whole rtx's mode. */ + break; + case RTX_TERNARY: + case RTX_BITFIELD_OPS: + if (CONST_INT_P (XEXP (copy, 0)) + && GET_MODE (XEXP (orig, 0)) != VOIDmode) + { + scopy = simplify_ternary_operation (code, mode, + GET_MODE (XEXP (orig, 0)), + XEXP (copy, 0), XEXP (copy, 1), + XEXP (copy, 2)); + if (scopy) + return scopy; + } + break; + case RTX_COMPARE: + case RTX_COMM_COMPARE: + if (CONST_INT_P (XEXP (copy, 0)) + && GET_MODE (XEXP (copy, 1)) == VOIDmode + && (GET_MODE (XEXP (orig, 0)) != VOIDmode + || GET_MODE (XEXP (orig, 1)) != VOIDmode)) + { + scopy = simplify_relational_operation (code, mode, + (GET_MODE (XEXP (orig, 0)) + != VOIDmode) + ? GET_MODE (XEXP (orig, 0)) + : GET_MODE (XEXP (orig, 1)), + XEXP (copy, 0), + XEXP (copy, 1)); + if (scopy) + return scopy; + } + break; + default: + break; + } + if (scopy == NULL_RTX) + { + XEXP (copy, 0) + = gen_rtx_CONST (GET_MODE (XEXP (orig, 0)), XEXP (copy, 0)); + if (dump_file) + fprintf (dump_file, " wrapping const_int result in const to preserve mode %s\n", + GET_MODE_NAME (GET_MODE (XEXP (copy, 0)))); + } scopy = simplify_rtx (copy); if (scopy) return scopy; @@ -1581,6 +1658,17 @@ cselib_record_sets (rtx insn) } } + if (n_sets == 1 + && MEM_P (sets[0].src) + && !cselib_record_memory + && MEM_READONLY_P (sets[0].src)) + { + rtx note = find_reg_equal_equiv_note (insn); + + if (note && CONSTANT_P (XEXP (note, 0))) + sets[0].src = XEXP (note, 0); + } + /* Look up the values that are read. Do this before invalidating the locations that are written. */ for (i = 0; i < n_sets; i++) |