d: Cache generated import declarations in a hash_map

Originally, these were cached in the front-end AST node field `isym'.
However, this field is due to be removed in the future.

gcc/d/ChangeLog:

	* imports.cc (imported_decls): Define.
	(class ImportVisitor): Add result_ field.
	(ImportVisitor::result): New method.
	(ImportVisitor::visit (Module *)): Store decl to result_.
	(ImportVisitor::visit (Import *)): Likewise.
	(ImportVisitor::visit (AliasDeclaration *)): Don't cache decl in
	front-end AST node.
	(ImportVisitor::visit (OverDeclaration *)): Likewise.
	(ImportVisitor::visit (FuncDeclaration *)): Likewise.
	(ImportVisitor::visit (Declaration *)): Likewise.
	(build_import_decl): Use imported_decls to cache and lookup built
	declarations.
This commit is contained in:
Iain Buclaw 2022-03-11 23:19:14 +01:00
parent 7a6ba7c7cb
commit 42d9ff3ac8
1 changed files with 39 additions and 34 deletions

View File

@ -31,14 +31,17 @@ along with GCC; see the file COPYING3. If not see
#include "d-tree.h" #include "d-tree.h"
static hash_map<Dsymbol *, tree> *imported_decls;
/* Implements the visitor interface to build debug trees for all /* Implements the visitor interface to build debug trees for all
module and import declarations, where ISYM holds the cached module and import declarations, where RESULT_ holds the back-end
back-end representation to be returned. */ representation to be cached and returned from the caller. */
class ImportVisitor : public Visitor class ImportVisitor : public Visitor
{ {
using Visitor::visit; using Visitor::visit;
tree result_;
/* Build the declaration DECL as an imported symbol. */ /* Build the declaration DECL as an imported symbol. */
tree make_import (tree decl) tree make_import (tree decl)
{ {
@ -55,6 +58,12 @@ class ImportVisitor : public Visitor
public: public:
ImportVisitor (void) ImportVisitor (void)
{ {
this->result_ = NULL_TREE;
}
tree result (void)
{
return this->result_;
} }
/* This should be overridden by each symbol class. */ /* This should be overridden by each symbol class. */
@ -70,16 +79,16 @@ public:
Loc loc = (m->md != NULL) ? m->md->loc Loc loc = (m->md != NULL) ? m->md->loc
: Loc (m->srcfile.toChars (), 1, 0); : Loc (m->srcfile.toChars (), 1, 0);
m->isym = build_decl (make_location_t (loc), NAMESPACE_DECL, this->result_ = build_decl (make_location_t (loc), NAMESPACE_DECL,
get_identifier (m->toPrettyChars ()), get_identifier (m->toPrettyChars ()),
void_type_node); void_type_node);
d_keep (m->isym); d_keep (this->result_);
if (!m->isRoot ()) if (!m->isRoot ())
DECL_EXTERNAL (m->isym) = 1; DECL_EXTERNAL (this->result_) = 1;
TREE_PUBLIC (m->isym) = 1; TREE_PUBLIC (this->result_) = 1;
DECL_CONTEXT (m->isym) = NULL_TREE; DECL_CONTEXT (this->result_) = NULL_TREE;
} }
/* Build an import of another module symbol. */ /* Build an import of another module symbol. */
@ -87,7 +96,7 @@ public:
void visit (Import *m) void visit (Import *m)
{ {
tree module = build_import_decl (m->mod); tree module = build_import_decl (m->mod);
m->isym = this->make_import (module); this->result_ = this->make_import (module);
} }
/* Build an import for any kind of user defined type. /* Build an import for any kind of user defined type.
@ -141,20 +150,14 @@ public:
/* This symbol is really an alias for another, visit the other. */ /* This symbol is really an alias for another, visit the other. */
if (dsym != d) if (dsym != d)
{
dsym->accept (this); dsym->accept (this);
d->isym = dsym->isym;
}
} }
/* Visit the underlying alias symbol of overloadable aliases. */ /* Visit the underlying alias symbol of overloadable aliases. */
void visit (OverDeclaration *d) void visit (OverDeclaration *d)
{ {
if (d->aliassym != NULL) if (d->aliassym != NULL)
{
d->aliassym->accept (this); d->aliassym->accept (this);
d->isym = d->aliassym->isym;
}
} }
/* Function aliases are the same as alias symbols. */ /* Function aliases are the same as alias symbols. */
@ -163,10 +166,7 @@ public:
FuncDeclaration *fd = d->toAliasFunc (); FuncDeclaration *fd = d->toAliasFunc ();
if (fd != NULL) if (fd != NULL)
{
fd->accept (this); fd->accept (this);
d->isym = fd->isym;
}
} }
/* Skip over importing templates and tuples. */ /* Skip over importing templates and tuples. */
@ -182,7 +182,7 @@ public:
symbol generation routines, the compiler will throw an error. */ symbol generation routines, the compiler will throw an error. */
void visit (Declaration *d) void visit (Declaration *d)
{ {
d->isym = this->make_import (get_symbol_decl (d)); this->result_ = this->make_import (get_symbol_decl (d));
} }
}; };
@ -192,17 +192,22 @@ public:
tree tree
build_import_decl (Dsymbol *d) build_import_decl (Dsymbol *d)
{ {
if (!d->isym) hash_map_maybe_create<hm_ggc> (imported_decls);
{
if (tree *decl = imported_decls->get (d))
return *decl;
location_t saved_location = input_location; location_t saved_location = input_location;
ImportVisitor v; ImportVisitor v = ImportVisitor ();
input_location = make_location_t (d->loc); input_location = make_location_t (d->loc);
d->accept (&v); d->accept (&v);
input_location = saved_location; input_location = saved_location;
}
/* Not all visitors set `isym'. */ /* Not all visitors set `result'. */
return d->isym ? d->isym : NULL_TREE; tree isym = v.result ();
} if (isym != NULL_TREE)
imported_decls->put (d, isym);
return isym;
}