OSDN Git Service

PR middle-end/44769
[pf3gnuchains/gcc-fork.git] / gcc / tree-inline.c
index 8a53d5e..2c05835 100644 (file)
@@ -242,10 +242,9 @@ remap_ssa_name (tree name, copy_body_data *id)
            {
              gimple_stmt_iterator gsi = gsi_last_bb (id->entry_bb);
              gimple init_stmt;
+             tree zero = build_zero_cst (TREE_TYPE (new_tree));
 
-             init_stmt = gimple_build_assign (new_tree,
-                                              fold_convert (TREE_TYPE (new_tree),
-                                                           integer_zero_node));
+             init_stmt = gimple_build_assign (new_tree, zero);
              gsi_insert_after (&gsi, init_stmt, GSI_NEW_STMT);
              SSA_NAME_IS_DEFAULT_DEF (new_tree) = 0;
            }
@@ -858,6 +857,7 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
                  *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
                                     ptr, TREE_OPERAND (*tp, 1));
                  TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
+                 TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
                }
              TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
              *walk_subtrees = 0;
@@ -1087,6 +1087,8 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
                      *tp = build1 (INDIRECT_REF, type, new_tree);
                      TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
                      TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old);
+                     TREE_READONLY (*tp) = TREE_READONLY (old);
+                     TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
                    }
                }
              *walk_subtrees = 0;
@@ -1558,7 +1560,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
          tree new_rhs;
          new_rhs = force_gimple_operand_gsi (&seq_gsi,
                                              gimple_assign_rhs1 (stmt),
-                                             true, NULL, false, GSI_NEW_STMT);
+                                             true, NULL, false,
+                                             GSI_CONTINUE_LINKING);
          gimple_assign_set_rhs1 (stmt, new_rhs);
          id->regimplify = false;
        }
@@ -3246,6 +3249,16 @@ estimate_move_cost (tree type)
 
   gcc_assert (!VOID_TYPE_P (type));
 
+  if (TREE_CODE (type) == VECTOR_TYPE)
+    {
+      enum machine_mode inner = TYPE_MODE (TREE_TYPE (type));
+      enum machine_mode simd
+       = targetm.vectorize.preferred_simd_mode (inner);
+      int simd_mode_size = GET_MODE_SIZE (simd);
+      return ((GET_MODE_SIZE (TYPE_MODE (type)) + simd_mode_size - 1)
+             / simd_mode_size);
+    }
+
   size = int_size_in_bytes (type);
 
   if (size < 0 || size > MOVE_MAX_PIECES * MOVE_RATIO (!optimize_size))
@@ -3280,6 +3293,7 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights,
     case POINTER_PLUS_EXPR:
     case MINUS_EXPR:
     case MULT_EXPR:
+    case FMA_EXPR:
 
     case ADDR_SPACE_CONVERT_EXPR:
     case FIXED_CONVERT_EXPR:
@@ -3480,10 +3494,16 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
        if (POINTER_TYPE_P (funtype))
          funtype = TREE_TYPE (funtype);
 
-       if (is_simple_builtin (decl))
+       /* Do not special case builtins where we see the body.
+          This just confuse inliner.  */
+       if (!decl || cgraph_node (decl)->analyzed)
+         cost = weights->call_cost;
+       /* For buitins that are likely expanded to nothing or
+          inlined do not account operand costs.  */
+       else if (is_simple_builtin (decl))
          return 0;
        else if (is_inexpensive_builtin (decl))
-         cost = weights->target_builtin_call_cost;
+         return weights->target_builtin_call_cost;
        else
          cost = weights->call_cost;
 
@@ -3532,11 +3552,13 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
        break;
       }
 
+    case GIMPLE_RETURN:
+      return weights->return_cost;
+
     case GIMPLE_GOTO:
     case GIMPLE_LABEL:
     case GIMPLE_NOP:
     case GIMPLE_PHI:
-    case GIMPLE_RETURN:
     case GIMPLE_PREDICT:
     case GIMPLE_DEBUG:
       return 0;
@@ -3636,16 +3658,18 @@ init_inline_once (void)
   eni_size_weights.div_mod_cost = 1;
   eni_size_weights.omp_cost = 40;
   eni_size_weights.time_based = false;
+  eni_size_weights.return_cost = 1;
 
   /* Estimating time for call is difficult, since we have no idea what the
      called function does.  In the current uses of eni_time_weights,
      underestimating the cost does less harm than overestimating it, so
      we choose a rather small value here.  */
   eni_time_weights.call_cost = 10;
-  eni_time_weights.target_builtin_call_cost = 10;
+  eni_time_weights.target_builtin_call_cost = 1;
   eni_time_weights.div_mod_cost = 10;
   eni_time_weights.omp_cost = 40;
   eni_time_weights.time_based = true;
+  eni_time_weights.return_cost = 2;
 }
 
 /* Estimate the number of instructions in a gimple_seq. */
@@ -4006,7 +4030,10 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
     }
 
   if (purge_dead_abnormal_edges)
-    gimple_purge_dead_abnormal_call_edges (return_block);
+    {
+      gimple_purge_dead_eh_edges (return_block);
+      gimple_purge_dead_abnormal_call_edges (return_block);
+    }
 
   /* If the value of the new expression is ignored, that's OK.  We
      don't warn about this for CALL_EXPRs, so we shouldn't warn about