Skip to content

Commit

Permalink
Speed up Compilation construction by reorganizing how built-in subrou…
Browse files Browse the repository at this point in the history
…tines get created and registered
  • Loading branch information
MikePopoloski committed May 9, 2024
1 parent ffbfee7 commit 931711e
Show file tree
Hide file tree
Showing 15 changed files with 345 additions and 289 deletions.
8 changes: 2 additions & 6 deletions bindings/python/CompBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,8 @@ void registerCompilation(py::module_& m) {
.def("addSyntaxTree", &Compilation::addSyntaxTree, "tree"_a)
.def("getSyntaxTrees", &Compilation::getSyntaxTrees)
.def("getRoot", py::overload_cast<>(&Compilation::getRoot), byrefint)
.def("addSystemSubroutine",
py::overload_cast<const SystemSubroutine&>(&Compilation::addSystemSubroutine),
py::keep_alive<1, 2>(), "subroutine"_a)
.def("addSystemMethod",
py::overload_cast<SymbolKind, const SystemSubroutine&>(&Compilation::addSystemMethod),
py::keep_alive<1, 3>(), "typeKind"_a, "method"_a)
.def("addSystemSubroutine", &Compilation::addSystemSubroutine, "subroutine"_a)
.def("addSystemMethod", &Compilation::addSystemMethod, "typeKind"_a, "method"_a)
.def("getSystemSubroutine", &Compilation::getSystemSubroutine, byrefint, "name"_a)
.def("getSystemMethod", &Compilation::getSystemMethod, byrefint, "typeKind"_a, "name"_a)
.def("parseName", &Compilation::parseName, byrefint, "name"_a)
Expand Down
22 changes: 5 additions & 17 deletions include/slang/ast/Compilation.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,20 +428,10 @@ class SLANG_EXPORT Compilation : public BumpAllocator {
/// @{

/// Registers a system subroutine handler, which can be accessed by compiled code.
void addSystemSubroutine(std::unique_ptr<SystemSubroutine> subroutine);

/// Registers an externally owned system subroutine handler,
/// which can be accessed by compiled code. The provided subroutine must remain
/// valid for the lifetime of this object.
void addSystemSubroutine(const SystemSubroutine& subroutine);
void addSystemSubroutine(std::shared_ptr<SystemSubroutine> subroutine);

/// Registers a type-based system method handler, which can be accessed by compiled code.
void addSystemMethod(SymbolKind typeKind, std::unique_ptr<SystemSubroutine> method);

/// Registers an externally owned type-based system method handler,
/// which can be accessed by compiled code. The provided subroutine must remain
/// valid for the lifetime of this object.
void addSystemMethod(SymbolKind typeKind, const SystemSubroutine& subroutine);
void addSystemMethod(SymbolKind typeKind, std::shared_ptr<SystemSubroutine> method);

/// Gets a system subroutine with the given name, or nullptr if there is no such subroutine
/// registered.
Expand Down Expand Up @@ -818,10 +808,11 @@ class SLANG_EXPORT Compilation : public BumpAllocator {
flat_hash_map<std::string_view, const PackageSymbol*> packageMap;

// The name map for system subroutines.
flat_hash_map<std::string_view, const SystemSubroutine*> subroutineMap;
flat_hash_map<std::string_view, std::shared_ptr<SystemSubroutine>> subroutineMap;

// The name map for system methods.
flat_hash_map<std::tuple<std::string_view, SymbolKind>, const SystemSubroutine*> methodMap;
flat_hash_map<std::tuple<std::string_view, SymbolKind>, std::shared_ptr<SystemSubroutine>>
methodMap;

// Map from pointers (to symbols, statements, expressions) to their associated attributes.
flat_hash_map<const void*, std::span<const AttributeSymbol* const>> attributeMap;
Expand Down Expand Up @@ -947,9 +938,6 @@ class SLANG_EXPORT Compilation : public BumpAllocator {
flat_hash_map<std::tuple<std::string_view, const Scope*>, const syntax::SyntaxNode*>
externDefMap;

// Storage for system subroutine instances.
std::vector<std::unique_ptr<SystemSubroutine>> subroutineStorage;

// The built-in std package.
const PackageSymbol* stdPkg = nullptr;

Expand Down
106 changes: 42 additions & 64 deletions source/ast/Compilation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "slang/ast/Compilation.h"

#include "ElabVisitors.h"
#include "builtins/Builtins.h"
#include <fmt/core.h>
#include <mutex>

Expand All @@ -29,16 +30,8 @@ using namespace slang::parsing;

namespace slang::ast::builtins {

void registerArrayMethods(Compilation&);
void registerConversionFuncs(Compilation&);
void registerCoverageFuncs(Compilation&);
void registerEnumMethods(Compilation&);
void registerMathFuncs(Compilation&);
void registerMiscSystemFuncs(Compilation&);
void registerNonConstFuncs(Compilation&);
void registerQueryFuncs(Compilation&);
void registerStringMethods(Compilation&);
void registerSystemTasks(Compilation&);
Builtins Builtins::Instance;

void registerGateTypes(Compilation&);
const PackageSymbol& createStdPackage(Compilation&);

Expand All @@ -51,35 +44,37 @@ Compilation::Compilation(const Bag& options, const SourceLibrary* defaultLib) :
unrollIntervalMapAllocator(*this), tempDiag({}, {}), defaultLibPtr(defaultLib) {

// Construct all built-in types.
bitType = emplace<ScalarType>(ScalarType::Bit);
logicType = emplace<ScalarType>(ScalarType::Logic);
intType = emplace<PredefinedIntegerType>(PredefinedIntegerType::Int);
byteType = emplace<PredefinedIntegerType>(PredefinedIntegerType::Byte);
integerType = emplace<PredefinedIntegerType>(PredefinedIntegerType::Integer);
realType = emplace<FloatingType>(FloatingType::Real);
shortRealType = emplace<FloatingType>(FloatingType::ShortReal);
stringType = emplace<StringType>();
voidType = emplace<VoidType>();
errorType = emplace<ErrorType>();

auto regType = emplace<ScalarType>(ScalarType::Reg);
auto signedBitType = emplace<ScalarType>(ScalarType::Bit, true);
auto signedLogicType = emplace<ScalarType>(ScalarType::Logic, true);
auto signedRegType = emplace<ScalarType>(ScalarType::Reg, true);
auto shortIntType = emplace<PredefinedIntegerType>(PredefinedIntegerType::ShortInt);
auto longIntType = emplace<PredefinedIntegerType>(PredefinedIntegerType::LongInt);
auto timeType = emplace<PredefinedIntegerType>(PredefinedIntegerType::Time);
auto realTimeType = emplace<FloatingType>(FloatingType::RealTime);
auto chandleType = emplace<CHandleType>();
auto nullType = emplace<NullType>();
auto eventType = emplace<EventType>();
auto unboundedType = emplace<UnboundedType>();
auto typeRefType = emplace<TypeRefType>();
auto untypedType = emplace<UntypedType>();
auto sequenceType = emplace<SequenceType>();
auto propertyType = emplace<PropertyType>();
auto& bi = slang::ast::builtins::Builtins::Instance;
bitType = &bi.bitType;
logicType = &bi.logicType;
intType = &bi.intType;
byteType = &bi.byteType;
integerType = &bi.integerType;
realType = &bi.realType;
shortRealType = &bi.shortRealType;
stringType = &bi.stringType;
voidType = &bi.voidType;
errorType = &bi.errorType;

auto regType = &bi.regType;
auto signedBitType = &bi.signedBitType;
auto signedLogicType = &bi.signedLogicType;
auto signedRegType = &bi.signedRegType;
auto shortIntType = &bi.shortIntType;
auto longIntType = &bi.longIntType;
auto timeType = &bi.timeType;
auto realTimeType = &bi.realTimeType;
auto chandleType = &bi.chandleType;
auto nullType = &bi.nullType;
auto eventType = &bi.eventType;
auto unboundedType = &bi.unboundedType;
auto typeRefType = &bi.typeRefType;
auto untypedType = &bi.untypedType;
auto sequenceType = &bi.sequenceType;
auto propertyType = &bi.propertyType;

// Register built-in types for lookup by syntax kind.
knownTypes.reserve(32);
knownTypes[SyntaxKind::ShortIntType] = shortIntType;
knownTypes[SyntaxKind::IntType] = intType;
knownTypes[SyntaxKind::LongIntType] = longIntType;
Expand Down Expand Up @@ -108,6 +103,7 @@ Compilation::Compilation(const Bag& options, const SourceLibrary* defaultLib) :
knownNetTypes[TokenKind::type##Keyword] = std::make_unique<NetType>( \
NetType::type, LexerFacts::getTokenKindText(TokenKind::type##Keyword), *logicType)

knownNetTypes.reserve(16);
MAKE_NETTYPE(Wire);
MAKE_NETTYPE(WAnd);
MAKE_NETTYPE(WOr);
Expand Down Expand Up @@ -141,17 +137,9 @@ Compilation::Compilation(const Bag& options, const SourceLibrary* defaultLib) :

root = std::make_unique<RootSymbol>(*this);

// Register all system tasks, functions, and methods.
builtins::registerArrayMethods(*this);
builtins::registerConversionFuncs(*this);
builtins::registerCoverageFuncs(*this);
builtins::registerEnumMethods(*this);
builtins::registerMathFuncs(*this);
builtins::registerMiscSystemFuncs(*this);
builtins::registerNonConstFuncs(*this);
builtins::registerQueryFuncs(*this);
builtins::registerStringMethods(*this);
builtins::registerSystemTasks(*this);
// Copy in all built-in system tasks, functions, and methods.
subroutineMap = bi.subroutineMap;
methodMap = bi.methodMap;

// Register the built-in std package.
stdPkg = &builtins::createStdPackage(*this);
Expand Down Expand Up @@ -1028,37 +1016,27 @@ void Compilation::addGateType(const PrimitiveSymbol& prim) {
gateMap.emplace(prim.name, &prim);
}

void Compilation::addSystemSubroutine(std::unique_ptr<SystemSubroutine> subroutine) {
subroutineMap.emplace(subroutine->name, subroutine.get());
subroutineStorage.emplace_back(std::move(subroutine));
}

void Compilation::addSystemSubroutine(const SystemSubroutine& subroutine) {
subroutineMap.emplace(subroutine.name, &subroutine);
void Compilation::addSystemSubroutine(std::shared_ptr<SystemSubroutine> subroutine) {
subroutineMap.emplace(subroutine->name, std::move(subroutine));
}

void Compilation::addSystemMethod(SymbolKind typeKind, std::unique_ptr<SystemSubroutine> method) {
methodMap.emplace(std::make_tuple(std::string_view(method->name), typeKind), method.get());
subroutineStorage.emplace_back(std::move(method));
}

void Compilation::addSystemMethod(SymbolKind typeKind, const SystemSubroutine& method) {
methodMap.emplace(std::make_tuple(std::string_view(method.name), typeKind), &method);
void Compilation::addSystemMethod(SymbolKind typeKind, std::shared_ptr<SystemSubroutine> method) {
methodMap.emplace(std::make_tuple(std::string_view(method->name), typeKind), std::move(method));
}

const SystemSubroutine* Compilation::getSystemSubroutine(std::string_view name) const {
auto it = subroutineMap.find(name);
if (it == subroutineMap.end())
return nullptr;
return it->second;
return it->second.get();
}

const SystemSubroutine* Compilation::getSystemMethod(SymbolKind typeKind,
std::string_view name) const {
auto it = methodMap.find(std::make_tuple(name, typeKind));
if (it == methodMap.end())
return nullptr;
return it->second;
return it->second.get();
}

void Compilation::setAttributes(const Symbol& symbol,
Expand Down
26 changes: 13 additions & 13 deletions source/ast/builtins/ArrayMethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
// SPDX-FileCopyrightText: Michael Popoloski
// SPDX-License-Identifier: MIT
//------------------------------------------------------------------------------
#include "Builtins.h"

#include "slang/ast/Compilation.h"
#include "slang/ast/EvalContext.h"
#include "slang/ast/SystemSubroutine.h"
Expand Down Expand Up @@ -534,8 +536,8 @@ class ArrayUniqueMethod : public SystemSubroutine {

class ArraySizeMethod : public SimpleSystemSubroutine {
public:
ArraySizeMethod(Compilation& comp, const std::string& name) :
SimpleSystemSubroutine(name, SubroutineKind::Function, 0, {}, comp.getIntType(), true) {}
ArraySizeMethod(const Builtins& builtins, const std::string& name) :
SimpleSystemSubroutine(name, SubroutineKind::Function, 0, {}, builtins.intType, true) {}

ConstantValue eval(EvalContext& context, const Args& args, SourceRange,
const CallExpression::SystemCallInfo&) const final {
Expand All @@ -549,8 +551,8 @@ class ArraySizeMethod : public SimpleSystemSubroutine {

class DynArrayDeleteMethod : public SimpleSystemSubroutine {
public:
explicit DynArrayDeleteMethod(Compilation& comp) :
SimpleSystemSubroutine("delete", SubroutineKind::Function, 0, {}, comp.getVoidType(), true,
explicit DynArrayDeleteMethod(const Builtins& builtins) :
SimpleSystemSubroutine("delete", SubroutineKind::Function, 0, {}, builtins.voidType, true,
/* isFirstArgLValue */ true) {}

ConstantValue eval(EvalContext& context, const Args& args, SourceRange,
Expand Down Expand Up @@ -1056,9 +1058,8 @@ class ArrayMapMethod : public SystemSubroutine {
}
};

void registerArrayMethods(Compilation& c) {
#define REGISTER(kind, name, ...) \
c.addSystemMethod(kind, std::make_unique<name##Method>(__VA_ARGS__))
void Builtins::registerArrayMethods() {
#define REGISTER(kind, name, ...) addSystemMethod(kind, std::make_shared<name##Method>(__VA_ARGS__))

for (auto kind : {SymbolKind::FixedSizeUnpackedArrayType, SymbolKind::DynamicArrayType,
SymbolKind::AssociativeArrayType, SymbolKind::QueueType}) {
Expand Down Expand Up @@ -1086,7 +1087,7 @@ void registerArrayMethods(Compilation& c) {

for (auto kind :
{SymbolKind::DynamicArrayType, SymbolKind::AssociativeArrayType, SymbolKind::QueueType}) {
REGISTER(kind, ArraySize, c, "size");
REGISTER(kind, ArraySize, *this, "size");
}

for (auto kind : {SymbolKind::FixedSizeUnpackedArrayType, SymbolKind::DynamicArrayType,
Expand All @@ -1095,16 +1096,15 @@ void registerArrayMethods(Compilation& c) {
REGISTER(kind, ArraySort, "rsort", true);
REGISTER(kind, ArrayReverse, );

c.addSystemMethod(kind,
std::make_unique<NonConstantFunction>("shuffle", c.getVoidType(), 0,
std::vector<const Type*>{}, true));
addSystemMethod(kind, std::make_shared<NonConstantFunction>(
"shuffle", voidType, 0, std::vector<const Type*>{}, true));
}

// Associative arrays also alias "size" to "num" for some reason.
REGISTER(SymbolKind::AssociativeArrayType, ArraySize, c, "num");
REGISTER(SymbolKind::AssociativeArrayType, ArraySize, *this, "num");

// "delete" methods
REGISTER(SymbolKind::DynamicArrayType, DynArrayDelete, c);
REGISTER(SymbolKind::DynamicArrayType, DynArrayDelete, *this);
REGISTER(SymbolKind::AssociativeArrayType, AssocArrayDelete, );
REGISTER(SymbolKind::QueueType, QueueDelete, );

Expand Down
91 changes: 91 additions & 0 deletions source/ast/builtins/Builtins.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//------------------------------------------------------------------------------
// Builtins.h
// Container type for canonical instance of various built-in types and methods
//
// SPDX-FileCopyrightText: Michael Popoloski
// SPDX-License-Identifier: MIT
//------------------------------------------------------------------------------

#include <memory>
#include <string_view>
#include <tuple>

#include "slang/ast/SystemSubroutine.h"
#include "slang/ast/types/AllTypes.h"
#include "slang/util/Hash.h"

namespace slang::ast::builtins {

class Builtins {
public:
ScalarType bitType{ScalarType::Bit};
ScalarType logicType{ScalarType::Logic};
ScalarType regType{ScalarType::Reg};
ScalarType signedBitType{ScalarType::Bit, true};
ScalarType signedLogicType{ScalarType::Logic, true};
ScalarType signedRegType{ScalarType::Reg, true};
PredefinedIntegerType intType{PredefinedIntegerType::Int};
PredefinedIntegerType uintType{PredefinedIntegerType::Int, false};
PredefinedIntegerType byteType{PredefinedIntegerType::Byte};
PredefinedIntegerType integerType{PredefinedIntegerType::Integer};
PredefinedIntegerType shortIntType{PredefinedIntegerType::ShortInt};
PredefinedIntegerType longIntType{PredefinedIntegerType::LongInt};
PredefinedIntegerType ulongIntType{PredefinedIntegerType::LongInt, false};
PredefinedIntegerType timeType{PredefinedIntegerType::Time};
FloatingType realType{FloatingType::Real};
FloatingType shortRealType{FloatingType::ShortReal};
FloatingType realTimeType{FloatingType::RealTime};
StringType stringType;
VoidType voidType;
CHandleType chandleType;
NullType nullType;
EventType eventType;
UnboundedType unboundedType;
TypeRefType typeRefType;
UntypedType untypedType;
SequenceType sequenceType;
PropertyType propertyType;
ErrorType errorType;

flat_hash_map<std::string_view, std::shared_ptr<SystemSubroutine>> subroutineMap;
flat_hash_map<std::tuple<std::string_view, SymbolKind>, std::shared_ptr<SystemSubroutine>>
methodMap;

static Builtins Instance;

Builtins() {
registerArrayMethods();
registerConversionFuncs();
registerCoverageFuncs();
registerEnumMethods();
registerMathFuncs();
registerMiscSystemFuncs();
registerNonConstFuncs();
registerQueryFuncs();
registerStringMethods();
registerSystemTasks();
}

private:
void registerArrayMethods();
void registerConversionFuncs();
void registerCoverageFuncs();
void registerEnumMethods();
void registerMathFuncs();
void registerMiscSystemFuncs();
void registerNonConstFuncs();
void registerQueryFuncs();
void registerStringMethods();
void registerSystemTasks();

void addSystemSubroutine(std::shared_ptr<SystemSubroutine> subroutine) {
subroutineMap.emplace(subroutine->name, std::move(subroutine));
}

void addSystemMethod(SymbolKind typeKind, std::shared_ptr<SystemSubroutine> method) {
methodMap.emplace(std::make_tuple(std::string_view(method->name), typeKind),
std::move(method));
}
};

} // namespace slang::ast::builtins
Loading

0 comments on commit 931711e

Please sign in to comment.