Mangled WHLSL names don't need to allocate Strings
authorweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Aug 2019 03:26:33 +0000 (03:26 +0000)
committerweinig@apple.com <weinig@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Aug 2019 03:26:33 +0000 (03:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200429

Reviewed by Saam Barati.

To avoid allocating strings for each mangled name used to transform WHLSL to Metal, which we'd
like to avoid since it is both unnecessarily expensive in time and space, we can instead just
store the unique integer identifier that was being used to construct the String.

Since the existing mangled names were all of the form "prefix" + unsigned integer value (where
prefix could be "type", "enumerationMember", "structureElement", "variable" or "function") we
strongly type the integer by storing it in a struct (MangledVariableName, MangledTypeName, etc.)
When the full name is actually needed, StringTypeAdapter's specialized for the structs are
used to write directly into the preallocated buffers of StringBuilders or makeString().

* Modules/webgpu/WHLSL/Metal/WHLSLMangledNames.h: Added.
(WebCore::WHLSL::Metal::MangledVariableName):
(WebCore::WHLSL::Metal::MangledTypeName):
(WebCore::WHLSL::Metal::MangledStructureElementName):
(WebCore::WHLSL::Metal::MangledEnumerationMemberName):
(WebCore::WHLSL::Metal::MangledFunctionName):
Adds structs for each type of mangled name and StringTypeAdapter specializations for
each to allow their use in StringBuilder.flexibleAppend() or makeString().

Additionally, a Variant, MangledOrNativeTypeName, of MangledTypeName and String is
declared to allow for the few cases where a native type (e.g. float4) is needed. The
StringTypeAdapter for MangledOrNativeTypeName could be generalized for any Variant
in the future, but I left it non-general for now, as it is non-obvious if one would
want to store Variant<Types...>, and have each member function construct a temporary
StringTypeAdapter, or store a Variant<StringTypeAdapter<Types>...> and perform conversion
in the construction.

* Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp:
(WebCore::WHLSL::Metal::EntryPointScaffolding::EntryPointScaffolding):
(WebCore::WHLSL::Metal::internalTypeForSemantic):
(WebCore::WHLSL::Metal::EntryPointScaffolding::builtInsSignature):
(WebCore::WHLSL::Metal::EntryPointScaffolding::mangledInputPath):
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::VertexEntryPointScaffolding):
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::signature):
(WebCore::WHLSL::Metal::VertexEntryPointScaffolding::pack):
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::FragmentEntryPointScaffolding):
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::signature):
(WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::pack):
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::ComputeEntryPointScaffolding):
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::signature):
(WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::pack):
* Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h:
(WebCore::WHLSL::Metal::EntryPointScaffolding::parameterVariables):
* Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
(WebCore::WHLSL::Metal::FunctionDeclarationWriter::FunctionDeclarationWriter):
(WebCore::WHLSL::Metal::FunctionDeclarationWriter::visit):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::FunctionDefinitionWriter):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::generateNextVariableName):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendRightValueWithNullability):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendRightValue):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendLeftValue):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastValue):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastValueAndNullability):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastLeftValue):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitLoop):
(WebCore::WHLSL::Metal::RenderFunctionDefinitionWriter::RenderFunctionDefinitionWriter):
(WebCore::WHLSL::Metal::RenderFunctionDefinitionWriter::createEntryPointScaffolding):
(WebCore::WHLSL::Metal::ComputeFunctionDefinitionWriter::ComputeFunctionDefinitionWriter):
(WebCore::WHLSL::Metal::ComputeFunctionDefinitionWriter::createEntryPointScaffolding):
(WebCore::WHLSL::Metal::sharedMetalFunctions):
* Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.h:
* Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.h:
* Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
(WebCore::WHLSL::Metal::writeNativeFunction):
* Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.h:
* Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
(WebCore::WHLSL::Metal::BaseTypeNameNode::BaseTypeNameNode):
(WebCore::WHLSL::Metal::BaseTypeNameNode::mangledName const):
(WebCore::WHLSL::Metal::ArrayTypeNameNode::ArrayTypeNameNode):
(WebCore::WHLSL::Metal::ArrayReferenceTypeNameNode::ArrayReferenceTypeNameNode):
(WebCore::WHLSL::Metal::PointerTypeNameNode::PointerTypeNameNode):
(WebCore::WHLSL::Metal::ReferenceTypeNameNode::ReferenceTypeNameNode):
(WebCore::WHLSL::Metal::MetalTypeDeclarationWriter::MetalTypeDeclarationWriter):
(WebCore::WHLSL::Metal::TypeNamer::metalTypeDeclarations):
(WebCore::WHLSL::Metal::TypeNamer::emitNamedTypeDefinition):
(WebCore::WHLSL::Metal::TypeNamer::mangledNameForType):
(WebCore::WHLSL::Metal::TypeNamer::mangledNameForEnumerationMember):
(WebCore::WHLSL::Metal::TypeNamer::mangledNameForStructureElement):
* Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h:
(WebCore::WHLSL::Metal::TypeNamer::generateNextTypeName):
(WebCore::WHLSL::Metal::TypeNamer::generateNextStructureElementName):
(WebCore::WHLSL::Metal::TypeNamer::generateNextEnumerationMemberName):
* Modules/webgpu/WHLSL/WHLSLPrepare.h:
Replace uses of String with the appropriate mangled name type.

* WebCore.xcodeproj/project.pbxproj:
Add WHLSLMangledNames.h

* platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm:
(WebCore::trySetFunctions):
* platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm:
(WebCore::trySetFunctions):
Convert the mangled names to Strings for passing to Metal API. NOTE: We could avoid having the
toString() member function on MangledFunctionName if we allowed makeString() to take a single
argument.

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

15 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.h
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMangledNames.h [new file with mode: 0644]
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.h
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.h
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm
Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm

index 5f96e12..3920ea9 100644 (file)
@@ -1,3 +1,107 @@
+2019-08-04  Sam Weinig  <weinig@apple.com>
+
+        Mangled WHLSL names don't need to allocate Strings
+        https://bugs.webkit.org/show_bug.cgi?id=200429
+
+        Reviewed by Saam Barati.
+
+        To avoid allocating strings for each mangled name used to transform WHLSL to Metal, which we'd
+        like to avoid since it is both unnecessarily expensive in time and space, we can instead just
+        store the unique integer identifier that was being used to construct the String. 
+        
+        Since the existing mangled names were all of the form "prefix" + unsigned integer value (where 
+        prefix could be "type", "enumerationMember", "structureElement", "variable" or "function") we
+        strongly type the integer by storing it in a struct (MangledVariableName, MangledTypeName, etc.)
+        When the full name is actually needed, StringTypeAdapter's specialized for the structs are
+        used to write directly into the preallocated buffers of StringBuilders or makeString().
+
+        * Modules/webgpu/WHLSL/Metal/WHLSLMangledNames.h: Added.
+        (WebCore::WHLSL::Metal::MangledVariableName):
+        (WebCore::WHLSL::Metal::MangledTypeName):
+        (WebCore::WHLSL::Metal::MangledStructureElementName):
+        (WebCore::WHLSL::Metal::MangledEnumerationMemberName):
+        (WebCore::WHLSL::Metal::MangledFunctionName):
+        Adds structs for each type of mangled name and StringTypeAdapter specializations for
+        each to allow their use in StringBuilder.flexibleAppend() or makeString(). 
+        
+        Additionally, a Variant, MangledOrNativeTypeName, of MangledTypeName and String is 
+        declared to allow for the few cases where a native type (e.g. float4) is needed. The
+        StringTypeAdapter for MangledOrNativeTypeName could be generalized for any Variant
+        in the future, but I left it non-general for now, as it is non-obvious if one would
+        want to store Variant<Types...>, and have each member function construct a temporary
+        StringTypeAdapter, or store a Variant<StringTypeAdapter<Types>...> and perform conversion
+        in the construction.
+
+        * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp:
+        (WebCore::WHLSL::Metal::EntryPointScaffolding::EntryPointScaffolding):
+        (WebCore::WHLSL::Metal::internalTypeForSemantic):
+        (WebCore::WHLSL::Metal::EntryPointScaffolding::builtInsSignature):
+        (WebCore::WHLSL::Metal::EntryPointScaffolding::mangledInputPath):
+        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::VertexEntryPointScaffolding):
+        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::signature):
+        (WebCore::WHLSL::Metal::VertexEntryPointScaffolding::pack):
+        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::FragmentEntryPointScaffolding):
+        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::signature):
+        (WebCore::WHLSL::Metal::FragmentEntryPointScaffolding::pack):
+        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::ComputeEntryPointScaffolding):
+        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::signature):
+        (WebCore::WHLSL::Metal::ComputeEntryPointScaffolding::pack):
+        * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h:
+        (WebCore::WHLSL::Metal::EntryPointScaffolding::parameterVariables):
+        * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
+        (WebCore::WHLSL::Metal::FunctionDeclarationWriter::FunctionDeclarationWriter):
+        (WebCore::WHLSL::Metal::FunctionDeclarationWriter::visit):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::FunctionDefinitionWriter):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::generateNextVariableName):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendRightValueWithNullability):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendRightValue):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::appendLeftValue):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastValue):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastValueAndNullability):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::takeLastLeftValue):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::emitLoop):
+        (WebCore::WHLSL::Metal::RenderFunctionDefinitionWriter::RenderFunctionDefinitionWriter):
+        (WebCore::WHLSL::Metal::RenderFunctionDefinitionWriter::createEntryPointScaffolding):
+        (WebCore::WHLSL::Metal::ComputeFunctionDefinitionWriter::ComputeFunctionDefinitionWriter):
+        (WebCore::WHLSL::Metal::ComputeFunctionDefinitionWriter::createEntryPointScaffolding):
+        (WebCore::WHLSL::Metal::sharedMetalFunctions):
+        * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.h:
+        * Modules/webgpu/WHLSL/Metal/WHLSLMetalCodeGenerator.h:
+        * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
+        (WebCore::WHLSL::Metal::writeNativeFunction):
+        * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.h:
+        * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
+        (WebCore::WHLSL::Metal::BaseTypeNameNode::BaseTypeNameNode):
+        (WebCore::WHLSL::Metal::BaseTypeNameNode::mangledName const):
+        (WebCore::WHLSL::Metal::ArrayTypeNameNode::ArrayTypeNameNode):
+        (WebCore::WHLSL::Metal::ArrayReferenceTypeNameNode::ArrayReferenceTypeNameNode):
+        (WebCore::WHLSL::Metal::PointerTypeNameNode::PointerTypeNameNode):
+        (WebCore::WHLSL::Metal::ReferenceTypeNameNode::ReferenceTypeNameNode):
+        (WebCore::WHLSL::Metal::MetalTypeDeclarationWriter::MetalTypeDeclarationWriter):
+        (WebCore::WHLSL::Metal::TypeNamer::metalTypeDeclarations):
+        (WebCore::WHLSL::Metal::TypeNamer::emitNamedTypeDefinition):
+        (WebCore::WHLSL::Metal::TypeNamer::mangledNameForType):
+        (WebCore::WHLSL::Metal::TypeNamer::mangledNameForEnumerationMember):
+        (WebCore::WHLSL::Metal::TypeNamer::mangledNameForStructureElement):
+        * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h:
+        (WebCore::WHLSL::Metal::TypeNamer::generateNextTypeName):
+        (WebCore::WHLSL::Metal::TypeNamer::generateNextStructureElementName):
+        (WebCore::WHLSL::Metal::TypeNamer::generateNextEnumerationMemberName):
+        * Modules/webgpu/WHLSL/WHLSLPrepare.h:
+        Replace uses of String with the appropriate mangled name type.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        Add WHLSLMangledNames.h
+
+        * platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm:
+        (WebCore::trySetFunctions):
+        * platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm:
+        (WebCore::trySetFunctions):
+        Convert the mangled names to Strings for passing to Metal API. NOTE: We could avoid having the
+        toString() member function on MangledFunctionName if we allowed makeString() to take a single
+        argument.
+
 2019-08-04  Chris Dumez  <cdumez@apple.com>
 
         Ping loads should not prevent page caching
index fc337f2..a142ec9 100644 (file)
@@ -91,7 +91,7 @@ static String attributeForSemantic(AST::Semantic& semantic)
     return makeString("[[user(user", stageInOutSemantic.index(), ")]]");
 }
 
-EntryPointScaffolding::EntryPointScaffolding(AST::FunctionDefinition& functionDefinition, Intrinsics& intrinsics, TypeNamer& typeNamer, EntryPointItems& entryPointItems, HashMap<Binding*, size_t>& resourceMap, Layout& layout, std::function<String()>&& generateNextVariableName)
+EntryPointScaffolding::EntryPointScaffolding(AST::FunctionDefinition& functionDefinition, Intrinsics& intrinsics, TypeNamer& typeNamer, EntryPointItems& entryPointItems, HashMap<Binding*, size_t>& resourceMap, Layout& layout, std::function<MangledVariableName()>&& generateNextVariableName)
     : m_functionDefinition(functionDefinition)
     , m_intrinsics(intrinsics)
     , m_typeNamer(typeNamer)
@@ -192,38 +192,38 @@ Optional<String> EntryPointScaffolding::resourceSignature()
     return stringBuilder.toString();
 }
 
-static String internalTypeForSemantic(const AST::BuiltInSemantic& builtInSemantic)
+static StringView internalTypeForSemantic(const AST::BuiltInSemantic& builtInSemantic)
 {
     switch (builtInSemantic.variable()) {
     case AST::BuiltInSemantic::Variable::SVInstanceID:
-        return "uint"_str;
+        return "uint";
     case AST::BuiltInSemantic::Variable::SVVertexID:
-        return "uint"_str;
+        return "uint";
     case AST::BuiltInSemantic::Variable::PSize:
-        return "float"_str;
+        return "float";
     case AST::BuiltInSemantic::Variable::SVPosition:
-        return "float4"_str;
+        return "float4";
     case AST::BuiltInSemantic::Variable::SVIsFrontFace:
-        return "bool"_str;
+        return "bool";
     case AST::BuiltInSemantic::Variable::SVSampleIndex:
-        return "uint"_str;
+        return "uint";
     case AST::BuiltInSemantic::Variable::SVInnerCoverage:
-        return "uint"_str;
+        return "uint";
     case AST::BuiltInSemantic::Variable::SVTarget:
-        return String();
+        return { };
     case AST::BuiltInSemantic::Variable::SVDepth:
-        return "float"_str;
+        return "float";
     case AST::BuiltInSemantic::Variable::SVCoverage:
-        return "uint"_str;
+        return "uint";
     case AST::BuiltInSemantic::Variable::SVDispatchThreadID:
-        return "uint3"_str;
+        return "uint3";
     case AST::BuiltInSemantic::Variable::SVGroupID:
-        return "uint3"_str;
+        return "uint3";
     case AST::BuiltInSemantic::Variable::SVGroupIndex:
-        return "uint"_str;
+        return "uint";
     default:
         ASSERT(builtInSemantic.variable() == AST::BuiltInSemantic::Variable::SVGroupThreadID);
-        return "uint3"_str;
+        return "uint3";
     }
 }
 
@@ -240,10 +240,11 @@ Optional<String> EntryPointScaffolding::builtInsSignature()
         auto& item = m_entryPointItems.inputs[namedBuiltIn.indexInEntryPointItems];
         auto& builtInSemantic = WTF::get<AST::BuiltInSemantic>(*item.semantic);
         auto internalType = internalTypeForSemantic(builtInSemantic);
-        if (internalType.isNull())
-            internalType = m_typeNamer.mangledNameForType(*item.unnamedType);
-        auto variableName = namedBuiltIn.variableName;
-        stringBuilder.flexibleAppend(internalType, ' ', variableName, ' ', attributeForSemantic(builtInSemantic));
+        if (!internalType.isNull())
+            stringBuilder.flexibleAppend(internalType);
+        else
+            stringBuilder.flexibleAppend(m_typeNamer.mangledNameForType(*item.unnamedType));
+        stringBuilder.flexibleAppend(' ', namedBuiltIn.variableName, ' ', attributeForSemantic(builtInSemantic));
     }
     return stringBuilder.toString();
 }
@@ -256,7 +257,7 @@ String EntryPointScaffolding::mangledInputPath(Vector<String>& path)
     AST::StructureDefinition* structureDefinition = nullptr;
     for (size_t i = 0; i < m_functionDefinition.parameters().size(); ++i) {
         if (m_functionDefinition.parameters()[i]->name() == path[0]) {
-            stringBuilder.append(m_parameterVariables[i]);
+            stringBuilder.flexibleAppend(m_parameterVariables[i]);
             auto& unifyNode = m_functionDefinition.parameters()[i]->type()->unifyNode();
             if (is<AST::NamedType>(unifyNode)) {
                 auto& namedType = downcast<AST::NamedType>(unifyNode);
@@ -356,7 +357,7 @@ String EntryPointScaffolding::unpackResourcesAndNamedBuiltIns()
     return stringBuilder.toString();
 }
 
-VertexEntryPointScaffolding::VertexEntryPointScaffolding(AST::FunctionDefinition& functionDefinition, Intrinsics& intrinsics, TypeNamer& typeNamer, EntryPointItems& entryPointItems, HashMap<Binding*, size_t>& resourceMap, Layout& layout, std::function<String()>&& generateNextVariableName, HashMap<VertexAttribute*, size_t>& matchedVertexAttributes)
+VertexEntryPointScaffolding::VertexEntryPointScaffolding(AST::FunctionDefinition& functionDefinition, Intrinsics& intrinsics, TypeNamer& typeNamer, EntryPointItems& entryPointItems, HashMap<Binding*, size_t>& resourceMap, Layout& layout, std::function<MangledVariableName()>&& generateNextVariableName, HashMap<VertexAttribute*, size_t>& matchedVertexAttributes)
     : EntryPointScaffolding(functionDefinition, intrinsics, typeNamer, entryPointItems, resourceMap, layout, WTFMove(generateNextVariableName))
     , m_matchedVertexAttributes(matchedVertexAttributes)
     , m_stageInStructName(typeNamer.generateNextTypeName())
@@ -377,9 +378,12 @@ VertexEntryPointScaffolding::VertexEntryPointScaffolding(AST::FunctionDefinition
         auto& outputItem = m_entryPointItems.outputs[i];
         NamedOutput namedOutput;
         namedOutput.elementName = m_typeNamer.generateNextStructureElementName();
+        StringView internalType;
         if (WTF::holds_alternative<AST::BuiltInSemantic>(*outputItem.semantic))
-            namedOutput.internalTypeName = internalTypeForSemantic(WTF::get<AST::BuiltInSemantic>(*outputItem.semantic));
-        if (namedOutput.internalTypeName.isNull())
+            internalType = internalTypeForSemantic(WTF::get<AST::BuiltInSemantic>(*outputItem.semantic));
+        if (!internalType.isNull())
+            namedOutput.internalTypeName = internalType.toString();
+        else
             namedOutput.internalTypeName = m_typeNamer.mangledNameForType(*outputItem.unnamedType);
         m_namedOutputs.uncheckedAppend(WTFMove(namedOutput));
     }
@@ -415,7 +419,7 @@ String VertexEntryPointScaffolding::helperTypes()
     return stringBuilder.toString();
 }
 
-String VertexEntryPointScaffolding::signature(String& functionName)
+String VertexEntryPointScaffolding::signature(MangledFunctionName functionName)
 {
     StringBuilder stringBuilder;
 
@@ -444,7 +448,7 @@ String VertexEntryPointScaffolding::unpack()
     return stringBuilder.toString();
 }
 
-String VertexEntryPointScaffolding::pack(const String& inputVariableName, const String& outputVariableName)
+String VertexEntryPointScaffolding::pack(MangledVariableName inputVariableName, MangledVariableName outputVariableName)
 {
     StringBuilder stringBuilder;
 
@@ -463,7 +467,7 @@ String VertexEntryPointScaffolding::pack(const String& inputVariableName, const
     return stringBuilder.toString();
 }
 
-FragmentEntryPointScaffolding::FragmentEntryPointScaffolding(AST::FunctionDefinition& functionDefinition, Intrinsics& intrinsics, TypeNamer& typeNamer, EntryPointItems& entryPointItems, HashMap<Binding*, size_t>& resourceMap, Layout& layout, std::function<String()>&& generateNextVariableName, HashMap<AttachmentDescriptor*, size_t>&)
+FragmentEntryPointScaffolding::FragmentEntryPointScaffolding(AST::FunctionDefinition& functionDefinition, Intrinsics& intrinsics, TypeNamer& typeNamer, EntryPointItems& entryPointItems, HashMap<Binding*, size_t>& resourceMap, Layout& layout, std::function<MangledVariableName()>&& generateNextVariableName, HashMap<AttachmentDescriptor*, size_t>&)
     : EntryPointScaffolding(functionDefinition, intrinsics, typeNamer, entryPointItems, resourceMap, layout, WTFMove(generateNextVariableName))
     , m_stageInStructName(typeNamer.generateNextTypeName())
     , m_returnStructName(typeNamer.generateNextTypeName())
@@ -486,9 +490,12 @@ FragmentEntryPointScaffolding::FragmentEntryPointScaffolding(AST::FunctionDefini
         auto& outputItem = m_entryPointItems.outputs[i];
         NamedOutput namedOutput;
         namedOutput.elementName = m_typeNamer.generateNextStructureElementName();
+        StringView internalType;
         if (WTF::holds_alternative<AST::BuiltInSemantic>(*outputItem.semantic))
-            namedOutput.internalTypeName = internalTypeForSemantic(WTF::get<AST::BuiltInSemantic>(*outputItem.semantic));
-        if (namedOutput.internalTypeName.isNull())
+            internalType = internalTypeForSemantic(WTF::get<AST::BuiltInSemantic>(*outputItem.semantic));
+        if (!internalType.isNull())
+            namedOutput.internalTypeName = internalType.toString();
+        else
             namedOutput.internalTypeName = m_typeNamer.mangledNameForType(*outputItem.unnamedType);
         m_namedOutputs.uncheckedAppend(WTFMove(namedOutput));
     }
@@ -524,7 +531,7 @@ String FragmentEntryPointScaffolding::helperTypes()
     return stringBuilder.toString();
 }
 
-String FragmentEntryPointScaffolding::signature(String& functionName)
+String FragmentEntryPointScaffolding::signature(MangledFunctionName functionName)
 {
     StringBuilder stringBuilder;
 
@@ -553,7 +560,7 @@ String FragmentEntryPointScaffolding::unpack()
     return stringBuilder.toString();
 }
 
-String FragmentEntryPointScaffolding::pack(const String& inputVariableName, const String& outputVariableName)
+String FragmentEntryPointScaffolding::pack(MangledVariableName inputVariableName, MangledVariableName outputVariableName)
 {
     StringBuilder stringBuilder;
 
@@ -572,7 +579,7 @@ String FragmentEntryPointScaffolding::pack(const String& inputVariableName, cons
     return stringBuilder.toString();
 }
 
-ComputeEntryPointScaffolding::ComputeEntryPointScaffolding(AST::FunctionDefinition& functionDefinition, Intrinsics& intrinsics, TypeNamer& typeNamer, EntryPointItems& entryPointItems, HashMap<Binding*, size_t>& resourceMap, Layout& layout, std::function<String()>&& generateNextVariableName)
+ComputeEntryPointScaffolding::ComputeEntryPointScaffolding(AST::FunctionDefinition& functionDefinition, Intrinsics& intrinsics, TypeNamer& typeNamer, EntryPointItems& entryPointItems, HashMap<Binding*, size_t>& resourceMap, Layout& layout, std::function<MangledVariableName()>&& generateNextVariableName)
     : EntryPointScaffolding(functionDefinition, intrinsics, typeNamer, entryPointItems, resourceMap, layout, WTFMove(generateNextVariableName))
 {
 }
@@ -582,7 +589,7 @@ String ComputeEntryPointScaffolding::helperTypes()
     return resourceHelperTypes();
 }
 
-String ComputeEntryPointScaffolding::signature(String& functionName)
+String ComputeEntryPointScaffolding::signature(MangledFunctionName functionName)
 {
     StringBuilder stringBuilder;
 
@@ -607,7 +614,7 @@ String ComputeEntryPointScaffolding::unpack()
     return unpackResourcesAndNamedBuiltIns();
 }
 
-String ComputeEntryPointScaffolding::pack(const String&, const String&)
+String ComputeEntryPointScaffolding::pack(MangledVariableName, MangledVariableName)
 {
     ASSERT_NOT_REACHED();
     return String();
index 0f5cea5..8f2d4d9 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLMangledNames.h"
 #include "WHLSLPipelineDescriptor.h"
 #include <wtf/HashMap.h>
 #include <wtf/text/WTFString.h>
@@ -50,17 +51,18 @@ class TypeNamer;
 
 class EntryPointScaffolding {
 public:
-    EntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<String()>&& generateNextVariableName);
     virtual ~EntryPointScaffolding() = default;
 
     virtual String helperTypes() = 0;
-    virtual String signature(String& functionName) = 0;
+    virtual String signature(MangledFunctionName) = 0;
     virtual String unpack() = 0;
-    virtual String pack(const String& existingVariableName, const String& variableName) = 0;
+    virtual String pack(MangledVariableName existingVariableName, MangledVariableName) = 0;
 
-    Vector<String>& parameterVariables() { return m_parameterVariables; }
+    Vector<MangledVariableName>& parameterVariables() { return m_parameterVariables; }
 
 protected:
+    EntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<MangledVariableName()>&& generateNextVariableName);
+
     String resourceHelperTypes();
     Optional<String> resourceSignature();
     Optional<String> builtInsSignature();
@@ -75,21 +77,21 @@ protected:
     EntryPointItems& m_entryPointItems;
     HashMap<Binding*, size_t>& m_resourceMap;
     Layout& m_layout;
-    std::function<String()> m_generateNextVariableName;
+    std::function<MangledVariableName()> m_generateNextVariableName;
 
     struct LengthInformation {
-        String elementName;
-        String temporaryName;
+        MangledStructureElementName elementName;
+        MangledVariableName temporaryName;
         unsigned index;
     };
     struct NamedBinding {
-        String elementName;
+        MangledStructureElementName elementName;
         unsigned index;
         Optional<LengthInformation> lengthInformation;
     };
     struct NamedBindGroup {
-        String structName;
-        String variableName;
+        MangledTypeName structName;
+        MangledVariableName variableName;
         Vector<NamedBinding> namedBindings;
         unsigned argumentBufferIndex;
     };
@@ -97,83 +99,81 @@ protected:
 
     struct NamedBuiltIn {
         size_t indexInEntryPointItems;
-        String variableName;
+        MangledVariableName variableName;
     };
     Vector<NamedBuiltIn> m_namedBuiltIns;
 
-    Vector<String> m_parameterVariables;
+    Vector<MangledVariableName> m_parameterVariables;
 };
 
 class VertexEntryPointScaffolding : public EntryPointScaffolding {
 public:
-    VertexEntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<String()>&& generateNextVariableName, HashMap<VertexAttribute*, size_t>& matchedVertexAttributes);
+    VertexEntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<MangledVariableName()>&& generateNextVariableName, HashMap<VertexAttribute*, size_t>& matchedVertexAttributes);
     virtual ~VertexEntryPointScaffolding() = default;
 
     String helperTypes() override;
-    String signature(String& functionName) override;
+    String signature(MangledFunctionName) override;
     String unpack() override;
-    String pack(const String& existingVariableName, const String& variableName) override;
+    String pack(MangledVariableName existingVariableName, MangledVariableName) override;
 
 private:
     HashMap<VertexAttribute*, size_t>& m_matchedVertexAttributes;
-    String m_stageInStructName;
-    String m_returnStructName;
-    String m_stageInParameterName;
+    MangledTypeName m_stageInStructName;
+    MangledTypeName m_returnStructName;
+    MangledVariableName m_stageInParameterName;
 
     struct NamedStageIn {
         size_t indexInEntryPointItems;
-        String elementName;
+        MangledStructureElementName elementName;
         unsigned attributeIndex;
     };
     Vector<NamedStageIn> m_namedStageIns;
 
     struct NamedOutput {
-        String elementName;
-        String internalTypeName;
+        MangledStructureElementName elementName;
+        MangledOrNativeTypeName internalTypeName;
     };
     Vector<NamedOutput> m_namedOutputs;
 };
 
 class FragmentEntryPointScaffolding : public EntryPointScaffolding {
 public:
-    FragmentEntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<String()>&& generateNextVariableName, HashMap<AttachmentDescriptor*, size_t>& matchedColorAttachments);
+    FragmentEntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<MangledVariableName()>&& generateNextVariableName, HashMap<AttachmentDescriptor*, size_t>& matchedColorAttachments);
     virtual ~FragmentEntryPointScaffolding() = default;
 
     String helperTypes() override;
-    String signature(String& functionName) override;
+    String signature(MangledFunctionName) override;
     String unpack() override;
-    String pack(const String& existingVariableName, const String& variableName) override;
+    String pack(MangledVariableName existingVariableName, MangledVariableName) override;
 
 private:
-    String m_stageInStructName;
-    String m_returnStructName;
-    String m_stageInParameterName;
+    MangledTypeName m_stageInStructName;
+    MangledTypeName m_returnStructName;
+    MangledVariableName m_stageInParameterName;
 
     struct NamedStageIn {
         size_t indexInEntryPointItems;
-        String elementName;
+        MangledStructureElementName elementName;
         unsigned attributeIndex;
     };
     Vector<NamedStageIn> m_namedStageIns;
 
     struct NamedOutput {
-        String elementName;
-        String internalTypeName;
+        MangledStructureElementName elementName;
+        MangledOrNativeTypeName internalTypeName;
     };
     Vector<NamedOutput> m_namedOutputs;
 };
 
 class ComputeEntryPointScaffolding : public EntryPointScaffolding {
 public:
-    ComputeEntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<String()>&& generateNextVariableName);
+    ComputeEntryPointScaffolding(AST::FunctionDefinition&, Intrinsics&, TypeNamer&, EntryPointItems&, HashMap<Binding*, size_t>& resourceMap, Layout&, std::function<MangledVariableName()>&& generateNextVariableName);
     virtual ~ComputeEntryPointScaffolding() = default;
 
     String helperTypes() override;
-    String signature(String& functionName) override;
+    String signature(MangledFunctionName) override;
     String unpack() override;
-    String pack(const String& existingVariableName, const String& variableName) override;
-
-private:
+    String pack(MangledVariableName existingVariableName, MangledVariableName) override;
 };
 
 }
index 9732bfc..05eb555 100644 (file)
@@ -49,7 +49,7 @@ namespace Metal {
 
 class FunctionDeclarationWriter : public Visitor {
 public:
-    FunctionDeclarationWriter(TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, String>& functionMapping)
+    FunctionDeclarationWriter(TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping)
         : m_typeNamer(typeNamer)
         , m_functionMapping(functionMapping)
     {
@@ -63,7 +63,7 @@ public:
 
 private:
     TypeNamer& m_typeNamer;
-    HashMap<AST::FunctionDeclaration*, String>& m_functionMapping;
+    HashMap<AST::FunctionDeclaration*, MangledFunctionName>& m_functionMapping;
     StringBuilder m_stringBuilder;
 };
 
@@ -78,14 +78,14 @@ void FunctionDeclarationWriter::visit(AST::FunctionDeclaration& functionDeclarat
     for (size_t i = 0; i < functionDeclaration.parameters().size(); ++i) {
         if (i)
             m_stringBuilder.append(", ");
-        m_stringBuilder.append(m_typeNamer.mangledNameForType(*functionDeclaration.parameters()[i]->type()));
+        m_stringBuilder.flexibleAppend(m_typeNamer.mangledNameForType(*functionDeclaration.parameters()[i]->type()));
     }
     m_stringBuilder.append(");\n");
 }
 
 class FunctionDefinitionWriter : public Visitor {
 public:
-    FunctionDefinitionWriter(Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, String>& functionMapping, Layout& layout)
+    FunctionDefinitionWriter(Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping, Layout& layout)
         : m_intrinsics(intrinsics)
         , m_typeNamer(typeNamer)
         , m_functionMapping(functionMapping)
@@ -150,10 +150,7 @@ protected:
 
     String constantExpressionString(AST::ConstantExpression&);
 
-    String generateNextVariableName()
-    {
-        return makeString("variable", m_variableCount++);
-    }
+    MangledVariableName generateNextVariableName() { return { m_variableCount++ }; }
 
     enum class Nullability : uint8_t {
         NotNull,
@@ -161,14 +158,14 @@ protected:
     };
 
     struct StackItem {
-        String value;
-        String leftValue;
+        MangledVariableName value;
+        Optional<MangledVariableName> leftValue;
         Nullability valueNullability;
         Nullability leftValueNullability;
     };
 
     struct StackValue {
-        String value;
+        MangledVariableName value;
         Nullability nullability;
     };
 
@@ -177,31 +174,29 @@ protected:
     // and DereferenceExpression. MakePointerExpression will try to produce rvalues which are
     // non-null, and DereferenceExpression will take a non-null rvalue and try to produce
     // a non-null lvalue.
-    void appendRightValueWithNullability(AST::Expression&, String value, Nullability nullability)
+    void appendRightValueWithNullability(AST::Expression&, MangledVariableName value, Nullability nullability)
     {
-        m_stack.append({ WTFMove(value), String(), nullability, Nullability::CanBeNull });
+        m_stack.append({ WTFMove(value), WTF::nullopt, nullability, Nullability::CanBeNull });
     }
 
-    void appendRightValue(AST::Expression& expression, String value)
+    void appendRightValue(AST::Expression& expression, MangledVariableName value)
     {
         appendRightValueWithNullability(expression, WTFMove(value), Nullability::CanBeNull);
     }
 
-    void appendLeftValue(AST::Expression& expression, String value, String leftValue, Nullability nullability)
+    void appendLeftValue(AST::Expression& expression, MangledVariableName value, MangledVariableName leftValue, Nullability nullability)
     {
         ASSERT_UNUSED(expression, expression.typeAnnotation().leftAddressSpace());
         m_stack.append({ WTFMove(value), WTFMove(leftValue), Nullability::CanBeNull, nullability });
     }
 
-    String takeLastValue()
+    MangledVariableName takeLastValue()
     {
-        ASSERT(m_stack.last().value);
         return m_stack.takeLast().value;
     }
 
     StackValue takeLastValueAndNullability()
     {
-        ASSERT(m_stack.last().value);
         auto last = m_stack.takeLast();
         return { last.value, last.valueNullability };
     }
@@ -210,7 +205,7 @@ protected:
     {
         ASSERT(m_stack.last().leftValue);
         auto last = m_stack.takeLast();
-        return { last.leftValue, last.leftValueNullability };
+        return { *last.leftValue, last.leftValueNullability };
     }
 
     enum class BreakContext {
@@ -222,15 +217,15 @@ protected:
 
     Intrinsics& m_intrinsics;
     TypeNamer& m_typeNamer;
-    HashMap<AST::FunctionDeclaration*, String>& m_functionMapping;
-    HashMap<AST::VariableDeclaration*, String> m_variableMapping;
+    HashMap<AST::FunctionDeclaration*, MangledFunctionName>& m_functionMapping;
+    HashMap<AST::VariableDeclaration*, MangledVariableName> m_variableMapping;
     StringBuilder m_stringBuilder;
 
     Vector<StackItem> m_stack;
     std::unique_ptr<EntryPointScaffolding> m_entryPointScaffolding;
     Layout& m_layout;
     unsigned m_variableCount { 0 };
-    String m_breakOutOfCurrentLoopEarlyVariable;
+    Optional<MangledVariableName> m_breakOutOfCurrentLoopEarlyVariable;
 };
 
 void FunctionDefinitionWriter::visit(AST::NativeFunctionDeclaration& nativeFunctionDeclaration)
@@ -307,9 +302,9 @@ void FunctionDefinitionWriter::visit(AST::Break&)
         m_stringBuilder.append("break;\n");
         break;
     case BreakContext::Loop:
-        ASSERT(m_breakOutOfCurrentLoopEarlyVariable.length());
+        ASSERT(m_breakOutOfCurrentLoopEarlyVariable);
         m_stringBuilder.flexibleAppend(
-            m_breakOutOfCurrentLoopEarlyVariable, " = true;\n"
+            *m_breakOutOfCurrentLoopEarlyVariable, " = true;\n"
             "break;\n"
         );
         break;
@@ -318,7 +313,7 @@ void FunctionDefinitionWriter::visit(AST::Break&)
 
 void FunctionDefinitionWriter::visit(AST::Continue&)
 {
-    ASSERT(m_breakOutOfCurrentLoopEarlyVariable.length());
+    ASSERT(m_breakOutOfCurrentLoopEarlyVariable);
     m_stringBuilder.append("break;\n");
 }
 
@@ -335,10 +330,10 @@ void FunctionDefinitionWriter::visit(AST::Fallthrough&)
 
 void FunctionDefinitionWriter::emitLoop(LoopConditionLocation loopConditionLocation, AST::Expression* conditionExpression, AST::Expression* increment, AST::Statement& body)
 {
-    SetForScope<String> loopVariableScope(m_breakOutOfCurrentLoopEarlyVariable, generateNextVariableName());
+    SetForScope<Optional<MangledVariableName>> loopVariableScope(m_breakOutOfCurrentLoopEarlyVariable, generateNextVariableName());
 
     m_stringBuilder.flexibleAppend(
-        "bool ", m_breakOutOfCurrentLoopEarlyVariable, " = false;\n",
+        "bool ", *m_breakOutOfCurrentLoopEarlyVariable, " = false;\n",
         "while (true) {\n"
     );
 
@@ -352,7 +347,7 @@ void FunctionDefinitionWriter::emitLoop(LoopConditionLocation loopConditionLocat
     checkErrorAndVisit(body);
     m_stringBuilder.flexibleAppend(
         "} while(false); \n"
-        "if (", m_breakOutOfCurrentLoopEarlyVariable, ") break;\n"
+        "if (", *m_breakOutOfCurrentLoopEarlyVariable, ") break;\n"
     );
 
     if (increment) {
@@ -516,7 +511,7 @@ void FunctionDefinitionWriter::visit(AST::DotExpression& dotExpression)
     // This should be lowered already.
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Replace this with ASSERT_NOT_REACHED().
     notImplemented();
-    appendRightValue(dotExpression, "dummy");
+    appendRightValue(dotExpression, generateNextVariableName());
 }
 
 void FunctionDefinitionWriter::visit(AST::GlobalVariableReference& globalVariableReference)
@@ -537,7 +532,7 @@ void FunctionDefinitionWriter::visit(AST::IndexExpression& indexExpression)
     // This should be lowered already.
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Replace this with ASSERT_NOT_REACHED().
     notImplemented();
-    appendRightValue(indexExpression, "dummy");
+    appendRightValue(indexExpression, generateNextVariableName());
 }
 
 void FunctionDefinitionWriter::visit(AST::PropertyAccessExpression& propertyAccessExpression)
@@ -545,7 +540,7 @@ void FunctionDefinitionWriter::visit(AST::PropertyAccessExpression& propertyAcce
     // This should be lowered already.
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195788 Replace this with ASSERT_NOT_REACHED().
     notImplemented();
-    appendRightValue(propertyAccessExpression, "dummy");
+    appendRightValue(propertyAccessExpression, generateNextVariableName());
 }
 
 void FunctionDefinitionWriter::visit(AST::VariableDeclaration& variableDeclaration)
@@ -577,7 +572,7 @@ void FunctionDefinitionWriter::visit(AST::AssignmentExpression& assignmentExpres
 
 void FunctionDefinitionWriter::visit(AST::CallExpression& callExpression)
 {
-    Vector<String> argumentNames;
+    Vector<MangledVariableName> argumentNames;
     for (auto& argument : callExpression.arguments()) {
         checkErrorAndVisit(argument);
         argumentNames.append(takeLastValue());
@@ -591,7 +586,7 @@ void FunctionDefinitionWriter::visit(AST::CallExpression& callExpression)
     for (size_t i = 0; i < argumentNames.size(); ++i) {
         if (i)
             m_stringBuilder.append(", ");
-        m_stringBuilder.append(argumentNames[i]);
+        m_stringBuilder.flexibleAppend(argumentNames[i]);
     }
     m_stringBuilder.append(");\n");
     appendRightValue(callExpression, variableName);
@@ -599,12 +594,13 @@ void FunctionDefinitionWriter::visit(AST::CallExpression& callExpression)
 
 void FunctionDefinitionWriter::visit(AST::CommaExpression& commaExpression)
 {
-    String result;
+    Optional<MangledVariableName> result;
     for (auto& expression : commaExpression.list()) {
         checkErrorAndVisit(expression);
         result = takeLastValue();
     }
-    appendRightValue(commaExpression, result);
+    ASSERT(result);
+    appendRightValue(commaExpression, *result);
 }
 
 void FunctionDefinitionWriter::visit(AST::DereferenceExpression& dereferenceExpression)
@@ -750,7 +746,7 @@ String FunctionDefinitionWriter::constantExpressionString(AST::ConstantExpressio
 
 class RenderFunctionDefinitionWriter : public FunctionDefinitionWriter {
 public:
-    RenderFunctionDefinitionWriter(Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, String>& functionMapping, MatchedRenderSemantics&& matchedSemantics, Layout& layout)
+    RenderFunctionDefinitionWriter(Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping, MatchedRenderSemantics&& matchedSemantics, Layout& layout)
         : FunctionDefinitionWriter(intrinsics, typeNamer, functionMapping, layout)
         , m_matchedSemantics(WTFMove(matchedSemantics))
     {
@@ -764,7 +760,7 @@ private:
 
 std::unique_ptr<EntryPointScaffolding> RenderFunctionDefinitionWriter::createEntryPointScaffolding(AST::FunctionDefinition& functionDefinition)
 {
-    auto generateNextVariableName = [this]() -> String {
+    auto generateNextVariableName = [this]() -> MangledVariableName {
         return this->generateNextVariableName();
     };
     if (&functionDefinition == m_matchedSemantics.vertexShader)
@@ -776,7 +772,7 @@ std::unique_ptr<EntryPointScaffolding> RenderFunctionDefinitionWriter::createEnt
 
 class ComputeFunctionDefinitionWriter : public FunctionDefinitionWriter {
 public:
-    ComputeFunctionDefinitionWriter(Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, String>& functionMapping, MatchedComputeSemantics&& matchedSemantics, Layout& layout)
+    ComputeFunctionDefinitionWriter(Intrinsics& intrinsics, TypeNamer& typeNamer, HashMap<AST::FunctionDeclaration*, MangledFunctionName>& functionMapping, MatchedComputeSemantics&& matchedSemantics, Layout& layout)
         : FunctionDefinitionWriter(intrinsics, typeNamer, functionMapping, layout)
         , m_matchedSemantics(WTFMove(matchedSemantics))
     {
@@ -790,7 +786,7 @@ private:
 
 std::unique_ptr<EntryPointScaffolding> ComputeFunctionDefinitionWriter::createEntryPointScaffolding(AST::FunctionDefinition& functionDefinition)
 {
-    auto generateNextVariableName = [this]() -> String {
+    auto generateNextVariableName = [this]() -> MangledVariableName {
         return this->generateNextVariableName();
     };
     if (&functionDefinition == m_matchedSemantics.shader)
@@ -799,7 +795,7 @@ std::unique_ptr<EntryPointScaffolding> ComputeFunctionDefinitionWriter::createEn
 }
 
 struct SharedMetalFunctionsResult {
-    HashMap<AST::FunctionDeclaration*, String> functionMapping;
+    HashMap<AST::FunctionDeclaration*, MangledFunctionName> functionMapping;
     String metalFunctions;
 };
 static SharedMetalFunctionsResult sharedMetalFunctions(Program& program, TypeNamer& typeNamer, const HashSet<AST::FunctionDeclaration*>& reachableFunctions)
@@ -807,13 +803,13 @@ static SharedMetalFunctionsResult sharedMetalFunctions(Program& program, TypeNam
     StringBuilder stringBuilder;
 
     unsigned numFunctions = 0;
-    HashMap<AST::FunctionDeclaration*, String> functionMapping;
+    HashMap<AST::FunctionDeclaration*, MangledFunctionName> functionMapping;
     for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) {
-        auto addResult = functionMapping.add(&nativeFunctionDeclaration, makeString("function", numFunctions++));
+        auto addResult = functionMapping.add(&nativeFunctionDeclaration, MangledFunctionName { numFunctions++ });
         ASSERT_UNUSED(addResult, addResult.isNewEntry);
     }
     for (auto& functionDefinition : program.functionDefinitions()) {
-        auto addResult = functionMapping.add(&functionDefinition, makeString("function", numFunctions++));
+        auto addResult = functionMapping.add(&functionDefinition, MangledFunctionName { numFunctions++ });
         ASSERT_UNUSED(addResult, addResult.isNewEntry);
     }
 
index dfa46ac..dfa23df 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLMangledNames.h"
 #include "WHLSLSemanticMatcher.h"
 
 namespace WebCore {
@@ -41,14 +42,14 @@ class TypeNamer;
 
 struct RenderMetalFunctions {
     String metalSource;
-    String mangledVertexEntryPointName;
-    String mangledFragmentEntryPointName;
+    MangledFunctionName mangledVertexEntryPointName;
+    MangledFunctionName mangledFragmentEntryPointName;
 };
 RenderMetalFunctions metalFunctions(Program&, TypeNamer&, MatchedRenderSemantics&&, Layout&);
 
 struct ComputeMetalFunctions {
     String metalSource;
-    String mangledEntryPointName;
+    MangledFunctionName mangledEntryPointName;
 };
 ComputeMetalFunctions metalFunctions(Program&, TypeNamer&, MatchedComputeSemantics&&, Layout&);
 
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMangledNames.h b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLMangledNames.h
new file mode 100644 (file)
index 0000000..762245f
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBGPU)
+
+#include <wtf/Variant.h>
+#include <wtf/text/StringConcatenate.h>
+#include <wtf/text/StringConcatenateNumbers.h>
+
+namespace WebCore {
+
+namespace WHLSL {
+
+namespace Metal {
+
+struct MangledVariableName {
+    unsigned value;
+    static constexpr const char* prefix = "variable";
+};
+
+struct MangledTypeName {
+    unsigned value;
+    static constexpr const char* prefix = "type";
+};
+
+struct MangledStructureElementName {
+    unsigned value;
+    static constexpr const char* prefix = "structureElement";
+};
+
+struct MangledEnumerationMemberName {
+    unsigned value;
+    static constexpr const char* prefix = "enumerationMember";
+};
+
+struct MangledFunctionName {
+    unsigned value;
+    static constexpr const char* prefix = "function";
+
+    String toString() const { return makeString(prefix, value); }
+};
+
+using MangledOrNativeTypeName = Variant<MangledTypeName, String>;
+
+} // namespace Metal
+
+} // namespace WHLSL
+
+} // namespace WebCore
+
+namespace WTF {
+
+template<typename MangledNameType>
+class MangledNameAdaptor {
+public:
+    MangledNameAdaptor(MangledNameType name)
+        : m_name { name }
+    {
+    }
+
+    unsigned length() { return strlen(MangledNameType::prefix) + lengthOfNumberAsStringUnsigned(m_name.value); }
+    bool is8Bit() { return true; }
+    template<typename CharacterType> void writeTo(CharacterType* destination)
+    {
+        StringImpl::copyCharacters(destination, reinterpret_cast<const LChar*>(MangledNameType::prefix), strlen(MangledNameType::prefix));
+        writeNumberToBufferUnsigned(m_name.value, destination + strlen(MangledNameType::prefix));
+    }
+
+private:
+    MangledNameType m_name;
+};
+
+template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledVariableName, void> : public MangledNameAdaptor<WebCore::WHLSL::Metal::MangledVariableName> {
+public:
+    StringTypeAdapter(WebCore::WHLSL::Metal::MangledVariableName name)
+        : MangledNameAdaptor(name)
+    {
+    }
+};
+template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledTypeName, void> : public MangledNameAdaptor<WebCore::WHLSL::Metal::MangledTypeName> {
+public:
+    StringTypeAdapter(WebCore::WHLSL::Metal::MangledTypeName name)
+        : MangledNameAdaptor(name)
+    {
+    }
+};
+template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledStructureElementName, void> : public MangledNameAdaptor<WebCore::WHLSL::Metal::MangledStructureElementName> {
+public:
+    StringTypeAdapter(WebCore::WHLSL::Metal::MangledStructureElementName name)
+        : MangledNameAdaptor(name)
+    {
+    }
+};
+template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledEnumerationMemberName, void> : public MangledNameAdaptor<WebCore::WHLSL::Metal::MangledEnumerationMemberName> {
+public:
+    StringTypeAdapter(WebCore::WHLSL::Metal::MangledEnumerationMemberName name)
+        : MangledNameAdaptor(name)
+    {
+    }
+};
+template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledFunctionName, void> : public MangledNameAdaptor<WebCore::WHLSL::Metal::MangledFunctionName> {
+public:
+    StringTypeAdapter(WebCore::WHLSL::Metal::MangledFunctionName name)
+        : MangledNameAdaptor(name)
+    {
+    }
+};
+
+template<> class StringTypeAdapter<WebCore::WHLSL::Metal::MangledOrNativeTypeName, void> {
+public:
+    StringTypeAdapter(const WebCore::WHLSL::Metal::MangledOrNativeTypeName& name)
+        : m_name { name }
+    {
+    }
+
+    unsigned length()
+    {
+        return WTF::switchOn(m_name,
+            [&] (const WebCore::WHLSL::Metal::MangledTypeName& mangledTypeName) {
+                return strlen(WebCore::WHLSL::Metal::MangledTypeName::prefix) + lengthOfNumberAsStringUnsigned(mangledTypeName.value);
+            },
+            [&] (const String& string) {
+                return string.length();
+            }
+        );
+    }
+
+    bool is8Bit()
+    {
+        return WTF::switchOn(m_name,
+            [&] (const WebCore::WHLSL::Metal::MangledTypeName&) {
+                return true;
+            },
+            [&] (const String& string) {
+                return string.is8Bit();
+            }
+        );
+    }
+
+    template<typename CharacterType> void writeTo(CharacterType* destination)
+    {
+        WTF::switchOn(m_name,
+            [&] (const WebCore::WHLSL::Metal::MangledTypeName& mangledTypeName) {
+                StringImpl::copyCharacters(destination, reinterpret_cast<const LChar*>(WebCore::WHLSL::Metal::MangledTypeName::prefix), strlen(WebCore::WHLSL::Metal::MangledTypeName::prefix));
+                writeNumberToBufferUnsigned(mangledTypeName.value, destination + strlen(WebCore::WHLSL::Metal::MangledTypeName::prefix));
+            },
+            [&] (const String& string) {
+                StringView { string }.getCharactersWithUpconvert(destination);
+            }
+        );
+    }
+
+private:
+    const WebCore::WHLSL::Metal::MangledOrNativeTypeName& m_name;
+};
+
+}
+
+#endif
index ea2b3ef..a22a8b9 100644 (file)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLMangledNames.h"
 #include "WHLSLPipelineDescriptor.h"
 #include "WHLSLSemanticMatcher.h"
 #include <wtf/Variant.h>
@@ -42,15 +43,15 @@ namespace Metal {
 
 struct RenderMetalCode {
     String metalSource;
-    String mangledVertexEntryPointName;
-    String mangledFragmentEntryPointName;
+    MangledFunctionName mangledVertexEntryPointName;
+    MangledFunctionName mangledFragmentEntryPointName;
 };
 // Can't fail. Any failure checks need to be done earlier, in the backend-agnostic part of the compiler.
 RenderMetalCode generateMetalCode(Program&, MatchedRenderSemantics&& matchedSemantics, Layout&);
 
 struct ComputeMetalCode {
     String metalSource;
-    String mangledEntryPointName;
+    MangledFunctionName mangledEntryPointName;
 };
 // Can't fail. Any failure checks need to be done earlier, in the backend-agnostic part of the compiler.
 ComputeMetalCode generateMetalCode(Program&, MatchedComputeSemantics&& matchedSemantics, Layout&);
index 8b63842..1e12f3d 100644 (file)
@@ -120,7 +120,7 @@ static const char* vectorSuffix(int vectorLength)
     }
 }
 
-String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclaration, String& outputFunctionName, Intrinsics& intrinsics, TypeNamer& typeNamer)
+String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclaration, MangledFunctionName outputFunctionName, Intrinsics& intrinsics, TypeNamer& typeNamer)
 {
     StringBuilder stringBuilder;
     if (nativeFunctionDeclaration.isCast()) {
@@ -205,17 +205,18 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
     }
 
     if (nativeFunctionDeclaration.name().startsWith("operator."_str)) {
-        auto mangledFieldName = [&](const String& fieldName) -> String {
+        auto appendMangledFieldName = [&](StringBuilder& stringBuilder, const String& fieldName) {
             auto& unifyNode = nativeFunctionDeclaration.parameters()[0]->type()->unifyNode();
             auto& namedType = downcast<AST::NamedType>(unifyNode);
             if (is<AST::StructureDefinition>(namedType)) {
                 auto& structureDefinition = downcast<AST::StructureDefinition>(namedType);
                 auto* structureElement = structureDefinition.find(fieldName);
                 ASSERT(structureElement);
-                return typeNamer.mangledNameForStructureElement(*structureElement);
+                stringBuilder.flexibleAppend(typeNamer.mangledNameForStructureElement(*structureElement));
+                return;
             }
             ASSERT(is<AST::NativeTypeDeclaration>(namedType));
-            return fieldName;
+            stringBuilder.append(fieldName);
         };
 
         if (nativeFunctionDeclaration.name().endsWith("=")) {
@@ -223,12 +224,16 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
             auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type());
             auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
             auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
-            auto fieldName = nativeFunctionDeclaration.name().substring("operator."_str.length());
-            fieldName = fieldName.substring(0, fieldName.length() - 1);
-            auto metalFieldName = mangledFieldName(fieldName);
             stringBuilder.flexibleAppend(
                 metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " v, ", metalParameter2Name, " n) {\n"
-                "    v.", metalFieldName, " = n;\n"
+                "    v."
+            );
+
+            auto fieldName = nativeFunctionDeclaration.name().substring("operator."_str.length());
+            fieldName = fieldName.substring(0, fieldName.length() - 1);
+            appendMangledFieldName(stringBuilder, fieldName);
+
+            stringBuilder.append(" = n;\n"
                 "    return v;\n"
                 "}\n"
             );
@@ -236,13 +241,17 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
         }
 
         ASSERT(nativeFunctionDeclaration.parameters().size() == 1);
-        auto fieldName = nativeFunctionDeclaration.name().substring("operator."_str.length());
         auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type());
         auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
-        auto metalFieldName = mangledFieldName(fieldName);
         stringBuilder.flexibleAppend(
             metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " v) {\n"
-            "    return v.", metalFieldName, ";\n"
+            "    return v."
+        );
+
+        auto fieldName = nativeFunctionDeclaration.name().substring("operator."_str.length());
+        appendMangledFieldName(stringBuilder, fieldName);
+            
+        stringBuilder.append(";\n"
             "}\n"
         );
         return stringBuilder.toString();
@@ -252,9 +261,13 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
         ASSERT(nativeFunctionDeclaration.parameters().size() == 1);
         auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type());
         auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
-        auto fieldName = nativeFunctionDeclaration.name().substring("operator&."_str.length());
 
-        String metalFieldName;
+        stringBuilder.flexibleAppend(
+            metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " v) {\n"
+            "    return &(v->"
+        );
+
+        auto fieldName = nativeFunctionDeclaration.name().substring("operator&."_str.length());
         auto& unnamedType = *nativeFunctionDeclaration.parameters()[0]->type();
         auto& unifyNode = downcast<AST::PointerType>(unnamedType).elementType().unifyNode();
         auto& namedType = downcast<AST::NamedType>(unifyNode);
@@ -262,13 +275,12 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
             auto& structureDefinition = downcast<AST::StructureDefinition>(namedType);
             auto* structureElement = structureDefinition.find(fieldName);
             ASSERT(structureElement);
-            metalFieldName = typeNamer.mangledNameForStructureElement(*structureElement);
+            stringBuilder.flexibleAppend(typeNamer.mangledNameForStructureElement(*structureElement));
         } else
-            metalFieldName = fieldName;
+            stringBuilder.flexibleAppend(fieldName);
 
-        stringBuilder.flexibleAppend(
-            metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " v) {\n"
-            "    return &(v->", metalFieldName, ");\n"
+        stringBuilder.append(
+            ");\n"
             "}\n"
         );
         return stringBuilder.toString();
@@ -512,13 +524,13 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
         auto metalParameter1Name = typeNamer.mangledNameForType(textureType);
         auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
         auto metalParameter3Name = typeNamer.mangledNameForType(locationType);
-        String metalParameter4Name;
+        Optional<MangledTypeName> metalParameter4Name;
         if (nativeFunctionDeclaration.parameters().size() == 4)
             metalParameter4Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[3]->type());
         auto metalReturnName = typeNamer.mangledNameForType(returnType);
         stringBuilder.flexibleAppend(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " theTexture, ", metalParameter2Name, " theSampler, ", metalParameter3Name, " location");
-        if (!metalParameter4Name.isNull())
-            stringBuilder.flexibleAppend(", ", metalParameter4Name, " offset");
+        if (metalParameter4Name)
+            stringBuilder.flexibleAppend(", ", *metalParameter4Name, " offset");
         stringBuilder.append(
             ") {\n"
             "    return theTexture.sample(theSampler, "
@@ -528,7 +540,7 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
             stringBuilder.flexibleAppend("location.", "xyzw"_str.substring(0, locationVectorLength - 1), ", location.", "xyzw"_str.substring(locationVectorLength - 1, 1));
         } else
             stringBuilder.append("location");
-        if (!metalParameter4Name.isNull())
+        if (metalParameter4Name)
             stringBuilder.append(", offset");
         stringBuilder.append(")");
         if (!textureType.isDepthTexture())
@@ -620,22 +632,22 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
             ++index;
         auto widthTypeName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[index]->type());
         ++index;
-        String heightTypeName;
+        Optional<MangledTypeName> heightTypeName;
         if (textureType.textureDimension() >= 2) {
             heightTypeName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[index]->type());
             ++index;
         }
-        String depthTypeName;
+        Optional<MangledTypeName> depthTypeName;
         if (textureType.textureDimension() >= 3) {
             depthTypeName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[index]->type());
             ++index;
         }
-        String elementsTypeName;
+        Optional<MangledTypeName> elementsTypeName;
         if (textureType.isTextureArray()) {
             elementsTypeName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[index]->type());
             ++index;
         }
-        String numberOfLevelsTypeName;
+        Optional<MangledTypeName> numberOfLevelsTypeName;
         if (!textureType.isWritableTexture() && textureType.textureDimension() != 1) {
             numberOfLevelsTypeName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[index]->type());
             ++index;
@@ -647,14 +659,14 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
         if (!textureType.isWritableTexture() && textureType.textureDimension() != 1)
             stringBuilder.append(", uint mipLevel");
         stringBuilder.flexibleAppend(", ", widthTypeName, " width");
-        if (!heightTypeName.isNull())
-            stringBuilder.flexibleAppend(", ", heightTypeName, " height");
-        if (!depthTypeName.isNull())
-            stringBuilder.flexibleAppend(", ", depthTypeName, " depth");
-        if (!elementsTypeName.isNull())
-            stringBuilder.flexibleAppend(", ", elementsTypeName, " elements");
-        if (!numberOfLevelsTypeName.isNull())
-            stringBuilder.flexibleAppend(", ", numberOfLevelsTypeName, " numberOfLevels");
+        if (heightTypeName)
+            stringBuilder.flexibleAppend(", ", *heightTypeName, " height");
+        if (depthTypeName)
+            stringBuilder.flexibleAppend(", ", *depthTypeName, " depth");
+        if (elementsTypeName)
+            stringBuilder.flexibleAppend(", ", *elementsTypeName, " elements");
+        if (numberOfLevelsTypeName)
+            stringBuilder.flexibleAppend(", ", *numberOfLevelsTypeName, " numberOfLevels");
         stringBuilder.append(
             ") {\n"
             "    if (width)\n"
@@ -663,7 +675,7 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
         if (!textureType.isWritableTexture() && textureType.textureDimension() != 1)
             stringBuilder.append("mipLevel");
         stringBuilder.append(");\n");
-        if (!heightTypeName.isNull()) {
+        if (heightTypeName) {
             stringBuilder.append(
                 "    if (height)\n"
                 "        *height = theTexture.get_height("
@@ -672,7 +684,7 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
                 stringBuilder.append("mipLevel");
             stringBuilder.append(");\n");
         }
-        if (!depthTypeName.isNull()) {
+        if (depthTypeName) {
             stringBuilder.append(
                 "    if (depth)\n"
                 "        *depth = theTexture.get_depth("
@@ -681,13 +693,13 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
                 stringBuilder.append("mipLevel");
             stringBuilder.append(");\n");
         }
-        if (!elementsTypeName.isNull()) {
+        if (elementsTypeName) {
             stringBuilder.append(
                 "    if (elements)\n"
                 "        *elements = theTexture.get_array_size();\n"
             );
         }
-        if (!numberOfLevelsTypeName.isNull()) {
+        if (numberOfLevelsTypeName) {
             stringBuilder.append(
                 "    if (numberOfLevels)\n"
                 "        *numberOfLevels = theTexture.get_num_mip_levels();\n"
index 257bb85..a02cb55 100644 (file)
@@ -27,7 +27,7 @@
 
 #if ENABLE(WEBGPU)
 
-#include <wtf/text/WTFString.h>
+#include "WHLSLMangledNames.h"
 
 namespace WebCore {
 
@@ -45,7 +45,7 @@ namespace Metal {
 
 class TypeNamer;
 
-String writeNativeFunction(AST::NativeFunctionDeclaration&, String& outputFunctionName, Intrinsics&, TypeNamer&);
+String writeNativeFunction(AST::NativeFunctionDeclaration&, MangledFunctionName outputFunctionName, Intrinsics&, TypeNamer&);
 
 }
 
index 4de3ded..8706c79 100644 (file)
@@ -61,7 +61,7 @@ namespace Metal {
 class BaseTypeNameNode {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    BaseTypeNameNode(BaseTypeNameNode* parent, String&& mangledName)
+    BaseTypeNameNode(BaseTypeNameNode* parent, MangledTypeName&& mangledName)
         : m_parent(parent)
         , m_mangledName(mangledName)
     {
@@ -77,18 +77,18 @@ public:
         m_children.append(WTFMove(child));
     }
     BaseTypeNameNode* parent() { return m_parent; }
-    const String& mangledName() const { return m_mangledName; }
+    MangledTypeName mangledName() const { return m_mangledName; }
 
 private:
     Vector<UniqueRef<BaseTypeNameNode>> m_children;
     BaseTypeNameNode* m_parent;
-    String m_mangledName;
+    MangledTypeName m_mangledName;
 };
 
 class ArrayTypeNameNode : public BaseTypeNameNode {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    ArrayTypeNameNode(BaseTypeNameNode* parent, String&& mangledName, unsigned numElements)
+    ArrayTypeNameNode(BaseTypeNameNode* parent, MangledTypeName&& mangledName, unsigned numElements)
         : BaseTypeNameNode(parent, WTFMove(mangledName))
         , m_numElements(numElements)
     {
@@ -104,7 +104,7 @@ private:
 class ArrayReferenceTypeNameNode : public BaseTypeNameNode {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    ArrayReferenceTypeNameNode(BaseTypeNameNode* parent, String&& mangledName, AST::AddressSpace addressSpace)
+    ArrayReferenceTypeNameNode(BaseTypeNameNode* parent, MangledTypeName&& mangledName, AST::AddressSpace addressSpace)
         : BaseTypeNameNode(parent, WTFMove(mangledName))
         , m_addressSpace(addressSpace)
     {
@@ -120,7 +120,7 @@ private:
 class PointerTypeNameNode : public BaseTypeNameNode {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    PointerTypeNameNode(BaseTypeNameNode* parent, String&& mangledName, AST::AddressSpace addressSpace)
+    PointerTypeNameNode(BaseTypeNameNode* parent, MangledTypeName&& mangledName, AST::AddressSpace addressSpace)
         : BaseTypeNameNode(parent, WTFMove(mangledName))
         , m_addressSpace(addressSpace)
     {
@@ -136,7 +136,7 @@ private:
 class ReferenceTypeNameNode : public BaseTypeNameNode {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    ReferenceTypeNameNode(BaseTypeNameNode* parent, String&& mangledName, AST::NamedType& namedType)
+    ReferenceTypeNameNode(BaseTypeNameNode* parent, MangledTypeName&& mangledName, AST::NamedType& namedType)
         : BaseTypeNameNode(parent, WTFMove(mangledName))
         , m_namedType(namedType)
     {
@@ -354,7 +354,7 @@ BaseTypeNameNode* TypeNamer::insert(AST::UnnamedType& unnamedType, Vector<Unique
 class MetalTypeDeclarationWriter : public Visitor {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    MetalTypeDeclarationWriter(std::function<String(AST::NamedType&)>&& mangledNameForNamedType)
+    MetalTypeDeclarationWriter(std::function<MangledOrNativeTypeName(AST::NamedType&)>&& mangledNameForNamedType)
         : m_mangledNameForNamedType(WTFMove(mangledNameForNamedType))
     {
     }
@@ -367,13 +367,13 @@ private:
         m_stringBuilder.flexibleAppend("struct ", m_mangledNameForNamedType(structureDefinition), ";\n");
     }
 
-    std::function<String(AST::NamedType&)> m_mangledNameForNamedType;
+    std::function<MangledOrNativeTypeName(AST::NamedType&)> m_mangledNameForNamedType;
     StringBuilder m_stringBuilder;
 };
 
 String TypeNamer::metalTypeDeclarations()
 {
-    MetalTypeDeclarationWriter metalTypeDeclarationWriter([&](AST::NamedType& namedType) -> String {
+    MetalTypeDeclarationWriter metalTypeDeclarationWriter([&](AST::NamedType& namedType) -> MangledOrNativeTypeName {
         return mangledNameForType(namedType);
     });
     metalTypeDeclarationWriter.Visitor::visit(m_program);
@@ -460,12 +460,12 @@ String TypeNamer::metalTypeDefinitions()
     return stringBuilder.toString();
 }
 
-String TypeNamer::mangledNameForType(AST::UnnamedType& unnamedType)
+MangledTypeName TypeNamer::mangledNameForType(AST::UnnamedType& unnamedType)
 {
     return find(unnamedType, m_trie).mangledName();
 }
 
-String TypeNamer::mangledNameForType(AST::NamedType& namedType)
+MangledOrNativeTypeName TypeNamer::mangledNameForType(AST::NamedType& namedType)
 {
     if (is<AST::NativeTypeDeclaration>(namedType))
         return mangledNameForType(downcast<AST::NativeTypeDeclaration>(namedType));
@@ -475,14 +475,14 @@ String TypeNamer::mangledNameForType(AST::NamedType& namedType)
 }
 
 
-String TypeNamer::mangledNameForEnumerationMember(AST::EnumerationMember& enumerationMember)
+MangledEnumerationMemberName TypeNamer::mangledNameForEnumerationMember(AST::EnumerationMember& enumerationMember)
 {
     auto iterator = m_enumerationMemberMapping.find(&enumerationMember);
     ASSERT(iterator != m_enumerationMemberMapping.end());
     return iterator->value;
 }
 
-String TypeNamer::mangledNameForStructureElement(AST::StructureElement& structureElement)
+MangledStructureElementName TypeNamer::mangledNameForStructureElement(AST::StructureElement& structureElement)
 {
     auto iterator = m_structureElementMapping.find(&structureElement);
     ASSERT(iterator != m_structureElementMapping.end());
index c4bc7a4..6d44d6c 100644 (file)
 
 #if ENABLE(WEBGPU)
 
+#include "WHLSLMangledNames.h"
 #include "WHLSLVisitor.h"
 #include <wtf/HashMap.h>
-#include <wtf/text/StringConcatenate.h>
-#include <wtf/text/StringConcatenateNumbers.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
@@ -64,20 +63,13 @@ public:
 
     // Must be called after calling metalTypes().
     String mangledNameForType(AST::NativeTypeDeclaration&);
-    String mangledNameForType(AST::UnnamedType&);
-    String mangledNameForType(AST::NamedType&);
-    String mangledNameForEnumerationMember(AST::EnumerationMember&);
-    String mangledNameForStructureElement(AST::StructureElement&);
+    MangledTypeName mangledNameForType(AST::UnnamedType&);
+    MangledOrNativeTypeName mangledNameForType(AST::NamedType&);
+    MangledEnumerationMemberName mangledNameForEnumerationMember(AST::EnumerationMember&);
+    MangledStructureElementName mangledNameForStructureElement(AST::StructureElement&);
 
-    String generateNextTypeName()
-    {
-        return makeString("type", m_typeCount++);
-    }
-
-    String generateNextStructureElementName()
-    {
-        return makeString("structureElement", m_structureElementCount++);
-    }
+    MangledTypeName generateNextTypeName() { return { m_typeCount++ }; }
+    MangledStructureElementName generateNextStructureElementName() { return { m_structureElementCount++ }; }
 
 private:
     void visit(AST::UnnamedType&) override;
@@ -88,10 +80,7 @@ private:
     void visit(AST::Expression&) override;
     void visit(AST::CallExpression&) override;
 
-    String generateNextEnumerationMemberName()
-    {
-        return makeString("enumerationMember", m_enumerationMemberCount++);
-    }
+    MangledEnumerationMemberName generateNextEnumerationMemberName() { return { m_enumerationMemberCount++ }; }
 
     void emitNamedTypeDefinition(AST::NamedType&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder&);
     void emitUnnamedTypeDefinition(BaseTypeNameNode&, HashSet<AST::NamedType*>& emittedNamedTypes, HashSet<BaseTypeNameNode*>& emittedUnnamedTypes, StringBuilder&);
@@ -105,10 +94,10 @@ private:
     Program& m_program;
     Vector<UniqueRef<BaseTypeNameNode>> m_trie;
     HashMap<AST::UnnamedType*, BaseTypeNameNode*> m_unnamedTypeMapping;
-    HashMap<AST::NamedType*, String> m_namedTypeMapping;
+    HashMap<AST::NamedType*, MangledTypeName> m_namedTypeMapping;
     HashMap<AST::NamedType*, Vector<std::reference_wrapper<BaseTypeNameNode>>> m_dependencyGraph;
-    HashMap<AST::EnumerationMember*, String> m_enumerationMemberMapping;
-    HashMap<AST::StructureElement*, String> m_structureElementMapping;
+    HashMap<AST::EnumerationMember*, MangledEnumerationMemberName> m_enumerationMemberMapping;
+    HashMap<AST::StructureElement*, MangledStructureElementName> m_structureElementMapping;
     unsigned m_typeCount { 0 };
     unsigned m_enumerationMemberCount { 0 };
     unsigned m_structureElementCount { 0 };
index 4ecc362..3366436 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLError.h"
+#include "WHLSLMangledNames.h"
 #include "WHLSLPipelineDescriptor.h"
 #include <wtf/text/WTFString.h>
 
@@ -37,8 +38,8 @@ namespace WHLSL {
 
 struct RenderPrepareResult {
     String metalSource;
-    String mangledVertexEntryPointName;
-    String mangledFragmentEntryPointName;
+    Metal::MangledFunctionName mangledVertexEntryPointName;
+    Metal::MangledFunctionName mangledFragmentEntryPointName;
 };
 Expected<RenderPrepareResult, String> prepare(String& whlslSource, RenderPipelineDescriptor&);
 
@@ -50,7 +51,7 @@ struct ComputeDimensions {
 
 struct ComputePrepareResult {
     String metalSource;
-    String mangledEntryPointName;
+    Metal::MangledFunctionName mangledEntryPointName;
     ComputeDimensions computeDimensions;
 };
 Expected<ComputePrepareResult, String> prepare(String& whlslSource, ComputePipelineDescriptor&);
index f7a1e48..9977668 100644 (file)
                7C7903BC1F86FF3400463A70 /* PlaceholderRenderingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlaceholderRenderingContext.h; sourceTree = "<group>"; };
                7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DataDetectorsCoreSoftLink.mm; sourceTree = "<group>"; };
                7C7941E31C56C29300A4C58E /* DataDetectorsCoreSoftLink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataDetectorsCoreSoftLink.h; sourceTree = "<group>"; };
+               7C7C769C22F67ECD0032BCCD /* WHLSLMangledNames.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLMangledNames.h; sourceTree = "<group>"; };
                7C8139A31ED6281D00CE26E8 /* JSDOMAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMAttribute.h; sourceTree = "<group>"; };
                7C8139A41ED6281D00CE26E8 /* JSDOMOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMOperation.h; sourceTree = "<group>"; };
                7C8139A51ED6281D00CE26E8 /* JSDOMOperationReturningPromise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMOperationReturningPromise.h; sourceTree = "<group>"; };
                                1CECB3BB21F511AA00F44542 /* WHLSLEntryPointScaffolding.h */,
                                1CECB3AF21F2B98400F44542 /* WHLSLFunctionWriter.cpp */,
                                1CECB3B221F2B98600F44542 /* WHLSLFunctionWriter.h */,
+                               7C7C769C22F67ECD0032BCCD /* WHLSLMangledNames.h */,
                                1CECB3B521F50AC700F44542 /* WHLSLMetalCodeGenerator.cpp */,
                                1CECB3B621F50AC700F44542 /* WHLSLMetalCodeGenerator.h */,
                                1CECB3B821F50D1000F44542 /* WHLSLNativeFunctionWriter.cpp */,
index a4745e5..5474820 100644 (file)
@@ -94,7 +94,7 @@ static Optional<WHLSL::ComputeDimensions> trySetFunctions(const GPUPipelineStage
         ASSERT(computeLibrary);
         // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195771 Once we zero-fill variables, there should be no warnings, so we should be able to ASSERT(!error) here.
 
-        computeEntryPoint = whlslCompileResult->mangledEntryPointName;
+        computeEntryPoint = whlslCompileResult->mangledEntryPointName.toString();
     } else {
         computeLibrary = computeStage.module->platformShaderModule();
         computeEntryPoint = computeStage.entryPoint;
index 810efd9..a545a1a 100644 (file)
@@ -411,8 +411,8 @@ static bool trySetFunctions(const GPUPipelineStageDescriptor& vertexStage, const
         // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195771 Once we zero-fill variables, there should be no warnings, so we should be able to ASSERT(!error) here.
 
         fragmentLibrary = vertexLibrary;
-        vertexEntryPoint = whlslCompileResult->mangledVertexEntryPointName;
-        fragmentEntryPoint = whlslCompileResult->mangledFragmentEntryPointName;
+        vertexEntryPoint = whlslCompileResult->mangledVertexEntryPointName.toString();
+        fragmentEntryPoint = whlslCompileResult->mangledFragmentEntryPointName.toString();
     } else {
         vertexLibrary = vertexStage.module->platformShaderModule();
         vertexEntryPoint = vertexStage.entryPoint;