From 97f3003f6f7f1710245307d0dc989955ad59e957 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 15 Apr 2016 10:51:06 -0400 Subject: [PATCH] re PR c++/70594 (-fcompare-debug failure) PR c++/70594 * constexpr.c (constexpr_call_table): Preserve in GC. (struct fundef_copy, struct fundef_copies_table_t): Delete. (fundef_copies_table): Preserve in GC. Change to pointer to tree->tree hash. (maybe_initialize_fundef_copies_table): Adjust. (get_fundef_copy): Return a TREE_LIST. Use non-inserting search. (save_fundef_copy): Adjust for a TREE_LIST. (cxx_eval_call_expression): Adjust for a fundef_copy TREE_LIST. (fini_constexpr): New. * cp-tree.h (fini_constexpr): Declare. * decl2.c (c_parse_final_cleanups): Call fini_constexpr. Co-Authored-By: Nathan Sidwell From-SVN: r235033 --- gcc/ChangeLog | 16 +++++++++++++ gcc/cp/constexpr.c | 68 +++++++++++++++++++++++++----------------------------- gcc/cp/cp-tree.h | 1 + gcc/cp/decl2.c | 2 ++ 4 files changed, 51 insertions(+), 36 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 063a5ec..a73fa88 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2016-04-15 Jason Merrill + Nathan Sidwell + + PR c++/70594 + * constexpr.c (constexpr_call_table): Preserve in GC. + (struct fundef_copy, struct fundef_copies_table_t): Delete. + (fundef_copies_table): Preserve in GC. Change to pointer to + tree->tree hash. + (maybe_initialize_fundef_copies_table): Adjust. + (get_fundef_copy): Return a TREE_LIST. Use non-inserting search. + (save_fundef_copy): Adjust for a TREE_LIST. + (cxx_eval_call_expression): Adjust for a fundef_copy TREE_LIST. + (fini_constexpr): New. + * cp-tree.h (fini_constexpr): Declare. + * decl2.c (c_parse_final_cleanups): Call fini_constexpr. + 2016-04-15 Alexander Monakov * config/nvptx/nvptx.opt (moptimize): Add a period at end of help text. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 4abff20..d9b9a28 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -915,7 +915,7 @@ struct constexpr_ctx { /* A table of all constexpr calls that have been evaluated by the compiler in this translation unit. */ -static GTY ((deletable)) hash_table *constexpr_call_table; +static GTY (()) hash_table *constexpr_call_table; static tree cxx_eval_constant_expression (const constexpr_ctx *, tree, bool, bool *, bool *, tree * = NULL); @@ -965,17 +965,6 @@ maybe_initialize_constexpr_call_table (void) constexpr_call_table = hash_table::create_ggc (101); } -/* The representation of a single node in the per-function freelist maintained - by FUNDEF_COPIES_TABLE. */ - -struct fundef_copy -{ - tree body; - tree parms; - tree res; - fundef_copy *prev; -}; - /* During constexpr CALL_EXPR evaluation, to avoid issues with sharing when a function happens to get called recursively, we unshare the callee function's body and evaluate this unshared copy instead of evaluating the @@ -983,45 +972,42 @@ struct fundef_copy FUNDEF_COPIES_TABLE is a per-function freelist of these unshared function copies. The underlying data structure of FUNDEF_COPIES_TABLE is a hash_map - that's keyed off of the original FUNCTION_DECL and whose value is the chain - of this function's unused copies awaiting reuse. */ + that's keyed off of the original FUNCTION_DECL and whose value is a + TREE_LIST of this function's unused copies awaiting reuse. -struct fundef_copies_table_t -{ - hash_map *map; -}; + This is not GC-deletable to avoid GC affecting UID generation. */ -static GTY((deletable)) fundef_copies_table_t fundef_copies_table; +static GTY(()) hash_map *fundef_copies_table; /* Initialize FUNDEF_COPIES_TABLE if it's not initialized. */ static void maybe_initialize_fundef_copies_table () { - if (fundef_copies_table.map == NULL) - fundef_copies_table.map = hash_map::create_ggc (101); + if (fundef_copies_table == NULL) + fundef_copies_table = hash_map::create_ggc (101); } /* Reuse a copy or create a new unshared copy of the function FUN. Return this copy. */ -static fundef_copy * +static tree get_fundef_copy (tree fun) { maybe_initialize_fundef_copies_table (); - fundef_copy *copy; - fundef_copy **slot = &fundef_copies_table.map->get_or_insert (fun, NULL); - if (*slot == NULL) + tree copy; + tree *slot = fundef_copies_table->get (fun); + if (slot == NULL) { - copy = ggc_alloc (); - copy->body = copy_fn (fun, copy->parms, copy->res); - copy->prev = NULL; + copy = build_tree_list (NULL, NULL); + /* PURPOSE is body, VALUE is parms, TYPE is result. */ + TREE_PURPOSE (copy) = copy_fn (fun, TREE_VALUE (copy), TREE_TYPE (copy)); } else { copy = *slot; - *slot = (*slot)->prev; + *slot = TREE_CHAIN (copy); } return copy; @@ -1030,10 +1016,10 @@ get_fundef_copy (tree fun) /* Save the copy COPY of function FUN for later reuse by get_fundef_copy(). */ static void -save_fundef_copy (tree fun, fundef_copy *copy) +save_fundef_copy (tree fun, tree copy) { - fundef_copy **slot = &fundef_copies_table.map->get_or_insert (fun, NULL); - copy->prev = *slot; + tree *slot = &fundef_copies_table->get_or_insert (fun, NULL); + TREE_CHAIN (copy) = *slot; *slot = copy; } @@ -1464,10 +1450,10 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, tree body, parms, res; /* Reuse or create a new unshared copy of this function's body. */ - fundef_copy *copy = get_fundef_copy (fun); - body = copy->body; - parms = copy->parms; - res = copy->res; + tree copy = get_fundef_copy (fun); + body = TREE_PURPOSE (copy); + parms = TREE_VALUE (copy); + res = TREE_TYPE (copy); /* Associate the bindings with the remapped parms. */ tree bound = new_call.bindings; @@ -5223,4 +5209,14 @@ potential_nondependent_static_init_expression (tree t) && !instantiation_dependent_expression_p (t)); } +/* Finalize constexpr processing after parsing. */ + +void +fini_constexpr (void) +{ + /* The contexpr call and fundef copies tables are no longer needed. */ + constexpr_call_table = NULL; + fundef_copies_table = NULL; +} + #include "gt-cp-constexpr.h" diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a3cd834..0df8470 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6880,6 +6880,7 @@ bool cilkplus_an_triplet_types_ok_p (location_t, tree, tree, tree, tree); /* In constexpr.c */ +extern void fini_constexpr (void); extern bool literal_type_p (tree); extern tree register_constexpr_fundef (tree, tree); extern bool check_constexpr_ctor_body (tree, tree, bool); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index b3cc99a..0ea326d 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4904,6 +4904,8 @@ c_parse_final_cleanups (void) finish_repo (); + fini_constexpr (); + /* The entire file is now complete. If requested, dump everything to a file. */ dump_tu (); -- 2.7.4