⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 249209 in webkit


Ignore:
Timestamp:
Aug 28, 2019, 11:11:12 AM (7 years ago)
Author:
weinig@apple.com
Message:

[WHLSL] Inline typedef'd types during Metal code generation to simplify generated code while also making it easier to read
https://bugs.webkit.org/show_bug.cgi?id=201185

Reviewed by Saam Barati.

The current Metal code generation generates many unnecessary typedefs during TypeNamer::emitMetalTypeDefinitions
such as 'typedef float2 type19;' that can be removed by just using resolved type whereever the typedef would have
been used. The only types that actually need to be predefined are the types that declare a new struct or enum, which
means we can stop emitting for AST::TypeReference, AST::Pointer, AST::Array, and AST::TypeDefinition. Instead, the
relevent mangledNameForType constructs the computed name on the fly.

This is a 25% speedup in the metal code generation phase.

  • Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:

(WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
Switch to using auto rather than Mangled*Name when it is obvious and the actual return type
may need to become more complicated (e.g. MangledOrNativeTypeName).

  • Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h:
  • Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:

(WebCore::WHLSL::Metal::TypeNamer::visit):
There is no need to generate typenames for AST::TypeDefinitions if they are never used.

(WebCore::WHLSL::Metal::TypeNamer::generateUniquedTypeName):
The only UnnamedType that needs a generated typename now is AST::ArrayReferenceType, which emits a struct interface.

(WebCore::WHLSL::Metal::TypeNamer::emitUnnamedTypeDefinition):
Stop generating type definitions for AST::TypeReference, AST::Pointer, AST::Array.

(WebCore::WHLSL::Metal::TypeNamer::emitNamedTypeDefinition):
Stop generating type definitions for AST::TypeDefinition.

(WebCore::WHLSL::Metal::TypeNamer::emitMetalTypeDefinitions):
Update for rename from m_unnamedTypeMapping to m_arrayReferenceTypeMapping.

(WebCore::WHLSL::Metal::TypeNamer::mangledNameForType):
Look into the types and generate a concrete type name when necessary. Lazily cache the constructed
names for AST::ArrayType and AST::Pointer.

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r249208 r249209  
     12019-08-28  Sam Weinig  <weinig@apple.com>
     2
     3        [WHLSL] Inline typedef'd types during Metal code generation to simplify generated code while also making it easier to read
     4        https://bugs.webkit.org/show_bug.cgi?id=201185
     5
     6        Reviewed by Saam Barati.
     7
     8        The current Metal code generation generates many unnecessary typedefs during TypeNamer::emitMetalTypeDefinitions
     9        such as 'typedef float2 type19;' that can be removed by just using resolved type whereever the typedef would have
     10        been used. The only types that actually need to be predefined are the types that declare a new struct or enum, which
     11        means we can stop emitting for AST::TypeReference, AST::Pointer, AST::Array, and AST::TypeDefinition. Instead, the
     12        relevent mangledNameForType constructs the computed name on the fly.
     13       
     14        This is a 25% speedup in the metal code generation phase.
     15
     16        * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
     17        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
     18        Switch to using auto rather than Mangled*Name when it is obvious and the actual return type
     19        may need to become more complicated (e.g. MangledOrNativeTypeName).
     20
     21        * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h:
     22        * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
     23        (WebCore::WHLSL::Metal::TypeNamer::visit):
     24        There is no need to generate typenames for AST::TypeDefinitions if they are never used.
     25
     26        (WebCore::WHLSL::Metal::TypeNamer::generateUniquedTypeName):
     27        The only UnnamedType that needs a generated typename now is AST::ArrayReferenceType, which emits a struct interface.
     28
     29        (WebCore::WHLSL::Metal::TypeNamer::emitUnnamedTypeDefinition):
     30        Stop generating type definitions for AST::TypeReference, AST::Pointer, AST::Array.
     31
     32        (WebCore::WHLSL::Metal::TypeNamer::emitNamedTypeDefinition):
     33        Stop generating type definitions for AST::TypeDefinition.
     34
     35        (WebCore::WHLSL::Metal::TypeNamer::emitMetalTypeDefinitions):
     36        Update for rename from m_unnamedTypeMapping to m_arrayReferenceTypeMapping.
     37
     38        (WebCore::WHLSL::Metal::TypeNamer::mangledNameForType):
     39        Look into the types and generate a concrete type name when necessary. Lazily cache the constructed
     40        names for AST::ArrayType and AST::Pointer.
     41
    1422019-08-28  Keith Rollin  <krollin@apple.com>
    243
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp

    r248994 r249209  
    526526{
    527527    auto valueName = generateNextVariableName();
    528     MangledTypeName mangledTypeName = m_typeNamer.mangledNameForType(globalVariableReference.resolvedType());
     528    auto mangledTypeName = m_typeNamer.mangledNameForType(globalVariableReference.resolvedType());
    529529
    530530    checkErrorAndVisit(globalVariableReference.base());
    531531    MangledVariableName structVariable = takeLastValue();
    532532
    533     MangledStructureElementName mangledFieldName = m_typeNamer.mangledNameForStructureElement(globalVariableReference.structField());
     533    auto mangledFieldName = m_typeNamer.mangledNameForStructureElement(globalVariableReference.structField());
    534534
    535535    m_stringBuilder.append(
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp

    r249109 r249209  
    119119void TypeNamer::visit(AST::TypeDefinition& typeDefinition)
    120120{
    121     {
    122         auto addResult = m_namedTypeMapping.add(&typeDefinition, generateNextTypeName());
    123         ASSERT_UNUSED(addResult, addResult.isNewEntry);
    124     }
    125121    Visitor::visit(typeDefinition);
    126122    {
     
    147143}
    148144
    149 static AST::UnnamedType* parent(AST::UnnamedType& unnamedType)
    150 {
    151     switch (unnamedType.kind()) {
    152     case AST::UnnamedType::Kind::TypeReference:
    153         return nullptr;
    154     case AST::UnnamedType::Kind::Pointer:
    155         return &downcast<AST::PointerType>(unnamedType).elementType();
    156     case AST::UnnamedType::Kind::ArrayReference:
    157         return &downcast<AST::ArrayReferenceType>(unnamedType).elementType();
    158     case AST::UnnamedType::Kind::Array:
    159         return &downcast<AST::ArrayType>(unnamedType).type();
    160     default:
    161         RELEASE_ASSERT_NOT_REACHED();
    162     }
    163 }
    164 
    165145void TypeNamer::generateUniquedTypeName(AST::UnnamedType& unnamedType)
    166146{
    167     auto* parentUnnamedType = parent(unnamedType);
    168     if (parentUnnamedType)
    169         generateUniquedTypeName(*parentUnnamedType);
    170 
    171     m_unnamedTypeMapping.ensure(UnnamedTypeKey { unnamedType }, [&] {
    172         return generateNextTypeName();
    173     });
     147    if (is<AST::ArrayReferenceType>(unnamedType)) {
     148        m_arrayReferenceTypeMapping.ensure(UnnamedTypeKey { unnamedType }, [&] {
     149            return generateNextTypeName();
     150        });
     151    }
    174152}
    175153
     
    201179}
    202180
    203 void TypeNamer::emitUnnamedTypeDefinition(StringBuilder& stringBuilder, AST::UnnamedType& unnamedType, MangledTypeName mangledName, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<UnnamedTypeKey>& emittedUnnamedTypes)
     181void TypeNamer::emitUnnamedTypeDefinition(StringBuilder& stringBuilder, AST::UnnamedType& unnamedType, MangledOrNativeTypeName mangledName, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<UnnamedTypeKey>& emittedUnnamedTypes)
    204182{
    205183    if (emittedUnnamedTypes.contains(UnnamedTypeKey { unnamedType }))
     
    208186    switch (unnamedType.kind()) {
    209187    case AST::UnnamedType::Kind::TypeReference: {
    210         auto& typeReference = downcast<AST::TypeReference>(unnamedType);
    211 
    212         auto& parent = typeReference.resolvedType();
    213         auto parentMangledName = mangledNameForType(typeReference.resolvedType());
    214         auto iterator = m_dependencyGraph.find(&parent);
    215         ASSERT(iterator != m_dependencyGraph.end());
    216         emitNamedTypeDefinition(stringBuilder, parent, iterator->value, emittedNamedTypes, emittedUnnamedTypes);
    217 
    218         stringBuilder.append("typedef ", parentMangledName, ' ', mangledName, ";\n");
    219188        break;
    220189    }
    221190    case AST::UnnamedType::Kind::Pointer: {
    222         auto& pointerType = downcast<AST::PointerType>(unnamedType);
    223 
    224         auto& parent = pointerType.elementType();
    225         auto parentMangledName = mangledNameForType(parent);
    226         emitUnnamedTypeDefinition(stringBuilder, parent, parentMangledName, emittedNamedTypes, emittedUnnamedTypes);
    227 
    228         stringBuilder.append("typedef ", toString(pointerType.addressSpace()), ' ', parentMangledName, "* ", mangledName, ";\n");
     191        break;
     192    }
     193    case AST::UnnamedType::Kind::Array: {
    229194        break;
    230195    }
     
    232197        auto& arrayReferenceType = downcast<AST::ArrayReferenceType>(unnamedType);
    233198
    234         auto& parent = arrayReferenceType.elementType();
    235         auto parentMangledName = mangledNameForType(parent);
    236         emitUnnamedTypeDefinition(stringBuilder, parent, parentMangledName, emittedNamedTypes, emittedUnnamedTypes);
     199        auto& elementType = arrayReferenceType.elementType();
     200        auto elementTypeMangledName = mangledNameForType(elementType);
     201        emitUnnamedTypeDefinition(stringBuilder, elementType, elementTypeMangledName, emittedNamedTypes, emittedUnnamedTypes);
    237202
    238203        stringBuilder.append(
    239204            "struct ", mangledName, " {\n"
    240             "    ", toString(arrayReferenceType.addressSpace()), ' ', parentMangledName, "* pointer;\n"
     205            "    ", toString(arrayReferenceType.addressSpace()), ' ', elementTypeMangledName, "* pointer;\n"
    241206            "    uint32_t length;\n"
    242207            "};\n"
     
    244209        break;
    245210    }
    246     case AST::UnnamedType::Kind::Array: {
    247         auto& arrayType = downcast<AST::ArrayType>(unnamedType);
    248 
    249         auto& parent = arrayType.type();
    250         auto parentMangledName = mangledNameForType(parent);
    251         emitUnnamedTypeDefinition(stringBuilder, parent, parentMangledName, emittedNamedTypes, emittedUnnamedTypes);
    252 
    253         stringBuilder.append("typedef array<", parentMangledName, ", ", arrayType.numElements(), "> ", mangledName, ";\n");
    254         break;
    255     }
    256211    default:
    257212        RELEASE_ASSERT_NOT_REACHED();
     
    270225
    271226    switch (namedType.kind()) {
     227    case AST::NamedType::Kind::NativeTypeDeclaration: {
     228        // Native types already have definitions. There's nothing to do.
     229        break;
     230    }
     231    case AST::NamedType::Kind::TypeDefinition: {
     232        // The mangled name of a AST::TypeDefinition looks through to the underlying type. There is nothing to do.
     233        break;
     234    }
    272235    case AST::NamedType::Kind::EnumerationDefinition: {
    273236        auto& enumerationDefinition = downcast<AST::EnumerationDefinition>(namedType);
     
    280243        break;
    281244    }
    282     case AST::NamedType::Kind::NativeTypeDeclaration: {
    283         // Native types already have definitions. There's nothing to do.
    284         break;
    285     }
    286245    case AST::NamedType::Kind::StructureDefinition: {
    287246        auto& structureDefinition = downcast<AST::StructureDefinition>(namedType);
     
    293252        break;
    294253    }
    295     case AST::NamedType::Kind::TypeDefinition: {
    296         auto& typeDefinition = downcast<AST::TypeDefinition>(namedType);
    297 
    298         stringBuilder.append("typedef ", mangledNameForType(typeDefinition.type()), ' ', mangledNameForType(typeDefinition), ";\n");
    299         break;
    300     }
    301254    default:
    302255        RELEASE_ASSERT_NOT_REACHED();
     
    312265    for (auto& [namedType, neighbors] : m_dependencyGraph)
    313266        emitNamedTypeDefinition(stringBuilder, *namedType, neighbors, emittedNamedTypes, emittedUnnamedTypes);
    314     for (auto& [unnamedTypeKey, mangledName] : m_unnamedTypeMapping)
     267    for (auto& [unnamedTypeKey, mangledName] : m_arrayReferenceTypeMapping)
    315268        emitUnnamedTypeDefinition(stringBuilder, unnamedTypeKey.unnamedType(), mangledName, emittedNamedTypes, emittedUnnamedTypes);
    316269}
    317270
    318 MangledTypeName TypeNamer::mangledNameForType(AST::UnnamedType& unnamedType)
    319 {
    320     auto iterator = m_unnamedTypeMapping.find(UnnamedTypeKey { unnamedType });
    321     ASSERT(iterator != m_unnamedTypeMapping.end());
    322     return iterator->value;
     271MangledOrNativeTypeName TypeNamer::mangledNameForType(AST::UnnamedType& unnamedType)
     272{
     273    switch (unnamedType.kind()) {
     274    case AST::UnnamedType::Kind::TypeReference: {
     275        auto& typeReference = downcast<AST::TypeReference>(unnamedType);
     276        return mangledNameForType(typeReference.resolvedType());
     277    }
     278    case AST::UnnamedType::Kind::Pointer: {
     279        auto& pointerType = downcast<AST::PointerType>(unnamedType);
     280        return m_lazyUnnamedTypeCache.ensure(UnnamedTypeKey { unnamedType }, [&] {
     281            return makeString(toString(pointerType.addressSpace()), ' ', mangledNameForType(pointerType.elementType()), '*');
     282        }).iterator->value;
     283    }
     284    case AST::UnnamedType::Kind::Array: {
     285        auto& arrayType = downcast<AST::ArrayType>(unnamedType);
     286        return m_lazyUnnamedTypeCache.ensure(UnnamedTypeKey { unnamedType }, [&] {
     287            return makeString("array<", mangledNameForType(arrayType.type()), ", ", arrayType.numElements(), '>');
     288        }).iterator->value;
     289    }
     290    case AST::UnnamedType::Kind::ArrayReference: {
     291        auto iterator = m_arrayReferenceTypeMapping.find(UnnamedTypeKey { unnamedType });
     292        ASSERT(iterator != m_arrayReferenceTypeMapping.end());
     293        return iterator->value;
     294    }
     295    default:
     296        RELEASE_ASSERT_NOT_REACHED();
     297    }
    323298}
    324299
    325300MangledOrNativeTypeName TypeNamer::mangledNameForType(AST::NamedType& namedType)
    326301{
    327     if (is<AST::NativeTypeDeclaration>(namedType))
     302    switch (namedType.kind()) {
     303    case AST::NamedType::Kind::NativeTypeDeclaration: {
    328304        return mangledNameForType(downcast<AST::NativeTypeDeclaration>(namedType));
    329     auto iterator = m_namedTypeMapping.find(&namedType);
    330     ASSERT(iterator != m_namedTypeMapping.end());
    331     return iterator->value;
     305    }
     306    case AST::NamedType::Kind::TypeDefinition: {
     307        return mangledNameForType(downcast<AST::TypeDefinition>(namedType).type());
     308    }
     309    case AST::NamedType::Kind::EnumerationDefinition:
     310    case AST::NamedType::Kind::StructureDefinition: {
     311        auto iterator = m_namedTypeMapping.find(&namedType);
     312        ASSERT(iterator != m_namedTypeMapping.end());
     313        return iterator->value;
     314    }
     315    default:
     316        RELEASE_ASSERT_NOT_REACHED();
     317    }
    332318}
    333319
  • trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h

    r249109 r249209  
    6565    // Must be called after calling emitMetalTypes().
    6666    String mangledNameForType(AST::NativeTypeDeclaration&);
    67     MangledTypeName mangledNameForType(AST::UnnamedType&);
     67    MangledOrNativeTypeName mangledNameForType(AST::UnnamedType&);
    6868    MangledOrNativeTypeName mangledNameForType(AST::NamedType&);
    6969    MangledEnumerationMemberName mangledNameForEnumerationMember(AST::EnumerationMember&);
     
    8585
    8686    void emitNamedTypeDefinition(StringBuilder&, AST::NamedType&, Vector<std::reference_wrapper<AST::UnnamedType>>&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<UnnamedTypeKey>& emittedUnnamedTypes);
    87     void emitUnnamedTypeDefinition(StringBuilder&, AST::UnnamedType&, MangledTypeName, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<UnnamedTypeKey>& emittedUnnamedTypes);
     87    void emitUnnamedTypeDefinition(StringBuilder&, AST::UnnamedType&, MangledOrNativeTypeName, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<UnnamedTypeKey>& emittedUnnamedTypes);
    8888    void emitMetalTypeDeclarations(StringBuilder&);
    8989    void emitMetalTypeDefinitions(StringBuilder&);
     
    9292
    9393    Program& m_program;
    94     HashMap<UnnamedTypeKey, MangledTypeName> m_unnamedTypeMapping;
     94    HashMap<UnnamedTypeKey, MangledTypeName> m_arrayReferenceTypeMapping;
     95    HashMap<UnnamedTypeKey, String> m_lazyUnnamedTypeCache;
    9596    HashMap<AST::NamedType*, MangledTypeName> m_namedTypeMapping;
    9697    HashMap<AST::NamedType*, Vector<std::reference_wrapper<AST::UnnamedType>>> m_dependencyGraph;
Note: See TracChangeset for help on using the changeset viewer.