aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-05-27 10:25:56 +0200
committerJakub Jelinek <jakub@redhat.com>2020-05-27 10:25:56 +0200
commitbaff22c48bdee9cb644b7336bf6f20f799531507 (patch)
tree4f364b848f4423d8b072c1c08da38a0c0ef1e43b
parent79ea774f9a9d36d986152d93f9eae4a9ba36b37b (diff)
downloadgcc-baff22c48bdee9cb644b7336bf6f20f799531507.zip
gcc-baff22c48bdee9cb644b7336bf6f20f799531507.tar.gz
gcc-baff22c48bdee9cb644b7336bf6f20f799531507.tar.bz2
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.
-rw-r--r--gcc/omp-general.c33
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr95315.c5
2 files changed, 38 insertions, 0 deletions
diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index 1a2e71e..ed27644 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 0000000..4981e0b
--- /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"