Title: [248378] trunk/Source/WebCore
Revision
248378
Author
[email protected]
Date
2019-08-07 11:13:57 -0700 (Wed, 07 Aug 2019)

Log Message

[WHLSL] cache results of argumentTypeForAndOverload inside Checker
https://bugs.webkit.org/show_bug.cgi?id=200462

Reviewed by Robin Morisset.

When I profiled the time we spent in the checker, it turned out that
argumentTypeForAndOverload is one of the most expensive functions. If
we just cache the results of that function, we can avoid 99% of the
duplicate allocations that function does in compute_boids. This patch
is a ~4ms speedup in the checker on compute_boids.

* Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp:
* Modules/webgpu/WHLSL/WHLSLChecker.cpp:
(WebCore::WHLSL::AndOverloadTypeKey::AndOverloadTypeKey):
(WebCore::WHLSL::AndOverloadTypeKey::isEmptyValue const):
(WebCore::WHLSL::AndOverloadTypeKey::isHashTableDeletedValue const):
(WebCore::WHLSL::AndOverloadTypeKey::hash const):
(WebCore::WHLSL::AndOverloadTypeKey::operator== const):
(WebCore::WHLSL::AndOverloadTypeKey::Hash::hash):
(WebCore::WHLSL::AndOverloadTypeKey::Hash::equal):
(WebCore::WHLSL::AndOverloadTypeKey::Traits::isEmptyValue):
(WebCore::WHLSL::Checker::argumentTypeForAndOverload):
(WebCore::WHLSL::Checker::finishVisiting):
(WebCore::WHLSL::argumentTypeForAndOverload): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (248377 => 248378)


--- trunk/Source/WebCore/ChangeLog	2019-08-07 18:05:12 UTC (rev 248377)
+++ trunk/Source/WebCore/ChangeLog	2019-08-07 18:13:57 UTC (rev 248378)
@@ -1,3 +1,30 @@
+2019-08-07  Saam Barati  <[email protected]>
+
+        [WHLSL] cache results of argumentTypeForAndOverload inside Checker
+        https://bugs.webkit.org/show_bug.cgi?id=200462
+
+        Reviewed by Robin Morisset.
+
+        When I profiled the time we spent in the checker, it turned out that 
+        argumentTypeForAndOverload is one of the most expensive functions. If
+        we just cache the results of that function, we can avoid 99% of the
+        duplicate allocations that function does in compute_boids. This patch
+        is a ~4ms speedup in the checker on compute_boids.
+
+        * Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp:
+        * Modules/webgpu/WHLSL/WHLSLChecker.cpp:
+        (WebCore::WHLSL::AndOverloadTypeKey::AndOverloadTypeKey):
+        (WebCore::WHLSL::AndOverloadTypeKey::isEmptyValue const):
+        (WebCore::WHLSL::AndOverloadTypeKey::isHashTableDeletedValue const):
+        (WebCore::WHLSL::AndOverloadTypeKey::hash const):
+        (WebCore::WHLSL::AndOverloadTypeKey::operator== const):
+        (WebCore::WHLSL::AndOverloadTypeKey::Hash::hash):
+        (WebCore::WHLSL::AndOverloadTypeKey::Hash::equal):
+        (WebCore::WHLSL::AndOverloadTypeKey::Traits::isEmptyValue):
+        (WebCore::WHLSL::Checker::argumentTypeForAndOverload):
+        (WebCore::WHLSL::Checker::finishVisiting):
+        (WebCore::WHLSL::argumentTypeForAndOverload): Deleted.
+
 2019-08-07  Youenn Fablet  <[email protected]>
 
         Remove IDBDatabaseIdentifier::m_sessionID

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp (248377 => 248378)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp	2019-08-07 18:05:12 UTC (rev 248377)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp	2019-08-07 18:13:57 UTC (rev 248378)
@@ -103,7 +103,6 @@
         }
 
         static const bool safeToCompareToEmptyOrDeleted = false;
-        static const bool emptyValueIsZero = true;
     };
 
     struct Traits : public WTF::SimpleClassHashTraits<DuplicateFunctionKey> {

Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp (248377 => 248378)


--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp	2019-08-07 18:05:12 UTC (rev 248377)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp	2019-08-07 18:13:57 UTC (rev 248378)
@@ -199,6 +199,57 @@
     AST::NamedType* m_castReturnType;
 };
 
+class AndOverloadTypeKey {
+public:
+    AndOverloadTypeKey() = default;
+    AndOverloadTypeKey(WTF::HashTableDeletedValueType)
+    {
+        m_type = bitwise_cast<AST::UnnamedType*>(static_cast<uintptr_t>(1));
+    }
+
+    AndOverloadTypeKey(AST::UnnamedType& type, AST::AddressSpace addressSpace)
+        : m_type(&type)
+        , m_addressSpace(addressSpace)
+    { }
+
+    bool isEmptyValue() const { return !m_type; }
+    bool isHashTableDeletedValue() const { return m_type == bitwise_cast<AST::UnnamedType*>(static_cast<uintptr_t>(1)); }
+
+    unsigned hash() const
+    {
+        return IntHash<uint8_t>::hash(static_cast<uint8_t>(m_addressSpace)) ^ m_type->hash();
+    }
+
+    bool operator==(const AndOverloadTypeKey& other) const
+    {
+        return m_addressSpace == other.m_addressSpace
+            && *m_type == *other.m_type;
+    }
+
+    struct Hash {
+        static unsigned hash(const AndOverloadTypeKey& key)
+        {
+            return key.hash();
+        }
+
+        static bool equal(const AndOverloadTypeKey& a, const AndOverloadTypeKey& b)
+        {
+            return a == b;
+        }
+
+        static const bool safeToCompareToEmptyOrDeleted = false;
+    };
+
+    struct Traits : public WTF::SimpleClassHashTraits<AndOverloadTypeKey> {
+        static const bool hasIsEmptyValueFunction = true;
+        static bool isEmptyValue(const AndOverloadTypeKey& key) { return key.isEmptyValue(); }
+    };
+
+private:
+    AST::UnnamedType* m_type { nullptr };
+    AST::AddressSpace m_addressSpace;
+};
+
 static AST::NativeFunctionDeclaration resolveWithOperatorAnderIndexer(CodeLocation location, AST::ArrayReferenceType& firstArgument, const Intrinsics& intrinsics)
 {
     const bool isOperator = true;
@@ -598,6 +649,8 @@
 
     AST::FunctionDeclaration* resolveFunction(Vector<std::reference_wrapper<ResolvingType>>& types, const String& name, CodeLocation, AST::NamedType* castReturnType = nullptr);
 
+    RefPtr<AST::UnnamedType> argumentTypeForAndOverload(AST::UnnamedType& baseType, AST::AddressSpace);
+
     AST::UnnamedType& wrappedFloatType()
     {
         if (!m_wrappedFloatType)
@@ -634,6 +687,7 @@
     Program& m_program;
     AST::FunctionDefinition* m_currentFunction { nullptr };
     HashMap<FunctionKey, Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>, FunctionKey::Hash, FunctionKey::Traits> m_functions;
+    HashMap<AndOverloadTypeKey, RefPtr<AST::UnnamedType>, AndOverloadTypeKey::Hash, AndOverloadTypeKey::Traits> m_andOverloadTypeMap;
 };
 
 void Checker::visit(Program& program)
@@ -1084,26 +1138,39 @@
     assignConcreteType(makeArrayReferenceExpression, AST::ArrayReferenceType::create(makeArrayReferenceExpression.codeLocation(), *leftAddressSpace, *leftValueType));
 }
 
-static RefPtr<AST::UnnamedType> argumentTypeForAndOverload(AST::UnnamedType& baseType, AST::AddressSpace addressSpace)
+RefPtr<AST::UnnamedType> Checker::argumentTypeForAndOverload(AST::UnnamedType& baseType, AST::AddressSpace addressSpace)
 {
-    auto& unifyNode = baseType.unifyNode();
-    if (is<AST::NamedType>(unifyNode)) {
-        auto& namedType = downcast<AST::NamedType>(unifyNode);
-        return { AST::PointerType::create(namedType.codeLocation(), addressSpace, AST::TypeReference::wrap(namedType.codeLocation(), namedType)) };
+    AndOverloadTypeKey key { baseType, addressSpace };
+    {
+        auto iter = m_andOverloadTypeMap.find(key);
+        if (iter != m_andOverloadTypeMap.end())
+            return iter->value;
     }
 
-    auto& unnamedType = downcast<AST::UnnamedType>(unifyNode);
+    auto createArgumentType = [&] () -> RefPtr<AST::UnnamedType> {
+        auto& unifyNode = baseType.unifyNode();
+        if (is<AST::NamedType>(unifyNode)) {
+            auto& namedType = downcast<AST::NamedType>(unifyNode);
+            return { AST::PointerType::create(namedType.codeLocation(), addressSpace, AST::TypeReference::wrap(namedType.codeLocation(), namedType)) };
+        }
 
-    if (is<AST::ArrayReferenceType>(unnamedType))
-        return &unnamedType;
+        auto& unnamedType = downcast<AST::UnnamedType>(unifyNode);
 
-    if (is<AST::ArrayType>(unnamedType))
-        return { AST::ArrayReferenceType::create(unnamedType.codeLocation(), addressSpace, downcast<AST::ArrayType>(unnamedType).type()) };
+        if (is<AST::ArrayReferenceType>(unnamedType))
+            return &unnamedType;
 
-    if (is<AST::PointerType>(unnamedType))
-        return nullptr;
+        if (is<AST::ArrayType>(unnamedType))
+            return { AST::ArrayReferenceType::create(unnamedType.codeLocation(), addressSpace, downcast<AST::ArrayType>(unnamedType).type()) };
 
-    return { AST::PointerType::create(unnamedType.codeLocation(), addressSpace, unnamedType) };
+        if (is<AST::PointerType>(unnamedType))
+            return nullptr;
+
+        return { AST::PointerType::create(unnamedType.codeLocation(), addressSpace, unnamedType) };
+    };
+
+    auto result = createArgumentType();
+    m_andOverloadTypeMap.add(key, result);
+    return result;
 }
 
 void Checker::finishVisiting(AST::PropertyAccessExpression& propertyAccessExpression, ResolvingType* additionalArgumentType)
@@ -1135,7 +1202,7 @@
     RefPtr<AST::UnnamedType> anderReturnType = nullptr;
     auto leftAddressSpace = baseInfo->typeAnnotation.leftAddressSpace();
     if (leftAddressSpace) {
-        if (auto argumentTypeForAndOverload = WHLSL::argumentTypeForAndOverload(*baseUnnamedType, *leftAddressSpace)) {
+        if (auto argumentTypeForAndOverload = this->argumentTypeForAndOverload(*baseUnnamedType, *leftAddressSpace)) {
             ResolvingType argumentType = { Ref<AST::UnnamedType>(*argumentTypeForAndOverload) };
             Vector<std::reference_wrapper<ResolvingType>> anderArgumentTypes { argumentType };
             if (additionalArgumentType)
@@ -1151,7 +1218,7 @@
 
     AST::FunctionDeclaration* threadAnderFunction = nullptr;
     RefPtr<AST::UnnamedType> threadAnderReturnType = nullptr;
-    if (auto argumentTypeForAndOverload = WHLSL::argumentTypeForAndOverload(*baseUnnamedType, AST::AddressSpace::Thread)) {
+    if (auto argumentTypeForAndOverload = this->argumentTypeForAndOverload(*baseUnnamedType, AST::AddressSpace::Thread)) {
         ResolvingType argumentType = { Ref<AST::UnnamedType>(AST::PointerType::create(propertyAccessExpression.codeLocation(), AST::AddressSpace::Thread, *baseUnnamedType)) };
         Vector<std::reference_wrapper<ResolvingType>> threadAnderArgumentTypes { argumentType };
         if (additionalArgumentType)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to