diff options
author | Martin Jambor <mjambor@suse.cz> | 2017-07-31 14:52:19 +0000 |
---|---|---|
committer | Martin Jambor <mjambor@suse.cz> | 2017-07-31 14:52:19 +0000 |
commit | 7e05bab54f745defb749670b8c84eaf513c0b214 (patch) | |
tree | 49524df297e69390449c3ef5037b2360d14c7b1a /gcc/tree-ssa-math-opts.c | |
parent | 77b800ca8b1cca32db99261ade36bf5f0eafaff8 (diff) |
Merged trunk revision 250739 into the hsa branch
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/hsa@250744 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-math-opts.c')
-rw-r--r-- | gcc/tree-ssa-math-opts.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index d044374dbc2..7ac1659fa06 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -1946,7 +1946,9 @@ make_pass_cse_sincos (gcc::context *ctxt) - a range which gives the difference between the highest and lowest accessed memory location to make such a symbolic number; - the address SRC of the source element of lowest address as a convenience - to easily get BASE_ADDR + offset + lowest bytepos. + to easily get BASE_ADDR + offset + lowest bytepos; + - number of expressions N_OPS bitwise ored together to represent + approximate cost of the computation. Note 1: the range is different from size as size reflects the size of the type of the current expression. For instance, for an array char a[], @@ -1968,6 +1970,7 @@ struct symbolic_number { tree alias_set; tree vuse; unsigned HOST_WIDE_INT range; + int n_ops; }; #define BITS_PER_MARKER 8 @@ -2083,6 +2086,7 @@ init_symbolic_number (struct symbolic_number *n, tree src) return false; n->range = size; n->n = CMPNOP; + n->n_ops = 1; if (size < 64 / BITS_PER_MARKER) n->n &= ((uint64_t) 1 << (size * BITS_PER_MARKER)) - 1; @@ -2293,6 +2297,7 @@ perform_symbolic_merge (gimple *source_stmt1, struct symbolic_number *n1, return NULL; } n->n = n1->n | n2->n; + n->n_ops = n1->n_ops + n2->n_ops; return source_stmt; } @@ -2588,7 +2593,7 @@ find_bswap_or_nop (gimple *stmt, struct symbolic_number *n, bool *bswap) return NULL; /* Useless bit manipulation performed by code. */ - if (!n->base_addr && n->n == cmpnop) + if (!n->base_addr && n->n == cmpnop && n->n_ops == 1) return NULL; n->range *= BITS_PER_UNIT; @@ -2747,6 +2752,36 @@ bswap_replace (gimple *cur_stmt, gimple *ins_stmt, tree fndecl, } src = val_tmp; } + else if (!bswap) + { + gimple *g; + if (!useless_type_conversion_p (TREE_TYPE (tgt), TREE_TYPE (src))) + { + if (!is_gimple_val (src)) + return false; + g = gimple_build_assign (tgt, NOP_EXPR, src); + } + else + g = gimple_build_assign (tgt, src); + if (n->range == 16) + nop_stats.found_16bit++; + else if (n->range == 32) + nop_stats.found_32bit++; + else + { + gcc_assert (n->range == 64); + nop_stats.found_64bit++; + } + if (dump_file) + { + fprintf (dump_file, + "%d bit reshuffle in target endianness found at: ", + (int) n->range); + print_gimple_stmt (dump_file, cur_stmt, 0); + } + gsi_replace (&gsi, g, true); + return true; + } else if (TREE_CODE (src) == BIT_FIELD_REF) src = TREE_OPERAND (src, 0); @@ -3842,7 +3877,7 @@ static bool divmod_candidate_p (gassign *stmt) { tree type = TREE_TYPE (gimple_assign_lhs (stmt)); - enum machine_mode mode = TYPE_MODE (type); + machine_mode mode = TYPE_MODE (type); optab divmod_optab, div_optab; if (TYPE_UNSIGNED (type)) |