1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

ADT: Save a word in every StringSet entry

Add a specialization to StringMap (actually StringMapEntry) for a
value type of NoneType (the type of llvm::None), and use it for
StringSet. This'll save us a word from every entry in a StringSet,
used for alignment with the size_t that stores the string length.

I could have gone all the way to some kind of empty base class
optimization, but that seemed like overkill. Someone can consider
adding that in the future, though.

https://reviews.llvm.org/D68586

llvm-svn: 374440
This commit is contained in:
Jordan Rose 2019-10-10 20:22:53 +00:00
parent 9d704780f9
commit fa21e7962b
5 changed files with 43 additions and 20 deletions

View File

@ -118,36 +118,59 @@ public:
}
};
/// StringMapEntry - This is used to represent one value that is inserted into
/// a StringMap. It contains the Value itself and the key: the string length
/// and data.
/// StringMapEntryStorage - Holds the value in a StringMapEntry.
///
/// Factored out into a separate base class to make it easier to specialize.
/// This is primarily intended to support StringSet, which doesn't need a value
/// stored at all.
template<typename ValueTy>
class StringMapEntry : public StringMapEntryBase {
class StringMapEntryStorage : public StringMapEntryBase {
public:
ValueTy second;
explicit StringMapEntry(size_t strLen)
explicit StringMapEntryStorage(size_t strLen)
: StringMapEntryBase(strLen), second() {}
template <typename... InitTy>
StringMapEntry(size_t strLen, InitTy &&... InitVals)
StringMapEntryStorage(size_t strLen, InitTy &&... InitVals)
: StringMapEntryBase(strLen), second(std::forward<InitTy>(InitVals)...) {}
StringMapEntry(StringMapEntry &E) = delete;
StringRef getKey() const {
return StringRef(getKeyData(), getKeyLength());
}
StringMapEntryStorage(StringMapEntryStorage &E) = delete;
const ValueTy &getValue() const { return second; }
ValueTy &getValue() { return second; }
void setValue(const ValueTy &V) { second = V; }
};
template<>
class StringMapEntryStorage<NoneType> : public StringMapEntryBase {
public:
explicit StringMapEntryStorage(size_t strLen, NoneType none = None)
: StringMapEntryBase(strLen) {}
StringMapEntryStorage(StringMapEntryStorage &E) = delete;
NoneType getValue() const { return None; }
};
/// StringMapEntry - This is used to represent one value that is inserted into
/// a StringMap. It contains the Value itself and the key: the string length
/// and data.
template<typename ValueTy>
class StringMapEntry final : public StringMapEntryStorage<ValueTy> {
public:
using StringMapEntryStorage<ValueTy>::StringMapEntryStorage;
StringRef getKey() const {
return StringRef(getKeyData(), this->getKeyLength());
}
/// getKeyData - Return the start of the string data that is the key for this
/// value. The string data is always stored immediately after the
/// StringMapEntry object.
const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
StringRef first() const { return StringRef(getKeyData(), getKeyLength()); }
StringRef first() const {
return StringRef(getKeyData(), this->getKeyLength());
}
/// Create a StringMapEntry for the specified key construct the value using
/// \p InitiVals.
@ -199,7 +222,7 @@ public:
template<typename AllocatorTy>
void Destroy(AllocatorTy &Allocator) {
// Free memory referenced by the item.
size_t AllocSize = sizeof(StringMapEntry) + getKeyLength() + 1;
size_t AllocSize = sizeof(StringMapEntry) + this->getKeyLength() + 1;
this->~StringMapEntry();
Allocator.Deallocate(static_cast<void *>(this), AllocSize);
}

View File

@ -24,8 +24,8 @@ namespace llvm {
/// StringSet - A wrapper for StringMap that provides set-like functionality.
template <class AllocatorTy = MallocAllocator>
class StringSet : public StringMap<char, AllocatorTy> {
using base = StringMap<char, AllocatorTy>;
class StringSet : public StringMap<NoneType, AllocatorTy> {
using base = StringMap<NoneType, AllocatorTy>;
public:
StringSet() = default;
@ -37,13 +37,13 @@ namespace llvm {
std::pair<typename base::iterator, bool> insert(StringRef Key) {
assert(!Key.empty());
return base::insert(std::make_pair(Key, '\0'));
return base::insert(std::make_pair(Key, None));
}
template <typename InputIt>
void insert(const InputIt &Begin, const InputIt &End) {
for (auto It = Begin; It != End; ++It)
base::insert(std::make_pair(*It, '\0'));
base::insert(std::make_pair(*It, None));
}
template <typename ValueTy>

View File

@ -601,7 +601,7 @@ dyn_extract_or_null(Y &&MD) {
/// These are used to efficiently contain a byte sequence for metadata.
/// MDString is always unnamed.
class MDString : public Metadata {
friend class StringMapEntry<MDString>;
friend class StringMapEntryStorage<MDString>;
StringMapEntry<MDString> *Entry = nullptr;

View File

@ -113,7 +113,7 @@ struct LTOCodeGenerator {
ShouldRestoreGlobalsLinkage = Value;
}
void addMustPreserveSymbol(StringRef Sym) { MustPreserveSymbols[Sym] = 1; }
void addMustPreserveSymbol(StringRef Sym) { MustPreserveSymbols.insert(Sym); }
/// Pass options to the driver and optimization passes.
///

View File

@ -151,7 +151,7 @@ void LTOCodeGenerator::initializeLTOPasses() {
void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
const std::vector<StringRef> &undefs = Mod->getAsmUndefinedRefs();
for (int i = 0, e = undefs.size(); i != e; ++i)
AsmUndefinedRefs[undefs[i]] = 1;
AsmUndefinedRefs.insert(undefs[i]);
}
bool LTOCodeGenerator::addModule(LTOModule *Mod) {