From baff22c48bdee9cb644b7336bf6f20f799531507 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 27 May 2020 10:25:56 +0200 Subject: [PATCH] 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 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. --- gcc/omp-general.c | 33 +++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/gomp/pr95315.c | 5 +++++ 2 files changed, 38 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/gomp/pr95315.c 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::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" -- 2.7.4