diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp index d4d12083197d..e895d641a600 100644 --- a/clang-tools-extra/clang-doc/JSONGenerator.cpp +++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp @@ -155,7 +155,7 @@ static void insertComment(Object &Description, json::Value &Comment, Description[Key] = std::move(CommentsArray); Description["Has" + Key.str()] = true; } else { - DescriptionIt->second.getAsArray()->push_back(Comment); + DescriptionIt->getSecond().getAsArray()->push_back(Comment); } } diff --git a/clang/include/clang/Basic/Sarif.h b/clang/include/clang/Basic/Sarif.h index a9099271ccc0..7651d2ac7a76 100644 --- a/clang/include/clang/Basic/Sarif.h +++ b/clang/include/clang/Basic/Sarif.h @@ -34,7 +34,6 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Version.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" diff --git a/clang/lib/Basic/DarwinSDKInfo.cpp b/clang/lib/Basic/DarwinSDKInfo.cpp index 39d08387f8d1..f7d02ef97f5a 100644 --- a/clang/lib/Basic/DarwinSDKInfo.cpp +++ b/clang/lib/Basic/DarwinSDKInfo.cpp @@ -25,7 +25,7 @@ std::optional DarwinSDKInfo::RelatedTargetVersionMapping::map( return MaximumValue; auto KV = Mapping.find(Key.normalize()); if (KV != Mapping.end()) - return KV->second; + return KV->getSecond(); // If no exact entry found, try just the major key version. Only do so when // a minor version number is present, to avoid recursing indefinitely into // the major-only check. @@ -43,10 +43,10 @@ DarwinSDKInfo::RelatedTargetVersionMapping::parseJSON( VersionTuple MinValue = Min; llvm::DenseMap Mapping; for (const auto &KV : Obj) { - if (auto Val = KV.second.getAsString()) { + if (auto Val = KV.getSecond().getAsString()) { llvm::VersionTuple KeyVersion; llvm::VersionTuple ValueVersion; - if (KeyVersion.tryParse(KV.first) || ValueVersion.tryParse(*Val)) + if (KeyVersion.tryParse(KV.getFirst()) || ValueVersion.tryParse(*Val)) return std::nullopt; Mapping[KeyVersion.normalize()] = ValueVersion; if (KeyVersion < Min) @@ -119,7 +119,7 @@ static DarwinSDKInfo::PlatformInfoStorageType parsePlatformInfos( for (auto SupportedTargetPair : *SupportedTargets) { llvm::json::Object *SupportedTarget = - SupportedTargetPair.second.getAsObject(); + SupportedTargetPair.getSecond().getAsObject(); auto Vendor = SupportedTarget->getString("LLVMTargetTripleVendor"); auto OS = SupportedTarget->getString("LLVMTargetTripleSys"); if (!Vendor || !OS) @@ -136,7 +136,7 @@ static DarwinSDKInfo::PlatformInfoStorageType parsePlatformInfos( // The key is either the Xcode platform, or a variant. The platform must be // the first entry in the returned PlatformInfoStorageType. - StringRef PlatformOrVariant = SupportedTargetPair.first; + StringRef PlatformOrVariant = SupportedTargetPair.getFirst(); StringRef EffectivePlatformPrefix; // Ignore iosmac value if it exists. @@ -202,12 +202,12 @@ DarwinSDKInfo::parseDarwinSDKSettingsJSON(std::string FilePath, // FIXME: Generalize this out beyond iOS-deriving targets. // Look for ios_ version mapping for targets that derive from ios. for (const auto &KV : *VM) { - auto Pair = StringRef(KV.first).split("_"); + auto Pair = StringRef(KV.getFirst()).split("_"); if (Pair.first.compare_insensitive("ios") == 0) { llvm::Triple TT(llvm::Twine("--") + Pair.second.lower()); if (TT.getOS() != llvm::Triple::UnknownOS) { auto Mapping = RelatedTargetVersionMapping::parseJSON( - *KV.second.getAsObject(), *MaximumDeploymentVersion); + *KV.getSecond().getAsObject(), *MaximumDeploymentVersion); if (Mapping) VersionMappings[OSEnvPair(llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp index 1151f65af4dc..f484d6f33ad8 100644 --- a/clang/tools/clang-installapi/Options.cpp +++ b/clang/tools/clang-installapi/Options.cpp @@ -84,8 +84,8 @@ getArgListFromJSON(const StringRef Input, llvm::opt::OptTable *Table, return llvm::opt::InputArgList(); for (const auto &KV : *Root) { - const Array *ArgList = KV.second.getAsArray(); - std::string Label = "-X" + KV.first.str(); + const Array *ArgList = KV.getSecond().getAsArray(); + std::string Label = "-X" + KV.getFirst().str(); if (!ArgList) return make_error(TextAPIErrorCode::InvalidInputFormat); for (auto Arg : *ArgList) { diff --git a/clang/unittests/Basic/SarifTest.cpp b/clang/unittests/Basic/SarifTest.cpp index cfae48a96c2a..42e85085d646 100644 --- a/clang/unittests/Basic/SarifTest.cpp +++ b/clang/unittests/Basic/SarifTest.cpp @@ -83,7 +83,7 @@ TEST_F(SarifDocumentWriterTest, canCreateEmptyDocument) { const llvm::json::Object &EmptyDoc = Writer.createDocument(); std::vector Keys(EmptyDoc.size()); std::transform(EmptyDoc.begin(), EmptyDoc.end(), Keys.begin(), - [](auto Item) { return Item.first; }); + [](auto Item) { return Item.getFirst(); }); // THEN: ASSERT_THAT(Keys, testing::UnorderedElementsAre("$schema", "version")); diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h index 603badf3330a..eebb5117b30c 100644 --- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h +++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h @@ -12,8 +12,6 @@ #include "lldb/Target/DynamicLoader.h" #include "lldb/lldb-forward.h" -#include "llvm/ADT/DenseMap.h" - namespace lldb_private { class DynamicLoaderWindowsDYLD : public DynamicLoader { diff --git a/lldb/source/Plugins/Process/Linux/IntelPTThreadTraceCollection.h b/lldb/source/Plugins/Process/Linux/IntelPTThreadTraceCollection.h index 31388d4b9be8..550cd46127ed 100644 --- a/lldb/source/Plugins/Process/Linux/IntelPTThreadTraceCollection.h +++ b/lldb/source/Plugins/Process/Linux/IntelPTThreadTraceCollection.h @@ -10,7 +10,6 @@ #define liblldb_IntelPTPerThreadTraceCollection_H_ #include "IntelPTSingleBufferTrace.h" -#include "llvm/ADT/DenseMap.h" #include namespace lldb_private { diff --git a/llvm/benchmarks/CMakeLists.txt b/llvm/benchmarks/CMakeLists.txt index bdd1ce40d2cb..69ebeaa78344 100644 --- a/llvm/benchmarks/CMakeLists.txt +++ b/llvm/benchmarks/CMakeLists.txt @@ -15,7 +15,6 @@ add_benchmark(MustacheBench Mustache.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(SpecialCaseListBM SpecialCaseListBM.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(DWARFVerifierBM DWARFVerifierBM.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(PointerUnionBM PointerUnionBM.cpp PARTIAL_SOURCES_INTENDED) -add_benchmark(JSONParserBM JSONParserBM.cpp PARTIAL_SOURCES_INTENDED) add_benchmark(RuntimeLibcallsBench RuntimeLibcalls.cpp PARTIAL_SOURCES_INTENDED) diff --git a/llvm/benchmarks/JSONParserBM.cpp b/llvm/benchmarks/JSONParserBM.cpp deleted file mode 100644 index b5deb0bbf2f6..000000000000 --- a/llvm/benchmarks/JSONParserBM.cpp +++ /dev/null @@ -1,299 +0,0 @@ -//===- JSONParserBM.cpp - JSON parser benchmarks --------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// \file -// Benchmarks for LLVM's JSON parser. -// Runs parsing, tree iteration, and object key lookup with generated inputs. -// Measures time performance and memory consumption. -// -//===----------------------------------------------------------------------===// - -#include "benchmark/benchmark.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/JSON.h" -#include -#include -#include - -using namespace llvm; - -//===----------------------------------------------------------------------===// -// Memory tracking via global operator new -// -// These are global overrides so the benchmark might be over-counting memory -// allocations and usage. The data is still useful for comparisons with this -// benchmark itself. -//===----------------------------------------------------------------------===// - -static std::atomic_size_t TotalAllocatedBytes{0}; -static std::atomic_size_t NumAllocs{0}; -static bool TrackMemory = false; - -// Single-object new/delete. -void *operator new(std::size_t Size) { - if (TrackMemory) { - TotalAllocatedBytes += Size; - ++NumAllocs; - } - return std::malloc(Size); -} - -void *operator new(std::size_t Size, std::align_val_t) { - if (TrackMemory) { - TotalAllocatedBytes += Size; - ++NumAllocs; - } - return std::malloc(Size); -} - -void *operator new(std::size_t Size, const std::nothrow_t &) noexcept { - if (TrackMemory) { - TotalAllocatedBytes += Size; - ++NumAllocs; - } - return std::malloc(Size); -} - -void *operator new(std::size_t Size, std::align_val_t, - const std::nothrow_t &) noexcept { - if (TrackMemory) { - TotalAllocatedBytes += Size; - ++NumAllocs; - } - return std::malloc(Size); -} - -void operator delete(void *Ptr) noexcept { std::free(Ptr); } -void operator delete(void *Ptr, std::align_val_t) noexcept { std::free(Ptr); } -void operator delete(void *Ptr, std::size_t) noexcept { std::free(Ptr); } -void operator delete(void *Ptr, std::size_t, std::align_val_t) noexcept { - std::free(Ptr); -} - -// Array new/delete. -void *operator new[](std::size_t Size) { - if (TrackMemory) { - TotalAllocatedBytes += Size; - ++NumAllocs; - } - return std::malloc(Size); -} - -void *operator new[](std::size_t Size, std::align_val_t) { - if (TrackMemory) { - TotalAllocatedBytes += Size; - ++NumAllocs; - } - return std::malloc(Size); -} - -void *operator new[](std::size_t Size, const std::nothrow_t &) noexcept { - if (TrackMemory) { - TotalAllocatedBytes += Size; - ++NumAllocs; - } - return std::malloc(Size); -} - -void *operator new[](std::size_t Size, std::align_val_t, - const std::nothrow_t &) noexcept { - if (TrackMemory) { - TotalAllocatedBytes += Size; - ++NumAllocs; - } - return std::malloc(Size); -} - -void operator delete[](void *Ptr) noexcept { std::free(Ptr); } -void operator delete[](void *Ptr, std::align_val_t) noexcept { std::free(Ptr); } -void operator delete[](void *Ptr, std::size_t) noexcept { std::free(Ptr); } -void operator delete[](void *Ptr, std::size_t, std::align_val_t) noexcept { - std::free(Ptr); -} - -//===----------------------------------------------------------------------===// -// Test data generation -//===----------------------------------------------------------------------===// - -/// Generate a JSON string with \p N entries in an array. Each entry is a nested -/// structure with objects and arrays to exercise parsing, iteration, and lookup -/// at multiple depths. -/// -/// Structure: -/// {"items": [ -/// { -/// "name": "item_I", -/// "value": I, -/// "tags": [ -/// {"label": "tag_0", "priority": 0}, -/// ... -/// ], -/// "details": { -/// "description": "description text for item I", -/// "active": true/false, -/// "nested": { "x": I, "y": I*100 } -/// } -/// }, -/// ... -/// ]} -static std::string generateJSON(int N) { - std::string S; - raw_string_ostream OS(S); - OS << "{\"items\": [\n"; - for (int I = 0; I < N; ++I) { - if (I > 0) - OS << ",\n"; - OS << " {\n" - << " \"name\": \"item_" << I << "\",\n" - << " \"value\": " << I << ",\n" - << " \"tags\": [\n" - << " {\"label\": \"tag_0\", \"priority\": 0},\n" - << " {\"label\": \"tag_1\", \"priority\": 1},\n" - << " {\"label\": \"tag_2\", \"priority\": 2}\n" - << " ],\n" - << " \"details\": {\n" - << " \"description\": \"description text for item " << I << "\",\n" - << " \"active\": " << (I % 2 == 0 ? "true" : "false") << ",\n" - << " \"nested\": {\"x\": " << I << ", \"y\": " << I * 100 << "}\n" - << " }\n" - << " }"; - } - OS << "\n]}"; - return S; -} - -//===----------------------------------------------------------------------===// -// Tree traversal helpers -//===----------------------------------------------------------------------===// - -/// Walk the JSON value tree, visiting every node. Returns the number of -/// nodes visited. -static size_t walkTree(const json::Value &V) { - size_t Count = 1; - if (const auto *Obj = V.getAsObject()) { - for (const auto &KV : *Obj) - Count += walkTree(KV.second); - } else if (const auto *Arr = V.getAsArray()) { - for (const auto &Elem : *Arr) - Count += walkTree(Elem); - } - return Count; -} - -/// An Object paired with its own keys, for lookup benchmarks. -struct ObjectWithKeys { - const json::Object *Obj; - SmallVector Keys; -}; - -/// Collect every Object in the tree together with its own keys. -static void collectObjectsWithKeys(const json::Value &V, - SmallVectorImpl &Result) { - if (const auto *Obj = V.getAsObject()) { - ObjectWithKeys Entry; - Entry.Obj = Obj; - for (const auto &KV : *Obj) { - Entry.Keys.push_back(std::string(StringRef(KV.first))); - collectObjectsWithKeys(KV.second, Result); - } - Result.push_back(std::move(Entry)); - } else if (const auto *Arr = V.getAsArray()) { - for (const auto &Elem : *Arr) - collectObjectsWithKeys(Elem, Result); - } -} - -//===----------------------------------------------------------------------===// -// Benchmarks -//===----------------------------------------------------------------------===// - -/// Benchmark json::parse(). Reports parse throughput and memory allocated. -static void BM_JSONParse(benchmark::State &State) { - std::string JSON = generateJSON(State.range(0)); - - // Measure memory for a single parse before the timed loop. - TotalAllocatedBytes = 0; - NumAllocs = 0; - TrackMemory = true; - { - auto V = json::parse(JSON); - benchmark::DoNotOptimize(V); - } - TrackMemory = false; - - State.counters["AllocBytes"] = TotalAllocatedBytes.load(); - State.counters["Allocs"] = NumAllocs.load(); - - for (auto _ : State) { - auto V = json::parse(JSON); - benchmark::DoNotOptimize(V); - } - State.counters["ParseByteRate"] = benchmark::Counter( - State.iterations() * JSON.size(), benchmark::Counter::kIsRate, - benchmark::Counter::kIs1024); -} -BENCHMARK(BM_JSONParse)->Arg(10)->Arg(1000)->Arg(100000); - -/// Benchmark recursive tree iteration over a parsed JSON value. -static void BM_JSONIterate(benchmark::State &State) { - std::string JSON = generateJSON(State.range(0)); - json::Value Root = cantFail(json::parse(JSON)); - size_t NodeCount = 0; - for (auto _ : State) { - NodeCount = walkTree(Root); - benchmark::DoNotOptimize(NodeCount); - } - State.SetItemsProcessed(State.iterations() * NodeCount); -} -BENCHMARK(BM_JSONIterate)->Arg(10)->Arg(1000)->Arg(100000); - -/// Benchmark Object::get() with each object's own keys in insertion order. -static void BM_JSONLookupSequential(benchmark::State &State) { - std::string JSON = generateJSON(State.range(0)); - json::Value Root = cantFail(json::parse(JSON)); - SmallVector ObjKeys; - collectObjectsWithKeys(Root, ObjKeys); - - size_t TotalLookups = 0; - for (const auto &OK : ObjKeys) - TotalLookups += OK.Keys.size(); - - for (auto _ : State) { - for (const auto &OK : ObjKeys) - for (const auto &K : OK.Keys) - benchmark::DoNotOptimize(OK.Obj->get(K)); - } - State.SetItemsProcessed(State.iterations() * TotalLookups); -} -BENCHMARK(BM_JSONLookupSequential)->Arg(10)->Arg(1000)->Arg(100000); - -/// Benchmark Object::get() with each object's own keys in random order. -static void BM_JSONLookupRandom(benchmark::State &State) { - std::string JSON = generateJSON(State.range(0)); - json::Value Root = cantFail(json::parse(JSON)); - SmallVector ObjKeys; - collectObjectsWithKeys(Root, ObjKeys); - - std::mt19937 RNG(42); - size_t TotalLookups = 0; - for (auto &OK : ObjKeys) { - TotalLookups += OK.Keys.size(); - std::shuffle(OK.Keys.begin(), OK.Keys.end(), RNG); - } - - for (auto _ : State) { - for (const auto &OK : ObjKeys) - for (const auto &K : OK.Keys) - benchmark::DoNotOptimize(OK.Obj->get(K)); - } - State.SetItemsProcessed(State.iterations() * TotalLookups); -} -BENCHMARK(BM_JSONLookupRandom)->Arg(10)->Arg(1000)->Arg(100000); - -BENCHMARK_MAIN(); diff --git a/llvm/include/llvm/Support/JSON.h b/llvm/include/llvm/Support/JSON.h index c2148547e525..27862eb7ab6b 100644 --- a/llvm/include/llvm/Support/JSON.h +++ b/llvm/include/llvm/Support/JSON.h @@ -46,17 +46,16 @@ #ifndef LLVM_SUPPORT_JSON_H #define LLVM_SUPPORT_JSON_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/AlignOf.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" #include #include -#include namespace llvm { namespace json { @@ -95,14 +94,9 @@ class Value; template Value toJSON(const std::optional &Opt); /// An Object is a JSON object, which maps strings to heterogenous JSON values. -/// ObjectKey is a maybe-owned string. +/// It simulates DenseMap. ObjectKey is a maybe-owned string. class Object { - struct ObjectKeyHash { - template size_t operator()(const T &Key) const { - return hash_value(Key); - } - }; - using Storage = std::unordered_map; + using Storage = DenseMap>; Storage M; public: @@ -139,11 +133,8 @@ public: bool erase(StringRef K); void erase(iterator I) { M.erase(I); } - // TODO: Implement heterogeneous lookup using StringRef directly. We need to - // make ObjectKey transparent with transparent hash and key equality check. - // This is supported for unordered containers in C++20. - iterator find(const ObjectKey &K) { return M.find(K); } - const_iterator find(const ObjectKey &K) const { return M.find(K); } + iterator find(StringRef K) { return M.find_as(K); } + const_iterator find(StringRef K) const { return M.find_as(K); } // operator[] acts as if Value was default-constructible as null. LLVM_ABI Value &operator[](const ObjectKey &K); LLVM_ABI Value &operator[](ObjectKey &&K); @@ -655,7 +646,7 @@ inline Object::Object(std::initializer_list Properties) { for (const auto &P : Properties) { auto R = try_emplace(P.K, nullptr); if (R.second) - R.first->second.moveFrom(std::move(P.V)); + R.first->getSecond().moveFrom(std::move(P.V)); } } inline std::pair Object::insert(KV E) { diff --git a/llvm/lib/Support/JSON.cpp b/llvm/lib/Support/JSON.cpp index 3124e6f0b8da..23c2542d7581 100644 --- a/llvm/lib/Support/JSON.cpp +++ b/llvm/lib/Support/JSON.cpp @@ -22,10 +22,10 @@ namespace llvm { namespace json { Value &Object::operator[](const ObjectKey &K) { - return try_emplace(K, nullptr).first->second; + return try_emplace(K, nullptr).first->getSecond(); } Value &Object::operator[](ObjectKey &&K) { - return try_emplace(std::move(K), nullptr).first->second; + return try_emplace(std::move(K), nullptr).first->getSecond(); } Value *Object::get(StringRef K) { auto I = find(K); diff --git a/llvm/tools/llvm-mca/Views/InstructionInfoView.h b/llvm/tools/llvm-mca/Views/InstructionInfoView.h index a54d21528b72..34c6fec46a6d 100644 --- a/llvm/tools/llvm-mca/Views/InstructionInfoView.h +++ b/llvm/tools/llvm-mca/Views/InstructionInfoView.h @@ -36,7 +36,6 @@ #include "Views/InstructionView.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h"