Index: include/llvm/ADT/StringMap.h =================================================================== --- include/llvm/ADT/StringMap.h +++ include/llvm/ADT/StringMap.h @@ -142,11 +142,11 @@ StringRef first() const { return StringRef(getKeyData(), getKeyLength()); } - /// Create - Create a StringMapEntry for the specified key and default - /// construct the value. - template + /// Create a StringMapEntry for the specified key construct the value using + /// \p InitiVals. + template static StringMapEntry *Create(StringRef Key, AllocatorTy &Allocator, - InitType &&InitVal) { + InitTypes &&... InitVals) { unsigned KeyLength = Key.size(); // Allocate a new item with space for the string at the end and a null @@ -158,8 +158,9 @@ StringMapEntry *NewItem = static_cast(Allocator.Allocate(AllocSize,Alignment)); - // Default construct the value. - new (NewItem) StringMapEntry(KeyLength, std::forward(InitVal)); + // Construct the value. + new (NewItem) + StringMapEntry(KeyLength, std::forward(InitVals)...); // Copy the string information. char *StrBuffer = const_cast(NewItem->getKeyData()); @@ -328,7 +329,16 @@ /// if and only if the insertion takes place, and the iterator component of /// the pair points to the element with key equivalent to the key of the pair. std::pair insert(std::pair KV) { - unsigned BucketNo = LookupBucketFor(KV.first); + return emplace(KV.first, std::move(KV.second)); + } + + /// Emplace a new element for the specified key into the map if the key isn't + /// already in the map. The bool component of the returned pair is true + /// if and only if the insertion takes place, and the iterator component of + /// the pair points to the element with key equivalent to the key of the pair. + template + std::pair emplace(StringRef Key, ArgsTy &&... Args) { + unsigned BucketNo = LookupBucketFor(Key); StringMapEntryBase *&Bucket = TheTable[BucketNo]; if (Bucket && Bucket != getTombstoneVal()) return std::make_pair(iterator(TheTable + BucketNo, false), @@ -336,8 +346,7 @@ if (Bucket == getTombstoneVal()) --NumTombstones; - Bucket = - MapEntryTy::Create(KV.first, Allocator, std::move(KV.second)); + Bucket = MapEntryTy::Create(Key, Allocator, std::forward(Args)...); ++NumItems; assert(NumItems + NumTombstones <= NumBuckets); Index: include/llvm/IR/Metadata.h =================================================================== --- include/llvm/IR/Metadata.h +++ include/llvm/IR/Metadata.h @@ -592,7 +592,7 @@ StringMapEntry *Entry; MDString() : Metadata(MDStringKind, Uniqued), Entry(nullptr) {} - MDString(MDString &&) : Metadata(MDStringKind, Uniqued) {} + MDString(MDString &&R) = default; public: static MDString *get(LLVMContext &Context, StringRef Str); Index: lib/IR/Metadata.cpp =================================================================== --- lib/IR/Metadata.cpp +++ lib/IR/Metadata.cpp @@ -397,17 +397,12 @@ MDString *MDString::get(LLVMContext &Context, StringRef Str) { auto &Store = Context.pImpl->MDStringCache; - auto I = Store.find(Str); - if (I != Store.end()) - return &I->second; - - auto *Entry = - StringMapEntry::Create(Str, Store.getAllocator(), MDString()); - bool WasInserted = Store.insert(Entry); - (void)WasInserted; - assert(WasInserted && "Expected entry to be inserted"); - Entry->second.Entry = Entry; - return &Entry->second; + auto I = Store.emplace(Str); + auto &MapEntry = I.first->getValue(); + if (!I.second) + return &MapEntry; + MapEntry.Entry = &*I.first; + return &MapEntry; } StringRef MDString::getString() const {