Commit 03bd2f1a by Andreas Krebbel Committed by Andreas Krebbel

passes.c: Add bswap pass.

2009-06-14  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* passes.c: Add bswap pass.
	* tree-pass.h: Add pass_optimize_bswap declaration.
	* tree-ssa-math-opts.c: Include diagnostics.h for print_gimple_stmt.
	Include rtl.h, expr.h and optabs.h for optab_handler check.
	(struct symbolic_number, pass_optimize_bswap): New definition.
	(do_shift_rotate, verify_symbolic_number_p): New functions.
	(find_bswap_1, find_bswap, execute_optimize_bswap): New functions.
	(gate_optimize_bswap): New function.
	* tree.c (widest_int_cst_value): New function.
	* tree.h (widest_int_cst_value): Prototype added.

2009-06-14  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>

	* gcc.dg/optimize-bswap-1.c: New testcase.

From-SVN: r148471
parent a810f82f
2009-06-14 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* passes.c: Add bswap pass.
* tree-pass.h: Add pass_optimize_bswap declaration.
* tree-ssa-math-opts.c: Include diagnostics.h for print_gimple_stmt.
Include rtl.h, expr.h and optabs.h for optab_handler check.
(struct symbolic_number, pass_optimize_bswap): New definition.
(do_shift_rotate, verify_symbolic_number_p): New functions.
(find_bswap_1, find_bswap, execute_optimize_bswap): New functions.
(gate_optimize_bswap): New function.
* tree.c (widest_int_cst_value): New function.
* tree.h (widest_int_cst_value): Prototype added.
2009-06-14 Steven Bosscher <steven@gcc.gnu.org>
* cfgcleanup.c (old_insns_match_p): Remove code to substitute
......
......@@ -638,6 +638,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_copy_prop);
NEXT_PASS (pass_fold_builtins);
NEXT_PASS (pass_cse_sincos);
NEXT_PASS (pass_optimize_bswap);
NEXT_PASS (pass_split_crit_edges);
NEXT_PASS (pass_pre);
NEXT_PASS (pass_sink_code);
......
2009-06-14 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* gcc.dg/optimize-bswap-1.c: New testcase.
2009-06-14 Richard Guenther <rguenther@suse.de>
PR middle-end/40389
......
/* { dg-do compile } */
/* { dg-require-effective-target stdint_types } */
/* { dg-options "-O2 -fdump-tree-bswap" } */
#include <stdint.h>
#define __const_swab32(x) ((uint32_t)( \
(((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
(((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
(((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
#define __const_swab64(x) ((uint64_t)( \
(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
/* This byte swap implementation is used by the Linux kernel and the
GNU C library. */
uint32_t
swap32_a (uint32_t in)
{
return __const_swab32 (in);
}
uint64_t
swap64 (uint64_t in)
{
return __const_swab64 (in);
}
/* The OpenSSH byte swap implementation. */
uint32_t
swap32_b (uint32_t in)
{
uint32_t a;
a = (in << 16) | (in >> 16);
a = ((a & 0x00ff00ff) << 8) | ((a & 0xff00ff00) >> 8);
return a;
}
/* { dg-final { scan-tree-dump-times "32 bit bswap implementation found at" 2 "bswap" } } */
/* { dg-final { scan-tree-dump-times "64 bit bswap implementation found at" 1 "bswap" } } */
/* { dg-final { cleanup-tree-dump "bswap" } } */
......@@ -377,6 +377,7 @@ extern struct gimple_opt_pass pass_late_warn_uninitialized;
extern struct gimple_opt_pass pass_cse_reciprocals;
extern struct gimple_opt_pass pass_cse_sincos;
extern struct gimple_opt_pass pass_convert_to_rsqrt;
extern struct gimple_opt_pass pass_optimize_bswap;
extern struct gimple_opt_pass pass_warn_function_return;
extern struct gimple_opt_pass pass_warn_function_noreturn;
extern struct gimple_opt_pass pass_cselim;
......
......@@ -8489,6 +8489,35 @@ int_cst_value (const_tree x)
return val;
}
/* Return value of a constant X and sign-extend it. */
HOST_WIDEST_INT
widest_int_cst_value (const_tree x)
{
unsigned bits = TYPE_PRECISION (TREE_TYPE (x));
unsigned HOST_WIDEST_INT val = TREE_INT_CST_LOW (x);
#if HOST_BITS_PER_WIDEST_INT > HOST_BITS_PER_WIDE_INT
gcc_assert (HOST_BITS_PER_WIDEST_INT >= 2 * HOST_BITS_PER_WIDE_INT);
val |= TREE_INT_CST_HIGH (x) << HOST_BITS_PER_WIDE_INT;
#else
/* Make sure the sign-extended value will fit in a HOST_WIDE_INT. */
gcc_assert (TREE_INT_CST_HIGH (x) == 0
|| TREE_INT_CST_HIGH (x) == -1);
#endif
if (bits < HOST_BITS_PER_WIDEST_INT)
{
bool negative = ((val >> (bits - 1)) & 1) != 0;
if (negative)
val |= (~(unsigned HOST_WIDEST_INT) 0) << (bits - 1) << 1;
else
val &= ~((~(unsigned HOST_WIDEST_INT) 0) << (bits - 1) << 1);
}
return val;
}
/* If TYPE is an integral type, return an equivalent type which is
unsigned iff UNSIGNEDP is true. If TYPE is not an integral type,
return TYPE itself. */
......
......@@ -4868,6 +4868,7 @@ extern tree build_nonstandard_integer_type (unsigned HOST_WIDE_INT, int);
extern tree build_range_type (tree, tree, tree);
extern bool subrange_type_for_debug_p (const_tree, tree *, tree *);
extern HOST_WIDE_INT int_cst_value (const_tree);
extern HOST_WIDEST_INT widest_int_cst_value (const_tree);
extern bool fields_compatible_p (const_tree, const_tree);
extern tree find_compatible_field (tree, tree);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment