]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-nested.c (convert_all_function_calls): Iterate until after the sum of static...
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 31 Aug 2010 21:05:22 +0000 (21:05 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 31 Aug 2010 21:05:22 +0000 (21:05 +0000)
* tree-nested.c (convert_all_function_calls): Iterate until after the
sum of static chains in the nest doesn't change.

From-SVN: r163698

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/nested-func-8.c [new file with mode: 0644]
gcc/tree-nested.c

index 865232c22c488dad352846377aa61d3d5c07f71d..3d10080611a32dea5429d202380337852d163853 100644 (file)
@@ -1,3 +1,8 @@
+2010-08-31  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * tree-nested.c (convert_all_function_calls): Iterate until after the
+       sum of static chains in the nest doesn't change.
+
 2010-08-31  Anatoly Sokolov  <aesok@post.ru>
 
        * config/m32c/m32c.c (classes_intersect): Remove.
index a42dfe0559e6560d6fed3688c97fc9c4a2f09a7c..3f9a2eee032fda989bcfad957570f8792476165d 100644 (file)
@@ -1,3 +1,7 @@
+2010-08-31  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.dg/nested-func-8.c: New test.
+
 2010-08-31  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
        PR fortran/38282
diff --git a/gcc/testsuite/gcc.dg/nested-func-8.c b/gcc/testsuite/gcc.dg/nested-func-8.c
new file mode 100644 (file)
index 0000000..ccec27d
--- /dev/null
@@ -0,0 +1,57 @@
+/* { dg-do run } */
+/* { dg-options "-O -fno-inline" } */
+
+extern void abort (void);
+
+/* Return 0 and clobber the static chain.  */
+
+int
+zero (int n)
+{
+  int
+  nested (int m)
+  {
+    return m - n;
+  }
+
+  return nested (n);
+}
+
+/* Return the triple of ARG in a convoluted manner.  */
+
+int
+triple (int arg)
+{
+  int
+  read_arg (void)
+  {
+    return arg;
+  }
+
+  int
+  parent (int nested_arg)
+  {
+    int
+    child1 (void)
+    {
+      return parent (zero (5));
+    }
+
+    int
+    child2 (void)
+    {
+      return nested_arg + read_arg ();
+    }
+
+    return (nested_arg == 0 ? 0 : child1 ()) + child2 ();
+  }
+
+  return parent (arg);
+}
+
+int main(void)
+{
+  if (triple (13) != 3 * 13)
+    abort ();
+  return 0;
+}
index 81ae38f6f3aca38ab85bb0cb3a8bdb0aa9d9808f..b811ec500dff75d70168be12ecaccf185d758ace 100644 (file)
@@ -2070,9 +2070,8 @@ convert_gimple_call (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 static void
 convert_all_function_calls (struct nesting_info *root)
 {
+  unsigned int chain_count = 0, old_chain_count, iter_count;
   struct nesting_info *n;
-  int iter_count;
-  bool any_changed;
 
   /* First, optimistically clear static_chain for all decls that haven't
      used the static chain already for variable access.  */
@@ -2088,6 +2087,7 @@ convert_all_function_calls (struct nesting_info *root)
        }
       else
        DECL_STATIC_CHAIN (decl) = 1;
+      chain_count += DECL_STATIC_CHAIN (decl);
     }
 
   /* Walk the functions and perform transformations.  Note that these
@@ -2100,7 +2100,8 @@ convert_all_function_calls (struct nesting_info *root)
   iter_count = 0;
   do
     {
-      any_changed = false;
+      old_chain_count = chain_count;
+      chain_count = 0;
       iter_count++;
 
       if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2109,22 +2110,16 @@ convert_all_function_calls (struct nesting_info *root)
       FOR_EACH_NEST_INFO (n, root)
        {
          tree decl = n->context;
-         bool old_static_chain = DECL_STATIC_CHAIN (decl);
-
          walk_function (convert_tramp_reference_stmt,
                         convert_tramp_reference_op, n);
          walk_function (convert_gimple_call, NULL, n);
-
-         /* If a call to another function created the use of a chain
-            within this function, we'll have to continue iteration.  */
-         if (!old_static_chain && DECL_STATIC_CHAIN (decl))
-           any_changed = true;
+         chain_count += DECL_STATIC_CHAIN (decl);
        }
     }
-  while (any_changed);
+  while (chain_count != old_chain_count);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
-    fprintf (dump_file, "convert_all_function_calls iterations: %d\n\n",
+    fprintf (dump_file, "convert_all_function_calls iterations: %u\n\n",
             iter_count);
 }