reader/spirv: Optimize FindUnusedDerivedName() Store the last search id suffix so that we don't research the same suffixes over and over again. Bug: oss-fuzz:38098 Bug: oss-fuzz:38606 Bug: oss-fuzz:39300 Bug: oss-fuzz:40339 Change-Id: I295147d91bb9f805170c49114267033bbb781e4d Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/75427 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: David Neto <dneto@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/reader/spirv/namer.cc b/src/reader/spirv/namer.cc index 4d819b4..c2b2e98 100644 --- a/src/reader/spirv/namer.cc +++ b/src/reader/spirv/namer.cc
@@ -104,20 +104,24 @@ return result; } -std::string Namer::FindUnusedDerivedName(const std::string& base_name) const { +std::string Namer::FindUnusedDerivedName(const std::string& base_name) { // Ensure uniqueness among names. std::string derived_name; - int i = 0; - do { + uint32_t& i = next_unusued_derived_name_id_[base_name]; + while (i != 0xffffffff) { std::stringstream new_name_stream; new_name_stream << base_name; if (i > 0) { new_name_stream << "_" << i; } - i++; derived_name = new_name_stream.str(); - } while (IsRegistered(derived_name)); - return derived_name; + if (!IsRegistered(derived_name)) { + return derived_name; + } + i++; + } + TINT_ASSERT(Reader, false /* FindUnusedDerivedName() overflowed u32 */); + return "<u32 overflow>"; } std::string Namer::MakeDerivedName(const std::string& base_name) {
diff --git a/src/reader/spirv/namer.h b/src/reader/spirv/namer.h index 1d231f4..c17d9f0 100644 --- a/src/reader/spirv/namer.h +++ b/src/reader/spirv/namer.h
@@ -92,7 +92,7 @@ /// Returns an unregistered name based on a given base name. /// @param base_name the base name /// @returns a new name - std::string FindUnusedDerivedName(const std::string& base_name) const; + std::string FindUnusedDerivedName(const std::string& base_name); /// Returns a newly registered name based on a given base name. /// In the internal table `name_to_id_`, it is mapped to the invalid @@ -152,6 +152,10 @@ // If entry k in the vector is an empty string, then a suggestion // was recorded for a higher-numbered index, but not for index k. std::unordered_map<uint32_t, std::vector<std::string>> struct_member_names_; + + // Saved search id suffix for a given base name. Used by + // FindUnusedDerivedName(). + std::unordered_map<std::string, uint32_t> next_unusued_derived_name_id_; }; } // namespace spirv