OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / gimple-iterator.c
index 9a3c382..f5a1d26 100644 (file)
@@ -1,5 +1,5 @@
 /* Iterator routines for GIMPLE statements.
-   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc.
    Contributed by Aldy Hernandez  <aldy@quesejoda.com>
 
 This file is part of GCC.
@@ -65,6 +65,35 @@ update_bb_for_stmts (gimple_seq_node first, basic_block bb)
     gimple_set_bb (n->stmt, bb);
 }
 
+/* Set the frequencies for the cgraph_edges for each of the calls
+   starting at FIRST for their new position within BB.  */
+
+static void
+update_call_edge_frequencies (gimple_seq_node first, basic_block bb)
+{
+  struct cgraph_node *cfun_node = NULL;
+  int bb_freq = 0;
+  gimple_seq_node n;
+
+  for (n = first; n ; n = n->next)
+    if (is_gimple_call (n->stmt))
+      {
+       struct cgraph_edge *e;
+
+       /* These function calls are expensive enough that we want
+          to avoid calling them if we never see any calls.  */
+       if (cfun_node == NULL)
+         {
+           cfun_node = cgraph_get_node (current_function_decl);
+           bb_freq = (compute_call_stmt_bb_frequency
+                      (current_function_decl, bb));
+         }
+
+       e = cgraph_edge (cfun_node, n->stmt);
+       if (e != NULL)
+         e->frequency = bb_freq;
+      }
+}
 
 /* Insert the sequence delimited by nodes FIRST and LAST before
    iterator I.  M specifies how to update iterator I after insertion
@@ -381,8 +410,12 @@ gsi_replace (gimple_stmt_iterator *gsi, gimple stmt, bool update_eh_info)
     maybe_clean_or_replace_eh_stmt (orig_stmt, stmt);
 
   gimple_duplicate_stmt_histograms (cfun, stmt, cfun, orig_stmt);
+
+  /* Free all the data flow information for ORIG_STMT.  */
+  gimple_set_bb (orig_stmt, NULL);
   gimple_remove_stmt_histograms (cfun, orig_stmt);
   delink_stmt_imm_use (orig_stmt);
+
   *gsi_stmt_ptr (gsi) = stmt;
   gimple_set_modified (stmt, true);
   update_modified_stmt (stmt);
@@ -404,7 +437,7 @@ gsi_insert_before_without_update (gimple_stmt_iterator *i, gimple stmt,
 {
   gimple_seq_node n;
 
-  n = GGC_NEW (struct gimple_seq_node_d);
+  n = ggc_alloc_gimple_seq_node_d ();
   n->prev = n->next = NULL;
   n->stmt = stmt;
   gsi_insert_seq_nodes_before (i, n, n, m);
@@ -439,7 +472,7 @@ gsi_insert_after_without_update (gimple_stmt_iterator *i, gimple stmt,
 {
   gimple_seq_node n;
 
-  n = GGC_NEW (struct gimple_seq_node_d);
+  n = ggc_alloc_gimple_seq_node_d ();
   n->prev = n->next = NULL;
   n->stmt = stmt;
   gsi_insert_seq_nodes_after (i, n, n, m);
@@ -474,7 +507,8 @@ gsi_remove (gimple_stmt_iterator *i, bool remove_permanently)
   gimple_seq_node cur, next, prev;
   gimple stmt = gsi_stmt (*i);
 
-  insert_debug_temps_for_defs (i);
+  if (gimple_code (stmt) != GIMPLE_PHI)
+    insert_debug_temps_for_defs (i);
 
   /* Free all the data flow information for STMT.  */
   gimple_set_bb (stmt, NULL);
@@ -563,9 +597,7 @@ void
 gsi_move_to_bb_end (gimple_stmt_iterator *from, basic_block bb)
 {
   gimple_stmt_iterator last = gsi_last_bb (bb);
-#ifdef ENABLE_CHECKING
-  gcc_assert (gsi_bb (last) == bb);
-#endif
+  gcc_checking_assert (gsi_bb (last) == bb);
 
   /* Have to check gsi_end_p because it could be an empty block.  */
   if (!gsi_end_p (last) && is_ctrl_stmt (gsi_stmt (last)))
@@ -691,11 +723,19 @@ basic_block
 gsi_insert_on_edge_immediate (edge e, gimple stmt)
 {
   gimple_stmt_iterator gsi;
+  struct gimple_seq_node_d node;
   basic_block new_bb = NULL;
+  bool ins_after;
 
   gcc_assert (!PENDING_STMT (e));
 
-  if (gimple_find_edge_insert_loc (e, &gsi, &new_bb))
+  ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb);
+
+  node.stmt = stmt;
+  node.prev = node.next = NULL;
+  update_call_edge_frequencies (&node, gsi.bb);
+
+  if (ins_after)
     gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
   else
     gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
@@ -711,10 +751,14 @@ gsi_insert_seq_on_edge_immediate (edge e, gimple_seq stmts)
 {
   gimple_stmt_iterator gsi;
   basic_block new_bb = NULL;
+  bool ins_after;
 
   gcc_assert (!PENDING_STMT (e));
 
-  if (gimple_find_edge_insert_loc (e, &gsi, &new_bb))
+  ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb);
+  update_call_edge_frequencies (gimple_seq_first (stmts), gsi.bb);
+
+  if (ins_after)
     gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
   else
     gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
@@ -753,10 +797,14 @@ gsi_commit_one_edge_insert (edge e, basic_block *new_bb)
     {
       gimple_stmt_iterator gsi;
       gimple_seq seq = PENDING_STMT (e);
+      bool ins_after;
 
       PENDING_STMT (e) = NULL;
 
-      if (gimple_find_edge_insert_loc (e, &gsi, new_bb))
+      ins_after = gimple_find_edge_insert_loc (e, &gsi, new_bb);
+      update_call_edge_frequencies (gimple_seq_first (seq), gsi.bb);
+
+      if (ins_after)
        gsi_insert_seq_after (&gsi, seq, GSI_NEW_STMT);
       else
        gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT);