re PR ipa/44563 (GCC uses a lot of RAM when compiling a large numbers of functions)
authorRichard Biener <rguenther@suse.de>
Fri, 13 Mar 2015 08:52:51 +0000 (08:52 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 13 Mar 2015 08:52:51 +0000 (08:52 +0000)
2015-03-12  Richard Biener  <rguenther@suse.de>

PR middle-end/44563
* tree-inline.c (gimple_expand_calls_inline): Walk BB backwards
to avoid quadratic behavior with inline expansion splitting blocks.
* tree-cfgcleanup.c (cleanup_tree_cfg_bb): Do not merge block
with the successor if the predecessor will be merged with it.
* tree-cfg.c (gimple_can_merge_blocks_p): We can't merge the
entry block with its successor.

From-SVN: r221410

gcc/ChangeLog
gcc/tree-cfg.c
gcc/tree-cfgcleanup.c
gcc/tree-inline.c

index 18ada57..3f24ed8 100644 (file)
@@ -1,3 +1,13 @@
+2015-03-12  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/44563
+       * tree-inline.c (gimple_expand_calls_inline): Walk BB backwards
+       to avoid quadratic behavior with inline expansion splitting blocks.
+       * tree-cfgcleanup.c (cleanup_tree_cfg_bb): Do not merge block
+       with the successor if the predecessor will be merged with it.
+       * tree-cfg.c (gimple_can_merge_blocks_p): We can't merge the
+       entry block with its successor.
+
 2015-03-13  Richard Biener  <rguenther@suse.de>
 
        PR middle-end/44563
index ac12a58..0f5e428 100644 (file)
@@ -1703,7 +1703,8 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b)
   if (!single_pred_p (b))
     return false;
 
-  if (b == EXIT_BLOCK_PTR_FOR_FN (cfun))
+  if (a == ENTRY_BLOCK_PTR_FOR_FN (cfun)
+      || b == EXIT_BLOCK_PTR_FOR_FN (cfun))
     return false;
 
   /* If A ends by a statement causing exceptions or something similar, we
index f5a21a3..e7122e3 100644 (file)
@@ -650,8 +650,18 @@ cleanup_tree_cfg_bb (basic_block bb)
   if (single_succ_p (bb)
       && can_merge_blocks_p (bb, single_succ (bb)))
     {
-      merge_blocks (bb, single_succ (bb));
-      return true;
+      /* If there is a merge opportunity with the predecessor
+         do nothing now but wait until we process the predecessor.
+        This happens when we visit BBs in a non-optimal order and
+        avoids quadratic behavior with adjusting stmts BB pointer.  */
+      if (single_pred_p (bb)
+         && can_merge_blocks_p (single_pred (bb), bb))
+       ;
+      else
+       {
+         merge_blocks (bb, single_succ (bb));
+         return true;
+       }
     }
 
   return retval;
index 259a348..83e4335 100644 (file)
@@ -4779,18 +4779,19 @@ static bool
 gimple_expand_calls_inline (basic_block bb, copy_body_data *id)
 {
   gimple_stmt_iterator gsi;
+  bool inlined = false;
 
-  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+  for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
     {
       gimple stmt = gsi_stmt (gsi);
+      gsi_prev (&gsi);
 
       if (is_gimple_call (stmt)
-         && !gimple_call_internal_p (stmt)
-         && expand_call_inline (bb, stmt, id))
-       return true;
+         && !gimple_call_internal_p (stmt))
+       inlined |= expand_call_inline (bb, stmt, id);
     }
 
-  return false;
+  return inlined;
 }