This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[LTO merge] gimplification of types and symbols [2/2]
- From: Diego Novillo <dnovillo at google dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Guenther <rguenther at suse dot de>, Jason Merrill <jason at redhat dot com>, Mark Mitchell <mark at codesourcery dot com>, Andrew Haley <aph at redhat dot com>
- Date: Wed, 2 Sep 2009 10:10:58 -0400
- Subject: [LTO merge] gimplification of types and symbols [2/2]
This is part 2 of the free-lang-data merge. The C++ changes
include the generation of Java hidden aliases and these patches
needed to clear out C++ data from types/symbols:
http://gcc.gnu.org/ml/gcc-patches/2008-09/msg01605.html
http://gcc.gnu.org/ml/gcc-patches/2008-08/msg01730.html
http://gcc.gnu.org/ml/gcc-patches/2008-12/msg00746.html
Bootstrapped and tested on x86_64 for all languages including Ada
and Obj-C++.
OK for trunk? This needs to be committed together with
http://gcc.gnu.org/ml/gcc-patches/2009-09/msg00125.html
Diego.
cp/ChangeLog
2009-09-01 Doug Kwan <dougkwan@google.com>
* tree.c (cp_fix_function_decl_p): New.
(cp_free_lang_data): New.
2009-09-01 Diego Novillo <dnovillo@google.com>
* Make-lang.in (decl2.o): Add dependency on $(POINTER_SET_H).
* decl2.c: Include pointer-set.h.
(collect_candidates_for_java_method_aliases): New.
(cp_write_global_declarations): Call it.
Add local variable CANDIDATES. If set, call
build_java_method_aliases.
(build_java_method_aliases): Add argument CANDIDATES.
Use it to determine if FNDECL should get a hidden alias.
* cp-objcp-common.h (LANG_HOOKS_FREE_LANG_DATA): Define.
* cp-tree.h (cp_free_lang_data): Declare.
2009-09-01 Simon Baldwin <simonb@google.com>
* mangle.c (mangle_decl_is_template_id): New.
* cp-tree.h (mangle_decl_is_template_id): Declare.
2009-09-01 Bill Maddox <maddox@google.com>
* mangle.c (decl_is_template_id): Protect against unexpected
node type as argument to PRIMARY_TEMPLATE_P.
Index: cp/Make-lang.in
===================================================================
--- cp/Make-lang.in (revision 151295)
+++ cp/Make-lang.in (working copy)
@@ -257,7 +257,7 @@ cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_
debug.h gt-cp-decl.h $(TIMEVAR_H) $(TREE_FLOW_H) $(TARGET_H) $(PLUGIN_H)
cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h $(EXPR_H) \
output.h except.h toplev.h $(RTL_H) $(C_COMMON_H) gt-cp-decl2.h $(CGRAPH_H) \
- $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H) $(GIMPLE_H)
+ $(C_PRAGMA_H) $(TREE_DUMP_H) intl.h $(TARGET_H) $(GIMPLE_H) $(POINTER_SET_H)
cp/cp-objcp-common.o : cp/cp-objcp-common.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(CXX_TREE_H) $(C_COMMON_H) toplev.h \
langhooks.h $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) debug.h \
Index: cp/tree.c
===================================================================
--- cp/tree.c (revision 151295)
+++ cp/tree.c (working copy)
@@ -3030,6 +3030,61 @@ cast_valid_in_integral_constant_expressi
|| type == error_mark_node);
}
+/* Return true if we need to fix linkage information of DECL. */
+
+static bool
+cp_fix_function_decl_p (tree decl)
+{
+ /* Skip if DECL is not externally visible. */
+ if (!TREE_PUBLIC (decl))
+ return false;
+
+ /* We need to fix DECL if it a appears to be exported but with no
+ function body. Thunks do not have CFGs and we may need to
+ handle them specially later. */
+ if (!gimple_has_body_p (decl)
+ && !DECL_THUNK_P (decl)
+ && !DECL_EXTERNAL (decl))
+ return true;
+
+ return false;
+}
+
+/* Clean the C++ specific parts of the tree T. */
+
+void
+cp_free_lang_data (tree t)
+{
+ if (TREE_CODE (t) == METHOD_TYPE
+ || TREE_CODE (t) == FUNCTION_TYPE)
+ {
+ /* Default args are not interesting anymore. */
+ tree argtypes = TYPE_ARG_TYPES (t);
+ while (argtypes)
+ {
+ TREE_PURPOSE (argtypes) = 0;
+ argtypes = TREE_CHAIN (argtypes);
+ }
+ }
+ else if (TREE_CODE (t) == TYPE_DECL)
+ {
+ tree template_info;
+
+ /* Remove context information held in templated decls. */
+ if (mangle_decl_is_template_id (t, &template_info))
+ DECL_CONTEXT (TREE_PURPOSE (template_info)) = NULL_TREE;
+ }
+ else if (TREE_CODE (t) == FUNCTION_DECL
+ && cp_fix_function_decl_p (t))
+ {
+ /* If T is used in this translation unit at all, the definition
+ must exist somewhere else since we have decided to not emit it
+ in this TU. So make it an external reference. */
+ DECL_EXTERNAL (t) = 1;
+ TREE_STATIC (t) = 0;
+ }
+}
+
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
/* Complain that some language-specific thing hanging off a tree
Index: cp/cp-lang.c
===================================================================
--- cp/cp-lang.c (revision 151295)
+++ cp/cp-lang.c (working copy)
@@ -73,7 +73,7 @@ static enum classify_record cp_classify_
#define LANG_HOOKS_INIT_TS cp_init_ts
/* Each front end provides its own lang hook initializer. */
-const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
/* Lang hook routines common to C++ and ObjC++ appear in cp/cp-objcp-common.c;
there should be very few routines below. */
Index: cp/semantics.c
===================================================================
--- cp/semantics.c (revision 151295)
+++ cp/semantics.c (working copy)
@@ -3186,7 +3186,9 @@ emit_associated_thunks (tree fn)
is so that you can know statically the entire set of thunks that
will ever be needed for a given virtual function, thereby
enabling you to output all the thunks with the function itself. */
- if (DECL_VIRTUAL_P (fn))
+ if (DECL_VIRTUAL_P (fn)
+ /* Do not emit thunks for extern template instantiations. */
+ && ! DECL_REALLY_EXTERN (fn))
{
tree thunk;
Index: cp/decl2.c
===================================================================
--- cp/decl2.c (revision 151295)
+++ cp/decl2.c (working copy)
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.
#include "tree-dump.h"
#include "intl.h"
#include "gimple.h"
+#include "pointer-set.h"
extern cpp_reader *parse_in;
@@ -3288,27 +3289,60 @@ cxx_callgraph_analyze_expr (tree *tp, in
/* Java requires that we be able to reference a local address for a
method, and not be confused by PLT entries. If hidden aliases are
- supported, emit one for each java function that we've emitted. */
+ supported, collect and return all the functions for which we should
+ emit a hidden alias. */
-static void
-build_java_method_aliases (void)
+static struct pointer_set_t *
+collect_candidates_for_java_method_aliases (void)
{
struct cgraph_node *node;
+ struct pointer_set_t *candidates = NULL;
#ifndef HAVE_GAS_HIDDEN
- return;
+ return candidates;
#endif
for (node = cgraph_nodes; node ; node = node->next)
{
tree fndecl = node->decl;
- if (TREE_ASM_WRITTEN (fndecl)
- && DECL_CONTEXT (fndecl)
+ if (DECL_CONTEXT (fndecl)
&& TYPE_P (DECL_CONTEXT (fndecl))
&& TYPE_FOR_JAVA (DECL_CONTEXT (fndecl))
&& TARGET_USE_LOCAL_THUNK_ALIAS_P (fndecl))
{
+ if (candidates == NULL)
+ candidates = pointer_set_create ();
+ pointer_set_insert (candidates, fndecl);
+ }
+ }
+
+ return candidates;
+}
+
+
+/* Java requires that we be able to reference a local address for a
+ method, and not be confused by PLT entries. If hidden aliases are
+ supported, emit one for each java function that we've emitted.
+ CANDIDATES is the set of FUNCTION_DECLs that were gathered
+ by collect_candidates_for_java_method_aliases. */
+
+static void
+build_java_method_aliases (struct pointer_set_t *candidates)
+{
+ struct cgraph_node *node;
+
+#ifndef HAVE_GAS_HIDDEN
+ return;
+#endif
+
+ for (node = cgraph_nodes; node ; node = node->next)
+ {
+ tree fndecl = node->decl;
+
+ if (TREE_ASM_WRITTEN (fndecl)
+ && pointer_set_contains (candidates, fndecl))
+ {
/* Mangle the name in a predictable way; we need to reference
this from a java compiled object file. */
tree oid, nid, alias;
@@ -3379,6 +3413,7 @@ cp_write_global_declarations (void)
unsigned ssdf_count = 0;
int retries = 0;
tree decl;
+ struct pointer_set_t *candidates;
locus = input_location;
at_eof = 1;
@@ -3676,6 +3711,9 @@ cp_write_global_declarations (void)
linkage now. */
pop_lang_context ();
+ /* Collect candidates for Java hidden aliases. */
+ candidates = collect_candidates_for_java_method_aliases ();
+
cgraph_finalize_compilation_unit ();
/* Now, issue warnings about static, but not defined, functions,
@@ -3690,7 +3728,11 @@ cp_write_global_declarations (void)
}
/* Generate hidden aliases for Java. */
- build_java_method_aliases ();
+ if (candidates)
+ {
+ build_java_method_aliases (candidates);
+ pointer_set_destroy (candidates);
+ }
finish_repo ();
Index: cp/cp-objcp-common.h
===================================================================
--- cp/cp-objcp-common.h (revision 151295)
+++ cp/cp-objcp-common.h (working copy)
@@ -32,6 +32,8 @@ extern bool cp_function_decl_explicit_p
specific to C++ or ObjC++ go in cp/cp-lang.c and objcp/objcp-lang.c,
respectively. */
+#undef LANG_HOOKS_FREE_LANG_DATA
+#define LANG_HOOKS_FREE_LANG_DATA cp_free_lang_data
#undef LANG_HOOKS_TREE_SIZE
#define LANG_HOOKS_TREE_SIZE cp_tree_size
#undef LANG_HOOKS_FINISH
Index: cp/mangle.c
===================================================================
--- cp/mangle.c (revision 151295)
+++ cp/mangle.c (working copy)
@@ -282,6 +282,8 @@ decl_is_template_id (const tree decl, tr
/* Check if this is a primary template. */
if (DECL_LANG_SPECIFIC (decl) != NULL
&& DECL_USE_TEMPLATE (decl)
+ && TREE_CODE (DECL_TI_TEMPLATE (decl)) != OVERLOAD
+ && TREE_CODE (DECL_TI_TEMPLATE (decl)) != IDENTIFIER_NODE
&& PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl))
&& TREE_CODE (decl) != TEMPLATE_DECL)
{
@@ -3130,6 +3132,15 @@ mangle_ref_init_variable (const tree var
write_name (variable, /*ignore_local_scope=*/0);
return finish_mangling_get_identifier (/*warn=*/false);
}
+
+/* Return true if decl is templated, along with the associated template info
+ node. TEMPLATE_INFO may be null. */
+
+int
+mangle_decl_is_template_id (const tree decl, tree * const template_info)
+{
+ return decl_is_template_id (decl, template_info);
+}
/* Foreign language type mangling section. */
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 151295)
+++ cp/cp-tree.h (working copy)
@@ -4888,6 +4888,7 @@ extern tree finish_decltype_type
extern tree finish_trait_expr (enum cp_trait_kind, tree, tree);
/* in tree.c */
+void cp_free_lang_data (tree t);
extern tree force_target_expr (tree, tree);
extern tree build_target_expr_with_type (tree, tree);
extern void lang_check_failed (const char *, int,
@@ -5118,6 +5119,7 @@ extern tree mangle_thunk (tree, int, t
extern tree mangle_conv_op_name_for_type (tree);
extern tree mangle_guard_variable (tree);
extern tree mangle_ref_init_variable (tree);
+extern int mangle_decl_is_template_id (const tree, tree * const);
/* in dump.c */
extern bool cp_dump_tree (void *, tree);