OSDN Git Service

* gcc.dg/vect/vect-105.c: Prevent compiler from hoisting abort
[pf3gnuchains/gcc-fork.git] / gcc / tree-sra.c
index abe0c9f..01c0e12 100644 (file)
@@ -1902,10 +1902,10 @@ decide_block_copy (struct sra_elt *elt)
             sensible default.  */
          max_size = SRA_MAX_STRUCTURE_SIZE
            ? SRA_MAX_STRUCTURE_SIZE
-           : MOVE_RATIO * UNITS_PER_WORD;
+           : MOVE_RATIO (optimize_function_for_speed_p (cfun)) * UNITS_PER_WORD;
          max_count = SRA_MAX_STRUCTURE_COUNT
            ? SRA_MAX_STRUCTURE_COUNT
-           : MOVE_RATIO;
+           : MOVE_RATIO (optimize_function_for_speed_p (cfun));
 
          full_size = tree_low_cst (size_tree, 1);
          full_count = count_type_elements (elt->type, false);
@@ -2144,7 +2144,7 @@ static gimple_seq
 sra_build_assignment (tree dst, tree src)
 {
   gimple stmt;
-  gimple_seq seq = NULL;
+  gimple_seq seq = NULL, seq2 = NULL;
   /* Turning BIT_FIELD_REFs into bit operations enables other passes
      to do a much better job at optimizing the code.
      From dst = BIT_FIELD_REF <var, sz, off> we produce
@@ -2158,9 +2158,10 @@ sra_build_assignment (tree dst, tree src)
   if (scalar_bitfield_p (src))
     {
       tree var, shift, width;
-      tree utype, stype, stmp, utmp, dtmp;
+      tree utype, stype;
       bool unsignedp = (INTEGRAL_TYPE_P (TREE_TYPE (src))
                        ? TYPE_UNSIGNED (TREE_TYPE (src)) : true);
+      struct gimplify_ctx gctx;
 
       var = TREE_OPERAND (src, 0);
       width = TREE_OPERAND (src, 1);
@@ -2191,28 +2192,15 @@ sra_build_assignment (tree dst, tree src)
       else if (!TYPE_UNSIGNED (utype))
        utype = unsigned_type_for (utype);
 
-      stmp = make_rename_temp (stype, "SR");
-
       /* Convert the base var of the BIT_FIELD_REF to the scalar type
         we use for computation if we cannot use it directly.  */
-      if (!useless_type_conversion_p (stype, TREE_TYPE (var)))
-       {
-         if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
-           stmt = gimple_build_assign (stmp, fold_convert (stype, var));
-         else
-           stmt = gimple_build_assign (stmp, fold_build1 (VIEW_CONVERT_EXPR,
-                                                          stype, var));
-         gimple_seq_add_stmt (&seq, stmt);
-         var = stmp;
-       }
+      if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
+       var = fold_convert (stype, var);
+      else
+       var = fold_build1 (VIEW_CONVERT_EXPR, stype, var);
 
       if (!integer_zerop (shift))
-       {
-         stmt = gimple_build_assign (stmp, fold_build2 (RSHIFT_EXPR, stype,
-                                                        var, shift));
-         gimple_seq_add_stmt (&seq, stmt);
-         var = stmp;
-       }
+       var = fold_build2 (RSHIFT_EXPR, stype, var, shift);
 
       /* If we need a masking operation, produce one.  */
       if (TREE_INT_CST_LOW (width) == TYPE_PRECISION (stype))
@@ -2222,24 +2210,11 @@ sra_build_assignment (tree dst, tree src)
          tree one = build_int_cst_wide (stype, 1, 0);
          tree mask = int_const_binop (LSHIFT_EXPR, one, width, 0);
          mask = int_const_binop (MINUS_EXPR, mask, one, 0);
-
-         stmt = gimple_build_assign (stmp, fold_build2 (BIT_AND_EXPR, stype,
-                                                        var, mask));
-         gimple_seq_add_stmt (&seq, stmt);
-         var = stmp;
+         var = fold_build2 (BIT_AND_EXPR, stype, var, mask);
        }
 
       /* After shifting and masking, convert to the target type.  */
-      utmp = stmp;
-      if (!useless_type_conversion_p (utype, stype))
-       {
-         utmp = make_rename_temp (utype, "SR");
-
-         stmt = gimple_build_assign (utmp, fold_convert (utype, var));
-         gimple_seq_add_stmt (&seq, stmt);
-
-         var = utmp;
-       }
+      var = fold_convert (utype, var);
 
       /* Perform sign extension, if required.
         ???  This should never be necessary.  */
@@ -2250,40 +2225,29 @@ sra_build_assignment (tree dst, tree src)
                                          size_binop (MINUS_EXPR, width,
                                                      bitsize_int (1)), 0);
 
-         stmt = gimple_build_assign (utmp, fold_build2 (BIT_XOR_EXPR, utype,
-                                                        var, signbit));
-         gimple_seq_add_stmt (&seq, stmt);
-
-         stmt = gimple_build_assign (utmp, fold_build2 (MINUS_EXPR, utype,
-                                                        utmp, signbit));
-         gimple_seq_add_stmt (&seq, stmt);
-
-         var = utmp;
+         var = fold_build2 (BIT_XOR_EXPR, utype, var, signbit);
+         var = fold_build2 (MINUS_EXPR, utype, var, signbit);
        }
 
       /* fold_build3 (BIT_FIELD_REF, ...) sometimes returns a cast.  */
       STRIP_NOPS (dst);
 
       /* Finally, move and convert to the destination.  */
-      if (!useless_type_conversion_p (TREE_TYPE (dst), TREE_TYPE (var)))
-       {
-         if (INTEGRAL_TYPE_P (TREE_TYPE (dst)))
-           var = fold_convert (TREE_TYPE (dst), var);
-         else
-           var = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dst), var);
+      if (INTEGRAL_TYPE_P (TREE_TYPE (dst)))
+       var = fold_convert (TREE_TYPE (dst), var);
+      else
+       var = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (dst), var);
 
-         /* If the destination is not a register the conversion needs
-            to be a separate statement.  */
-         if (!is_gimple_reg (dst))
-           {
-             dtmp = make_rename_temp (TREE_TYPE (dst), "SR");
-             stmt = gimple_build_assign (dtmp, var);
-             gimple_seq_add_stmt (&seq, stmt);
-             var = dtmp;
-           }
-       }
-      stmt = gimple_build_assign (dst, var);
-      gimple_seq_add_stmt (&seq, stmt);
+      push_gimplify_context (&gctx);
+      gctx.into_ssa = true;
+      gctx.allow_rhs_cond_expr = true;
+
+      gimplify_assign (dst, var, &seq);
+
+      if (gimple_referenced_vars (cfun))
+       for (var = gctx.temps; var; var = TREE_CHAIN (var))
+         add_referenced_var (var);
+      pop_gimplify_context (NULL);
 
       return seq;
     }
@@ -2308,6 +2272,14 @@ sra_build_assignment (tree dst, tree src)
           && !useless_type_conversion_p (TREE_TYPE (dst), TREE_TYPE (src)))
     src = fold_convert (TREE_TYPE (dst), src);
 
+  /* ???  Only call the gimplifier if we need to.  Otherwise we may 
+     end up substituting with DECL_VALUE_EXPR - see PR37380.  */
+  if (!handled_component_p (src)
+      && !SSA_VAR_P (src))
+    {
+      src = force_gimple_operand (src, &seq2, false, NULL_TREE);
+      gimple_seq_add_seq (&seq, seq2);
+    }
   stmt = gimple_build_assign (dst, src);
   gimple_seq_add_stmt (&seq, stmt);
   return seq;
@@ -2382,14 +2354,17 @@ sra_build_bf_assignment (tree dst, tree src)
       tmp = var;
       if (!is_gimple_variable (tmp))
        tmp = unshare_expr (var);
+      else
+       TREE_NO_WARNING (var) = true;
 
       tmp2 = make_rename_temp (utype, "SR");
 
       if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
-       stmt = gimple_build_assign (tmp2, fold_convert (utype, tmp));
+       tmp = fold_convert (utype, tmp);
       else
-       stmt = gimple_build_assign (tmp2, fold_build1 (VIEW_CONVERT_EXPR,
-                                                      utype, tmp));
+       tmp = fold_build1 (VIEW_CONVERT_EXPR, utype, tmp);
+
+      stmt = gimple_build_assign (tmp2, tmp);
       gimple_seq_add_stmt (&seq, stmt);
     }
   else
@@ -2597,8 +2572,7 @@ generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr,
 
       t = build2 (COMPLEX_EXPR, elt->type, r, i);
       tmp_seq = sra_build_bf_assignment (expr, t);
-      gcc_assert (gimple_seq_singleton_p (tmp_seq));
-      SSA_NAME_DEF_STMT (expr) = gimple_seq_first_stmt (tmp_seq);
+      SSA_NAME_DEF_STMT (expr) = gimple_seq_last_stmt (tmp_seq);
       gimple_seq_add_seq (seq_p, tmp_seq);
     }
   else if (elt->replacement)
@@ -2954,8 +2928,13 @@ bitfield_overlaps_p (tree blen, tree bpos, struct sra_elt *fld,
     }
   else if (TREE_CODE (fld->element) == INTEGER_CST)
     {
+      tree domain_type = TYPE_DOMAIN (TREE_TYPE (fld->parent->element));
       flen = fold_convert (bitsizetype, TYPE_SIZE (fld->type));
       fpos = fold_convert (bitsizetype, fld->element);
+      if (domain_type && TYPE_MIN_VALUE (domain_type))
+       fpos = size_binop (MINUS_EXPR, fpos,
+                          fold_convert (bitsizetype,
+                                        TYPE_MIN_VALUE (domain_type)));
       fpos = size_binop (MULT_EXPR, flen, fpos);
     }
   else
@@ -3037,11 +3016,9 @@ sra_explode_bitfield_assignment (tree var, tree vpos, bool to_var,
 
          infld = fld->replacement;
 
-         type = TREE_TYPE (infld);
+         type = unsigned_type_for (TREE_TYPE (infld));
          if (TYPE_PRECISION (type) != TREE_INT_CST_LOW (flen))
-           type = lang_hooks.types.type_for_size (TREE_INT_CST_LOW (flen), 1);
-         else
-           type = unsigned_type_for (type);
+           type = build_nonstandard_integer_type (TREE_INT_CST_LOW (flen), 1);
 
          if (TREE_CODE (infld) == BIT_FIELD_REF)
            {
@@ -3249,12 +3226,20 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, gimple_stmt_iterator *gsi,
       if (!elt->use_block_copy)
        {
          tree type = TREE_TYPE (bfexpr);
-         tree var, vpos;
+         tree var = make_rename_temp (type, "SR"), tmp, vpos;
+         gimple st = NULL;
 
-         if (!TYPE_UNSIGNED (type))
-           type = unsigned_type_for (type);
+         gimple_assign_set_rhs1 (stmt, var);
+         update = true;
 
-         var = make_rename_temp (type, "SR");
+         if (!TYPE_UNSIGNED (type))
+           {
+             type = unsigned_type_for (type);
+             tmp = make_rename_temp (type, "SR");
+             st = gimple_build_assign (var,
+                                       fold_convert (TREE_TYPE (var), tmp));
+             var = tmp;
+           }
 
          gimple_seq_add_stmt (&seq,
                                gimple_build_assign
@@ -3271,8 +3256,8 @@ scalarize_use (struct sra_elt *elt, tree *expr_p, gimple_stmt_iterator *gsi,
          sra_explode_bitfield_assignment
            (var, vpos, true, &seq, blen, bpos, elt);
 
-         gimple_assign_set_rhs1 (stmt, var);
-         update = true;
+         if (st)
+           gimple_seq_add_stmt (&seq, st);
        }
       else
        sra_sync_for_bitfield_assignment