public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-2058] d: Defer compiling inline definitions until after the module has finished.
@ 2022-08-15 19:37 Iain Buclaw
0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2022-08-15 19:37 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:8db5b71e212debcc4f6a17f80191ca187c307fcb
commit r13-2058-g8db5b71e212debcc4f6a17f80191ca187c307fcb
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Mon Aug 15 19:00:43 2022 +0200
d: Defer compiling inline definitions until after the module has finished.
This is to prevent the case of when generating the methods of a struct
type, we don't accidentally emit an inline function that references it,
as the outer struct itself would still be incomplete.
gcc/d/ChangeLog:
* d-tree.h (d_defer_declaration): Declare.
* decl.cc (function_needs_inline_definition_p): Defer checking
DECL_UNINLINABLE and DECL_DECLARED_INLINE_P.
(maybe_build_decl_tree): Call d_defer_declaration instead of
build_decl_tree.
* modules.cc (deferred_inline_declarations): New variable.
(build_module_tree): Set deferred_inline_declarations and a handle
declarations pushed to it.
(d_defer_declaration): New function.
Diff:
---
gcc/d/d-tree.h | 1 +
gcc/d/decl.cc | 22 +++++++++++-----------
gcc/d/modules.cc | 20 ++++++++++++++++++++
3 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 809a242ea93..4885cfe2b15 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -673,6 +673,7 @@ extern tree maybe_expand_intrinsic (tree);
extern void build_module_tree (Module *);
extern tree d_module_context (void);
extern void register_module_decl (Declaration *);
+extern void d_defer_declaration (Declaration *);
extern void d_finish_compilation (tree *, int);
/* In runtime.cc. */
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 0131b01dcc9..e91aee30845 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -1046,18 +1046,10 @@ function_needs_inline_definition_p (FuncDeclaration *fd)
if (!DECL_EXTERNAL (fd->csym))
return false;
- /* Non-inlineable functions are always external. */
- if (DECL_UNINLINABLE (fd->csym))
- return false;
-
/* No function body available for inlining. */
if (!fd->fbody)
return false;
- /* Ignore functions that aren't decorated with `pragma(inline)'. */
- if (fd->inlining != PINLINE::always)
- return false;
-
/* These functions are tied to the module they are defined in. */
if (fd->isFuncLiteralDeclaration ()
|| fd->isUnitTestDeclaration ()
@@ -1070,6 +1062,14 @@ function_needs_inline_definition_p (FuncDeclaration *fd)
if (function_defined_in_root_p (fd))
return false;
+ /* Non-inlineable functions are always external. */
+ if (DECL_UNINLINABLE (fd->csym))
+ return false;
+
+ /* Ignore functions that aren't decorated with `pragma(inline)'. */
+ if (!DECL_DECLARED_INLINE_P (fd->csym))
+ return false;
+
/* Weak functions cannot be inlined. */
if (lookup_attribute ("weak", DECL_ATTRIBUTES (fd->csym)))
return false;
@@ -1081,8 +1081,8 @@ function_needs_inline_definition_p (FuncDeclaration *fd)
return true;
}
-/* If the variable or function declaration in DECL needs to be defined, call
- build_decl_tree on it now before returning its back-end symbol. */
+/* If the variable or function declaration in DECL needs to be defined, add it
+ to the list of deferred declarations to build later. */
static tree
maybe_build_decl_tree (Declaration *decl)
@@ -1103,7 +1103,7 @@ maybe_build_decl_tree (Declaration *decl)
if (function_needs_inline_definition_p (fd))
{
DECL_EXTERNAL (fd->csym) = 0;
- build_decl_tree (fd);
+ d_defer_declaration (fd);
}
}
diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc
index edc79122365..0aac8fe3545 100644
--- a/gcc/d/modules.cc
+++ b/gcc/d/modules.cc
@@ -121,6 +121,9 @@ static module_info *current_testing_module;
static Module *current_module_decl;
+/* Any inline symbols that were deferred during codegen. */
+vec<Declaration *> *deferred_inline_declarations;
+
/* Returns an internal function identified by IDENT. This is used
by both module initialization and dso handlers. */
@@ -724,6 +727,9 @@ build_module_tree (Module *decl)
current_testing_module = &mitest;
current_module_decl = decl;
+ vec<Declaration *> deferred_decls = vNULL;
+ deferred_inline_declarations = &deferred_decls;
+
/* Layout module members. */
if (decl->members)
{
@@ -811,9 +817,14 @@ build_module_tree (Module *decl)
layout_moduleinfo (decl);
}
+ /* Process all deferred functions after finishing module. */
+ for (size_t i = 0; i < deferred_decls.length (); ++i)
+ build_decl_tree (deferred_decls[i]);
+
current_moduleinfo = NULL;
current_testing_module = NULL;
current_module_decl = NULL;
+ deferred_inline_declarations = NULL;
}
/* Returns the current function or module context for the purpose
@@ -888,6 +899,15 @@ register_module_decl (Declaration *d)
}
}
+/* Add DECL as a declaration to emit at the end of the current module. */
+
+void
+d_defer_declaration (Declaration *decl)
+{
+ gcc_assert (deferred_inline_declarations != NULL);
+ deferred_inline_declarations->safe_push (decl);
+}
+
/* Wrapup all global declarations and start the final compilation. */
void
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-08-15 19:37 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-15 19:37 [gcc r13-2058] d: Defer compiling inline definitions until after the module has finished Iain Buclaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).