OSDN Git Service

* objc.dg/objc-fast-4.m: Skip for ppc64.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-math-opts.c
index 825c0bd..ee5ff8f 100644 (file)
@@ -279,6 +279,35 @@ is_division_by (tree use_stmt, tree def)
         && TREE_OPERAND (TREE_OPERAND (use_stmt, 1), 1) == def;
 }
 
+/* Return the LHS of a RDIV_EXPR that computes a reciprocal in type TYPE.  */
+static tree
+get_constant_one (tree type)
+{
+  tree scalar, cst;
+  int i;
+
+  gcc_assert (FLOAT_TYPE_P (type));
+  switch (TREE_CODE (type))
+    {
+    case REAL_TYPE:
+      return build_real (type, dconst1);
+
+    case VECTOR_TYPE:
+      scalar = build_real (TREE_TYPE (type), dconst1);
+
+      /* Create 'vect_cst_ = {cst,cst,...,cst}'  */
+      cst = NULL_TREE;
+      for (i = TYPE_VECTOR_SUBPARTS (type); --i >= 0; )
+        cst = tree_cons (NULL_TREE, scalar, cst);
+
+      return build_vector (type, cst);
+
+    default:
+      /* Complex operations have been split already.  */
+      gcc_unreachable ();
+    }
+}
+
 /* Walk the subset of the dominator tree rooted at OCC, setting the
    RECIP_DEF field to a definition of 1.0 / DEF that can be used in
    the given basic block.  The field may be left NULL, of course,
@@ -304,8 +333,8 @@ insert_reciprocals (block_stmt_iterator *def_bsi, struct occurrence *occ,
       type = TREE_TYPE (def);
       recip_def = make_rename_temp (type, "reciptmp");
       new_stmt = build2 (MODIFY_EXPR, void_type_node, recip_def,
-                        fold_build2 (RDIV_EXPR, type,
-                                     build_real (type, dconst1), def));
+                        fold_build2 (RDIV_EXPR, type, get_constant_one (type),
+                                     def));
   
   
       if (occ->bb_has_division)
@@ -417,17 +446,20 @@ execute_cse_reciprocals_1 (block_stmt_iterator *def_bsi, tree def)
   threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def)));
   if (count >= threshold)
     {
+      tree use_stmt;
       for (occ = occ_head; occ; occ = occ->next)
        {
          compute_merit (occ);
          insert_reciprocals (def_bsi, occ, def, NULL, threshold);
        }
 
-      FOR_EACH_IMM_USE_SAFE (use_p, use_iter, def)
+      FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def)
        {
-         tree use_stmt = USE_STMT (use_p);
          if (is_division_by (use_stmt, def))
-           replace_reciprocal (use_p);
+           {
+             FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter)
+               replace_reciprocal (use_p);
+           }
        }
     }
 
@@ -447,7 +479,7 @@ gate_cse_reciprocals (void)
 
 /* Go through all the floating-point SSA_NAMEs, and call
    execute_cse_reciprocals_1 on each of them.  */
-static void
+static unsigned int
 execute_cse_reciprocals (void)
 {
   basic_block bb;
@@ -496,6 +528,7 @@ execute_cse_reciprocals (void)
 
   free_dominance_info (CDI_DOMINATORS | CDI_POST_DOMINATORS);
   free_alloc_pool (occ_pool);
+  return 0;
 }
 
 struct tree_opt_pass pass_cse_reciprocals =