]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/56524 (Compiler ICE when compiling with -mips16)
authorRichard Sandiford <rdsandiford@googlemail.com>
Sat, 9 Mar 2013 07:54:02 +0000 (07:54 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sat, 9 Mar 2013 07:54:02 +0000 (07:54 +0000)
gcc/
PR middle-end/56524
* tree.h (tree_optimization_option): Rename target_optabs to optabs.
Add base_optabs.
(TREE_OPTIMIZATION_OPTABS): Update after previous field change.
(TREE_OPTIMIZATION_BASE_OPTABS): New macro.
(save_optabs_if_changed): Replace with...
(init_tree_optimization_optabs): ...this.
* optabs.c (save_optabs_if_changed): Rename to...
(init_tree_optimization_optabs): ...this.  Take the optimization node
as argument.  Do nothing if the base optabs are already correct.
Reuse the existing TREE_OPTIMIZATION_OPTABS memory if we need
to recompute optabs.
* function.h (function): Remove optabs field.
* function.c (invoke_set_current_function_hook): Call
init_tree_optimization_optabs.  Use the result to initialize
this_fn_optabs.

gcc/c-family/
PR middle-end/56524
* c-common.c (handle_optimize_attribute): Don't call
save_optabs_if_changed.

gcc/testsuite/
PR middle-end/56524
* gcc.target/mips/pr56524.c: New test.

From-SVN: r196570

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/function.c
gcc/function.h
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/pr56524.c [new file with mode: 0644]
gcc/tree.h

index 7a4de2537e7bf7f7596d0352ccdcf870621c0dc7..3ae6c4c84b59eb14855b5e9d7280748cfd0cde52 100644 (file)
@@ -1,3 +1,22 @@
+2013-03-09  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       PR middle-end/56524
+       * tree.h (tree_optimization_option): Rename target_optabs to optabs.
+       Add base_optabs.
+       (TREE_OPTIMIZATION_OPTABS): Update after previous field change.
+       (TREE_OPTIMIZATION_BASE_OPTABS): New macro.
+       (save_optabs_if_changed): Replace with...
+       (init_tree_optimization_optabs): ...this.
+       * optabs.c (save_optabs_if_changed): Rename to...
+       (init_tree_optimization_optabs): ...this.  Take the optimization node
+       as argument.  Do nothing if the base optabs are already correct.
+       Reuse the existing TREE_OPTIMIZATION_OPTABS memory if we need
+       to recompute optabs.
+       * function.h (function): Remove optabs field.
+       * function.c (invoke_set_current_function_hook): Call
+       init_tree_optimization_optabs.  Use the result to initialize
+       this_fn_optabs.
+
 2013-02-27  Aldy Hernandez  <aldyh@redhat.com>
 
        * trans-mem.c (expand_transaction): Do not set PR_INSTRUMENTEDCODE
index 6d90bfb37d27ac475ae1627604372bb7afef3873..dd6cb296a4446ad7f301362a6f4e00e7fd9c59c8 100644 (file)
@@ -1,3 +1,9 @@
+2013-03-09  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       PR middle-end/56524
+       * c-common.c (handle_optimize_attribute): Don't call
+       save_optabs_if_changed.
+
 2013-03-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR middle-end/56461
index d01de3e40d5f53e986874db748553f2d3daa153d..c7cdd0fc7a0bbe44d259429261df602f294ccf03 100644 (file)
@@ -8947,8 +8947,6 @@ handle_optimize_attribute (tree *node, tree name, tree args,
       DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
        = build_optimization_node ();
 
-      save_optabs_if_changed (*node);
-
       /* Restore current options.  */
       cl_optimization_restore (&global_options, &cur_opts);
     }
index 1b41cf2cb34cc0dee3478873bf8298b8ca1e320c..e673f21a57d892851f0333e2f74661c82c498ca3 100644 (file)
@@ -4400,25 +4400,14 @@ invoke_set_current_function_hook (tree fndecl)
        }
 
       targetm.set_current_function (fndecl);
+      this_fn_optabs = this_target_optabs;
 
-      if (opts == optimization_default_node)
-       this_fn_optabs = this_target_optabs;
-      else
+      if (opts != optimization_default_node)
        {
-         struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
-         if (fn->optabs == NULL)
-           {
-             if (this_target_optabs == &default_target_optabs)
-               fn->optabs = TREE_OPTIMIZATION_OPTABS (opts);
-             else
-               {
-                 fn->optabs = (unsigned char *)
-                   ggc_alloc_atomic (sizeof (struct target_optabs));
-                 init_all_optabs ((struct target_optabs *) fn->optabs);
-               }
-           }
-         this_fn_optabs = fn->optabs ? (struct target_optabs *) fn->optabs
-                                     : this_target_optabs;
+         init_tree_optimization_optabs (opts);
+         if (TREE_OPTIMIZATION_OPTABS (opts))
+           this_fn_optabs = (struct target_optabs *)
+             TREE_OPTIMIZATION_OPTABS (opts);
        }
     }
 }
index 53e28b768c0b061cbbcdcc779eaa070730deb4cf..89d71e592dd227e52422dc4249037fac54e6d346 100644 (file)
@@ -580,9 +580,6 @@ struct GTY(()) function {
      a string describing the reason for failure.  */
   const char * GTY((skip)) cannot_be_copied_reason;
 
-  /* Optabs for this function.  This is of type `struct target_optabs *'.  */
-  unsigned char *GTY ((atomic)) optabs;
-
   /* Collected bit flags.  */
 
   /* Number of units of general registers that need saving in stdarg
index c5778d1928bfc98048504c79a6a6ec239b0c02d5..a3051ad9d9ae66e3a7d4b19d1a12d4d6e0272322 100644 (file)
@@ -6208,31 +6208,32 @@ init_optabs (void)
   targetm.init_libfuncs ();
 }
 
-/* Recompute the optabs and save them if they have changed.  */
+/* Use the current target and options to initialize
+   TREE_OPTIMIZATION_OPTABS (OPTNODE).  */
 
 void
-save_optabs_if_changed (tree fndecl)
+init_tree_optimization_optabs (tree optnode)
 {
-  /* ?? If this fails, we should temporarily restore the default
-     target first (set_cfun (NULL) ??), do the rest of this function,
-     and then restore it.  */
-  gcc_assert (this_target_optabs == &default_target_optabs);
+  /* Quick exit if we have already computed optabs for this target.  */
+  if (TREE_OPTIMIZATION_BASE_OPTABS (optnode) == this_target_optabs)
+    return;
 
+  /* Forget any previous information and set up for the current target.  */
+  TREE_OPTIMIZATION_BASE_OPTABS (optnode) = this_target_optabs;
   struct target_optabs *tmp_optabs = (struct target_optabs *)
-    ggc_alloc_atomic (sizeof (struct target_optabs));
-  tree optnode = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
+    TREE_OPTIMIZATION_OPTABS (optnode);
+  if (tmp_optabs)
+    memset (tmp_optabs, 0, sizeof (struct target_optabs));
+  else
+    tmp_optabs = (struct target_optabs *)
+      ggc_alloc_atomic (sizeof (struct target_optabs));
 
   /* Generate a new set of optabs into tmp_optabs.  */
   init_all_optabs (tmp_optabs);
 
   /* If the optabs changed, record it.  */
   if (memcmp (tmp_optabs, this_target_optabs, sizeof (struct target_optabs)))
-    {
-      if (TREE_OPTIMIZATION_OPTABS (optnode))
-       ggc_free (TREE_OPTIMIZATION_OPTABS (optnode));
-
-      TREE_OPTIMIZATION_OPTABS (optnode) = (unsigned char *) tmp_optabs;
-    }
+    TREE_OPTIMIZATION_OPTABS (optnode) = (unsigned char *) tmp_optabs;
   else
     {
       TREE_OPTIMIZATION_OPTABS (optnode) = NULL;
index b1043301fa3291be25f6dacaf8e59d1b1f6ba9e9..15156f7ae8c61dc8f3980d7aeb83576e4ef6f6ed 100644 (file)
@@ -1,3 +1,8 @@
+2013-03-09  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       PR middle-end/56524
+       * gcc.target/mips/pr56524.c: New test.
+
 2013-03-08  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/56565
diff --git a/gcc/testsuite/gcc.target/mips/pr56524.c b/gcc/testsuite/gcc.target/mips/pr56524.c
new file mode 100644 (file)
index 0000000..7df021b
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-options "-mips16" } */
+
+void bar (void) {}
+
+void __attribute__((optimize("schedule-insns")))
+foo (void)
+{
+}
index 740d43827127172d9599120eab680001494ca8c2..b852f1d9434a1c843fcc64f3a1c1192aa4586623 100644 (file)
@@ -3589,21 +3589,26 @@ struct GTY(()) tree_optimization_option {
 
   /* Target optabs for this set of optimization options.  This is of
      type `struct target_optabs *'.  */
-  unsigned char *GTY ((atomic)) target_optabs;
+  unsigned char *GTY ((atomic)) optabs;
+
+  /* The value of this_target_optabs against which the optabs above were
+     generated.  */
+  struct target_optabs *GTY ((skip)) base_optabs;
 };
 
 #define TREE_OPTIMIZATION(NODE) \
   (&OPTIMIZATION_NODE_CHECK (NODE)->optimization.opts)
 
 #define TREE_OPTIMIZATION_OPTABS(NODE) \
-  (OPTIMIZATION_NODE_CHECK (NODE)->optimization.target_optabs)
+  (OPTIMIZATION_NODE_CHECK (NODE)->optimization.optabs)
+
+#define TREE_OPTIMIZATION_BASE_OPTABS(NODE) \
+  (OPTIMIZATION_NODE_CHECK (NODE)->optimization.base_optabs)
 
 /* Return a tree node that encapsulates the current optimization options.  */
 extern tree build_optimization_node (void);
 
-/* Save a new set of target_optabs in a TREE_OPTIMIZATION node if the
-   current set of optabs has changed.  */
-extern void save_optabs_if_changed (tree);
+extern void init_tree_optimization_optabs (tree);
 
 /* Target options used by a function.  */