------- Comment #3 from dberlin at gcc dot gnu dot org  2007-06-10 03:31 -------
It won't be fixed by sccvn, at least not initially.
SCCVN has very strict rules about what expressions it decides are worth trying
to keep around to simplify other expressions.

Right now, we only keep those for which fold_binary returns two non-recursive
expressions, to control expand into infinite sized trees.

Even if you change this to keep around those which produce constants for one
operand, fold_binary returns null when given (a_1 * 2) + 4

You could work around this by also keeping around those expressions whose
valuized expansion ends up being  different than the original expression.

The following rewritten simplify_binary_expression, based on what it is
tree-ssa-sccvn.c that is about to be committed will do it.

(We don't bother simplifying comparisons, leaving it to another pass, feel free
to add support. They just don't occur enough and const/copyprop will figure it
out when we replace the supporting values)

/* Simplify the binary expression RHS, and return the result if
   simplified. */

static tree
simplify_binary_expression (tree rhs)
{
  tree result = NULL_TREE;
  tree op0 = TREE_OPERAND (rhs, 0);
  tree op1 = TREE_OPERAND (rhs, 1);
  tree oldop0 = op0;
  tree oldop1 = op1;
  bool valueized0 = false;
  bool valueized1 = false;

  /* This will not catch every single case we could combine, but will
     catch those with constants.  The goal here is to simultaneously
     combine constants between expressions, but avoid infinite
     expansion of expressions during simplification.  */
  if (TREE_CODE (op0) == SSA_NAME)
    {
      if (VN_INFO (op0)->has_constants)
        {
          valueized0 = true;
          op0 = valueize_expr (VN_INFO (op0)->expr);
        }
      else if (SSA_VAL (op0) != VN_TOP && SSA_VAL (op0) != op0)
        op0 = VN_INFO (op0)->valnum;      
    }

  if (TREE_CODE (op1) == SSA_NAME)
    {
      if (VN_INFO (op1)->has_constants)
        {
          valueized1 = true;
          op1 = valueize_expr (VN_INFO (op1)->expr);
        }
      else if (SSA_VAL (op1) != VN_TOP && SSA_VAL (op1) != op1)
        op1 = VN_INFO (op1)->valnum;
    }
  result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);

  /* Make sure result is not a complex expression consiting
     of operators of operators (IE (a + b) + (a + c))
     Otherwise, we will end up with unbounded expressions if
     fold does anything at all.  */
  if (result)
    {
      if (is_gimple_min_invariant (result))
        return result;
      else if (SSA_VAR_P (result))
        return result;
      else if (EXPR_P (result))
        {
          switch (TREE_CODE_CLASS (TREE_CODE (result)))
            {
            case tcc_unary:
              {
                tree op0 = TREE_OPERAND (result, 0);
                if (!EXPR_P (op0))
                  return result;
              }
              break;
            case tcc_binary:
              {
                tree op0 = TREE_OPERAND (result, 0);
                tree op1 = TREE_OPERAND (result, 1);
                if ((!EXPR_P (op0) && !EXPR_P (op1))
                    || (is_gimple_min_invariant (op0) 
                        || is_gimple_min_invariant (op1)))
                  return result;
              }
              break;
            default:
              break;
            }
        }
    }
  else if ((op0 != oldop0 && valueized0) || (op1 != oldop1 && valueized1))
    {
      /* Canonicalized to the valuized expression */
      return fold_build2 (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);
    }

  return NULL_TREE;
}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32120

Reply via email to