[WHLSL] TypeNamer can be simplified by replacing BaseTypeNameNode with uniqued AST...
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Aug 2019 18:58:00 +0000 (18:58 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 26 Aug 2019 18:58:00 +0000 (18:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200632

Reviewed by Saam Barati.

There is no longer a reason to keep a parallel tree of the UnnamedType-like objects
BaseTypeNameNodes. Instead, we can store a single HashMap mapping from UnnamedTypeKeys
to MangledTypeName, and use the the UnnamedType stored in the UnnamedTypeKey while
emitting the metal code. This removes the parallel BaseTypeNameNode type hierarchy
and removes an extra allocation for each UnnamedType.

* Modules/webgpu/WHLSL/AST/WHLSLUnnamedTypeHash.h:
Define HashTraits and DefaultHash specializations for UnnamedTypeKey to simplify
uses of UnnamedTypeKey as a key in HashMap/HashSet.

* Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h:
* Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
(WebCore::WHLSL::Metal::TypeNamer::insert): Deleted.
(WebCore::WHLSL::Metal::TypeNamer::generateUniquedTypeName):
Replace old insert function with generateUniquedTypeName, which uniques and generates
names for the UnnamedType and any 'parent' UnnamedTypes.

(WebCore::WHLSL::Metal::BaseTypeNameNode): Deleted.
Remove BaseTypeNameNode and subclasses.

(WebCore::WHLSL::Metal::TypeNamer::find): Deleted.
(WebCore::WHLSL::Metal::TypeNamer::createNameNode): Deleted.
We no longer need the find or createNameNode functions, as the UnnamedTypes can be now be
used directly everywhere.

(WebCore::WHLSL::Metal::TypeNamer::emitUnnamedTypeDefinition):
Switch to directly using the UnnamedType and always have the caller pass in the mangled
name, since in the main emit loop, we always have access to the them. Also, inline the
the recursive calls to emitNamedTypeDefinition for 'parent' types to avoid unnecessary
extra switch over the kind getting the parent, and avoid it entirely for TypeReference
which never has a parent.

(WebCore::WHLSL::Metal::TypeNamer::emitNamedTypeDefinition):
Switches to now passing in the neighbors, since they are always available in the main
emit loop. Also move to a switch statement rather than ifs for consistency.

(WebCore::WHLSL::Metal::TypeNamer::emitMetalTypeDefinitions):
Pass keys and values into the emit functions to avoid double lookups.

(WebCore::WHLSL::Metal::TypeNamer::mangledNameForType):
Update to hash lookup.

* Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp:
Take advantage of default HashTraits and DefaultHash for UnnamedTypeKey.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249109 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLUnnamedTypeHash.h
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp

index 86c94ca..2fb87ac 100644 (file)
@@ -1,3 +1,55 @@
+2019-08-26  Sam Weinig  <weinig@apple.com>
+
+        [WHLSL] TypeNamer can be simplified by replacing BaseTypeNameNode with uniqued AST::UnnamedTypes
+        https://bugs.webkit.org/show_bug.cgi?id=200632
+
+        Reviewed by Saam Barati.
+
+        There is no longer a reason to keep a parallel tree of the UnnamedType-like objects
+        BaseTypeNameNodes. Instead, we can store a single HashMap mapping from UnnamedTypeKeys
+        to MangledTypeName, and use the the UnnamedType stored in the UnnamedTypeKey while 
+        emitting the metal code. This removes the parallel BaseTypeNameNode type hierarchy
+        and removes an extra allocation for each UnnamedType. 
+
+        * Modules/webgpu/WHLSL/AST/WHLSLUnnamedTypeHash.h:
+        Define HashTraits and DefaultHash specializations for UnnamedTypeKey to simplify
+        uses of UnnamedTypeKey as a key in HashMap/HashSet.
+
+        * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h:
+        * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
+        (WebCore::WHLSL::Metal::TypeNamer::insert): Deleted.
+        (WebCore::WHLSL::Metal::TypeNamer::generateUniquedTypeName):
+        Replace old insert function with generateUniquedTypeName, which uniques and generates
+        names for the UnnamedType and any 'parent' UnnamedTypes.
+
+        (WebCore::WHLSL::Metal::BaseTypeNameNode): Deleted.
+        Remove BaseTypeNameNode and subclasses.
+
+        (WebCore::WHLSL::Metal::TypeNamer::find): Deleted.
+        (WebCore::WHLSL::Metal::TypeNamer::createNameNode): Deleted.
+        We no longer need the find or createNameNode functions, as the UnnamedTypes can be now be
+        used directly everywhere.
+
+        (WebCore::WHLSL::Metal::TypeNamer::emitUnnamedTypeDefinition):
+        Switch to directly using the UnnamedType and always have the caller pass in the mangled
+        name, since in the main emit loop, we always have access to the them. Also, inline the
+        the recursive calls to emitNamedTypeDefinition for 'parent' types to avoid unnecessary
+        extra switch over the kind getting the parent, and avoid it entirely for TypeReference
+        which never has a parent.
+        
+        (WebCore::WHLSL::Metal::TypeNamer::emitNamedTypeDefinition):
+        Switches to now passing in the neighbors, since they are always available in the main 
+        emit loop. Also move to a switch statement rather than ifs for consistency. 
+        
+        (WebCore::WHLSL::Metal::TypeNamer::emitMetalTypeDefinitions):
+        Pass keys and values into the emit functions to avoid double lookups.
+
+        (WebCore::WHLSL::Metal::TypeNamer::mangledNameForType):
+        Update to hash lookup.
+
+        * Modules/webgpu/WHLSL/WHLSLSynthesizeConstructors.cpp:
+        Take advantage of default HashTraits and DefaultHash for UnnamedTypeKey.
+
 2019-08-26  Peng Liu  <peng.liu6@apple.com>
 
         REGRESSION (18E140): “return streaming movie to real time” suggesting “resume real time streaming”
index 3dbbb05..3c248b1 100644 (file)
@@ -74,4 +74,13 @@ private:
 
 }
 
+namespace WTF {
+
+template<> struct HashTraits<WebCore::WHLSL::UnnamedTypeKey> : WebCore::WHLSL::UnnamedTypeKey::Traits { };
+template<> struct DefaultHash<WebCore::WHLSL::UnnamedTypeKey> {
+    typedef WebCore::WHLSL::UnnamedTypeKey::Hash Hash;
+};
+
+} // namespace WTF
+
 #endif
index ce3144b..55d253e 100644 (file)
@@ -58,118 +58,6 @@ namespace WHLSL {
 
 namespace Metal {
 
-// FIXME: Look into replacing BaseTypeNameNode with a simple struct { RefPtr<UnnamedType> parent; MangledTypeName; } that UnnamedTypeKeys map to.
-class BaseTypeNameNode {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    BaseTypeNameNode(BaseTypeNameNode* parent, MangledTypeName&& mangledName, AST::UnnamedType::Kind kind)
-        : m_parent(parent)
-        , m_mangledName(mangledName)
-        , m_kind(kind)
-    {
-    }
-    virtual ~BaseTypeNameNode() = default;
-    
-    AST::UnnamedType::Kind kind() { return m_kind; }
-    bool isReferenceTypeNameNode() const { return m_kind == AST::UnnamedType::Kind::TypeReference; }
-    bool isPointerTypeNameNode() const { return m_kind == AST::UnnamedType::Kind::Pointer; }
-    bool isArrayReferenceTypeNameNode() const { return m_kind == AST::UnnamedType::Kind::ArrayReference; }
-    bool isArrayTypeNameNode() const { return m_kind == AST::UnnamedType::Kind::Array; }
-
-    BaseTypeNameNode* parent() { return m_parent; }
-    MangledTypeName mangledName() const { return m_mangledName; }
-
-private:
-    BaseTypeNameNode* m_parent;
-    MangledTypeName m_mangledName;
-    AST::UnnamedType::Kind m_kind;
-};
-
-class ArrayTypeNameNode final : public BaseTypeNameNode {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    ArrayTypeNameNode(BaseTypeNameNode* parent, MangledTypeName&& mangledName, unsigned numElements)
-        : BaseTypeNameNode(parent, WTFMove(mangledName), AST::UnnamedType::Kind::Array)
-        , m_numElements(numElements)
-    {
-    }
-    virtual ~ArrayTypeNameNode() = default;
-    unsigned numElements() const { return m_numElements; }
-
-private:
-    unsigned m_numElements;
-};
-
-class ArrayReferenceTypeNameNode final : public BaseTypeNameNode {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    ArrayReferenceTypeNameNode(BaseTypeNameNode* parent, MangledTypeName&& mangledName, AST::AddressSpace addressSpace)
-        : BaseTypeNameNode(parent, WTFMove(mangledName), AST::UnnamedType::Kind::ArrayReference)
-        , m_addressSpace(addressSpace)
-    {
-    }
-    virtual ~ArrayReferenceTypeNameNode() = default;
-    AST::AddressSpace addressSpace() const { return m_addressSpace; }
-
-private:
-    AST::AddressSpace m_addressSpace;
-};
-
-class PointerTypeNameNode final : public BaseTypeNameNode {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    PointerTypeNameNode(BaseTypeNameNode* parent, MangledTypeName&& mangledName, AST::AddressSpace addressSpace)
-        : BaseTypeNameNode(parent, WTFMove(mangledName), AST::UnnamedType::Kind::Pointer)
-        , m_addressSpace(addressSpace)
-    {
-    }
-    virtual ~PointerTypeNameNode() = default;
-    AST::AddressSpace addressSpace() const { return m_addressSpace; }
-
-private:
-    AST::AddressSpace m_addressSpace;
-};
-
-class ReferenceTypeNameNode final : public BaseTypeNameNode {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    ReferenceTypeNameNode(BaseTypeNameNode* parent, MangledTypeName&& mangledName, AST::NamedType& namedType)
-        : BaseTypeNameNode(parent, WTFMove(mangledName), AST::UnnamedType::Kind::TypeReference)
-        , m_namedType(namedType)
-    {
-    }
-    virtual ~ReferenceTypeNameNode() = default;
-    AST::NamedType& namedType() { return m_namedType; }
-
-private:
-    AST::NamedType& m_namedType;
-};
-
-}
-
-}
-
-}
-
-#define SPECIALIZE_TYPE_TRAITS_WHLSL_BASE_TYPE_NAMED_NODE(ToValueTypeName, predicate) \
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WHLSL::Metal::ToValueTypeName) \
-    static bool isType(const WebCore::WHLSL::Metal::BaseTypeNameNode& type) { return type.predicate; } \
-SPECIALIZE_TYPE_TRAITS_END()
-
-SPECIALIZE_TYPE_TRAITS_WHLSL_BASE_TYPE_NAMED_NODE(ArrayTypeNameNode, isArrayTypeNameNode())
-
-SPECIALIZE_TYPE_TRAITS_WHLSL_BASE_TYPE_NAMED_NODE(ArrayReferenceTypeNameNode, isArrayReferenceTypeNameNode())
-
-SPECIALIZE_TYPE_TRAITS_WHLSL_BASE_TYPE_NAMED_NODE(PointerTypeNameNode, isPointerTypeNameNode())
-
-SPECIALIZE_TYPE_TRAITS_WHLSL_BASE_TYPE_NAMED_NODE(ReferenceTypeNameNode, isReferenceTypeNameNode())
-
-namespace WebCore {
-
-namespace WHLSL {
-
-namespace Metal {
-
 TypeNamer::TypeNamer(Program& program)
     : m_program(program)
 {
@@ -179,7 +67,7 @@ TypeNamer::~TypeNamer() = default;
 
 void TypeNamer::visit(AST::UnnamedType& unnamedType)
 {
-    insert(unnamedType);
+    generateUniquedTypeName(unnamedType);
 }
 
 void TypeNamer::visit(AST::EnumerationDefinition& enumerationDefinition)
@@ -197,8 +85,7 @@ void TypeNamer::visit(AST::EnumerationDefinition& enumerationDefinition)
     Visitor::visit(enumerationDefinition);
 
     {
-        Vector<std::reference_wrapper<BaseTypeNameNode>> neighbors = { find(enumerationDefinition.type()) };
-        auto addResult = m_dependencyGraph.add(&enumerationDefinition, WTFMove(neighbors));
+        auto addResult = m_dependencyGraph.add(&enumerationDefinition, Vector<std::reference_wrapper<AST::UnnamedType>> { enumerationDefinition.type() });
         ASSERT_UNUSED(addResult, addResult.isNewEntry);
     }
 }
@@ -206,7 +93,7 @@ void TypeNamer::visit(AST::EnumerationDefinition& enumerationDefinition)
 void TypeNamer::visit(AST::NativeTypeDeclaration& nativeTypeDeclaration)
 {
     // Native type declarations already have names, and are already declared in Metal.
-    auto addResult = m_dependencyGraph.add(&nativeTypeDeclaration, Vector<std::reference_wrapper<BaseTypeNameNode>>());
+    auto addResult = m_dependencyGraph.add(&nativeTypeDeclaration, Vector<std::reference_wrapper<AST::UnnamedType>> { });
     ASSERT_UNUSED(addResult, addResult.isNewEntry);
 }
 
@@ -218,11 +105,11 @@ void TypeNamer::visit(AST::StructureDefinition& structureDefinition)
     }
     Visitor::visit(structureDefinition);
     {
-        Vector<std::reference_wrapper<BaseTypeNameNode>> neighbors;
+        Vector<std::reference_wrapper<AST::UnnamedType>> neighbors;
         for (auto& structureElement : structureDefinition.structureElements()) {
             auto addResult = m_structureElementMapping.add(&structureElement, generateNextStructureElementName());
             ASSERT_UNUSED(addResult, addResult.isNewEntry);
-            neighbors.append(find(structureElement.type()));
+            neighbors.append(structureElement.type());
         }
         auto addResult = m_dependencyGraph.add(&structureDefinition, WTFMove(neighbors));
         ASSERT_UNUSED(addResult, addResult.isNewEntry);
@@ -237,15 +124,14 @@ void TypeNamer::visit(AST::TypeDefinition& typeDefinition)
     }
     Visitor::visit(typeDefinition);
     {
-        Vector<std::reference_wrapper<BaseTypeNameNode>> neighbors = { find(typeDefinition.type()) };
-        auto addResult = m_dependencyGraph.add(&typeDefinition, WTFMove(neighbors));
+        auto addResult = m_dependencyGraph.add(&typeDefinition, Vector<std::reference_wrapper<AST::UnnamedType>> { typeDefinition.type() });
         ASSERT_UNUSED(addResult, addResult.isNewEntry);
     }
 }
 
 void TypeNamer::visit(AST::Expression& expression)
 {
-    insert(expression.resolvedType());
+    generateUniquedTypeName(expression.resolvedType());
     Visitor::visit(expression);
 }
 
@@ -260,37 +146,6 @@ String TypeNamer::mangledNameForType(AST::NativeTypeDeclaration& nativeTypeDecla
     return writeNativeType(nativeTypeDeclaration);
 }
 
-BaseTypeNameNode& TypeNamer::find(AST::UnnamedType& unnamedType)
-{
-    auto iterator = m_unnamedTypesUniquingMap.find(unnamedType);
-    ASSERT(iterator != m_unnamedTypesUniquingMap.end());
-    return *iterator->value;
-}
-
-std::unique_ptr<BaseTypeNameNode> TypeNamer::createNameNode(AST::UnnamedType& unnamedType, BaseTypeNameNode* parent)
-{
-    switch (unnamedType.kind()) {
-    case AST::UnnamedType::Kind::TypeReference: {
-        auto& typeReference = downcast<AST::TypeReference>(unnamedType);
-        return makeUnique<ReferenceTypeNameNode>(parent, generateNextTypeName(), typeReference.resolvedType());
-    }
-    case AST::UnnamedType::Kind::Pointer: {
-        auto& pointerType = downcast<AST::PointerType>(unnamedType);
-        return makeUnique<PointerTypeNameNode>(parent, generateNextTypeName(), pointerType.addressSpace());
-    }
-    case AST::UnnamedType::Kind::ArrayReference: {
-        auto& arrayReferenceType = downcast<AST::ArrayReferenceType>(unnamedType);
-        return makeUnique<ArrayReferenceTypeNameNode>(parent, generateNextTypeName(), arrayReferenceType.addressSpace());
-    }
-    case AST::UnnamedType::Kind::Array: {
-        auto& arrayType = downcast<AST::ArrayType>(unnamedType);
-        return makeUnique<ArrayTypeNameNode>(parent, generateNextTypeName(), arrayType.numElements());
-    }
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-}
-
 static AST::UnnamedType* parent(AST::UnnamedType& unnamedType)
 {
     switch (unnamedType.kind()) {
@@ -307,20 +162,15 @@ static AST::UnnamedType* parent(AST::UnnamedType& unnamedType)
     }
 }
 
-BaseTypeNameNode* TypeNamer::insert(AST::UnnamedType& unnamedType)
+void TypeNamer::generateUniquedTypeName(AST::UnnamedType& unnamedType)
 {
-    if (auto* result = m_unnamedTypeMapping.get(&unnamedType))
-        return result;
-
     auto* parentUnnamedType = parent(unnamedType);
-    BaseTypeNameNode* parentNode = parentUnnamedType ? insert(*parentUnnamedType) : nullptr;
+    if (parentUnnamedType)
+        generateUniquedTypeName(*parentUnnamedType);
 
-    auto addResult = m_unnamedTypesUniquingMap.ensure(UnnamedTypeKey { unnamedType }, [&] {
-        return createNameNode(unnamedType, parentNode);
+    m_unnamedTypeMapping.ensure(UnnamedTypeKey { unnamedType }, [&] {
+        return generateNextTypeName();
     });
-
-    m_unnamedTypeMapping.add(&unnamedType, addResult.iterator->value.get());
-    return addResult.iterator->value.get();
 }
 
 class MetalTypeDeclarationWriter final : public Visitor {
@@ -350,94 +200,126 @@ void TypeNamer::emitMetalTypeDeclarations(StringBuilder& stringBuilder)
     metalTypeDeclarationWriter.Visitor::visit(m_program);
 }
 
-void TypeNamer::emitUnnamedTypeDefinition(StringBuilder& stringBuilder, BaseTypeNameNode& baseTypeNameNode, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes)
+void TypeNamer::emitUnnamedTypeDefinition(StringBuilder& stringBuilder, AST::UnnamedType& unnamedType, MangledTypeName mangledName, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<UnnamedTypeKey>& emittedUnnamedTypes)
 {
-    if (emittedUnnamedTypes.contains(&baseTypeNameNode))
+    if (emittedUnnamedTypes.contains(UnnamedTypeKey { unnamedType }))
         return;
 
-    if (baseTypeNameNode.parent())
-        emitUnnamedTypeDefinition(stringBuilder, *baseTypeNameNode.parent(), emittedNamedTypes, emittedUnnamedTypes);
-    
-    switch (baseTypeNameNode.kind()) {
+    switch (unnamedType.kind()) {
     case AST::UnnamedType::Kind::TypeReference: {
-        auto& namedType = downcast<ReferenceTypeNameNode>(baseTypeNameNode).namedType();
-        emitNamedTypeDefinition(stringBuilder, namedType, emittedNamedTypes, emittedUnnamedTypes);
-        stringBuilder.append("typedef ", mangledNameForType(namedType), ' ', baseTypeNameNode.mangledName(), ";\n");
+        auto& typeReference = downcast<AST::TypeReference>(unnamedType);
+
+        auto& parent = typeReference.resolvedType();
+        auto parentMangledName = mangledNameForType(typeReference.resolvedType());
+        auto iterator = m_dependencyGraph.find(&parent);
+        ASSERT(iterator != m_dependencyGraph.end());
+        emitNamedTypeDefinition(stringBuilder, parent, iterator->value, emittedNamedTypes, emittedUnnamedTypes);
+
+        stringBuilder.append("typedef ", parentMangledName, ' ', mangledName, ";\n");
         break;
     }
     case AST::UnnamedType::Kind::Pointer: {
-        auto& pointerType = downcast<PointerTypeNameNode>(baseTypeNameNode);
-        ASSERT(baseTypeNameNode.parent());
-        stringBuilder.append("typedef ", toString(pointerType.addressSpace()), ' ', pointerType.parent()->mangledName(), "* ", pointerType.mangledName(), ";\n");
+        auto& pointerType = downcast<AST::PointerType>(unnamedType);
+
+        auto& parent = pointerType.elementType();
+        auto parentMangledName = mangledNameForType(parent);
+        emitUnnamedTypeDefinition(stringBuilder, parent, parentMangledName, emittedNamedTypes, emittedUnnamedTypes);
+
+        stringBuilder.append("typedef ", toString(pointerType.addressSpace()), ' ', parentMangledName, "* ", mangledName, ";\n");
         break;
     }
     case AST::UnnamedType::Kind::ArrayReference: {
-        auto& arrayReferenceType = downcast<ArrayReferenceTypeNameNode>(baseTypeNameNode);
-        ASSERT(baseTypeNameNode.parent());
+        auto& arrayReferenceType = downcast<AST::ArrayReferenceType>(unnamedType);
+
+        auto& parent = arrayReferenceType.elementType();
+        auto parentMangledName = mangledNameForType(parent);
+        emitUnnamedTypeDefinition(stringBuilder, parent, parentMangledName, emittedNamedTypes, emittedUnnamedTypes);
+
         stringBuilder.append(
-            "struct ", arrayReferenceType.mangledName(), " {\n"
-            "    ", toString(arrayReferenceType.addressSpace()), ' ', arrayReferenceType.parent()->mangledName(), "* pointer;\n"
+            "struct ", mangledName, " {\n"
+            "    ", toString(arrayReferenceType.addressSpace()), ' ', parentMangledName, "* pointer;\n"
             "    uint32_t length;\n"
             "};\n"
         );
         break;
     }
     case AST::UnnamedType::Kind::Array: {
-        auto& arrayType = downcast<ArrayTypeNameNode>(baseTypeNameNode);
-        ASSERT(baseTypeNameNode.parent());
-        stringBuilder.append("typedef array<", arrayType.parent()->mangledName(), ", ", arrayType.numElements(), "> ", arrayType.mangledName(), ";\n");
+        auto& arrayType = downcast<AST::ArrayType>(unnamedType);
+
+        auto& parent = arrayType.type();
+        auto parentMangledName = mangledNameForType(parent);
+        emitUnnamedTypeDefinition(stringBuilder, parent, parentMangledName, emittedNamedTypes, emittedUnnamedTypes);
+
+        stringBuilder.append("typedef array<", parentMangledName, ", ", arrayType.numElements(), "> ", mangledName, ";\n");
         break;
     }
     default:
         RELEASE_ASSERT_NOT_REACHED();
     }
 
-    emittedUnnamedTypes.add(&baseTypeNameNode);
+    emittedUnnamedTypes.add(UnnamedTypeKey { unnamedType });
 }
 
-void TypeNamer::emitNamedTypeDefinition(StringBuilder& stringBuilder, AST::NamedType& namedType, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes)
+void TypeNamer::emitNamedTypeDefinition(StringBuilder& stringBuilder, AST::NamedType& namedType, Vector<std::reference_wrapper<AST::UnnamedType>>& neighbors, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<UnnamedTypeKey>& emittedUnnamedTypes)
 {
     if (emittedNamedTypes.contains(&namedType))
         return;
-    auto iterator = m_dependencyGraph.find(&namedType);
-    ASSERT(iterator != m_dependencyGraph.end());
-    for (auto& baseTypeNameNode : iterator->value)
-        emitUnnamedTypeDefinition(stringBuilder, baseTypeNameNode, emittedNamedTypes, emittedUnnamedTypes);
-    if (is<AST::EnumerationDefinition>(namedType)) {
+
+    for (auto& unnameType : neighbors)
+        emitUnnamedTypeDefinition(stringBuilder, unnameType, mangledNameForType(unnameType), emittedNamedTypes, emittedUnnamedTypes);
+
+    switch (namedType.kind()) {
+    case AST::NamedType::Kind::EnumerationDefinition: {
         auto& enumerationDefinition = downcast<AST::EnumerationDefinition>(namedType);
         auto& baseType = enumerationDefinition.type().unifyNode();
+
         stringBuilder.append("enum class ", mangledNameForType(enumerationDefinition), " : ", mangledNameForType(downcast<AST::NamedType>(baseType)), " {\n");
         for (auto& enumerationMember : enumerationDefinition.enumerationMembers())
             stringBuilder.append("    ", mangledNameForEnumerationMember(enumerationMember), " = ", enumerationMember.get().value(), ",\n");
         stringBuilder.append("};\n");
-    } else if (is<AST::NativeTypeDeclaration>(namedType)) {
+        break;
+    }
+    case AST::NamedType::Kind::NativeTypeDeclaration: {
         // Native types already have definitions. There's nothing to do.
-    } else if (is<AST::StructureDefinition>(namedType)) {
+        break;
+    }
+    case AST::NamedType::Kind::StructureDefinition: {
         auto& structureDefinition = downcast<AST::StructureDefinition>(namedType);
+
         stringBuilder.append("struct ", mangledNameForType(structureDefinition), " {\n");
         for (auto& structureElement : structureDefinition.structureElements())
             stringBuilder.append("    ", mangledNameForType(structureElement.type()), ' ', mangledNameForStructureElement(structureElement), ";\n");
         stringBuilder.append("};\n");
-    } else {
+        break;
+    }
+    case AST::NamedType::Kind::TypeDefinition: {
         auto& typeDefinition = downcast<AST::TypeDefinition>(namedType);
+
         stringBuilder.append("typedef ", mangledNameForType(typeDefinition.type()), ' ', mangledNameForType(typeDefinition), ";\n");
+        break;
+    }
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
     }
+
     emittedNamedTypes.add(&namedType);
 }
 
 void TypeNamer::emitMetalTypeDefinitions(StringBuilder& stringBuilder)
 {
     HashSet<AST::NamedType*> emittedNamedTypes;
-    HashSet<BaseTypeNameNode*> emittedUnnamedTypes;
-    for (auto& namedType : m_dependencyGraph.keys())
-        emitNamedTypeDefinition(stringBuilder, *namedType, emittedNamedTypes, emittedUnnamedTypes);
-    for (auto& node : m_unnamedTypesUniquingMap.values())
-        emitUnnamedTypeDefinition(stringBuilder, *node, emittedNamedTypes, emittedUnnamedTypes);
+    HashSet<UnnamedTypeKey> emittedUnnamedTypes;
+    for (auto& [namedType, neighbors] : m_dependencyGraph)
+        emitNamedTypeDefinition(stringBuilder, *namedType, neighbors, emittedNamedTypes, emittedUnnamedTypes);
+    for (auto& [unnamedTypeKey, mangledName] : m_unnamedTypeMapping)
+        emitUnnamedTypeDefinition(stringBuilder, unnamedTypeKey.unnamedType(), mangledName, emittedNamedTypes, emittedUnnamedTypes);
 }
 
 MangledTypeName TypeNamer::mangledNameForType(AST::UnnamedType& unnamedType)
 {
-    return find(unnamedType).mangledName();
+    auto iterator = m_unnamedTypeMapping.find(UnnamedTypeKey { unnamedType });
+    ASSERT(iterator != m_unnamedTypeMapping.end());
+    return iterator->value;
 }
 
 MangledOrNativeTypeName TypeNamer::mangledNameForType(AST::NamedType& namedType)
@@ -449,7 +331,6 @@ MangledOrNativeTypeName TypeNamer::mangledNameForType(AST::NamedType& namedType)
     return iterator->value;
 }
 
-
 MangledEnumerationMemberName TypeNamer::mangledNameForEnumerationMember(AST::EnumerationMember& enumerationMember)
 {
     auto iterator = m_enumerationMemberMapping.find(&enumerationMember);
index b383cb5..abef123 100644 (file)
@@ -62,7 +62,7 @@ public:
 
     void emitMetalTypes(StringBuilder&);
 
-    // Must be called after calling metalTypes().
+    // Must be called after calling emitMetalTypes().
     String mangledNameForType(AST::NativeTypeDeclaration&);
     MangledTypeName mangledNameForType(AST::UnnamedType&);
     MangledOrNativeTypeName mangledNameForType(AST::NamedType&);
@@ -83,20 +83,17 @@ private:
 
     MangledEnumerationMemberName generateNextEnumerationMemberName() { return { m_enumerationMemberCount++ }; }
 
-    void emitNamedTypeDefinition(StringBuilder&, AST::NamedType&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes);
-    void emitUnnamedTypeDefinition(StringBuilder&, BaseTypeNameNode&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes);
+    void emitNamedTypeDefinition(StringBuilder&, AST::NamedType&, Vector<std::reference_wrapper<AST::UnnamedType>>&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<UnnamedTypeKey>& emittedUnnamedTypes);
+    void emitUnnamedTypeDefinition(StringBuilder&, AST::UnnamedType&, MangledTypeName, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<UnnamedTypeKey>& emittedUnnamedTypes);
     void emitMetalTypeDeclarations(StringBuilder&);
     void emitMetalTypeDefinitions(StringBuilder&);
 
-    std::unique_ptr<BaseTypeNameNode> createNameNode(AST::UnnamedType&, BaseTypeNameNode* parent);
-    BaseTypeNameNode* insert(AST::UnnamedType&);
-    BaseTypeNameNode& find(AST::UnnamedType&);
+    void generateUniquedTypeName(AST::UnnamedType&);
 
     Program& m_program;
-    HashMap<UnnamedTypeKey, std::unique_ptr<BaseTypeNameNode>, UnnamedTypeKey::Hash, UnnamedTypeKey::Traits> m_unnamedTypesUniquingMap;
-    HashMap<AST::UnnamedType*, BaseTypeNameNode*> m_unnamedTypeMapping;
+    HashMap<UnnamedTypeKey, MangledTypeName> m_unnamedTypeMapping;
     HashMap<AST::NamedType*, MangledTypeName> m_namedTypeMapping;
-    HashMap<AST::NamedType*, Vector<std::reference_wrapper<BaseTypeNameNode>>> m_dependencyGraph;
+    HashMap<AST::NamedType*, Vector<std::reference_wrapper<AST::UnnamedType>>> m_dependencyGraph;
     HashMap<AST::EnumerationMember*, MangledEnumerationMemberName> m_enumerationMemberMapping;
     HashMap<AST::StructureElement*, MangledStructureElementName> m_structureElementMapping;
     unsigned m_typeCount { 0 };
index 00d98fb..193e5e9 100644 (file)
@@ -86,7 +86,7 @@ public:
         Visitor::visit(nativeTypeDeclaration);
     }
 
-    HashSet<UnnamedTypeKey, UnnamedTypeKey::Hash, UnnamedTypeKey::Traits> takeUnnamedTypes()
+    HashSet<UnnamedTypeKey> takeUnnamedTypes()
     {
         return WTFMove(m_unnamedTypes);
     }
@@ -107,7 +107,7 @@ private:
         m_namedTypes.append(type);
     }
 
-    HashSet<UnnamedTypeKey, UnnamedTypeKey::Hash, UnnamedTypeKey::Traits> m_unnamedTypes;
+    HashSet<UnnamedTypeKey> m_unnamedTypes;
     Vector<std::reference_wrapper<AST::NamedType>> m_namedTypes;
 };