summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-math-opts.c
diff options
context:
space:
mode:
authorthopre01 <thopre01@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-31 11:55:07 +0000
committerthopre01 <thopre01@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-31 11:55:07 +0000
commit0b6c968ac9248282f0b33a45f07cb1d336bba063 (patch)
treec8d332a3425f18aaecef6c4864fecfd21349ed66 /gcc/tree-ssa-math-opts.c
parenteca9489da83767a445c92b8b9f0c3009eef7abcf (diff)
downloadgcc-0b6c968ac9248282f0b33a45f07cb1d336bba063.tar.gz
2014-10-31 Thomas Preud'homme <thomas.preudhomme@arm.com>
gcc/ PR tree-optimization/63259 * tree-ssa-math-opts.c (bswap_replace): Replace expression by a rotation left if it is a 16 bit byte swap. (pass_optimize_bswap::execute): Also consider bswap in LROTATE_EXPR and RROTATE_EXPR statements if it is a byte rotation. gcc/testsuite/ PR tree-optimization/63259 * optimize-bswapsi-1.c (swap32_f): New bswap pass test. * optimize-bswaphi-1.c: Drop useless SIType definition and fix typo in following comment. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@216971 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-math-opts.c')
-rw-r--r--gcc/tree-ssa-math-opts.c52
1 files changed, 40 insertions, 12 deletions
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 5daeff26ab3..27825895a27 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -2187,7 +2187,7 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt,
struct symbolic_number *n, bool bswap)
{
tree src, tmp, tgt;
- gimple call;
+ gimple bswap_stmt;
src = gimple_assign_rhs1 (src_stmt);
tgt = gimple_assign_lhs (cur_stmt);
@@ -2293,16 +2293,28 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt,
tmp = src;
- /* Convert the src expression if necessary. */
- if (!useless_type_conversion_p (TREE_TYPE (tmp), bswap_type))
+ /* Canonical form for 16 bit bswap is a rotate expression. */
+ if (bswap && n->range == 16)
{
- gimple convert_stmt;
- tmp = make_temp_ssa_name (bswap_type, NULL, "bswapsrc");
- convert_stmt = gimple_build_assign_with_ops (NOP_EXPR, tmp, src, NULL);
- gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT);
+ tree count = build_int_cst (NULL, BITS_PER_UNIT);
+ bswap_type = TREE_TYPE (src);
+ src = fold_build2 (LROTATE_EXPR, bswap_type, src, count);
+ bswap_stmt = gimple_build_assign (NULL, src);
}
+ else
+ {
+ /* Convert the src expression if necessary. */
+ if (!useless_type_conversion_p (TREE_TYPE (tmp), bswap_type))
+ {
+ gimple convert_stmt;
+ tmp = make_temp_ssa_name (bswap_type, NULL, "bswapsrc");
+ convert_stmt = gimple_build_assign_with_ops (NOP_EXPR, tmp, src,
+ NULL);
+ gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT);
+ }
- call = gimple_build_call (fndecl, 1, tmp);
+ bswap_stmt = gimple_build_call (fndecl, 1, tmp);
+ }
tmp = tgt;
@@ -2315,7 +2327,7 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt,
gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT);
}
- gimple_call_set_lhs (call, tmp);
+ gimple_set_lhs (bswap_stmt, tmp);
if (dump_file)
{
@@ -2324,7 +2336,7 @@ bswap_replace (gimple cur_stmt, gimple_stmt_iterator gsi, gimple src_stmt,
print_gimple_stmt (dump_file, cur_stmt, 0, 0);
}
- gsi_insert_after (&gsi, call, GSI_SAME_STMT);
+ gsi_insert_after (&gsi, bswap_stmt, GSI_SAME_STMT);
gsi_remove (&gsi, true);
return true;
}
@@ -2388,13 +2400,29 @@ pass_optimize_bswap::execute (function *fun)
{
gimple src_stmt, cur_stmt = gsi_stmt (gsi);
tree fndecl = NULL_TREE, bswap_type = NULL_TREE, load_type;
+ enum tree_code code;
struct symbolic_number n;
bool bswap;
- if (!is_gimple_assign (cur_stmt)
- || gimple_assign_rhs_code (cur_stmt) != BIT_IOR_EXPR)
+ if (!is_gimple_assign (cur_stmt))
continue;
+ code = gimple_assign_rhs_code (cur_stmt);
+ switch (code)
+ {
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ if (!tree_fits_uhwi_p (gimple_assign_rhs2 (cur_stmt))
+ || tree_to_uhwi (gimple_assign_rhs2 (cur_stmt))
+ % BITS_PER_UNIT)
+ continue;
+ /* Fall through. */
+ case BIT_IOR_EXPR:
+ break;
+ default:
+ continue;
+ }
+
src_stmt = find_bswap_or_nop (cur_stmt, &n, &bswap);
if (!src_stmt)