Merge branch 'vendor/GCC44'
[dragonfly.git] / contrib / gcc-4.4 / gcc / tree-inline.c
index 6f1533e..e85e148 100644 (file)
@@ -1737,12 +1737,13 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
   edge_iterator ei;
   gimple phi;
   gimple_stmt_iterator si;
+  edge new_edge;
+  bool inserted = false;
 
   for (si = gsi_start (phi_nodes (bb)); !gsi_end_p (si); gsi_next (&si))
     {
       tree res, new_res;
       gimple new_phi;
-      edge new_edge;
 
       phi = gsi_stmt (si);
       res = PHI_RESULT (phi);
@@ -1771,12 +1772,18 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
                {
                  gimple_seq stmts = NULL;
                  new_arg = force_gimple_operand (new_arg, &stmts, true, NULL);
-                 gsi_insert_seq_on_edge_immediate (new_edge, stmts);
+                 gsi_insert_seq_on_edge (new_edge, stmts);
+                 inserted = true;
                }
              add_phi_arg (new_phi, new_arg, new_edge);
            }
        }
     }
+
+  /* Commit the delayed edge insertions.  */
+  if (inserted)
+    FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
+      gsi_commit_one_edge_insert (new_edge, NULL);
 }
 
 
@@ -2729,6 +2736,8 @@ estimate_move_cost (tree type)
 {
   HOST_WIDE_INT size;
 
+  gcc_assert (!VOID_TYPE_P (type));
+
   size = int_size_in_bytes (type);
 
   if (size < 0 || size > MOVE_MAX_PIECES * MOVE_RATIO (!optimize_size))
@@ -2980,7 +2989,8 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
          {
            tree t;
            for (t = TYPE_ARG_TYPES (funtype); t; t = TREE_CHAIN (t))
-             cost += estimate_move_cost (TREE_VALUE (t));
+             if (!VOID_TYPE_P (TREE_VALUE (t)))
+               cost += estimate_move_cost (TREE_VALUE (t));
          }
        else
          {
@@ -4269,6 +4279,46 @@ tree_versionable_function_p (tree fndecl)
   return true;
 }
 
+/* Delete all unreachable basic blocks and update callgraph.
+   Doing so is somewhat nontrivial because we need to update all clones and
+   remove inline function that become unreachable.  */
+
+static bool
+delete_unreachable_blocks_update_callgraph (copy_body_data *id)
+{
+  bool changed = false;
+  basic_block b, next_bb;
+
+  find_unreachable_blocks ();
+
+  /* Delete all unreachable basic blocks.  */
+
+  for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR; b = next_bb)
+    {
+      next_bb = b->next_bb;
+
+      if (!(b->flags & BB_REACHABLE))
+       {
+          gimple_stmt_iterator bsi;
+
+          for (bsi = gsi_start_bb (b); !gsi_end_p (bsi); gsi_next (&bsi))
+           if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL)
+             {
+               struct cgraph_edge *e;
+
+               if ((e = cgraph_edge (id->dst_node, gsi_stmt (bsi))) != NULL)
+                 cgraph_remove_edge (e);
+             }
+         delete_basic_block (b);
+         changed = true;
+       }
+    }
+
+  if (changed)
+    tidy_fallthru_edges ();
+  return changed;
+}
+
 /* Create a copy of a function's tree.
    OLD_DECL and NEW_DECL are FUNCTION_DECL tree nodes
    of the original function and the new copied function
@@ -4443,7 +4493,7 @@ tree_function_versioning (tree old_decl, tree new_decl, varray_type tree_map,
       free_dominance_info (CDI_DOMINATORS);
       free_dominance_info (CDI_POST_DOMINATORS);
       if (!update_clones)
-        delete_unreachable_blocks ();
+        delete_unreachable_blocks_update_callgraph (&id);
       update_ssa (TODO_update_ssa);
       if (!update_clones)
        {