[gcc(refs/users/guojiufu/heads/personal-branch)] openmp: Fix up omp_declare_variant{s, _alt} htab handling

Jiu Fu Guo guojiufu@gcc.gnu.org
Wed Jun 10 03:12:26 GMT 2020


https://gcc.gnu.org/g:baff22c48bdee9cb644b7336bf6f20f799531507

commit baff22c48bdee9cb644b7336bf6f20f799531507
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed May 27 10:25:56 2020 +0200

    openmp: Fix up omp_declare_variant{s,_alt} htab handling
    
    This patch fixes a GC ICE.  During debugging, I've found that during
    gimplification we can actually call omp_resolve_declare_variant multiple
    times and it would create a new magic declare_variant_alt FUNCTION_DECL
    each time, which is undesirable, once we have such a decl, we should just
    use that.  The other problem is that there was no cgraph node removal hook.
    As the omp_declare_variants htab is used just early during gimplification,
    we can just clear the whole htab, rather than trying to lookup and remove
    a particular entry.  The other hash table is used later as well and that
    one uses just DECL_UID as hash, so in that case the patch removes the elt.
    
    2020-05-27  Jakub Jelinek  <jakub@redhat.com>
    
            PR middle-end/95315
            * omp-general.c (omp_declare_variant_remove_hook): New function.
            (omp_resolve_declare_variant): Always return base if it is already
            declare_variant_alt magic decl itself.  Register
            omp_declare_variant_remove_hook as cgraph node removal hook.
    
            * gcc.dg/gomp/pr95315.c: New test.

Diff:
---
 gcc/omp-general.c                   | 33 +++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/gomp/pr95315.c |  5 +++++
 2 files changed, 38 insertions(+)

diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index 1a2e71ecf8c..ed2764416e4 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -1695,6 +1695,28 @@ omp_resolve_late_declare_variant (tree alt)
   return varentry2->variant->decl;
 }
 
+/* Hook to adjust hash tables on cgraph_node removal.  */
+
+static void
+omp_declare_variant_remove_hook (struct cgraph_node *node, void *)
+{
+  if (!node->declare_variant_alt)
+    return;
+
+  /* Drop this hash table completely.  */
+  omp_declare_variants = NULL;
+  /* And remove node from the other hash table.  */
+  if (omp_declare_variant_alt)
+    {
+      omp_declare_variant_base_entry entry;
+      entry.base = NULL;
+      entry.node = node;
+      entry.variants = NULL;
+      omp_declare_variant_alt->remove_elt_with_hash (&entry,
+						     DECL_UID (node->decl));
+    }
+}
+
 /* Try to resolve declare variant, return the variant decl if it should
    be used instead of base, or base otherwise.  */
 
@@ -1715,6 +1737,11 @@ omp_resolve_declare_variant (tree base)
 	break;
       if (TREE_CODE (TREE_PURPOSE (TREE_VALUE (attr))) != FUNCTION_DECL)
 	continue;
+      cgraph_node *node = cgraph_node::get (base);
+      /* If this is already a magic decl created by this function,
+	 don't process it again.  */
+      if (node && node->declare_variant_alt)
+	return base;
       switch (omp_context_selector_matches (TREE_VALUE (TREE_VALUE (attr))))
 	{
 	case 0:
@@ -1823,6 +1850,12 @@ omp_resolve_declare_variant (tree base)
 	    }
 	}
 
+      static struct cgraph_node_hook_list *node_removal_hook_holder;
+      if (node_removal_hook_holder)
+	node_removal_hook_holder
+	  = symtab->add_cgraph_removal_hook (omp_declare_variant_remove_hook,
+					     NULL);
+
       if (omp_declare_variants == NULL)
 	omp_declare_variants
 	  = hash_table<omp_declare_variant_hasher>::create_ggc (64);
diff --git a/gcc/testsuite/gcc.dg/gomp/pr95315.c b/gcc/testsuite/gcc.dg/gomp/pr95315.c
new file mode 100644
index 00000000000..4981e0b8949
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr95315.c
@@ -0,0 +1,5 @@
+/* PR middle-end/95315 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp --param ggc-min-heapsize=0" } */
+
+#include "../../c-c++-common/gomp/declare-variant-5.c"


More information about the Gcc-cvs mailing list