OSDN Git Service

2006-02-19 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-ccp.c
index c428ef0..ec70c36 100644 (file)
@@ -855,11 +855,19 @@ ccp_fold (tree stmt)
       /* If the RHS is a memory load, see if the VUSEs associated with
         it are a valid constant for that memory load.  */
       prop_value_t *val = get_value_loaded_by (stmt, const_val);
-      if (val && val->mem_ref
-         && operand_equal_p (val->mem_ref, rhs, 0))
-       return val->value;
-      else
-       return NULL_TREE;
+      if (val && val->mem_ref)
+       {
+         if (operand_equal_p (val->mem_ref, rhs, 0))
+           return val->value;
+
+         /* If RHS is extracting REALPART_EXPR or IMAGPART_EXPR of a
+            complex type with a known constant value, return it.  */
+         if ((TREE_CODE (rhs) == REALPART_EXPR
+              || TREE_CODE (rhs) == IMAGPART_EXPR)
+             && operand_equal_p (val->mem_ref, TREE_OPERAND (rhs, 0), 0))
+           return fold_build1 (TREE_CODE (rhs), TREE_TYPE (rhs), val->value);
+       }
+      return NULL_TREE;
     }
 
   /* Unary operators.  Note that we know the single operand must
@@ -1191,9 +1199,9 @@ visit_assignment (tree stmt, tree *output_p)
     if (TREE_CODE (orig_lhs) == VIEW_CONVERT_EXPR
        && val.lattice_val == CONSTANT)
       {
-       tree w = fold_build1 (VIEW_CONVERT_EXPR,
-                             TREE_TYPE (TREE_OPERAND (orig_lhs, 0)),
-                             val.value);
+       tree w = fold_unary (VIEW_CONVERT_EXPR,
+                            TREE_TYPE (TREE_OPERAND (orig_lhs, 0)),
+                            val.value);
 
        orig_lhs = TREE_OPERAND (orig_lhs, 0);
        if (w && is_gimple_min_invariant (w))
@@ -1901,9 +1909,9 @@ maybe_fold_stmt_addition (tree expr)
     {
       if (TYPE_UNSIGNED (TREE_TYPE (op1)))
        return NULL;
-      op1 = fold_build1 (NEGATE_EXPR, TREE_TYPE (op1), op1);
+      op1 = fold_unary (NEGATE_EXPR, TREE_TYPE (op1), op1);
       /* ??? In theory fold should always produce another integer.  */
-      if (TREE_CODE (op1) != INTEGER_CST)
+      if (op1 == NULL || TREE_CODE (op1) != INTEGER_CST)
        return NULL;
     }
 
@@ -2342,38 +2350,6 @@ fold_stmt (tree *stmt_p)
       callee = get_callee_fndecl (rhs);
       if (callee && DECL_BUILT_IN (callee))
        result = ccp_fold_builtin (stmt, rhs);
-      else
-       {
-         /* Check for resolvable OBJ_TYPE_REF.  The only sorts we can resolve
-            here are when we've propagated the address of a decl into the
-            object slot.  */
-         /* ??? Should perhaps do this in fold proper.  However, doing it
-            there requires that we create a new CALL_EXPR, and that requires
-            copying EH region info to the new node.  Easier to just do it
-            here where we can just smash the call operand.  */
-         callee = TREE_OPERAND (rhs, 0);
-         if (TREE_CODE (callee) == OBJ_TYPE_REF
-             && lang_hooks.fold_obj_type_ref
-             && TREE_CODE (OBJ_TYPE_REF_OBJECT (callee)) == ADDR_EXPR
-             && DECL_P (TREE_OPERAND
-                        (OBJ_TYPE_REF_OBJECT (callee), 0)))
-           {
-             tree t;
-
-             /* ??? Caution: Broken ADDR_EXPR semantics means that
-                looking at the type of the operand of the addr_expr
-                can yield an array type.  See silly exception in
-                check_pointer_types_r.  */
-
-             t = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (callee)));
-             t = lang_hooks.fold_obj_type_ref (callee, t);
-             if (t)
-               {
-                 TREE_OPERAND (rhs, 0) = t;
-                 changed = true;
-               }
-           }
-       }
     }
 
   /* If we couldn't fold the RHS, hand over to the generic fold routines.  */