From 549896a7368869a9f93b59071a5bcf11b2383a88 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 5 Aug 2017 22:48:37 +0000 Subject: [PATCH] [ADT] Add a much simpler loop to DenseMap::clear when the types are POD-like and we can just splat the empty key across memory. Sadly we can't optimize the normal loop well enough because we can't turn the conditional store into an unconditional store according to the memory model. This loop actually showed up in a profile of code that was calling clear as a serious source of time. =[ git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310189 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/DenseMap.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index b311e69ec9d..84ebae08634 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -107,17 +107,23 @@ public: } const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); - unsigned NumEntries = getNumEntries(); - for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) { - if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) { - if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) { - P->getSecond().~ValueT(); - --NumEntries; - } + if (isPodLike::value && isPodLike::value) { + // Use a simpler loop when these are trivial types. + for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) P->getFirst() = EmptyKey; + } else { + unsigned NumEntries = getNumEntries(); + for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) { + if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) { + if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) { + P->getSecond().~ValueT(); + --NumEntries; + } + P->getFirst() = EmptyKey; + } } + assert(NumEntries == 0 && "Node count imbalance!"); } - assert(NumEntries == 0 && "Node count imbalance!"); setNumEntries(0); setNumTombstones(0); } -- 2.50.1