This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Minimize IDENTIFIER_GLOBAL_VALUE recomputations
- From: Gabriel Dos Reis <gdr at integrable-solutions dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: 27 Sep 2003 18:49:53 +0200
- Subject: C++ PATCH: Minimize IDENTIFIER_GLOBAL_VALUE recomputations
- Organization: Integrable Solutions
This patchlet minimizes recomputations of IDENTIFIER_GLOBAL_VALUE.
Despite its macro looking, it is NOT a simple member access; rather it
is a call to namespace_binding(). Its uses are in recuring patterns
like
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
or
if (IDENTIFIER_GLOBAL_VALUE (name)
&& TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
This patch wraps such patterns into two small inline functions that
compute IDENTIFIER_GLOBAL_VALUE only once.
Bootstrapped and regtested on i686-pc-linux-gnu.
Installed as obvious.
-- Gaby
2003-09-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
Minimise recomputations of IDENTIFIER_GLOBAL_VALUE.
* name-lookup.h (get_global_value_if_present): New function.
(is_typename_at_global_scope): Likewise.
* except.c (do_begin_catch): Use get_global_value_if_present.
(do_end_catch): Likewise.
(do_allocate_exception): Likewise.
(do_free_exception): Likewise.
(build_throw): Likewise.
* parser.c (cp_parser_member_declaration): Likewise.
* rtti.c (throw_bad_cast): Likewise.
(throw_bad_typeid): Likewise.
* decl.c (check_tag_decl): Use is_typename_at_global_scope.
(grokdeclarator): Likewise.
* cp-tree.h (global_namespace): Move to name-lookup.h
* call.c (call_builtin_trap): Tidy.
Index: call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.436
diff -p -r1.436 call.c
*** call.c 21 Sep 2003 05:07:16 -0000 1.436
--- call.c 27 Sep 2003 16:27:16 -0000
*************** convert_like_real (tree convs, tree expr
*** 4192,4203 ****
static tree
call_builtin_trap (void)
{
! tree fn = get_identifier ("__builtin_trap");
! if (IDENTIFIER_GLOBAL_VALUE (fn))
! fn = IDENTIFIER_GLOBAL_VALUE (fn);
! else
! abort ();
fn = build_call (fn, NULL_TREE);
fn = build (COMPOUND_EXPR, integer_type_node, fn, integer_zero_node);
return fn;
--- 4192,4200 ----
static tree
call_builtin_trap (void)
{
! tree fn = IDENTIFIER_GLOBAL_VALUE (get_identifier ("__builtin_trap"));
+ my_friendly_assert (fn != NULL, 20030927);
fn = build_call (fn, NULL_TREE);
fn = build (COMPOUND_EXPR, integer_type_node, fn, integer_zero_node);
return fn;
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.922
diff -p -r1.922 cp-tree.h
*** cp-tree.h 27 Sep 2003 01:55:07 -0000 1.922
--- cp-tree.h 27 Sep 2003 16:27:18 -0000
*************** struct language_function GTY(())
*** 870,877 ****
#define current_function_return_value \
(cp_function_chain->x_return_value)
- extern GTY(()) tree global_namespace;
-
#define ansi_opname(CODE) \
(operator_name_info[(int) (CODE)].identifier)
#define ansi_assopname(CODE) \
--- 870,875 ----
Index: decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1134
diff -p -r1.1134 decl.c
*** decl.c 27 Sep 2003 01:55:08 -0000 1.1134
--- decl.c 27 Sep 2003 16:27:26 -0000
*************** check_tag_decl (tree declspecs)
*** 6589,6599 ****
{
tree value = TREE_VALUE (link);
! if (TYPE_P (value)
! || TREE_CODE (value) == TYPE_DECL
|| (TREE_CODE (value) == IDENTIFIER_NODE
! && IDENTIFIER_GLOBAL_VALUE (value)
! && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (value)) == TYPE_DECL))
{
++found_type;
--- 6589,6597 ----
{
tree value = TREE_VALUE (link);
! if (TYPE_P (value) || TREE_CODE (value) == TYPE_DECL
|| (TREE_CODE (value) == IDENTIFIER_NODE
! && is_typename_at_global_scope (value)))
{
++found_type;
*************** grokdeclarator (tree declarator,
*** 9674,9682 ****
flags = TYPENAME_FLAG;
ctor_return_type = TREE_TYPE (dname);
sfk = sfk_conversion;
! if (IDENTIFIER_GLOBAL_VALUE (dname)
! && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (dname))
! == TYPE_DECL))
name = IDENTIFIER_POINTER (dname);
else
name = "<invalid operator>";
--- 9672,9678 ----
flags = TYPENAME_FLAG;
ctor_return_type = TREE_TYPE (dname);
sfk = sfk_conversion;
! if (is_typename_at_global_scope (dname))
name = IDENTIFIER_POINTER (dname);
else
name = "<invalid operator>";
*************** grokdeclarator (tree declarator,
*** 10309,10317 ****
op = IDENTIFIER_OPNAME_P (tmp);
if (IDENTIFIER_TYPENAME_P (tmp))
{
! if (IDENTIFIER_GLOBAL_VALUE (tmp)
! && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (tmp))
! == TYPE_DECL))
name = IDENTIFIER_POINTER (tmp);
else
name = "<invalid operator>";
--- 10305,10311 ----
op = IDENTIFIER_OPNAME_P (tmp);
if (IDENTIFIER_TYPENAME_P (tmp))
{
! if (is_typename_at_global_scope (tmp))
name = IDENTIFIER_POINTER (tmp);
else
name = "<invalid operator>";
Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/except.c,v
retrieving revision 1.158
diff -p -r1.158 except.c
*** except.c 15 Aug 2003 11:14:01 -0000 1.158
--- except.c 27 Sep 2003 16:27:26 -0000
*************** do_begin_catch (void)
*** 161,169 ****
tree fn;
fn = get_identifier ("__cxa_begin_catch");
! if (IDENTIFIER_GLOBAL_VALUE (fn))
! fn = IDENTIFIER_GLOBAL_VALUE (fn);
! else
{
/* Declare void* __cxa_begin_catch (void *). */
tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
--- 161,167 ----
tree fn;
fn = get_identifier ("__cxa_begin_catch");
! if (!get_global_value_if_present (fn, &fn))
{
/* Declare void* __cxa_begin_catch (void *). */
tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
*************** do_end_catch (tree type)
*** 198,206 ****
tree fn, cleanup;
fn = get_identifier ("__cxa_end_catch");
! if (IDENTIFIER_GLOBAL_VALUE (fn))
! fn = IDENTIFIER_GLOBAL_VALUE (fn);
! else
{
/* Declare void __cxa_end_catch (). */
fn = push_void_library_fn (fn, void_list_node);
--- 196,202 ----
tree fn, cleanup;
fn = get_identifier ("__cxa_end_catch");
! if (!get_global_value_if_present (fn, &fn))
{
/* Declare void __cxa_end_catch (). */
fn = push_void_library_fn (fn, void_list_node);
*************** do_allocate_exception (tree type)
*** 498,506 ****
tree fn;
fn = get_identifier ("__cxa_allocate_exception");
! if (IDENTIFIER_GLOBAL_VALUE (fn))
! fn = IDENTIFIER_GLOBAL_VALUE (fn);
! else
{
/* Declare void *__cxa_allocate_exception(size_t). */
tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
--- 494,500 ----
tree fn;
fn = get_identifier ("__cxa_allocate_exception");
! if (!get_global_value_if_present (fn, &fn))
{
/* Declare void *__cxa_allocate_exception(size_t). */
tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
*************** do_free_exception (tree ptr)
*** 521,529 ****
tree fn;
fn = get_identifier ("__cxa_free_exception");
! if (IDENTIFIER_GLOBAL_VALUE (fn))
! fn = IDENTIFIER_GLOBAL_VALUE (fn);
! else
{
/* Declare void __cxa_free_exception (void *). */
fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
--- 515,521 ----
tree fn;
fn = get_identifier ("__cxa_free_exception");
! if (!get_global_value_if_present (fn, &fn))
{
/* Declare void __cxa_free_exception (void *). */
fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
*************** build_throw (tree exp)
*** 644,652 ****
if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
{
tree fn = get_identifier ("_Jv_Throw");
! if (IDENTIFIER_GLOBAL_VALUE (fn))
! fn = IDENTIFIER_GLOBAL_VALUE (fn);
! else
{
/* Declare void _Jv_Throw (void *). */
tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
--- 636,642 ----
if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
{
tree fn = get_identifier ("_Jv_Throw");
! if (!get_global_value_if_present (fn, &fn))
{
/* Declare void _Jv_Throw (void *). */
tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
*************** build_throw (tree exp)
*** 665,673 ****
tree temp_expr, allocate_expr;
fn = get_identifier ("__cxa_throw");
! if (IDENTIFIER_GLOBAL_VALUE (fn))
! fn = IDENTIFIER_GLOBAL_VALUE (fn);
! else
{
/* The CLEANUP_TYPE is the internal type of a destructor. */
if (cleanup_type == NULL_TREE)
--- 655,661 ----
tree temp_expr, allocate_expr;
fn = get_identifier ("__cxa_throw");
! if (!get_global_value_if_present (fn, &fn))
{
/* The CLEANUP_TYPE is the internal type of a destructor. */
if (cleanup_type == NULL_TREE)
*************** build_throw (tree exp)
*** 772,780 ****
/* Rethrow current exception. */
tree fn = get_identifier ("__cxa_rethrow");
! if (IDENTIFIER_GLOBAL_VALUE (fn))
! fn = IDENTIFIER_GLOBAL_VALUE (fn);
! else
{
/* Declare void __cxa_rethrow (void). */
fn = push_throw_library_fn
--- 760,766 ----
/* Rethrow current exception. */
tree fn = get_identifier ("__cxa_rethrow");
! if (!get_global_value_if_present (fn, &fn))
{
/* Declare void __cxa_rethrow (void). */
fn = push_throw_library_fn
Index: name-lookup.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.h,v
retrieving revision 1.6
diff -p -r1.6 name-lookup.h
*** name-lookup.h 27 Sep 2003 01:55:13 -0000 1.6
--- name-lookup.h 27 Sep 2003 16:27:26 -0000
*************** extern cxx_binding *cxx_binding_make (tr
*** 97,102 ****
--- 97,105 ----
extern void cxx_binding_free (cxx_binding *);
extern bool supplement_binding (cxx_binding *, tree);
+ /* The tree node representing the global scope. */
+ extern GTY(()) tree global_namespace;
+
/* True if SCOPE designates the global scope binding contour. */
#define global_scope_p(SCOPE) \
((SCOPE) == NAMESPACE_LEVEL (global_namespace))
*************** extern cxx_binding *binding_for_name (cx
*** 106,110 ****
--- 109,137 ----
extern tree namespace_binding (tree, tree);
extern void set_namespace_binding (tree, tree, tree);
+
+
+ /* Set *DECL to the (non-hidden) declaration for ID at global scope,
+ if present and return true; otherwise return false. */
+
+ static inline bool
+ get_global_value_if_present (tree id, tree *decl)
+ {
+ tree global_value = namespace_binding (id, global_namespace);
+
+ if (global_value)
+ *decl = global_value;
+ return global_value != NULL;
+ }
+
+ /* True is the binding of IDENTIFIER at global scope names a type. */
+
+ static inline bool
+ is_typename_at_global_scope (tree id)
+ {
+ tree global_value = namespace_binding (id, global_namespace);
+
+ return global_value && TREE_CODE (global_value) == TYPE_DECL;
+ }
#endif /* GCC_CP_NAME_LOOKUP_H */
Index: parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.112
diff -p -r1.112 parser.c
*** parser.c 25 Sep 2003 12:51:35 -0000 1.112
--- parser.c 27 Sep 2003 16:27:32 -0000
*************** cp_parser_member_declaration (cp_parser*
*** 11836,11844 ****
{
tree s = TREE_VALUE (specifier);
! if (TREE_CODE (s) == IDENTIFIER_NODE
! && IDENTIFIER_GLOBAL_VALUE (s))
! type = IDENTIFIER_GLOBAL_VALUE (s);
if (TREE_CODE (s) == TYPE_DECL)
s = TREE_TYPE (s);
if (TYPE_P (s))
--- 11836,11843 ----
{
tree s = TREE_VALUE (specifier);
! if (TREE_CODE (s) == IDENTIFIER_NODE)
! get_global_value_if_present (s, &type);
if (TREE_CODE (s) == TYPE_DECL)
s = TREE_TYPE (s);
if (TYPE_P (s))
Index: rtti.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/rtti.c,v
retrieving revision 1.174
diff -p -r1.174 rtti.c
*** rtti.c 14 Sep 2003 20:24:00 -0000 1.174
--- rtti.c 27 Sep 2003 16:27:33 -0000
*************** static tree
*** 172,180 ****
throw_bad_cast (void)
{
tree fn = get_identifier ("__cxa_bad_cast");
! if (IDENTIFIER_GLOBAL_VALUE (fn))
! fn = IDENTIFIER_GLOBAL_VALUE (fn);
! else
fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
void_list_node));
--- 172,178 ----
throw_bad_cast (void)
{
tree fn = get_identifier ("__cxa_bad_cast");
! if (!get_global_value_if_present (fn, &fn))
fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
void_list_node));
*************** static tree
*** 188,196 ****
throw_bad_typeid (void)
{
tree fn = get_identifier ("__cxa_bad_typeid");
! if (IDENTIFIER_GLOBAL_VALUE (fn))
! fn = IDENTIFIER_GLOBAL_VALUE (fn);
! else
{
tree t = build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
t = build_function_type (build_reference_type (t), void_list_node);
--- 186,192 ----
throw_bad_typeid (void)
{
tree fn = get_identifier ("__cxa_bad_typeid");
! if (!get_global_value_if_present (fn, &fn))
{
tree t = build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
t = build_function_type (build_reference_type (t), void_list_node);