diff options
author | Jan Hubicka <jh@suse.cz> | 2007-01-28 20:38:39 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2007-01-28 19:38:39 +0000 |
commit | 079a182e02a0720f9ac230c212fd202df3e6bd9e (patch) | |
tree | f0b99d930c723a2db6886a47a653581d98be0f1a /gcc/expr.c | |
parent | 2472200d9c53250482c75443611251490b23e5f2 (diff) | |
download | gcc-079a182e02a0720f9ac230c212fd202df3e6bd9e.zip gcc-079a182e02a0720f9ac230c212fd202df3e6bd9e.tar.gz gcc-079a182e02a0720f9ac230c212fd202df3e6bd9e.tar.bz2 |
expr.c (emit_block_move_via_movmem, [...]): Add variant handling histograms; add wrapper.
* expr.c (emit_block_move_via_movmem, emit_block_move_via_libcall): Add
variant handling histograms; add wrapper.
(clear_storage_via_libcall): Export.
(emit_block_move_hints): Break out from ...; add histograms.
(emit_block_move): ... this one.
(clear_storage_hints): Break out from ...; add histograms.
(clear_storage): ... this one.
(set_storage_via_memset): Handle histogram.
* expr.h (emit_block_move_via_libcall, emit_block_move_hints): Declare.
(clear_storage_hints, clear_storage_via_libcall): Declare.
(set_storage_via_setmem): Update prototype.
* doc/md.texi (movmem, setmem): Document new arguments.
* value-prof.c (dump_histogram_value, tree_find_values_to_profile): Add
new histograms.
(stringop_block_profile): New global function.
(tree_stringops_values_to_profile): Profile block size and alignment.
* value-prof.h (enum hist_type): add HIST_TYPE_AVERAGE and
HIST_TYPE_IOR.
(struct profile_hooks): Add gen_average_profiler and gen_ior_profiler.
(stringop_block_profile): Declare.
* builtins.c: Include value-prof.h.
(expand_builtin_memcpy, expand_builtin_memset): Pass block profile.
* gcov-ui.h (GCOV_COUNTER_NAMES): Add new counter.
(GCOV_COUNTER_AVERAGE, GCOV_COUNTER_IOR): New constants.
(GCOV_COUNTERS, GCOV_LAST_VALUE_COUNTER): Update.
* profile.c (instrument_values): Add new counters.
* cfgexpand.c (expand_gimple_basic_block): Propagate histograms to
calls.
* tree-profile.c (tree_average_profiler_fn, tree_ior_profiler_fn): New.
(tree_init_edge_profiler): Build new profilers.
(tree_gen_average_profiler, tree_gen_ior_profiler): New.
(pass_tree_profile): Add dump.
(tree_profile_hooks): Update.
* Makefile.in (LIBGCOV): Add new constants.
* libgcov.c (__gcov_merge_ior, __gcov_average_profiler,
__gcov_ior_profiler): New.
* i386.md (movmem/setmem expanders): Add new optional arguments.
From-SVN: r121270
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 53 |
1 files changed, 44 insertions, 9 deletions
@@ -126,7 +126,7 @@ static unsigned HOST_WIDE_INT move_by_pieces_ninsns (unsigned HOST_WIDE_INT, static void move_by_pieces_1 (rtx (*) (rtx, ...), enum machine_mode, struct move_by_pieces *); static bool block_move_libcall_safe_for_call_parm (void); -static bool emit_block_move_via_movmem (rtx, rtx, rtx, unsigned); +static bool emit_block_move_via_movmem (rtx, rtx, rtx, unsigned, unsigned, HOST_WIDE_INT); static tree emit_block_move_libcall_fn (int); static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned); static rtx clear_by_pieces_1 (void *, HOST_WIDE_INT, enum machine_mode); @@ -1147,7 +1147,8 @@ move_by_pieces_1 (rtx (*genfun) (rtx, ...), enum machine_mode mode, 0 otherwise. */ rtx -emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method) +emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method, + unsigned int expected_align, HOST_WIDE_INT expected_size) { bool may_use_call; rtx retval = 0; @@ -1202,7 +1203,8 @@ emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method) if (GET_CODE (size) == CONST_INT && MOVE_BY_PIECES_P (INTVAL (size), align)) move_by_pieces (x, y, INTVAL (size), align, 0); - else if (emit_block_move_via_movmem (x, y, size, align)) + else if (emit_block_move_via_movmem (x, y, size, align, + expected_align, expected_size)) ; else if (may_use_call) retval = emit_block_move_via_libcall (x, y, size, @@ -1216,6 +1218,12 @@ emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method) return retval; } +rtx +emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method) +{ + return emit_block_move_hints (x, y, size, method, 0, -1); +} + /* A subroutine of emit_block_move. Returns true if calling the block move libcall will not clobber any parameters which may have already been placed on the stack. */ @@ -1266,12 +1274,16 @@ block_move_libcall_safe_for_call_parm (void) return true if successful. */ static bool -emit_block_move_via_movmem (rtx x, rtx y, rtx size, unsigned int align) +emit_block_move_via_movmem (rtx x, rtx y, rtx size, unsigned int align, + unsigned int expected_align, HOST_WIDE_INT expected_size) { rtx opalign = GEN_INT (align / BITS_PER_UNIT); int save_volatile_ok = volatile_ok; enum machine_mode mode; + if (expected_align < align) + expected_align = align; + /* Since this is a move insn, we don't care about volatility. */ volatile_ok = 1; @@ -1315,7 +1327,12 @@ emit_block_move_via_movmem (rtx x, rtx y, rtx size, unsigned int align) that it doesn't fail the expansion because it thinks emitting the libcall would be more efficient. */ - pat = GEN_FCN ((int) code) (x, y, op2, opalign); + if (insn_data[(int) code].n_operands == 4) + pat = GEN_FCN ((int) code) (x, y, op2, opalign); + else + pat = GEN_FCN ((int) code) (x, y, op2, opalign, + GEN_INT (expected_align), + GEN_INT (expected_size)); if (pat) { emit_insn (pat); @@ -2495,7 +2512,8 @@ store_by_pieces_2 (rtx (*genfun) (rtx, ...), enum machine_mode mode, its length in bytes. */ rtx -clear_storage (rtx object, rtx size, enum block_op_methods method) +clear_storage_hints (rtx object, rtx size, enum block_op_methods method, + unsigned int expected_align, HOST_WIDE_INT expected_size) { enum machine_mode mode = GET_MODE (object); unsigned int align; @@ -2535,7 +2553,8 @@ clear_storage (rtx object, rtx size, enum block_op_methods method) if (GET_CODE (size) == CONST_INT && CLEAR_BY_PIECES_P (INTVAL (size), align)) clear_by_pieces (object, INTVAL (size), align); - else if (set_storage_via_setmem (object, size, const0_rtx, align)) + else if (set_storage_via_setmem (object, size, const0_rtx, align, + expected_align, expected_size)) ; else return set_storage_via_libcall (object, size, const0_rtx, @@ -2544,6 +2563,13 @@ clear_storage (rtx object, rtx size, enum block_op_methods method) return NULL; } +rtx +clear_storage (rtx object, rtx size, enum block_op_methods method) +{ + return clear_storage_hints (object, size, method, 0, -1); +} + + /* A subroutine of clear_storage. Expand a call to memset. Return the return value of memset, 0 otherwise. */ @@ -2645,7 +2671,8 @@ clear_storage_libcall_fn (int for_call) /* Expand a setmem pattern; return true if successful. */ bool -set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align) +set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align, + unsigned int expected_align, HOST_WIDE_INT expected_size) { /* Try the most limited insn first, because there's no point including more than one in the machine description unless @@ -2654,6 +2681,9 @@ set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align) rtx opalign = GEN_INT (align / BITS_PER_UNIT); enum machine_mode mode; + if (expected_align < align) + expected_align = align; + for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode)) { @@ -2694,7 +2724,12 @@ set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align) opchar = copy_to_mode_reg (char_mode, opchar); } - pat = GEN_FCN ((int) code) (object, opsize, opchar, opalign); + if (insn_data[(int) code].n_operands == 4) + pat = GEN_FCN ((int) code) (object, opsize, opchar, opalign); + else + pat = GEN_FCN ((int) code) (object, opsize, opchar, opalign, + GEN_INT (expected_align), + GEN_INT (expected_size)); if (pat) { emit_insn (pat); |