Skip to content

Commit af010e7

Browse files
authored
Metadata: Optimize metadata queries (llvm#70700)
Optimize metadata query code: - Avoid `DenseMap::operator[]` in situations where it is known that the key exists in the map. Instead use `DenseMap::at()`/ `DenseMap::find()->second`. This avoids code-bloat and bad inlining decisions for the unused insertion/growing code in `operator[]`. - Avoid a redundant `Value::hasMetadata()` check. - Move the `KindID == LLVMContext::MD_dbg` case to `Instruction::getMetadata` and check it first assuming that it can be constant folded after inlining in many situations. The motivation for this change is a regression triggered by e3cf80c which could attributed to the compiler inlining the insertion part of `DenseMap::operator[]` in more cases while unbeknownst to a compiler (without PGO) that code is never used in this context. This change improves performance and eliminates difference before and after that change in my measurements.
1 parent 98a6edd commit af010e7

File tree

3 files changed

+33
-30
lines changed

3 files changed

+33
-30
lines changed

llvm/include/llvm/IR/Instruction.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,10 @@ class Instruction : public User,
303303
/// Get the metadata of given kind attached to this Instruction.
304304
/// If the metadata is not found then return null.
305305
MDNode *getMetadata(unsigned KindID) const {
306-
if (!hasMetadata()) return nullptr;
307-
return getMetadataImpl(KindID);
306+
// Handle 'dbg' as a special case since it is not stored in the hash table.
307+
if (KindID == LLVMContext::MD_dbg)
308+
return DbgLoc.getAsMDNode();
309+
return Value::getMetadata(KindID);
308310
}
309311

310312
/// Get the metadata of given kind attached to this Instruction.
@@ -594,7 +596,6 @@ class Instruction : public User,
594596

595597
private:
596598
// These are all implemented in Metadata.cpp.
597-
MDNode *getMetadataImpl(unsigned KindID) const;
598599
MDNode *getMetadataImpl(StringRef Kind) const;
599600
void
600601
getAllMetadataImpl(SmallVectorImpl<std::pair<unsigned, MDNode *>> &) const;

llvm/include/llvm/IR/Value.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,11 @@ class Value {
562562
/// These functions require that the value have at most a single attachment
563563
/// of the given kind, and return \c nullptr if such an attachment is missing.
564564
/// @{
565-
MDNode *getMetadata(unsigned KindID) const;
565+
MDNode *getMetadata(unsigned KindID) const {
566+
if (!HasMetadata)
567+
return nullptr;
568+
return getMetadataImpl(KindID);
569+
}
566570
MDNode *getMetadata(StringRef Kind) const;
567571
/// @}
568572

@@ -617,6 +621,11 @@ class Value {
617621
/// Erase all metadata attached to this Value.
618622
void clearMetadata();
619623

624+
/// Get metadata for the given kind, if any.
625+
/// This is an internal function that must only be called after
626+
/// checking that `hasMetadata()` returns true.
627+
MDNode *getMetadataImpl(unsigned KindID) const;
628+
620629
public:
621630
/// Return true if this value is a swifterror value.
622631
///

llvm/lib/IR/Metadata.cpp

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,25 +1351,22 @@ bool MDAttachments::erase(unsigned ID) {
13511351
return OldSize != Attachments.size();
13521352
}
13531353

1354-
MDNode *Value::getMetadata(unsigned KindID) const {
1354+
MDNode *Value::getMetadata(StringRef Kind) const {
13551355
if (!hasMetadata())
13561356
return nullptr;
1357-
const auto &Info = getContext().pImpl->ValueMetadata[this];
1358-
assert(!Info.empty() && "bit out of sync with hash table");
1359-
return Info.lookup(KindID);
1357+
unsigned KindID = getContext().getMDKindID(Kind);
1358+
return getMetadataImpl(KindID);
13601359
}
13611360

1362-
MDNode *Value::getMetadata(StringRef Kind) const {
1363-
if (!hasMetadata())
1364-
return nullptr;
1365-
const auto &Info = getContext().pImpl->ValueMetadata[this];
1366-
assert(!Info.empty() && "bit out of sync with hash table");
1367-
return Info.lookup(getContext().getMDKindID(Kind));
1361+
MDNode *Value::getMetadataImpl(unsigned KindID) const {
1362+
const LLVMContext &Ctx = getContext();
1363+
const MDAttachments &Attachements = Ctx.pImpl->ValueMetadata.at(this);
1364+
return Attachements.lookup(KindID);
13681365
}
13691366

13701367
void Value::getMetadata(unsigned KindID, SmallVectorImpl<MDNode *> &MDs) const {
13711368
if (hasMetadata())
1372-
getContext().pImpl->ValueMetadata[this].get(KindID, MDs);
1369+
getContext().pImpl->ValueMetadata.at(this).get(KindID, MDs);
13731370
}
13741371

13751372
void Value::getMetadata(StringRef Kind, SmallVectorImpl<MDNode *> &MDs) const {
@@ -1382,8 +1379,7 @@ void Value::getAllMetadata(
13821379
if (hasMetadata()) {
13831380
assert(getContext().pImpl->ValueMetadata.count(this) &&
13841381
"bit out of sync with hash table");
1385-
const auto &Info = getContext().pImpl->ValueMetadata.find(this)->second;
1386-
assert(!Info.empty() && "Shouldn't have called this");
1382+
const MDAttachments &Info = getContext().pImpl->ValueMetadata.at(this);
13871383
Info.getAll(MDs);
13881384
}
13891385
}
@@ -1393,7 +1389,7 @@ void Value::setMetadata(unsigned KindID, MDNode *Node) {
13931389

13941390
// Handle the case when we're adding/updating metadata on a value.
13951391
if (Node) {
1396-
auto &Info = getContext().pImpl->ValueMetadata[this];
1392+
MDAttachments &Info = getContext().pImpl->ValueMetadata[this];
13971393
assert(!Info.empty() == HasMetadata && "bit out of sync with hash table");
13981394
if (Info.empty())
13991395
HasMetadata = true;
@@ -1406,7 +1402,7 @@ void Value::setMetadata(unsigned KindID, MDNode *Node) {
14061402
"bit out of sync with hash table");
14071403
if (!HasMetadata)
14081404
return; // Nothing to remove!
1409-
auto &Info = getContext().pImpl->ValueMetadata[this];
1405+
MDAttachments &Info = getContext().pImpl->ValueMetadata.find(this)->second;
14101406

14111407
// Handle removal of an existing value.
14121408
Info.erase(KindID);
@@ -1438,7 +1434,7 @@ bool Value::eraseMetadata(unsigned KindID) {
14381434
if (!HasMetadata)
14391435
return false;
14401436

1441-
auto &Store = getContext().pImpl->ValueMetadata[this];
1437+
MDAttachments &Store = getContext().pImpl->ValueMetadata.find(this)->second;
14421438
bool Changed = Store.erase(KindID);
14431439
if (Store.empty())
14441440
clearMetadata();
@@ -1461,7 +1457,11 @@ void Instruction::setMetadata(StringRef Kind, MDNode *Node) {
14611457
}
14621458

14631459
MDNode *Instruction::getMetadataImpl(StringRef Kind) const {
1464-
return getMetadataImpl(getContext().getMDKindID(Kind));
1460+
const LLVMContext &Ctx = getContext();
1461+
unsigned KindID = Ctx.getMDKindID(Kind);
1462+
if (KindID == LLVMContext::MD_dbg)
1463+
return DbgLoc.getAsMDNode();
1464+
return Value::getMetadata(KindID);
14651465
}
14661466

14671467
void Instruction::dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs) {
@@ -1475,7 +1475,7 @@ void Instruction::dropUnknownNonDebugMetadata(ArrayRef<unsigned> KnownIDs) {
14751475
KnownSet.insert(LLVMContext::MD_DIAssignID);
14761476

14771477
auto &MetadataStore = getContext().pImpl->ValueMetadata;
1478-
auto &Info = MetadataStore[this];
1478+
MDAttachments &Info = MetadataStore.find(this)->second;
14791479
assert(!Info.empty() && "bit out of sync with hash table");
14801480
Info.remove_if([&KnownSet](const MDAttachments::Attachment &I) {
14811481
return !KnownSet.count(I.MDKind);
@@ -1598,7 +1598,7 @@ AAMDNodes Instruction::getAAMetadata() const {
15981598
// Not using Instruction::hasMetadata() because we're not interested in
15991599
// DebugInfoMetadata.
16001600
if (Value::hasMetadata()) {
1601-
const auto &Info = getContext().pImpl->ValueMetadata[this];
1601+
const MDAttachments &Info = getContext().pImpl->ValueMetadata.at(this);
16021602
Result.TBAA = Info.lookup(LLVMContext::MD_tbaa);
16031603
Result.TBAAStruct = Info.lookup(LLVMContext::MD_tbaa_struct);
16041604
Result.Scope = Info.lookup(LLVMContext::MD_alias_scope);
@@ -1619,13 +1619,6 @@ void Instruction::setNoSanitizeMetadata() {
16191619
llvm::MDNode::get(getContext(), std::nullopt));
16201620
}
16211621

1622-
MDNode *Instruction::getMetadataImpl(unsigned KindID) const {
1623-
// Handle 'dbg' as a special case since it is not stored in the hash table.
1624-
if (KindID == LLVMContext::MD_dbg)
1625-
return DbgLoc.getAsMDNode();
1626-
return Value::getMetadata(KindID);
1627-
}
1628-
16291622
void Instruction::getAllMetadataImpl(
16301623
SmallVectorImpl<std::pair<unsigned, MDNode *>> &Result) const {
16311624
Result.clear();

0 commit comments

Comments
 (0)