[PATCH] Optimize manual byte swap implementations v3
Nathan Froyd
froydnj@codesourcery.com
Tue Feb 10 16:14:00 GMT 2009
On Tue, Feb 10, 2009 at 04:17:02PM +0100, Andreas Krebbel wrote:
> Ok. Here is an updated version.
[...]
> +static tree
> +find_bswap_1 (gimple stmt, struct symbolic_number *n, int limit)
> +{
> + enum tree_code code;
> + tree rhs1, rhs2 = NULL;
> + gimple rhs1_stmt, rhs2_stmt;
> + tree source_expr1;
> +
> + if (!limit || !is_gimple_assign (stmt))
> + return NULL;
> +
> + rhs1 = gimple_assign_rhs1 (stmt);
> +
> + if (TREE_CODE (rhs1) != SSA_NAME)
> + return NULL;
> +
> + code = gimple_assign_rhs_code (stmt);
> + rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
> +
> + if (gimple_assign_rhs_class (stmt) == GIMPLE_BINARY_RHS)
> + rhs2 = gimple_assign_rhs2 (stmt);
> +
> + /* Handle unary rhs and binary rhs with integer constants as second
> + operand. */
> +
> + if (gimple_assign_rhs_class (stmt) == GIMPLE_UNARY_RHS
> + || (gimple_assign_rhs_class (stmt) == GIMPLE_BINARY_RHS
> + && TREE_CODE (rhs2) == INTEGER_CST))
> + {
> + if (code != BIT_AND_EXPR
> + && code != LSHIFT_EXPR
> + && code != RSHIFT_EXPR
> + && code != LROTATE_EXPR
> + && code != RROTATE_EXPR
> + && code != NOP_EXPR
> + && code != CONVERT_EXPR)
> + return NULL;
> +
> + source_expr1 = find_bswap_1 (rhs1_stmt, n, limit - 1);
> +
> + /* If find_bswap_1 returned NULL STMT is a leaf node and we have
> + to initialize the symbolic number. */
> + if (!source_expr1)
> + {
> + /* Set up the symbolic number N by setting each byte to a
> + value between 1 and the byte size of rhs1. The highest
> + order byte is set to 1 and the lowest order byte to
> + n.size. */
> + n->size = (int)TREE_INT_CST_LOW (TYPE_SIZE (
> + TREE_TYPE (rhs1))) / BITS_PER_UNIT;
> +
> + n->n = BSWAP_INITIAL_SYM_NUMBER >>
> + (sizeof (HOST_WIDEST_INT) - n->size) * BITS_PER_UNIT;
> +
> + source_expr1 = rhs1;
> + }
> +
> + switch (code)
> + {
> + case BIT_AND_EXPR:
> + {
> + int i;
> + unsigned HOST_WIDEST_INT val = widest_int_cst_value (rhs2);
> + unsigned HOST_WIDEST_INT tmp = val;
> +
> + /* Only constants masking full bytes are allowed. */
> + for (i = 0; i < n->size; i++, tmp >>= BITS_PER_UNIT)
> + if ((tmp & 0xff) != 0 && (tmp & 0xff) != 0xff)
> + return false;
At the very least, this should be NULL, for consistency with the other
returns from this function. Better would be to use NULL_TREE, since
this function returns a `tree'.
-Nathan
More information about the Gcc-patches
mailing list