Skip to content

Commit ef06d44

Browse files
committed
IR: Use DenseSet instead of DenseMap for ConstantUniqueMap; NFC
Use a DenseSet instead of a DenseMap for constants in LLVMContextImpl. Last time I looked at this was some time before r223588, when DenseSet<V> had no advantage over DenseMap<V,char>. After r223588, there's a 50% memory savings. This is all mechanical. There were little bits of missing API from DenseSet so I added the trivial implementations: - iterator::operator++(int) - template <class LookupKeyT> insert_as(ValueTy, LookupKeyT) There should be no functionality change, just reduced memory consumption (this wasn't on a profile or anything; just a cleanup I stumbled on). llvm-svn: 265577
1 parent f3d08ef commit ef06d44

File tree

3 files changed

+35
-43
lines changed

3 files changed

+35
-43
lines changed

llvm/include/llvm/ADT/DenseSet.h

+15
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class DenseSet {
9494
ValueT *operator->() { return &I->getFirst(); }
9595

9696
Iterator& operator++() { ++I; return *this; }
97+
Iterator operator++(int) { auto T = *this; ++I; return T; }
9798
bool operator==(const Iterator& X) const { return I == X.I; }
9899
bool operator!=(const Iterator& X) const { return I != X.I; }
99100
};
@@ -115,6 +116,7 @@ class DenseSet {
115116
const ValueT *operator->() { return &I->getFirst(); }
116117

117118
ConstIterator& operator++() { ++I; return *this; }
119+
ConstIterator operator++(int) { auto T = *this; ++I; return T; }
118120
bool operator==(const ConstIterator& X) const { return I == X.I; }
119121
bool operator!=(const ConstIterator& X) const { return I != X.I; }
120122
};
@@ -152,6 +154,19 @@ class DenseSet {
152154
return TheMap.insert(std::make_pair(V, Empty));
153155
}
154156

157+
/// Alternative version of insert that uses a different (and possibly less
158+
/// expensive) key type.
159+
template <typename LookupKeyT>
160+
std::pair<iterator, bool> insert_as(const ValueT &V,
161+
const LookupKeyT &LookupKey) {
162+
return insert_as(ValueT(V), LookupKey);
163+
}
164+
template <typename LookupKeyT>
165+
std::pair<iterator, bool> insert_as(ValueT &&V, const LookupKeyT &LookupKey) {
166+
detail::DenseSetEmpty Empty;
167+
return TheMap.insert_as(std::make_pair(std::move(V), Empty), LookupKey);
168+
}
169+
155170
// Range insertion of values.
156171
template<typename InputIt>
157172
void insert(InputIt I, InputIt E) {

llvm/lib/IR/ConstantsContext.h

+10-11
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#ifndef LLVM_LIB_IR_CONSTANTSCONTEXT_H
1616
#define LLVM_LIB_IR_CONSTANTSCONTEXT_H
1717

18-
#include "llvm/ADT/DenseMap.h"
18+
#include "llvm/ADT/DenseSet.h"
1919
#include "llvm/ADT/Hashing.h"
2020
#include "llvm/IR/InlineAsm.h"
2121
#include "llvm/IR/Instructions.h"
@@ -584,26 +584,25 @@ template <class ConstantClass> class ConstantUniqueMap {
584584
};
585585

586586
public:
587-
typedef DenseMap<ConstantClass *, char, MapInfo> MapTy;
587+
typedef DenseSet<ConstantClass *, MapInfo> MapTy;
588588

589589
private:
590590
MapTy Map;
591591

592592
public:
593-
typename MapTy::iterator map_begin() { return Map.begin(); }
594-
typename MapTy::iterator map_end() { return Map.end(); }
593+
typename MapTy::iterator begin() { return Map.begin(); }
594+
typename MapTy::iterator end() { return Map.end(); }
595595

596596
void freeConstants() {
597597
for (auto &I : Map)
598-
// Asserts that use_empty().
599-
delete I.first;
598+
delete I; // Asserts that use_empty().
600599
}
601600
private:
602601
ConstantClass *create(TypeClass *Ty, ValType V, LookupKeyHashed &HashKey) {
603602
ConstantClass *Result = V.create(Ty);
604603

605604
assert(Result->getType() == Ty && "Type specified is not correct!");
606-
Map.insert_as(std::make_pair(Result, '\0'), HashKey);
605+
Map.insert_as(Result, HashKey);
607606

608607
return Result;
609608
}
@@ -621,7 +620,7 @@ template <class ConstantClass> class ConstantUniqueMap {
621620
if (I == Map.end())
622621
Result = create(Ty, V, Lookup);
623622
else
624-
Result = I->first;
623+
Result = *I;
625624
assert(Result && "Unexpected nullptr");
626625

627626
return Result;
@@ -631,7 +630,7 @@ template <class ConstantClass> class ConstantUniqueMap {
631630
void remove(ConstantClass *CP) {
632631
typename MapTy::iterator I = Map.find(CP);
633632
assert(I != Map.end() && "Constant not found in constant table!");
634-
assert(I->first == CP && "Didn't find correct element?");
633+
assert(*I == CP && "Didn't find correct element?");
635634
Map.erase(I);
636635
}
637636

@@ -645,7 +644,7 @@ template <class ConstantClass> class ConstantUniqueMap {
645644

646645
auto I = Map.find_as(Lookup);
647646
if (I != Map.end())
648-
return I->first;
647+
return *I;
649648

650649
// Update to the new value. Optimize for the case when we have a single
651650
// operand that we're changing, but handle bulk updates efficiently.
@@ -659,7 +658,7 @@ template <class ConstantClass> class ConstantUniqueMap {
659658
if (CP->getOperand(I) == From)
660659
CP->setOperand(I, To);
661660
}
662-
Map.insert_as(std::make_pair(CP, '\0'), Lookup);
661+
Map.insert_as(CP, Lookup);
663662
return nullptr;
664663
}
665664

llvm/lib/IR/LLVMContextImpl.cpp

+10-32
Original file line numberDiff line numberDiff line change
@@ -48,26 +48,6 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
4848
NamedStructTypesUniqueID = 0;
4949
}
5050

51-
namespace {
52-
struct DropReferences {
53-
// Takes the value_type of a ConstantUniqueMap's internal map, whose 'second'
54-
// is a Constant*.
55-
template <typename PairT> void operator()(const PairT &P) {
56-
P.second->dropAllReferences();
57-
}
58-
};
59-
60-
// Temporary - drops pair.first instead of second.
61-
struct DropFirst {
62-
// Takes the value_type of a ConstantUniqueMap's internal map, whose 'second'
63-
// is a Constant*.
64-
template<typename PairT>
65-
void operator()(const PairT &P) {
66-
P.first->dropAllReferences();
67-
}
68-
};
69-
}
70-
7151
LLVMContextImpl::~LLVMContextImpl() {
7252
// NOTE: We need to delete the contents of OwnedModules, but Module's dtor
7353
// will call LLVMContextImpl::removeModule, thus invalidating iterators into
@@ -99,14 +79,14 @@ LLVMContextImpl::~LLVMContextImpl() {
9979
#include "llvm/IR/Metadata.def"
10080

10181
// Free the constants.
102-
std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(),
103-
DropFirst());
104-
std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(),
105-
DropFirst());
106-
std::for_each(StructConstants.map_begin(), StructConstants.map_end(),
107-
DropFirst());
108-
std::for_each(VectorConstants.map_begin(), VectorConstants.map_end(),
109-
DropFirst());
82+
for (auto *I : ExprConstants)
83+
I->dropAllReferences();
84+
for (auto *I : ArrayConstants)
85+
I->dropAllReferences();
86+
for (auto *I : StructConstants)
87+
I->dropAllReferences();
88+
for (auto *I : VectorConstants)
89+
I->dropAllReferences();
11090
ExprConstants.freeConstants();
11191
ArrayConstants.freeConstants();
11292
StructConstants.freeConstants();
@@ -165,10 +145,8 @@ void LLVMContextImpl::dropTriviallyDeadConstantArrays() {
165145
do {
166146
Changed = false;
167147

168-
for (auto I = ArrayConstants.map_begin(), E = ArrayConstants.map_end();
169-
I != E; ) {
170-
auto *C = I->first;
171-
I++;
148+
for (auto I = ArrayConstants.begin(), E = ArrayConstants.end(); I != E;) {
149+
auto *C = *I++;
172150
if (C->use_empty()) {
173151
Changed = true;
174152
C->destroyConstant();

0 commit comments

Comments
 (0)