From: Roger Sayle Date: Tue, 18 Feb 2003 19:37:01 +0000 (+0000) Subject: fold-const.c (negate_expr_p): New function to determine whether an expression can... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=080ea642c0b75fe30d551afe5e3ab0ab70e78720;p=gcc.git fold-const.c (negate_expr_p): New function to determine whether an expression can be negated cheaply. * fold-const.c (negate_expr_p): New function to determine whether an expression can be negated cheaply. (fold) [MINUS_EXPR]: Use it to determine whether to transform -A - B into -B - A for floating point types. From-SVN: r63059 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d791614a133..42b21cf4d32 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2003-02-18 Roger Sayle + + * fold-const.c (negate_expr_p): New function to determine whether + an expression can be negated cheaply. + (fold) [MINUS_EXPR]: Use it to determine whether to transform + -A - B into -B - A for floating point types. + 2003-02-18 Roger Sayle * sbitmap.c (sbitmap_resize): New function. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index d6f356104c3..5dfa1e413ec 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1,6 +1,6 @@ /* Fold a constant sub-tree into a single node for C-compiler - Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2002, - 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, + 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of GCC. @@ -63,6 +63,7 @@ static void encode PARAMS ((HOST_WIDE_INT *, static void decode PARAMS ((HOST_WIDE_INT *, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *)); +static bool negate_expr_p PARAMS ((tree)); static tree negate_expr PARAMS ((tree)); static tree split_tree PARAMS ((tree, enum tree_code, tree *, tree *, tree *, int)); @@ -835,6 +836,55 @@ div_and_round_double (code, uns, return overflow; } +/* Determine whether an expression T can be cheaply negated using + the function negate_expr. */ + +static bool +negate_expr_p (t) + tree t; +{ + unsigned HOST_WIDE_INT val; + unsigned int prec; + tree type; + + if (t == 0) + return false; + + type = TREE_TYPE (t); + + STRIP_SIGN_NOPS (t); + switch (TREE_CODE (t)) + { + case INTEGER_CST: + if (TREE_UNSIGNED (type)) + return false; + + /* Check that -CST will not overflow type. */ + prec = TYPE_PRECISION (type); + if (prec > HOST_BITS_PER_WIDE_INT) + { + if (TREE_INT_CST_LOW (t) != 0) + return true; + prec -= HOST_BITS_PER_WIDE_INT; + val = TREE_INT_CST_HIGH (t); + } + else + val = TREE_INT_CST_LOW (t); + if (prec < HOST_BITS_PER_WIDE_INT) + val &= ((unsigned HOST_WIDE_INT) 1 << prec) - 1; + return val != ((unsigned HOST_WIDE_INT) 1 << (prec - 1)); + + case REAL_CST: + case NEGATE_EXPR: + case MINUS_EXPR: + return true; + + default: + break; + } + return false; +} + /* Given T, an expression, return the negation of T. Allow for T to be null, in which case return null. */ @@ -5479,13 +5529,14 @@ fold (expr) /* A - (-B) -> A + B */ if (TREE_CODE (arg1) == NEGATE_EXPR) return fold (build (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0))); - /* (-A) - CST -> (-CST) - A for floating point (what about ints ?) */ - if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == REAL_CST) - return - fold (build (MINUS_EXPR, type, - build_real (TREE_TYPE (arg1), - REAL_VALUE_NEGATE (TREE_REAL_CST (arg1))), - TREE_OPERAND (arg0, 0))); + /* (-A) - B -> (-B) - A where B is easily negated and we can swap. */ + if (TREE_CODE (arg0) == NEGATE_EXPR + && FLOAT_TYPE_P (type) + && negate_expr_p (arg1) + && (! TREE_SIDE_EFFECTS (arg0) || TREE_CONSTANT (arg1)) + && (! TREE_SIDE_EFFECTS (arg1) || TREE_CONSTANT (arg0))) + return fold (build (MINUS_EXPR, type, negate_expr (arg1), + TREE_OPERAND (arg0, 0))); if (! FLOAT_TYPE_P (type)) {