Changeset 248378 in webkit
- Timestamp:
- Aug 7, 2019 11:13:57 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r248377 r248378 1 2019-08-07 Saam Barati <sbarati@apple.com> 2 3 [WHLSL] cache results of argumentTypeForAndOverload inside Checker 4 https://bugs.webkit.org/show_bug.cgi?id=200462 5 6 Reviewed by Robin Morisset. 7 8 When I profiled the time we spent in the checker, it turned out that 9 argumentTypeForAndOverload is one of the most expensive functions. If 10 we just cache the results of that function, we can avoid 99% of the 11 duplicate allocations that function does in compute_boids. This patch 12 is a ~4ms speedup in the checker on compute_boids. 13 14 * Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp: 15 * Modules/webgpu/WHLSL/WHLSLChecker.cpp: 16 (WebCore::WHLSL::AndOverloadTypeKey::AndOverloadTypeKey): 17 (WebCore::WHLSL::AndOverloadTypeKey::isEmptyValue const): 18 (WebCore::WHLSL::AndOverloadTypeKey::isHashTableDeletedValue const): 19 (WebCore::WHLSL::AndOverloadTypeKey::hash const): 20 (WebCore::WHLSL::AndOverloadTypeKey::operator== const): 21 (WebCore::WHLSL::AndOverloadTypeKey::Hash::hash): 22 (WebCore::WHLSL::AndOverloadTypeKey::Hash::equal): 23 (WebCore::WHLSL::AndOverloadTypeKey::Traits::isEmptyValue): 24 (WebCore::WHLSL::Checker::argumentTypeForAndOverload): 25 (WebCore::WHLSL::Checker::finishVisiting): 26 (WebCore::WHLSL::argumentTypeForAndOverload): Deleted. 27 1 28 2019-08-07 Youenn Fablet <youenn@apple.com> 2 29 -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLCheckDuplicateFunctions.cpp
r247878 r248378 104 104 105 105 static const bool safeToCompareToEmptyOrDeleted = false; 106 static const bool emptyValueIsZero = true;107 106 }; 108 107 -
trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
r248339 r248378 198 198 Vector<std::reference_wrapper<AST::UnnamedType>> m_types; 199 199 AST::NamedType* m_castReturnType; 200 }; 201 202 class AndOverloadTypeKey { 203 public: 204 AndOverloadTypeKey() = default; 205 AndOverloadTypeKey(WTF::HashTableDeletedValueType) 206 { 207 m_type = bitwise_cast<AST::UnnamedType*>(static_cast<uintptr_t>(1)); 208 } 209 210 AndOverloadTypeKey(AST::UnnamedType& type, AST::AddressSpace addressSpace) 211 : m_type(&type) 212 , m_addressSpace(addressSpace) 213 { } 214 215 bool isEmptyValue() const { return !m_type; } 216 bool isHashTableDeletedValue() const { return m_type == bitwise_cast<AST::UnnamedType*>(static_cast<uintptr_t>(1)); } 217 218 unsigned hash() const 219 { 220 return IntHash<uint8_t>::hash(static_cast<uint8_t>(m_addressSpace)) ^ m_type->hash(); 221 } 222 223 bool operator==(const AndOverloadTypeKey& other) const 224 { 225 return m_addressSpace == other.m_addressSpace 226 && *m_type == *other.m_type; 227 } 228 229 struct Hash { 230 static unsigned hash(const AndOverloadTypeKey& key) 231 { 232 return key.hash(); 233 } 234 235 static bool equal(const AndOverloadTypeKey& a, const AndOverloadTypeKey& b) 236 { 237 return a == b; 238 } 239 240 static const bool safeToCompareToEmptyOrDeleted = false; 241 }; 242 243 struct Traits : public WTF::SimpleClassHashTraits<AndOverloadTypeKey> { 244 static const bool hasIsEmptyValueFunction = true; 245 static bool isEmptyValue(const AndOverloadTypeKey& key) { return key.isEmptyValue(); } 246 }; 247 248 private: 249 AST::UnnamedType* m_type { nullptr }; 250 AST::AddressSpace m_addressSpace; 200 251 }; 201 252 … … 599 650 AST::FunctionDeclaration* resolveFunction(Vector<std::reference_wrapper<ResolvingType>>& types, const String& name, CodeLocation, AST::NamedType* castReturnType = nullptr); 600 651 652 RefPtr<AST::UnnamedType> argumentTypeForAndOverload(AST::UnnamedType& baseType, AST::AddressSpace); 653 601 654 AST::UnnamedType& wrappedFloatType() 602 655 { … … 635 688 AST::FunctionDefinition* m_currentFunction { nullptr }; 636 689 HashMap<FunctionKey, Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>, FunctionKey::Hash, FunctionKey::Traits> m_functions; 690 HashMap<AndOverloadTypeKey, RefPtr<AST::UnnamedType>, AndOverloadTypeKey::Hash, AndOverloadTypeKey::Traits> m_andOverloadTypeMap; 637 691 }; 638 692 … … 1085 1139 } 1086 1140 1087 static RefPtr<AST::UnnamedType> argumentTypeForAndOverload(AST::UnnamedType& baseType, AST::AddressSpace addressSpace) 1088 { 1089 auto& unifyNode = baseType.unifyNode(); 1090 if (is<AST::NamedType>(unifyNode)) { 1091 auto& namedType = downcast<AST::NamedType>(unifyNode); 1092 return { AST::PointerType::create(namedType.codeLocation(), addressSpace, AST::TypeReference::wrap(namedType.codeLocation(), namedType)) }; 1093 } 1094 1095 auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); 1096 1097 if (is<AST::ArrayReferenceType>(unnamedType)) 1098 return &unnamedType; 1099 1100 if (is<AST::ArrayType>(unnamedType)) 1101 return { AST::ArrayReferenceType::create(unnamedType.codeLocation(), addressSpace, downcast<AST::ArrayType>(unnamedType).type()) }; 1102 1103 if (is<AST::PointerType>(unnamedType)) 1104 return nullptr; 1105 1106 return { AST::PointerType::create(unnamedType.codeLocation(), addressSpace, unnamedType) }; 1141 RefPtr<AST::UnnamedType> Checker::argumentTypeForAndOverload(AST::UnnamedType& baseType, AST::AddressSpace addressSpace) 1142 { 1143 AndOverloadTypeKey key { baseType, addressSpace }; 1144 { 1145 auto iter = m_andOverloadTypeMap.find(key); 1146 if (iter != m_andOverloadTypeMap.end()) 1147 return iter->value; 1148 } 1149 1150 auto createArgumentType = [&] () -> RefPtr<AST::UnnamedType> { 1151 auto& unifyNode = baseType.unifyNode(); 1152 if (is<AST::NamedType>(unifyNode)) { 1153 auto& namedType = downcast<AST::NamedType>(unifyNode); 1154 return { AST::PointerType::create(namedType.codeLocation(), addressSpace, AST::TypeReference::wrap(namedType.codeLocation(), namedType)) }; 1155 } 1156 1157 auto& unnamedType = downcast<AST::UnnamedType>(unifyNode); 1158 1159 if (is<AST::ArrayReferenceType>(unnamedType)) 1160 return &unnamedType; 1161 1162 if (is<AST::ArrayType>(unnamedType)) 1163 return { AST::ArrayReferenceType::create(unnamedType.codeLocation(), addressSpace, downcast<AST::ArrayType>(unnamedType).type()) }; 1164 1165 if (is<AST::PointerType>(unnamedType)) 1166 return nullptr; 1167 1168 return { AST::PointerType::create(unnamedType.codeLocation(), addressSpace, unnamedType) }; 1169 }; 1170 1171 auto result = createArgumentType(); 1172 m_andOverloadTypeMap.add(key, result); 1173 return result; 1107 1174 } 1108 1175 … … 1136 1203 auto leftAddressSpace = baseInfo->typeAnnotation.leftAddressSpace(); 1137 1204 if (leftAddressSpace) { 1138 if (auto argumentTypeForAndOverload = WHLSL::argumentTypeForAndOverload(*baseUnnamedType, *leftAddressSpace)) {1205 if (auto argumentTypeForAndOverload = this->argumentTypeForAndOverload(*baseUnnamedType, *leftAddressSpace)) { 1139 1206 ResolvingType argumentType = { Ref<AST::UnnamedType>(*argumentTypeForAndOverload) }; 1140 1207 Vector<std::reference_wrapper<ResolvingType>> anderArgumentTypes { argumentType }; … … 1152 1219 AST::FunctionDeclaration* threadAnderFunction = nullptr; 1153 1220 RefPtr<AST::UnnamedType> threadAnderReturnType = nullptr; 1154 if (auto argumentTypeForAndOverload = WHLSL::argumentTypeForAndOverload(*baseUnnamedType, AST::AddressSpace::Thread)) {1221 if (auto argumentTypeForAndOverload = this->argumentTypeForAndOverload(*baseUnnamedType, AST::AddressSpace::Thread)) { 1155 1222 ResolvingType argumentType = { Ref<AST::UnnamedType>(AST::PointerType::create(propertyAccessExpression.codeLocation(), AST::AddressSpace::Thread, *baseUnnamedType)) }; 1156 1223 Vector<std::reference_wrapper<ResolvingType>> threadAnderArgumentTypes { argumentType };
Note: See TracChangeset
for help on using the changeset viewer.