]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/42706 (ICE in gimple_op, at gimple.h:1634, (IPA SRA))
authorMartin Jambor <mjambor@suse.cz>
Thu, 14 Jan 2010 18:00:34 +0000 (19:00 +0100)
committerMartin Jambor <jamborm@gcc.gnu.org>
Thu, 14 Jan 2010 18:00:34 +0000 (19:00 +0100)
2010-01-14  Martin Jambor  <mjambor@suse.cz>

PR tree-optimization/42706
* tree-sra.c (encountered_recursive_call): New variable.
(encountered_unchangable_recursive_call): Likewise.
(sra_initialize): Initialize both new variables.
(callsite_has_enough_arguments_p): New function.
(scan_function): Call decl and flags check only for IPA-SRA, check
whether there is a recursive call and whether it has enough arguments.
(all_callers_have_enough_arguments_p): New function.
(convert_callers): Look for recursive calls only when
encountered_recursive_call is set.
(ipa_early_sra): Bail out either if
!all_callers_have_enough_arguments_p or
encountered_unchangable_recursive_call.

* testsuite/gcc.dg/ipa/pr42706.c: New testcase.

From-SVN: r155911

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/pr42706.c [new file with mode: 0644]
gcc/tree-sra.c

index 161756dc4a236d08949b4099c73b22092b110839..9c2e7ef4dc1140f7ff20898a7082a5ef1ccb33fe 100644 (file)
@@ -1,3 +1,19 @@
+2010-01-14  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/42706
+       * tree-sra.c (encountered_recursive_call): New variable.
+       (encountered_unchangable_recursive_call): Likewise.
+       (sra_initialize): Initialize both new variables.
+       (callsite_has_enough_arguments_p): New function.
+       (scan_function): Call decl and flags check only for IPA-SRA, check
+       whether there is a recursive call and whether it has enough arguments.
+       (all_callers_have_enough_arguments_p): New function.
+       (convert_callers): Look for recursive calls only when
+       encountered_recursive_call is set.
+       (ipa_early_sra): Bail out either if
+       !all_callers_have_enough_arguments_p or
+       encountered_unchangable_recursive_call.
+
 2010-01-14  Alexander Monakov  <amonakov@ispras.ru>
 
        * sel-sched.c: Add 2010 to copyright years.
index 69404084a1cecd660840750485a430d2f2254c8f..cfebc861535cb101e44d271d9a5c40a4d5985d6d 100644 (file)
@@ -1,3 +1,8 @@
+2010-01-14  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/42706
+       * gcc.dg/ipa/pr42706.c: New testcase.   
+
 2010-01-14  H.J. Lu  <hongjiu.lu@intel.com>
 
        * g++.dg/graphite/pr42681.C (size_t): Use __SIZE_TYPE__.
@@ -5,7 +10,7 @@
 2010-01-14  Martin Jambor  <mjambor@suse.cz>
 
        PR tree-optimization/42714
-       * gcc/testsuite/g++.dg/torture/pr42714.C: New test.
+       * g++.dg/torture/pr42714.C: New test.
 
 2010-01-14  Alexander Monakov  <amonakov@ispras.ru>
 
diff --git a/gcc/testsuite/gcc.dg/ipa/pr42706.c b/gcc/testsuite/gcc.dg/ipa/pr42706.c
new file mode 100644 (file)
index 0000000..9c5f43a
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-early-inlining -fipa-sra"  } */
+
+struct S
+{
+  float red;
+  int green;
+  void *blue;
+};
+
+extern int gi;
+static int foo ();
+
+int
+bar (void)
+{
+  foo ();
+  return 0;
+}
+
+static int
+foo (struct S s)
+{
+  gi = s.green;
+  return 0;
+}
+
index 47976679a11f3eae2a6674ac590c9aca519e5fe8..dd62cc53798653c9ccd8eee8d46aa48e7eb2eecd 100644 (file)
@@ -258,6 +258,13 @@ static int func_param_count;
    __builtin_apply_args.  */
 static bool encountered_apply_args;
 
+/* Set by scan_function when it finds a recursive call.  */
+static bool encountered_recursive_call;
+
+/* Set by scan_function when it finds a recursive call with less actual
+   arguments than formal parameters..  */
+static bool encountered_unchangable_recursive_call;
+
 /* This is a table in which for each basic block and parameter there is a
    distance (offset + size) in that parameter which is dereferenced and
    accessed in that BB.  */
@@ -545,6 +552,8 @@ sra_initialize (void)
   base_access_vec = pointer_map_create ();
   memset (&sra_stats, 0, sizeof (sra_stats));
   encountered_apply_args = false;
+  encountered_recursive_call = false;
+  encountered_unchangable_recursive_call = false;
 }
 
 /* Hook fed to pointer_map_traverse, deallocate stored vectors.  */
@@ -944,6 +953,14 @@ asm_visit_addr (gimple stmt ATTRIBUTE_UNUSED, tree op,
   return false;
 }
 
+/* Return true iff callsite CALL has at least as many actual arguments as there
+   are formal parameters of the function currently processed by IPA-SRA.  */
+
+static inline bool
+callsite_has_enough_arguments_p (gimple call)
+{
+  return gimple_call_num_args (call) >= (unsigned) func_param_count;
+}
 
 /* Scan function and look for interesting statements. Return true if any has
    been found or processed, as indicated by callbacks.  SCAN_EXPR is a callback
@@ -1014,15 +1031,24 @@ scan_function (bool (*scan_expr) (tree *, gimple_stmt_iterator *, bool, void *),
                  any |= scan_expr (argp, &gsi, false, data);
                }
 
-             if (analysis_stage)
+             if (analysis_stage && sra_mode == SRA_MODE_EARLY_IPA)
                {
                  tree dest = gimple_call_fndecl (stmt);
                  int flags = gimple_call_flags (stmt);
 
-                 if (dest
-                     && DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
-                     && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
-                   encountered_apply_args = true;
+                 if (dest)
+                   {
+                     if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
+                         && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
+                       encountered_apply_args = true;
+                     if (cgraph_get_node (dest)
+                         == cgraph_get_node (current_function_decl))
+                       {
+                         encountered_recursive_call = true;
+                         if (!callsite_has_enough_arguments_p (stmt))
+                           encountered_unchangable_recursive_call = true;
+                       }
+                   }
 
                  if (final_bbs
                      && (flags & (ECF_CONST | ECF_PURE)) == 0)
@@ -3780,6 +3806,21 @@ sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
     }
 }
 
+/* Return true iff all callers have at least as many actual arguments as there
+   are formal parameters in the current function.  */
+
+static bool
+all_callers_have_enough_arguments_p (struct cgraph_node *node)
+{
+  struct cgraph_edge *cs;
+  for (cs = node->callers; cs; cs = cs->next_caller)
+    if (!callsite_has_enough_arguments_p (cs->call_stmt))
+      return false;
+
+  return true;
+}
+
+
 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS.  */
 
 static void
@@ -3815,6 +3856,10 @@ convert_callers (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
   BITMAP_FREE (recomputed_callers);
 
   current_function_decl = old_cur_fndecl;
+
+  if (!encountered_recursive_call)
+    return;
+
   FOR_EACH_BB (this_block)
     {
       gimple_stmt_iterator gsi;
@@ -3927,6 +3972,14 @@ ipa_early_sra (void)
       goto simple_out;
     }
 
+  if (!all_callers_have_enough_arguments_p (node))
+    {
+      if (dump_file)
+       fprintf (dump_file, "There are callers with insufficient number of "
+                "arguments.\n");
+      goto simple_out;
+    }
+
   bb_dereferences = XCNEWVEC (HOST_WIDE_INT,
                                 func_param_count
                                 * last_basic_block_for_function (cfun));
@@ -3941,6 +3994,14 @@ ipa_early_sra (void)
       goto out;
     }
 
+  if (encountered_unchangable_recursive_call)
+    {
+      if (dump_file)
+       fprintf (dump_file, "Function calls itself with insufficient "
+                "number of arguments.\n");
+      goto out;
+    }
+
   adjustments = analyze_all_param_acesses ();
   if (!adjustments)
     goto out;