aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-11-19 12:18:37 -0800
committerNathan Sidwell <nathan@acm.org>2020-11-19 12:21:31 -0800
commitbfc139e2b190187cb8478f8858cbce6ab9c5d4e7 (patch)
treeb7d9f708e52aa5409981b0af670c2aa0e1f605b0 /gcc
parent0862d007b564eca8c9a48fca0e689dd3f90db828 (diff)
downloadgcc-bfc139e2b190187cb8478f8858cbce6ab9c5d4e7.zip
gcc-bfc139e2b190187cb8478f8858cbce6ab9c5d4e7.tar.gz
gcc-bfc139e2b190187cb8478f8858cbce6ab9c5d4e7.tar.bz2
c++: Expose constexpr hash table
This patch exposes the constexpr hash table so that the modules machinery can save and load constexpr bodies. While there I noticed that we could do a little constification of the hasher and comparator functions. Also combine the saving machinery to a single function returning void -- nothing ever looked at its return value. gcc/cp/ * cp-tree.h (struct constexpr_fundef): Moved from constexpr.c. (maybe_save_constexpr_fundef): Declare. (register_constexpr_fundef): Take constexpr_fundef object, return void. * decl.c (mabe_save_function_definition): Delete, functionality moved to maybe_save_constexpr_fundef. (emit_coro_helper, finish_function): Adjust. * constexpr.c (struct constexpr_fundef): Moved to cp-tree.h. (constexpr_fundef_hasher::equal): Constify. (constexpr_fundef_hasher::hash): Constify. (retrieve_constexpr_fundef): Make non-static. (maybe_save_constexpr_fundef): Break out checking and duplication from ... (register_constexpr_fundef): ... here. Just register the constexpr.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/constexpr.c89
-rw-r--r--gcc/cp/cp-tree.h13
-rw-r--r--gcc/cp/decl.c18
3 files changed, 59 insertions, 61 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index e6ab5ee..6254103 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -133,19 +133,10 @@ ensure_literal_type_for_constexpr_object (tree decl)
return decl;
}
-/* Representation of entries in the constexpr function definition table. */
-
-struct GTY((for_user)) constexpr_fundef {
- tree decl;
- tree body;
- tree parms;
- tree result;
-};
-
struct constexpr_fundef_hasher : ggc_ptr_hash<constexpr_fundef>
{
- static hashval_t hash (constexpr_fundef *);
- static bool equal (constexpr_fundef *, constexpr_fundef *);
+ static hashval_t hash (const constexpr_fundef *);
+ static bool equal (const constexpr_fundef *, const constexpr_fundef *);
};
/* This table holds all constexpr function definitions seen in
@@ -158,7 +149,8 @@ static GTY (()) hash_table<constexpr_fundef_hasher> *constexpr_fundef_table;
same constexpr function. */
inline bool
-constexpr_fundef_hasher::equal (constexpr_fundef *lhs, constexpr_fundef *rhs)
+constexpr_fundef_hasher::equal (const constexpr_fundef *lhs,
+ const constexpr_fundef *rhs)
{
return lhs->decl == rhs->decl;
}
@@ -167,20 +159,20 @@ constexpr_fundef_hasher::equal (constexpr_fundef *lhs, constexpr_fundef *rhs)
Return a hash value for the entry pointed to by Q. */
inline hashval_t
-constexpr_fundef_hasher::hash (constexpr_fundef *fundef)
+constexpr_fundef_hasher::hash (const constexpr_fundef *fundef)
{
return DECL_UID (fundef->decl);
}
/* Return a previously saved definition of function FUN. */
-static constexpr_fundef *
+constexpr_fundef *
retrieve_constexpr_fundef (tree fun)
{
if (constexpr_fundef_table == NULL)
return NULL;
- constexpr_fundef fundef = { fun, NULL, NULL, NULL };
+ constexpr_fundef fundef = { fun, NULL_TREE, NULL_TREE, NULL_TREE };
return constexpr_fundef_table->find (&fundef);
}
@@ -669,7 +661,7 @@ get_function_named_in_call (tree t)
return fun;
}
-/* Subroutine of register_constexpr_fundef. BODY is the body of a function
+/* Subroutine of check_constexpr_fundef. BODY is the body of a function
declared to be constexpr, or a sub-statement thereof. Returns the
return value if suitable, error_mark_node for a statement not allowed in
a constexpr function, or NULL_TREE if no return value was found. */
@@ -738,7 +730,7 @@ constexpr_fn_retval (tree body)
}
}
-/* Subroutine of register_constexpr_fundef. BODY is the DECL_SAVED_TREE of
+/* Subroutine of check_constexpr_fundef. BODY is the DECL_SAVED_TREE of
FUN; do the necessary transformations to turn it into a single expression
that we can store in the hash table. */
@@ -868,27 +860,28 @@ cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
}
/* We are processing the definition of the constexpr function FUN.
- Check that its BODY fulfills the propriate requirements and
- enter it in the constexpr function definition table.
- For constructor BODY is actually the TREE_LIST of the
- member-initializer list. */
+ Check that its body fulfills the apropriate requirements and
+ enter it in the constexpr function definition table. */
-tree
-register_constexpr_fundef (tree fun, tree body)
+void
+maybe_save_constexpr_fundef (tree fun)
{
- constexpr_fundef entry;
- constexpr_fundef **slot;
+ if (processing_template_decl
+ || !DECL_DECLARED_CONSTEXPR_P (fun)
+ || cp_function_chain->invalid_constexpr
+ || DECL_CLONED_FUNCTION_P (fun))
+ return;
if (!is_valid_constexpr_fn (fun, !DECL_GENERATED_P (fun)))
- return NULL;
+ return;
- tree massaged = massage_constexpr_body (fun, body);
+ tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
if (massaged == NULL_TREE || massaged == error_mark_node)
{
if (!DECL_CONSTRUCTOR_P (fun))
error ("body of %<constexpr%> function %qD not a return-statement",
fun);
- return NULL;
+ return;
}
bool potential = potential_rvalue_constant_expression (massaged);
@@ -901,39 +894,47 @@ register_constexpr_fundef (tree fun, tree body)
potential = false;
if (!potential && !DECL_GENERATED_P (fun))
- return NULL;
-
- /* Create the constexpr function table if necessary. */
- if (constexpr_fundef_table == NULL)
- constexpr_fundef_table
- = hash_table<constexpr_fundef_hasher>::create_ggc (101);
+ return;
- entry.decl = fun;
- tree saved_fn = current_function_decl;
+ constexpr_fundef entry = {fun, NULL_TREE, NULL_TREE, NULL_TREE};
bool clear_ctx = false;
- current_function_decl = fun;
if (DECL_RESULT (fun) && DECL_CONTEXT (DECL_RESULT (fun)) == NULL_TREE)
{
clear_ctx = true;
DECL_CONTEXT (DECL_RESULT (fun)) = fun;
}
- entry.body = copy_fn (fun, entry.parms, entry.result);
+ tree saved_fn = current_function_decl;
+ current_function_decl = fun;
+ entry.body = copy_fn (entry.decl, entry.parms, entry.result);
current_function_decl = saved_fn;
- slot = constexpr_fundef_table->find_slot (&entry, INSERT);
if (clear_ctx)
- DECL_CONTEXT (DECL_RESULT (fun)) = NULL_TREE;
-
+ DECL_CONTEXT (DECL_RESULT (entry.decl)) = NULL_TREE;
if (!potential)
/* For a template instantiation, we want to remember the pre-generic body
for explain_invalid_constexpr_fn, but do tell cxx_eval_call_expression
that it doesn't need to bother trying to expand the function. */
entry.result = error_mark_node;
+ register_constexpr_fundef (entry);
+}
+
+/* BODY is a validated and massaged definition of a constexpr
+ function. Register it in the hash table. */
+
+void
+register_constexpr_fundef (const constexpr_fundef &value)
+{
+ /* Create the constexpr function table if necessary. */
+ if (constexpr_fundef_table == NULL)
+ constexpr_fundef_table
+ = hash_table<constexpr_fundef_hasher>::create_ggc (101);
+
+ constexpr_fundef **slot = constexpr_fundef_table->find_slot
+ (const_cast<constexpr_fundef *> (&value), INSERT);
+
gcc_assert (*slot == NULL);
*slot = ggc_alloc<constexpr_fundef> ();
- **slot = entry;
-
- return fun;
+ **slot = value;
}
/* FUN is a non-constexpr function called in a context that requires a
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 81485de..0c4b74a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7895,9 +7895,20 @@ extern void vtv_recover_class_info (void);
extern void vtv_build_vtable_verify_fndecl (void);
/* In constexpr.c */
+/* Representation of entries in the constexpr function definition table. */
+
+struct GTY((for_user)) constexpr_fundef {
+ tree decl;
+ tree body;
+ tree parms;
+ tree result;
+};
+
extern void fini_constexpr (void);
extern bool literal_type_p (tree);
-extern tree register_constexpr_fundef (tree, tree);
+extern void maybe_save_constexpr_fundef (tree);
+extern void register_constexpr_fundef (const constexpr_fundef &);
+extern constexpr_fundef *retrieve_constexpr_fundef (tree);
extern bool is_valid_constexpr_fn (tree, bool);
extern bool check_constexpr_ctor_body (tree, tree, bool);
extern tree constexpr_fn_retval (tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index f5c6f5c..1c6dcdb 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -16872,20 +16872,6 @@ record_key_method_defined (tree fndecl)
}
}
-/* Subroutine of finish_function.
- Save the body of constexpr functions for possible
- future compile time evaluation. */
-
-static void
-maybe_save_function_definition (tree fun)
-{
- if (!processing_template_decl
- && DECL_DECLARED_CONSTEXPR_P (fun)
- && !cp_function_chain->invalid_constexpr
- && !DECL_CLONED_FUNCTION_P (fun))
- register_constexpr_fundef (fun, DECL_SAVED_TREE (fun));
-}
-
/* Attempt to add a fix-it hint to RICHLOC suggesting the insertion
of "return *this;" immediately before its location, using FNDECL's
first statement (if any) to give the indentation, if appropriate. */
@@ -16919,7 +16905,7 @@ emit_coro_helper (tree helper)
allocate_struct_function (helper, false);
cfun->language = ggc_cleared_alloc<language_function> ();
poplevel (1, 0, 1);
- maybe_save_function_definition (helper);
+ maybe_save_constexpr_fundef (helper);
/* We must start each function with a clear fold cache. */
clear_fold_cache ();
cp_fold_function (helper);
@@ -17153,7 +17139,7 @@ finish_function (bool inline_p)
/* Save constexpr function body before it gets munged by
the NRV transformation. */
- maybe_save_function_definition (fndecl);
+ maybe_save_constexpr_fundef (fndecl);
/* Invoke the pre-genericize plugin before we start munging things. */
if (!processing_template_decl)