Skip to content

Instantly share code, notes, and snippets.

@ssvb
Created January 31, 2022 22:28
Show Gist options
  • Save ssvb/d8a67fb445e96f9e66d0516a3ba62475 to your computer and use it in GitHub Desktop.
Save ssvb/d8a67fb445e96f9e66d0516a3ba62475 to your computer and use it in GitHub Desktop.
GDC 11 -fno-weak-templates functionality revert
From 7ed6c100f051a820922c90ba5270356a436786a1 Mon Sep 17 00:00:00 2001
From: Siarhei Siamashka <siarhei.siamashka@gmail.com>
Date: Mon, 31 Jan 2022 08:19:02 +0200
Subject: [PATCH] Revert "d: Add TARGET_D_TEMPLATES_ALWAYS_COMDAT"
This reverts commit bda519596543e49f77914b5677693e86be5d01d0.
Revert "d: Move call to set_linkage_for_decl to declare_extern_var."
This reverts commit 5b63eb17d863ac080cf3c7df08233054b09d3747.
Revert "d: Use weak linkage for template symbols instead of gnu.linkonce (PR99914)"
This reverts commit 76a7e7e706ac4c01cead3c6514322aaad88f9a63.
---
gcc/config/i386/winnt-d.c | 5 --
gcc/d/d-lang.cc | 2 +-
gcc/d/d-target.def | 8 ---
gcc/d/d-tree.h | 16 ++---
gcc/d/decl.cc | 107 ++++++++++++---------------------
gcc/d/gdc.texi | 14 ++---
gcc/d/lang.opt | 6 +-
gcc/d/modules.cc | 20 +++---
gcc/d/typeinfo.cc | 12 +++-
gcc/doc/tm.texi | 6 --
gcc/doc/tm.texi.in | 2 -
gcc/testsuite/gdc.dg/pr99914.d | 5 --
12 files changed, 75 insertions(+), 128 deletions(-)
delete mode 100644 gcc/testsuite/gdc.dg/pr99914.d
diff --git a/gcc/config/i386/winnt-d.c b/gcc/config/i386/winnt-d.c
index ea4cd13d0bf..b9780258549 100644
--- a/gcc/config/i386/winnt-d.c
+++ b/gcc/config/i386/winnt-d.c
@@ -78,9 +78,4 @@ winnt_d_register_target_info (void)
#undef TARGET_D_MINFO_END_NAME
#define TARGET_D_MINFO_END_NAME "__stop_minfo"
-/* Define TARGET_D_TEMPLATES_ALWAYS_COMDAT for Windows targets. */
-
-#undef TARGET_D_TEMPLATES_ALWAYS_COMDAT
-#define TARGET_D_TEMPLATES_ALWAYS_COMDAT true
-
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc
index 3e6566a3689..16bff2d0db3 100644
--- a/gcc/d/d-lang.cc
+++ b/gcc/d/d-lang.cc
@@ -389,7 +389,7 @@ d_init (void)
using_eh_for_cleanups ();
if (!supports_one_only ())
- flag_weak_templates = 0;
+ flag_weak = 0;
/* This is the C main, not the D main. */
main_identifier_node = get_identifier ("main");
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index 67647515cf2..aa6bf55e6e6 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -104,13 +104,5 @@ and @var{link_windows} to @code{1} to apply @code{stdcall} to functions with\n\
bool, (unsigned int *link_system, unsigned int *link_windows),
hook_bool_uintp_uintp_false)
-/* True if instantiations are always COMDAT if they have external linkage. */
-DEFHOOKPOD
-(d_templates_always_comdat,
- "This flag is true if instantiated functions and variables are always COMDAT\n\
-if they have external linkage. If this flag is false, then instantiated\n\
-decls will be emitted as weak symbols. The default is @code{false}.",
- bool, false)
-
/* Close the 'struct gcc_targetdm' definition. */
HOOK_VECTOR_END (C90_EMPTY_HACK)
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index f210b8b1a6e..32b751242ee 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -59,13 +59,7 @@ typedef Array <Expression *> Expressions;
Usage of DECL_LANG_FLAG_?:
0: LABEL_VARIABLE_CASE (in LABEL_DECL).
DECL_BUILT_IN_CTFE (in FUNCTION_DECL).
- 1: DECL_IN_UNITTEST_CONDITION_P (in FUNCTION_DECL).
- 2: DECL_INSTANTIATED (in FUNCTION_DECL, VAR_DECL). */
-
-/* Language-specific tree checkers. */
-
-#define VAR_OR_FUNCTION_DECL_CHECK(NODE) \
- TREE_CHECK2 (NODE, VAR_DECL, FUNCTION_DECL)
+ 1: DECL_IN_UNITTEST_CONDITION_P (in FUNCTION_DECL). */
/* The kinds of scopes we recognize. */
@@ -394,10 +388,6 @@ lang_tree_node
#define DECL_IN_UNITTEST_CONDITION_P(NODE) \
(DECL_LANG_FLAG_1 (FUNCTION_DECL_CHECK (NODE)))
-/* True if the decl comes from a template instance. */
-#define DECL_INSTANTIATED(NODE) \
- (DECL_LANG_FLAG_1 (VAR_OR_FUNCTION_DECL_CHECK (NODE)))
-
enum d_tree_index
{
DTI_VTABLE_ENTRY_TYPE,
@@ -633,6 +623,7 @@ extern void d_finish_decl (tree);
extern tree make_thunk (FuncDeclaration *, int);
extern tree start_function (FuncDeclaration *);
extern void finish_function (tree);
+extern void mark_needed (tree);
extern tree get_vtable_decl (ClassDeclaration *);
extern tree build_new_class_expr (ClassReferenceExp *);
extern tree aggregate_initializer_decl (AggregateDeclaration *);
@@ -642,7 +633,8 @@ extern tree enum_initializer_decl (EnumDeclaration *);
extern tree build_artificial_decl (tree, tree, const char * = NULL);
extern tree create_field_decl (tree, const char *, int, int);
extern void build_type_decl (tree, Dsymbol *);
-extern void set_linkage_for_decl (tree);
+extern void d_comdat_linkage (tree);
+extern void d_linkonce_linkage (tree);
/* In expr.cc. */
extern tree build_expr (Expression *, bool = false, bool = false);
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index a30549ce8e0..bd1c689f5f0 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -59,7 +59,6 @@ along with GCC; see the file COPYING3. If not see
#include "symtab-thunks.h"
#include "d-tree.h"
-#include "d-target.h"
/* Return identifier for the external mangled name of DECL. */
@@ -388,6 +387,10 @@ public:
/* Generate static initializer. */
d->sinit = aggregate_initializer_decl (d);
DECL_INITIAL (d->sinit) = layout_struct_initializer (d);
+
+ if (d->isInstantiated ())
+ d_linkonce_linkage (d->sinit);
+
d_finish_decl (d->sinit);
/* Put out the members. There might be static constructors in the members
@@ -500,6 +503,7 @@ public:
/* Generate static initializer. */
DECL_INITIAL (d->sinit) = layout_class_initializer (d);
+ d_linkonce_linkage (d->sinit);
d_finish_decl (d->sinit);
/* Put out the TypeInfo. */
@@ -507,6 +511,7 @@ public:
create_typeinfo (d->type, NULL);
DECL_INITIAL (d->csym) = layout_classinfo (d);
+ d_linkonce_linkage (d->csym);
d_finish_decl (d->csym);
/* Put out the vtbl[]. */
@@ -529,6 +534,7 @@ public:
DECL_INITIAL (d->vtblsym)
= build_constructor (TREE_TYPE (d->vtblsym), elms);
+ d_comdat_linkage (d->vtblsym);
d_finish_decl (d->vtblsym);
/* Add this decl to the current binding level. */
@@ -572,6 +578,7 @@ public:
}
DECL_INITIAL (d->csym) = layout_classinfo (d);
+ d_linkonce_linkage (d->csym);
d_finish_decl (d->csym);
/* Add this decl to the current binding level. */
@@ -610,6 +617,10 @@ public:
/* Generate static initializer. */
d->sinit = enum_initializer_decl (d);
DECL_INITIAL (d->sinit) = build_expr (tc->sym->defaultval, true);
+
+ if (d->isInstantiated ())
+ d_linkonce_linkage (d->sinit);
+
d_finish_decl (d->sinit);
}
@@ -1253,22 +1264,22 @@ get_symbol_decl (Declaration *decl)
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl->csym) = 1;
}
- /* Mark compiler generated functions as artificial. */
- if (fd->generated)
- DECL_ARTIFICIAL (decl->csym) = 1;
-
/* Vector array operations are always compiler generated. */
if (fd->isArrayOp)
{
+ TREE_PUBLIC (decl->csym) = 1;
DECL_ARTIFICIAL (decl->csym) = 1;
DECL_DECLARED_INLINE_P (decl->csym) = 1;
+ d_comdat_linkage (decl->csym);
}
- /* Ensure and require contracts are lexically nested in the function they
- part of, but are always publicly callable. */
+ /* And so are ensure and require contracts. */
if (fd->ident == Identifier::idPool ("ensure")
|| fd->ident == Identifier::idPool ("require"))
- TREE_PUBLIC (decl->csym) = 1;
+ {
+ DECL_ARTIFICIAL (decl->csym) = 1;
+ TREE_PUBLIC (decl->csym) = 1;
+ }
if (decl->storage_class & STCfinal)
DECL_FINAL_P (decl->csym) = 1;
@@ -1332,8 +1343,8 @@ get_symbol_decl (Declaration *decl)
/* The decl has not been defined -- yet. */
DECL_EXTERNAL (decl->csym) = 1;
- DECL_INSTANTIATED (decl->csym) = (decl->isInstantiated () != NULL);
- set_linkage_for_decl (decl->csym);
+ if (decl->isInstantiated ())
+ d_linkonce_linkage (decl->csym);
}
/* Symbol is going in thread local storage. */
@@ -1380,8 +1391,6 @@ declare_extern_var (tree ident, tree type)
/* The decl has not been defined -- yet. */
DECL_EXTERNAL (decl) = 1;
- set_linkage_for_decl (decl);
-
return decl;
}
@@ -1965,8 +1974,8 @@ finish_function (tree old_context)
/* Mark DECL, which is a VAR_DECL or FUNCTION_DECL as a symbol that
must be emitted in this, output module. */
-static void
-d_mark_needed (tree decl)
+void
+mark_needed (tree decl)
{
TREE_USED (decl) = 1;
@@ -2326,15 +2335,12 @@ d_comdat_group (tree decl)
/* Set DECL up to have the closest approximation of "initialized common"
linkage available. */
-static void
+void
d_comdat_linkage (tree decl)
{
- /* COMDAT definitions have to be public. */
- gcc_assert (TREE_PUBLIC (decl));
-
- if (supports_one_only ())
+ if (flag_weak)
make_decl_one_only (decl, d_comdat_group (decl));
- else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INSTANTIATED (decl))
+ else if (TREE_CODE (decl) == FUNCTION_DECL
|| (VAR_P (decl) && DECL_ARTIFICIAL (decl)))
/* We can just emit function and compiler-generated variables statically;
having multiple copies is (for the most part) only a waste of space. */
@@ -2344,65 +2350,26 @@ d_comdat_linkage (tree decl)
/* Fallback, cannot have multiple copies. */
DECL_COMMON (decl) = 1;
- if (TREE_PUBLIC (decl) && DECL_INSTANTIATED (decl))
+ if (TREE_PUBLIC (decl))
DECL_COMDAT (decl) = 1;
}
-/* Set DECL up to have the closest approximation of "weak" linkage. */
-
-static void
-d_weak_linkage (tree decl)
-{
- /* Weak definitions have to be public. */
- gcc_assert (TREE_PUBLIC (decl));
-
- /* Allow comdat linkage to be forced with the flag `-fno-weak-templates'. */
- if (!flag_weak_templates || !TARGET_SUPPORTS_WEAK)
- return d_comdat_linkage (decl);
-
- declare_weak (decl);
-}
-
-/* DECL is a FUNCTION_DECL or a VAR_DECL with static storage. Set flags to
- reflect the linkage that DECL will receive in the object file. */
+/* Set DECL up to have the closest approximation of "linkonce" linkage. */
void
-set_linkage_for_decl (tree decl)
+d_linkonce_linkage (tree decl)
{
- gcc_assert (VAR_OR_FUNCTION_DECL_P (decl) && TREE_STATIC (decl));
-
- /* Non-public decls keep their internal linkage. */
+ /* Weak definitions have to be public. */
if (!TREE_PUBLIC (decl))
return;
- /* Don't need to give private or protected symbols a special linkage. */
- if ((TREE_PRIVATE (decl) || TREE_PROTECTED (decl))
- && !DECL_INSTANTIATED (decl))
- return;
-
- /* Functions declared as `pragma(inline, true)' can appear in multiple
- translation units. */
- if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
- return d_comdat_linkage (decl);
-
- /* If all instantiations must go in COMDAT, give them that linkage.
- This also applies to other extern declarations, so that it is possible
- for them to override template declarations. */
- if (targetdm.d_templates_always_comdat)
- {
- /* Make sure that instantiations are not removed. */
- if (flag_weak_templates && DECL_INSTANTIATED (decl))
- d_mark_needed (decl);
-
- return d_comdat_linkage (decl);
- }
+ /* Necessary to allow DECL_ONE_ONLY or DECL_WEAK functions to be inlined. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ DECL_DECLARED_INLINE_P (decl) = 1;
- /* Instantiated variables and functions need to be overridable by any other
- symbol with the same name, so give them weak linkage. */
- if (DECL_INSTANTIATED (decl))
- return d_weak_linkage (decl);
+ /* No weak support, fallback to COMDAT linkage. */
+ if (!flag_weak)
+ return d_comdat_linkage (decl);
- /* Compiler generated public symbols can appear in multiple contexts. */
- if (DECL_ARTIFICIAL (decl))
- return d_weak_linkage (decl);
+ make_decl_one_only (decl, d_comdat_group (decl));
}
diff --git a/gcc/d/gdc.texi b/gcc/d/gdc.texi
index 095f7ecca41..e727848895d 100644
--- a/gcc/d/gdc.texi
+++ b/gcc/d/gdc.texi
@@ -325,13 +325,13 @@ is compiled into the program.
Turns on compilation of @code{version} code identified by @var{ident}.
@end table
-@item -fno-weak-templates
-@cindex @option{-fweak-templates}
-@cindex @option{-fno-weak-templates}
-Turns off emission of declarations that can be defined in multiple objects as
-weak symbols. The default is to emit all public symbols as weak, unless the
-target lacks support for weak symbols. Disabling this option means that common
-symbols are instead put in COMDAT or become private.
+@item -fno-weak
+@cindex @option{-fweak}
+@cindex @option{-fno-weak}
+Turns off emission of instantiated declarations that can be defined in multiple
+objects as weak or one-only symbols. The default is to emit all public symbols
+as weak, unless the target lacks support for weak symbols. Disabling this
+option means that common symbols are instead put in COMDAT or become private.
@end table
diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt
index ded218fc5e3..62e9f8ecfd2 100644
--- a/gcc/d/lang.opt
+++ b/gcc/d/lang.opt
@@ -321,9 +321,9 @@ fversion=
D Joined RejectNegative
-fversion=<level|ident> Compile in version code >= <level> or identified by <ident>.
-fweak-templates
-D Var(flag_weak_templates) Init(1)
-Emit template instantiations as weak symbols.
+fweak
+D Var(flag_weak) Init(1)
+Emit common-like symbols as weak symbols.
imultilib
D Joined Separate
diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc
index 8786344d954..af69815deb9 100644
--- a/gcc/d/modules.cc
+++ b/gcc/d/modules.cc
@@ -125,7 +125,7 @@ static Module *current_module_decl;
by both module initialization and dso handlers. */
static FuncDeclaration *
-get_internal_fn (tree ident, const Prot &prot)
+get_internal_fn (tree ident)
{
Module *mod = current_module_decl;
const char *name = IDENTIFIER_POINTER (ident);
@@ -141,10 +141,9 @@ get_internal_fn (tree ident, const Prot &prot)
FuncDeclaration *fd = FuncDeclaration::genCfunc (NULL, Type::tvoid,
Identifier::idPool (name));
- fd->generated = true;
fd->loc = Loc (mod->srcfile->toChars (), 1, 0);
fd->parent = mod;
- fd->protection = prot;
+ fd->protection.kind = Prot::private_;
fd->semanticRun = PASSsemantic3done;
return fd;
@@ -156,7 +155,7 @@ get_internal_fn (tree ident, const Prot &prot)
static tree
build_internal_fn (tree ident, tree expr)
{
- FuncDeclaration *fd = get_internal_fn (ident, Prot (Prot::private_));
+ FuncDeclaration *fd = get_internal_fn (ident);
tree decl = get_symbol_decl (fd);
tree old_context = start_function (fd);
@@ -338,8 +337,7 @@ build_dso_cdtor_fn (bool ctor_p)
}
}
*/
- FuncDeclaration *fd = get_internal_fn (get_identifier (name),
- Prot (Prot::public_));
+ FuncDeclaration *fd = get_internal_fn (get_identifier (name));
tree decl = get_symbol_decl (fd);
TREE_PUBLIC (decl) = 1;
@@ -347,6 +345,8 @@ build_dso_cdtor_fn (bool ctor_p)
DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (decl) = 1;
+ d_comdat_linkage (decl);
+
/* Start laying out the body. */
tree old_context = start_function (fd);
rest_of_decl_compilation (decl, 1, 0);
@@ -443,11 +443,15 @@ register_moduleinfo (Module *decl, tree minfo)
/* Declare dso_slot and dso_initialized. */
dso_slot_node = build_dso_registry_var (GDC_PREFIX ("dso_slot"),
ptr_type_node);
- d_finish_decl (dso_slot_node);
+ DECL_EXTERNAL (dso_slot_node) = 0;
+ d_comdat_linkage (dso_slot_node);
+ rest_of_decl_compilation (dso_slot_node, 1, 0);
dso_initialized_node = build_dso_registry_var (GDC_PREFIX ("dso_initialized"),
boolean_type_node);
- d_finish_decl (dso_initialized_node);
+ DECL_EXTERNAL (dso_initialized_node) = 0;
+ d_comdat_linkage (dso_initialized_node);
+ rest_of_decl_compilation (dso_initialized_node, 1, 0);
/* Declare dso_ctor() and dso_dtor(). */
tree dso_ctor = build_dso_cdtor_fn (true);
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 9d6464deb07..925c4688743 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -359,7 +359,7 @@ class TypeInfoVisitor : public Visitor
DECL_EXTERNAL (decl) = 0;
TREE_PUBLIC (decl) = 1;
DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
- set_linkage_for_decl (decl);
+ d_comdat_linkage (decl);
d_pushdecl (decl);
return decl;
@@ -1321,6 +1321,14 @@ public:
DECL_CONTEXT (tid->csym) = d_decl_context (tid);
TREE_READONLY (tid->csym) = 1;
+
+ /* Built-in typeinfo will be referenced as one-only. */
+ gcc_assert (!tid->isInstantiated ());
+
+ if (builtin_typeinfo_p (tid->tinfo))
+ d_linkonce_linkage (tid->csym);
+ else
+ d_comdat_linkage (tid->csym);
}
void visit (TypeInfoClassDeclaration *tid)
@@ -1485,6 +1493,8 @@ get_cpp_typeinfo_decl (ClassDeclaration *decl)
= TREE_TYPE (build_ctype (decl->type));
TREE_READONLY (decl->cpp_type_info_ptr_sym) = 1;
+ d_comdat_linkage (decl->cpp_type_info_ptr_sym);
+
/* Layout the initializer and emit the symbol. */
layout_cpp_typeinfo (decl);
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b370bc76b25..0f24285fcbf 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10859,12 +10859,6 @@ and @var{link_windows} to @code{1} to apply @code{stdcall} to functions with
@code{extern(Windows)} linkage.
@end deftypefn
-@deftypevr {D Target Hook} bool TARGET_D_TEMPLATES_ALWAYS_COMDAT
-This flag is true if instantiated functions and variables are always COMDAT
-if they have external linkage. If this flag is false, then instantiated
-decls will be emitted as weak symbols. The default is @code{false}.
-@end deftypevr
-
@node Named Address Spaces
@section Adding support for named address spaces
@cindex named address spaces
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 2974dae2701..4fc3fed94be 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7371,8 +7371,6 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_HAS_STDCALL_CONVENTION
-@hook TARGET_D_TEMPLATES_ALWAYS_COMDAT
-
@node Named Address Spaces
@section Adding support for named address spaces
@cindex named address spaces
diff --git a/gcc/testsuite/gdc.dg/pr99914.d b/gcc/testsuite/gdc.dg/pr99914.d
deleted file mode 100644
index 689eae02136..00000000000
--- a/gcc/testsuite/gdc.dg/pr99914.d
+++ /dev/null
@@ -1,5 +0,0 @@
-// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99914
-// { dg-additional-options "-fmain" }
-// { dg-do link { target d_runtime } }
-
-extern(C) __gshared bool rt_cmdline_enabled = false;
--
2.32.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment