[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