===================================================================
@@ -1624,30 +1624,56 @@ simplify_bitwise_binary (gimple_stmt_ite
/* If the first argument is an SSA name that is itself a result of a
typecast of an ADDR_EXPR to an integer, feed the ADDR_EXPR to the
folder rather than the ssa name. */
- if (code == BIT_AND_EXPR
- && TREE_CODE (arg2) == INTEGER_CST
+ if (TREE_CODE (arg2) == INTEGER_CST
&& TREE_CODE (arg1) == SSA_NAME)
{
gimple def = SSA_NAME_DEF_STMT (arg1);
tree op = arg1;
+ tree opp = NULL_TREE;
+ tree folded_int = NULL_TREE;
- /* ??? This looks bogus - the conversion could be truncating. */
if (is_gimple_assign (def)
&& CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def))
&& INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
{
- tree opp = gimple_assign_rhs1 (def);
- if (TREE_CODE (opp) == ADDR_EXPR)
+ opp = gimple_assign_rhs1 (def);
+ folded_int = fold_convert_loc (gimple_location (stmt),
+ TREE_TYPE (opp), arg2);
+ /* Check if integer value remains the same on cast back
+ to original type. */
+ if (!operand_equal_p (arg2, fold_convert (TREE_TYPE (arg1),
+ folded_int), 0))
+ folded_int = NULL_TREE;
+ if (TREE_CODE (opp) == ADDR_EXPR && folded_int)
op = opp;
}
+ if (code == BIT_AND_EXPR)
+ {
+ res = fold_binary_loc (gimple_location (stmt),
+ BIT_AND_EXPR,
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ op, arg2);
+ if (res && is_gimple_min_invariant (res))
+ {
+ gimple_assign_set_rhs_from_tree (gsi, res);
+ update_stmt (stmt);
+ return true;
+ }
+ }
- res = fold_binary_loc (gimple_location (stmt),
- BIT_AND_EXPR, TREE_TYPE (gimple_assign_lhs (stmt)),
- op, arg2);
- if (res && is_gimple_min_invariant (res))
- {
- gimple_assign_set_rhs_from_tree (gsi, res);
- update_stmt (stmt);
+ /* Convert (type) X & CST -> (type) (X & (typeof-X) CST),
+ if conversion of CST is reversible. */
+ if (opp != NULL_TREE && folded_int != NULL_TREE)
+ {
+ gimple newop;
+ tree tem = create_tmp_reg (TREE_TYPE (opp), NULL);
+ newop = gimple_build_assign_with_ops (code, tem, opp, folded_int);
+ tem = make_ssa_name (tem, newop);
+ gimple_assign_set_lhs (newop, tem);
+ gsi_insert_before (gsi, newop, GSI_SAME_STMT);
+ gimple_assign_set_rhs_with_ops_1 (gsi, NOP_EXPR,
+ tem, NULL_TREE, NULL_TREE);
+ update_stmt (gsi_stmt (*gsi));
return true;
}
}
@@ -1682,10 +1708,11 @@ simplify_bitwise_binary (gimple_stmt_ite
if (CONVERT_EXPR_CODE_P (def1_code)
&& CONVERT_EXPR_CODE_P (def2_code)
&& types_compatible_p (TREE_TYPE (def1_arg1), TREE_TYPE (def2_arg1))
- /* Make sure that the conversion widens the operands or that it
- changes the operation to a bitfield precision. */
+ /* Make sure that the conversion widens the operands, or has same
+ precision, or that it changes the operation to a bitfield
+ precision. */
&& ((TYPE_PRECISION (TREE_TYPE (def1_arg1))
- < TYPE_PRECISION (TREE_TYPE (arg1)))
+ <= TYPE_PRECISION (TREE_TYPE (arg1)))
|| (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (arg1)))
!= MODE_INT)
|| (TYPE_PRECISION (TREE_TYPE (arg1))
===================================================================
@@ -1785,6 +1785,7 @@ execute_optimize_bswap (void)
bool bswap32_p, bswap64_p;
bool changed = false;
tree bswap32_type = NULL_TREE, bswap64_type = NULL_TREE;
+ int iter = 0;
if (BITS_PER_UNIT != 8)
return 0;
@@ -1815,108 +1816,123 @@ execute_optimize_bswap (void)
bswap64_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
}
+ /* Is 64-bit bswap not supported? */
+ if (!bswap64_p)
+ iter = 1;
+
memset (&bswap_stats, 0, sizeof (bswap_stats));
- FOR_EACH_BB (bb)
+ /* If iter has value of zero, then seek for 64-bit bswap,
+ If iter has value of one, then seek for 32-bit bswap. */
+ for (; iter < 2; iter++)
{
- gimple_stmt_iterator gsi;
+ FOR_EACH_BB (bb)
+ {
+ gimple_stmt_iterator gsi;
- for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- gimple stmt = gsi_stmt (gsi);
- tree bswap_src, bswap_type;
- tree bswap_tmp;
- tree fndecl = NULL_TREE;
- int type_size;
- gimple call;
-
- if (!is_gimple_assign (stmt)
- || gimple_assign_rhs_code (stmt) != BIT_IOR_EXPR)
- continue;
+ for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ tree bswap_src, bswap_type;
+ tree bswap_tmp;
+ tree fndecl = NULL_TREE;
+ int type_size;
+ gimple call;
+
+ if (!is_gimple_assign (stmt)
+ || gimple_assign_rhs_code (stmt) != BIT_IOR_EXPR)
+ continue;
- type_size = TYPE_PRECISION (gimple_expr_type (stmt));
+ type_size = TYPE_PRECISION (gimple_expr_type (stmt));
- switch (type_size)
- {
- case 32:
- if (bswap32_p)
+ switch (type_size)
{
- fndecl = built_in_decls[BUILT_IN_BSWAP32];
- bswap_type = bswap32_type;
- }
- break;
- case 64:
- if (bswap64_p)
- {
- fndecl = built_in_decls[BUILT_IN_BSWAP64];
- bswap_type = bswap64_type;
+ case 32:
+ if (iter != 1)
+ continue;
+ if (bswap32_p)
+ {
+ fndecl = built_in_decls[BUILT_IN_BSWAP32];
+ bswap_type = bswap32_type;
+ }
+ break;
+ case 64:
+ if (iter != 0)
+ continue;
+ if (bswap64_p)
+ {
+ fndecl = built_in_decls[BUILT_IN_BSWAP64];
+ bswap_type = bswap64_type;
+ }
+ break;
+ default:
+ continue;
}
- break;
- default:
- continue;
- }
- if (!fndecl)
- continue;
+ if (!fndecl)
+ continue;
- bswap_src = find_bswap (stmt);
+ bswap_src = find_bswap (stmt);
- if (!bswap_src)
- continue;
+ if (!bswap_src)
+ continue;
- changed = true;
- if (type_size == 32)
- bswap_stats.found_32bit++;
- else
- bswap_stats.found_64bit++;
+ changed = true;
+ if (type_size == 32)
+ bswap_stats.found_32bit++;
+ else
+ bswap_stats.found_64bit++;
- bswap_tmp = bswap_src;
+ bswap_tmp = bswap_src;
- /* Convert the src expression if necessary. */
- if (!useless_type_conversion_p (TREE_TYPE (bswap_tmp), bswap_type))
- {
- gimple convert_stmt;
+ /* Convert the src expression if necessary. */
+ if (!useless_type_conversion_p (TREE_TYPE (bswap_tmp),
+ bswap_type))
+ {
+ gimple convert_stmt;
- bswap_tmp = create_tmp_var (bswap_type, "bswapsrc");
- add_referenced_var (bswap_tmp);
- bswap_tmp = make_ssa_name (bswap_tmp, NULL);
-
- convert_stmt = gimple_build_assign_with_ops (
- CONVERT_EXPR, bswap_tmp, bswap_src, NULL);
- gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT);
- }
+ bswap_tmp = create_tmp_var (bswap_type, "bswapsrc");
+ add_referenced_var (bswap_tmp);
+ bswap_tmp = make_ssa_name (bswap_tmp, NULL);
+
+ convert_stmt = gimple_build_assign_with_ops (
+ CONVERT_EXPR, bswap_tmp, bswap_src, NULL);
+ gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT);
+ }
- call = gimple_build_call (fndecl, 1, bswap_tmp);
+ call = gimple_build_call (fndecl, 1, bswap_tmp);
- bswap_tmp = gimple_assign_lhs (stmt);
+ bswap_tmp = gimple_assign_lhs (stmt);
- /* Convert the result if necessary. */
- if (!useless_type_conversion_p (TREE_TYPE (bswap_tmp), bswap_type))
- {
- gimple convert_stmt;
+ /* Convert the result if necessary. */
+ if (!useless_type_conversion_p (TREE_TYPE (bswap_tmp),
+ bswap_type))
+ {
+ gimple convert_stmt;
- bswap_tmp = create_tmp_var (bswap_type, "bswapdst");
- add_referenced_var (bswap_tmp);
- bswap_tmp = make_ssa_name (bswap_tmp, NULL);
- convert_stmt = gimple_build_assign_with_ops (
- CONVERT_EXPR, gimple_assign_lhs (stmt), bswap_tmp, NULL);
- gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT);
- }
+ bswap_tmp = create_tmp_var (bswap_type, "bswapdst");
+ add_referenced_var (bswap_tmp);
+ bswap_tmp = make_ssa_name (bswap_tmp, NULL);
+ convert_stmt = gimple_build_assign_with_ops (
+ CONVERT_EXPR, gimple_assign_lhs (stmt),
+ bswap_tmp, NULL);
+ gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT);
+ }
- gimple_call_set_lhs (call, bswap_tmp);
+ gimple_call_set_lhs (call, bswap_tmp);
- if (dump_file)
- {
- fprintf (dump_file, "%d bit bswap implementation found at: ",
- (int)type_size);
- print_gimple_stmt (dump_file, stmt, 0, 0);
- }
+ if (dump_file)
+ {
+ fprintf (dump_file, "%d bit bswap implementation found at: ",
+ (int) type_size);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
+ }
- gsi_insert_after (&gsi, call, GSI_SAME_STMT);
- gsi_remove (&gsi, true);
+ gsi_insert_after (&gsi, call, GSI_SAME_STMT);
+ gsi_remove (&gsi, true);
+ }
}
}
-
statistics_counter_event (cfun, "32-bit bswap implementations found",
bswap_stats.found_32bit);
statistics_counter_event (cfun, "64-bit bswap implementations found",