//===-- Metadata.cpp - Implement Metadata classes -------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the Metadata classes. // //===----------------------------------------------------------------------===// #include "llvm/IR/Metadata.h" #include "LLVMContextImpl.h" #include "SymbolTableListTraitsImpl.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LeakDetector.h" #include "llvm/IR/Module.h" #include "llvm/IR/ValueHandle.h" using namespace llvm; MetadataAsValue::MetadataAsValue(Type *Ty, Metadata *MD) : Value(Ty, MetadataAsValueVal), MD(MD) { track(); } MetadataAsValue::~MetadataAsValue() { getType()->getContext().pImpl->MetadataAsValues.erase(MD); untrack(); } /// \brief Canonicalize metadata arguments to intrinsics. /// /// To support bitcode upgrades (and assembly semantic sugar) for \a /// MetadataAsValue, we need to canonicalize certain metadata. /// /// - nullptr is replaced by an empty MDNode. /// - An MDNode with a single null operand is replaced by an empty MDNode. /// - An MDNode whose only operand is a \a ConstantAsMetadata gets skipped. /// /// This maintains readability of bitcode from when metadata was a type of /// value, and these bridges were unnecessary. static Metadata *canonicalizeMetadataForValue(LLVMContext &Context, Metadata *MD) { if (!MD) // !{} return MDNode::get(Context, None); // Return early if this isn't a single-operand MDNode. auto *N = dyn_cast(MD); if (!N || N->getNumOperands() != 1) return MD; if (!N->getOperand(0)) // !{} return MDNode::get(Context, None); if (auto *C = dyn_cast(N->getOperand(0))) // Look through the MDNode. return C; return MD; } MetadataAsValue *MetadataAsValue::get(LLVMContext &Context, Metadata *MD) { MD = canonicalizeMetadataForValue(Context, MD); auto *&Entry = Context.pImpl->MetadataAsValues[MD]; if (!Entry) Entry = new MetadataAsValue(Type::getMetadataTy(Context), MD); return Entry; } MetadataAsValue *MetadataAsValue::getIfExists(LLVMContext &Context, Metadata *MD) { MD = canonicalizeMetadataForValue(Context, MD); auto &Store = Context.pImpl->MetadataAsValues; auto I = Store.find(MD); return I == Store.end() ? nullptr : I->second; } void MetadataAsValue::handleChangedMetadata(Metadata *MD) { LLVMContext &Context = getContext(); MD = canonicalizeMetadataForValue(Context, MD); auto &Store = Context.pImpl->MetadataAsValues; // Stop tracking the old metadata. Store.erase(this->MD); untrack(); this->MD = nullptr; // Start tracking MD, or RAUW if necessary. auto *&Entry = Store[MD]; if (Entry) { replaceAllUsesWith(Entry); delete this; return; } this->MD = MD; track(); Entry = this; } void MetadataAsValue::track() { if (MD) MetadataTracking::track(&MD, *MD, *this); } void MetadataAsValue::untrack() { if (MD) MetadataTracking::untrack(MD); } void ReplaceableMetadataImpl::addRef(void *Ref, OwnerTy Owner) { bool WasInserted = UseMap.insert(std::make_pair(Ref, Owner)).second; (void)WasInserted; assert(WasInserted && "Expected to add a reference"); } void ReplaceableMetadataImpl::dropRef(void *Ref) { bool WasErased = UseMap.erase(Ref); (void)WasErased; assert(WasErased && "Expected to drop a reference"); } void ReplaceableMetadataImpl::moveRef(void *Ref, void *New, const Metadata &MD) { auto I = UseMap.find(Ref); assert(I != UseMap.end() && "Expected to move a reference"); OwnerTy Owner = I->second; UseMap.erase(I); addRef(New, Owner); // Check that the references are direct if there's no owner. (void)MD; assert((Owner || *static_cast(Ref) == &MD) && "Reference without owner must be direct"); assert((Owner || *static_cast(New) == &MD) && "Reference without owner must be direct"); } void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) { assert(!(MD && isa(MD)) && "Expected non-temp node"); if (UseMap.empty()) return; // Copy out uses since UseMap will get touched below. SmallVector, 8> Uses(UseMap.begin(), UseMap.end()); for (const auto &Pair : Uses) { if (!Pair.second) { // Update unowned tracking references directly. Metadata *&Ref = *static_cast(Pair.first); Ref = MD; MetadataTracking::track(Ref); UseMap.erase(Pair.first); continue; } // Check for MetadataAsValue. if (Pair.second.is()) { Pair.second.get()->handleChangedMetadata(MD); continue; } // There's a Metadata owner -- dispatch. Metadata *Owner = Pair.second.get(); switch (Owner->getMetadataID()) { #define HANDLE_METADATA_LEAF(CLASS) \ case Metadata::CLASS##Kind: \ cast(Owner)->handleChangedOperand(Pair.first, MD); \ continue; #include "llvm/IR/Metadata.def" default: llvm_unreachable("Invalid metadata subclass"); } } assert(UseMap.empty() && "Expected all uses to be replaced"); } void ReplaceableMetadataImpl::resolveAllUses(bool ResolveUsers) { if (UseMap.empty()) return; if (!ResolveUsers) { UseMap.clear(); return; } // Copy out uses since UseMap could get touched below. SmallVector, 8> Uses(UseMap.begin(), UseMap.end()); UseMap.clear(); for (const auto &Pair : Uses) { if (!Pair.second) continue; if (Pair.second.is()) continue; // Resolve GenericMDNodes that point at this. auto *Owner = dyn_cast(Pair.second.get()); if (!Owner) continue; if (Owner->isResolved()) continue; Owner->decrementUnresolvedOperands(); if (!Owner->hasUnresolvedOperands()) Owner->resolve(); } } static Function *getLocalFunction(Value *V) { assert(V && "Expected value"); if (auto *A = dyn_cast(V)) return A->getParent(); if (BasicBlock *BB = cast(V)->getParent()) return BB->getParent(); return nullptr; } ValueAsMetadata *ValueAsMetadata::get(Value *V) { assert(V && "Unexpected null Value"); auto &Context = V->getContext(); auto *&Entry = Context.pImpl->ValuesAsMetadata[V]; if (!Entry) { assert((isa(V) || isa(V) || isa(V)) && "Expected constant or function-local value"); assert(!V->NameAndIsUsedByMD.getInt() && "Expected this to be the only metadata use"); V->NameAndIsUsedByMD.setInt(true); if (auto *C = dyn_cast(V)) Entry = new ConstantAsMetadata(Context, C); else Entry = new LocalAsMetadata(Context, V); } return Entry; } ValueAsMetadata *ValueAsMetadata::getIfExists(Value *V) { assert(V && "Unexpected null Value"); return V->getContext().pImpl->ValuesAsMetadata.lookup(V); } void ValueAsMetadata::handleDeletion(Value *V) { assert(V && "Expected valid value"); auto &Store = V->getType()->getContext().pImpl->ValuesAsMetadata; auto I = Store.find(V); if (I == Store.end()) return; // Remove old entry from the map. ValueAsMetadata *MD = I->second; assert(MD && "Expected valid metadata"); assert(MD->getValue() == V && "Expected valid mapping"); Store.erase(I); // Delete the metadata. MD->replaceAllUsesWith(nullptr); delete MD; } void ValueAsMetadata::handleRAUW(Value *From, Value *To) { assert(From && "Expected valid value"); assert(To && "Expected valid value"); assert(From != To && "Expected changed value"); assert(From->getType() == To->getType() && "Unexpected type change"); LLVMContext &Context = From->getType()->getContext(); auto &Store = Context.pImpl->ValuesAsMetadata; auto I = Store.find(From); if (I == Store.end()) { assert(!From->NameAndIsUsedByMD.getInt() && "Expected From not to be used by metadata"); return; } // Remove old entry from the map. assert(From->NameAndIsUsedByMD.getInt() && "Expected From to be used by metadata"); From->NameAndIsUsedByMD.setInt(false); ValueAsMetadata *MD = I->second; assert(MD && "Expected valid metadata"); assert(MD->getValue() == From && "Expected valid mapping"); Store.erase(I); if (isa(MD)) { if (auto *C = dyn_cast(To)) { // Local became a constant. MD->replaceAllUsesWith(ConstantAsMetadata::get(C)); delete MD; return; } if (getLocalFunction(From) && getLocalFunction(To) && getLocalFunction(From) != getLocalFunction(To)) { // Function changed. MD->replaceAllUsesWith(nullptr); delete MD; return; } } else if (!isa(To)) { // Changed to function-local value. MD->replaceAllUsesWith(nullptr); delete MD; return; } auto *&Entry = Store[To]; if (Entry) { // The target already exists. MD->replaceAllUsesWith(Entry); delete MD; return; } // Update MD in place (and update the map entry). assert(!To->NameAndIsUsedByMD.getInt() && "Expected this to be the only metadata use"); To->NameAndIsUsedByMD.setInt(true); MD->V = To; Entry = MD; } //===----------------------------------------------------------------------===// // MDString implementation. // 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; } StringRef MDString::getString() const { assert(Entry && "Expected to find string map entry"); return Entry->first(); } //===----------------------------------------------------------------------===// // MDNode implementation. // void *MDNode::operator new(size_t Size, unsigned NumOps) { void *Ptr = ::operator new(Size + NumOps * sizeof(MDOperand)); MDOperand *First = new (Ptr) MDOperand[NumOps]; return First + NumOps; } void MDNode::operator delete(void *Mem) { MDNode *N = static_cast(Mem); MDOperand *Last = static_cast(Mem); ::operator delete(Last - N->NumOperands); } MDNode::MDNode(LLVMContext &Context, unsigned ID, ArrayRef MDs) : Metadata(ID), Context(Context), NumOperands(MDs.size()), MDNodeSubclassData(0) { for (unsigned I = 0, E = MDs.size(); I != E; ++I) setOperand(I, MDs[I]); } bool MDNode::isResolved() const { if (isa(this)) return false; return cast(this)->isResolved(); } static bool isOperandUnresolved(Metadata *Op) { if (auto *N = dyn_cast_or_null(Op)) return !N->isResolved(); return false; } GenericMDNode::GenericMDNode(LLVMContext &C, ArrayRef Vals) : MDNode(C, GenericMDNodeKind, Vals) { // Check whether any operands are unresolved, requiring re-uniquing. for (const auto &Op : operands()) if (isOperandUnresolved(Op)) incrementUnresolvedOperands(); if (hasUnresolvedOperands()) ReplaceableUses.reset(new ReplaceableMetadataImpl); } GenericMDNode::~GenericMDNode() { LLVMContextImpl *pImpl = getContext().pImpl; if (isStoredDistinctInContext()) pImpl->NonUniquedMDNodes.erase(this); else pImpl->MDNodeSet.erase(this); } void GenericMDNode::resolve() { assert(!isResolved() && "Expected this to be unresolved"); // Move the map, so that this immediately looks resolved. auto Uses = std::move(ReplaceableUses); SubclassData32 = 0; assert(isResolved() && "Expected this to be resolved"); // Drop RAUW support. Uses->resolveAllUses(); } void GenericMDNode::resolveCycles() { if (isResolved()) return; // Resolve this node immediately. resolve(); // Resolve all operands. for (const auto &Op : operands()) { if (!Op) continue; assert(!isa(Op) && "Expected all forward declarations to be resolved"); if (auto *N = dyn_cast(Op)) if (!N->isResolved()) N->resolveCycles(); } } void MDNode::dropAllReferences() { for (unsigned I = 0, E = NumOperands; I != E; ++I) setOperand(I, nullptr); if (auto *G = dyn_cast(this)) if (!G->isResolved()) { G->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false); G->ReplaceableUses.reset(); } } namespace llvm { /// \brief Make MDOperand transparent for hashing. /// /// This overload of an implementation detail of the hashing library makes /// MDOperand hash to the same value as a \a Metadata pointer. /// /// Note that overloading \a hash_value() as follows: /// /// \code /// size_t hash_value(const MDOperand &X) { return hash_value(X.get()); } /// \endcode /// /// does not cause MDOperand to be transparent. In particular, a bare pointer /// doesn't get hashed before it's combined, whereas \a MDOperand would. static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); } } void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) { unsigned Op = static_cast(Ref) - op_begin(); assert(Op < getNumOperands() && "Expected valid operand"); if (isStoredDistinctInContext()) { assert(isResolved() && "Expected distinct node to be resolved"); // This node is not uniqued. Just set the operand and be done with it. setOperand(Op, New); return; } auto &Store = getContext().pImpl->MDNodeSet; Store.erase(this); Metadata *Old = getOperand(Op); setOperand(Op, New); // Drop uniquing for self-reference cycles or if an operand drops to null. // // FIXME: Stop dropping uniquing when an operand drops to null. The original // motivation was to prevent madness during teardown of LLVMContextImpl, but // dropAllReferences() fixes that problem in a better way. (It's just here // now for better staging of semantic changes.) if (New == this || !New) { storeDistinctInContext(); setHash(0); if (!isResolved()) resolve(); return; } // Re-calculate the hash. setHash(hash_combine_range(op_begin(), op_end())); #ifndef NDEBUG { SmallVector MDs(op_begin(), op_end()); unsigned RawHash = hash_combine_range(MDs.begin(), MDs.end()); assert(getHash() == RawHash && "Expected hash of MDOperand to equal hash of Metadata*"); } #endif // Re-unique the node. GenericMDNodeInfo::KeyTy Key(this); auto I = Store.find_as(Key); if (I == Store.end()) { Store.insert(this); if (!isResolved()) { // Check if the last unresolved operand has just been resolved; if so, // resolve this as well. if (isOperandUnresolved(Old)) decrementUnresolvedOperands(); if (isOperandUnresolved(New)) incrementUnresolvedOperands(); if (!hasUnresolvedOperands()) resolve(); } return; } // Collision. if (!isResolved()) { // Still unresolved, so RAUW. ReplaceableUses->replaceAllUsesWith(*I); delete this; return; } // Store in non-uniqued form if this node has already been resolved. setHash(0); storeDistinctInContext(); } MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef MDs, bool Insert) { auto &Store = Context.pImpl->MDNodeSet; GenericMDNodeInfo::KeyTy Key(MDs); auto I = Store.find_as(Key); if (I != Store.end()) return *I; if (!Insert) return nullptr; // Coallocate space for the node and Operands together, then placement new. GenericMDNode *N = new (MDs.size()) GenericMDNode(Context, MDs); N->setHash(Key.Hash); Store.insert(N); return N; } MDNodeFwdDecl *MDNode::getTemporary(LLVMContext &Context, ArrayRef MDs) { MDNodeFwdDecl *N = new (MDs.size()) MDNodeFwdDecl(Context, MDs); LeakDetector::addGarbageObject(N); return N; } void MDNode::deleteTemporary(MDNode *N) { assert(isa(N) && "Expected forward declaration"); LeakDetector::removeGarbageObject(N); delete cast(N); } void MDNode::storeDistinctInContext() { assert(!IsDistinctInContext && "Expected newly distinct metadata"); IsDistinctInContext = true; auto *G = cast(this); G->setHash(0); getContext().pImpl->NonUniquedMDNodes.insert(G); } // Replace value from this node's operand list. void MDNode::replaceOperandWith(unsigned I, Metadata *New) { if (getOperand(I) == New) return; if (auto *N = dyn_cast(this)) { N->handleChangedOperand(mutable_begin() + I, New); return; } assert(isa(this) && "Expected an MDNode"); setOperand(I, New); } void MDNode::setOperand(unsigned I, Metadata *New) { assert(I < NumOperands); if (isStoredDistinctInContext() || isa(this)) // No need for a callback, this isn't uniqued. mutable_begin()[I].reset(New, nullptr); else mutable_begin()[I].reset(New, this); } /// \brief Get a node, or a self-reference that looks like it. /// /// Special handling for finding self-references, for use by \a /// MDNode::concatenate() and \a MDNode::intersect() to maintain behaviour from /// when self-referencing nodes were still uniqued. If the first operand has /// the same operands as \c Ops, return the first operand instead. static MDNode *getOrSelfReference(LLVMContext &Context, ArrayRef Ops) { if (!Ops.empty()) if (MDNode *N = dyn_cast_or_null(Ops[0])) if (N->getNumOperands() == Ops.size() && N == N->getOperand(0)) { for (unsigned I = 1, E = Ops.size(); I != E; ++I) if (Ops[I] != N->getOperand(I)) return MDNode::get(Context, Ops); return N; } return MDNode::get(Context, Ops); } MDNode *MDNode::concatenate(MDNode *A, MDNode *B) { if (!A) return B; if (!B) return A; SmallVector MDs(A->getNumOperands() + B->getNumOperands()); unsigned j = 0; for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i) MDs[j++] = A->getOperand(i); for (unsigned i = 0, ie = B->getNumOperands(); i != ie; ++i) MDs[j++] = B->getOperand(i); // FIXME: This preserves long-standing behaviour, but is it really the right // behaviour? Or was that an unintended side-effect of node uniquing? return getOrSelfReference(A->getContext(), MDs); } MDNode *MDNode::intersect(MDNode *A, MDNode *B) { if (!A || !B) return nullptr; SmallVector MDs; for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i) { Metadata *MD = A->getOperand(i); for (unsigned j = 0, je = B->getNumOperands(); j != je; ++j) if (MD == B->getOperand(j)) { MDs.push_back(MD); break; } } // FIXME: This preserves long-standing behaviour, but is it really the right // behaviour? Or was that an unintended side-effect of node uniquing? return getOrSelfReference(A->getContext(), MDs); } MDNode *MDNode::getMostGenericFPMath(MDNode *A, MDNode *B) { if (!A || !B) return nullptr; APFloat AVal = mdconst::extract(A->getOperand(0))->getValueAPF(); APFloat BVal = mdconst::extract(B->getOperand(0))->getValueAPF(); if (AVal.compare(BVal) == APFloat::cmpLessThan) return A; return B; } static bool isContiguous(const ConstantRange &A, const ConstantRange &B) { return A.getUpper() == B.getLower() || A.getLower() == B.getUpper(); } static bool canBeMerged(const ConstantRange &A, const ConstantRange &B) { return !A.intersectWith(B).isEmptySet() || isContiguous(A, B); } static bool tryMergeRange(SmallVectorImpl &EndPoints, ConstantInt *Low, ConstantInt *High) { ConstantRange NewRange(Low->getValue(), High->getValue()); unsigned Size = EndPoints.size(); APInt LB = EndPoints[Size - 2]->getValue(); APInt LE = EndPoints[Size - 1]->getValue(); ConstantRange LastRange(LB, LE); if (canBeMerged(NewRange, LastRange)) { ConstantRange Union = LastRange.unionWith(NewRange); Type *Ty = High->getType(); EndPoints[Size - 2] = cast(ConstantInt::get(Ty, Union.getLower())); EndPoints[Size - 1] = cast(ConstantInt::get(Ty, Union.getUpper())); return true; } return false; } static void addRange(SmallVectorImpl &EndPoints, ConstantInt *Low, ConstantInt *High) { if (!EndPoints.empty()) if (tryMergeRange(EndPoints, Low, High)) return; EndPoints.push_back(Low); EndPoints.push_back(High); } MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) { // Given two ranges, we want to compute the union of the ranges. This // is slightly complitade by having to combine the intervals and merge // the ones that overlap. if (!A || !B) return nullptr; if (A == B) return A; // First, walk both lists in older of the lower boundary of each interval. // At each step, try to merge the new interval to the last one we adedd. SmallVector EndPoints; int AI = 0; int BI = 0; int AN = A->getNumOperands() / 2; int BN = B->getNumOperands() / 2; while (AI < AN && BI < BN) { ConstantInt *ALow = mdconst::extract(A->getOperand(2 * AI)); ConstantInt *BLow = mdconst::extract(B->getOperand(2 * BI)); if (ALow->getValue().slt(BLow->getValue())) { addRange(EndPoints, ALow, mdconst::extract(A->getOperand(2 * AI + 1))); ++AI; } else { addRange(EndPoints, BLow, mdconst::extract(B->getOperand(2 * BI + 1))); ++BI; } } while (AI < AN) { addRange(EndPoints, mdconst::extract(A->getOperand(2 * AI)), mdconst::extract(A->getOperand(2 * AI + 1))); ++AI; } while (BI < BN) { addRange(EndPoints, mdconst::extract(B->getOperand(2 * BI)), mdconst::extract(B->getOperand(2 * BI + 1))); ++BI; } // If we have more than 2 ranges (4 endpoints) we have to try to merge // the last and first ones. unsigned Size = EndPoints.size(); if (Size > 4) { ConstantInt *FB = EndPoints[0]; ConstantInt *FE = EndPoints[1]; if (tryMergeRange(EndPoints, FB, FE)) { for (unsigned i = 0; i < Size - 2; ++i) { EndPoints[i] = EndPoints[i + 2]; } EndPoints.resize(Size - 2); } } // If in the end we have a single range, it is possible that it is now the // full range. Just drop the metadata in that case. if (EndPoints.size() == 2) { ConstantRange Range(EndPoints[0]->getValue(), EndPoints[1]->getValue()); if (Range.isFullSet()) return nullptr; } SmallVector MDs; MDs.reserve(EndPoints.size()); for (auto *I : EndPoints) MDs.push_back(ConstantAsMetadata::get(I)); return MDNode::get(A->getContext(), MDs); } //===----------------------------------------------------------------------===// // NamedMDNode implementation. // static SmallVector &getNMDOps(void *Operands) { return *(SmallVector *)Operands; } NamedMDNode::NamedMDNode(const Twine &N) : Name(N.str()), Parent(nullptr), Operands(new SmallVector()) {} NamedMDNode::~NamedMDNode() { dropAllReferences(); delete &getNMDOps(Operands); } unsigned NamedMDNode::getNumOperands() const { return (unsigned)getNMDOps(Operands).size(); } MDNode *NamedMDNode::getOperand(unsigned i) const { assert(i < getNumOperands() && "Invalid Operand number!"); auto *N = getNMDOps(Operands)[i].get(); if (N && i > 10000) N->dump(); return cast_or_null(N); } void NamedMDNode::addOperand(MDNode *M) { getNMDOps(Operands).emplace_back(M); } void NamedMDNode::eraseFromParent() { getParent()->eraseNamedMetadata(this); } void NamedMDNode::dropAllReferences() { getNMDOps(Operands).clear(); } StringRef NamedMDNode::getName() const { return StringRef(Name); } //===----------------------------------------------------------------------===// // Instruction Metadata method implementations. // void Instruction::setMetadata(StringRef Kind, MDNode *Node) { if (!Node && !hasMetadata()) return; setMetadata(getContext().getMDKindID(Kind), Node); } MDNode *Instruction::getMetadataImpl(StringRef Kind) const { return getMetadataImpl(getContext().getMDKindID(Kind)); } void Instruction::dropUnknownMetadata(ArrayRef KnownIDs) { SmallSet KnownSet; KnownSet.insert(KnownIDs.begin(), KnownIDs.end()); // Drop debug if needed if (KnownSet.erase(LLVMContext::MD_dbg)) DbgLoc = DebugLoc(); if (!hasMetadataHashEntry()) return; // Nothing to remove! DenseMap &MetadataStore = getContext().pImpl->MetadataStore; if (KnownSet.empty()) { // Just drop our entry at the store. MetadataStore.erase(this); setHasMetadataHashEntry(false); return; } LLVMContextImpl::MDMapTy &Info = MetadataStore[this]; unsigned I; unsigned E; // Walk the array and drop any metadata we don't know. for (I = 0, E = Info.size(); I != E;) { if (KnownSet.count(Info[I].first)) { ++I; continue; } Info[I] = std::move(Info.back()); Info.pop_back(); --E; } assert(E == Info.size()); if (E == 0) { // Drop our entry at the store. MetadataStore.erase(this); setHasMetadataHashEntry(false); } } /// setMetadata - Set the metadata of of the specified kind to the specified /// node. This updates/replaces metadata if already present, or removes it if /// Node is null. void Instruction::setMetadata(unsigned KindID, MDNode *Node) { if (!Node && !hasMetadata()) return; // Handle 'dbg' as a special case since it is not stored in the hash table. if (KindID == LLVMContext::MD_dbg) { DbgLoc = DebugLoc::getFromDILocation(Node); return; } // Handle the case when we're adding/updating metadata on an instruction. if (Node) { LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this]; assert(!Info.empty() == hasMetadataHashEntry() && "HasMetadata bit is wonked"); if (Info.empty()) { setHasMetadataHashEntry(true); } else { // Handle replacement of an existing value. for (auto &P : Info) if (P.first == KindID) { P.second.reset(Node); return; } } // No replacement, just add it to the list. Info.emplace_back(std::piecewise_construct, std::make_tuple(KindID), std::make_tuple(Node)); return; } // Otherwise, we're removing metadata from an instruction. assert((hasMetadataHashEntry() == (getContext().pImpl->MetadataStore.count(this) > 0)) && "HasMetadata bit out of date!"); if (!hasMetadataHashEntry()) return; // Nothing to remove! LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this]; // Common case is removing the only entry. if (Info.size() == 1 && Info[0].first == KindID) { getContext().pImpl->MetadataStore.erase(this); setHasMetadataHashEntry(false); return; } // Handle removal of an existing value. for (unsigned i = 0, e = Info.size(); i != e; ++i) if (Info[i].first == KindID) { Info[i] = std::move(Info.back()); Info.pop_back(); assert(!Info.empty() && "Removing last entry should be handled above"); return; } // Otherwise, removing an entry that doesn't exist on the instruction. } void Instruction::setAAMetadata(const AAMDNodes &N) { setMetadata(LLVMContext::MD_tbaa, N.TBAA); setMetadata(LLVMContext::MD_alias_scope, N.Scope); setMetadata(LLVMContext::MD_noalias, N.NoAlias); } MDNode *Instruction::getMetadataImpl(unsigned KindID) const { // Handle 'dbg' as a special case since it is not stored in the hash table. if (KindID == LLVMContext::MD_dbg) return DbgLoc.getAsMDNode(); if (!hasMetadataHashEntry()) return nullptr; LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this]; assert(!Info.empty() && "bit out of sync with hash table"); for (const auto &I : Info) if (I.first == KindID) return I.second; return nullptr; } void Instruction::getAllMetadataImpl( SmallVectorImpl> &Result) const { Result.clear(); // Handle 'dbg' as a special case since it is not stored in the hash table. if (!DbgLoc.isUnknown()) { Result.push_back( std::make_pair((unsigned)LLVMContext::MD_dbg, DbgLoc.getAsMDNode())); if (!hasMetadataHashEntry()) return; } assert(hasMetadataHashEntry() && getContext().pImpl->MetadataStore.count(this) && "Shouldn't have called this"); const LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore.find(this)->second; assert(!Info.empty() && "Shouldn't have called this"); Result.reserve(Result.size() + Info.size()); for (auto &I : Info) Result.push_back(std::make_pair(I.first, cast(I.second.get()))); // Sort the resulting array so it is stable. if (Result.size() > 1) array_pod_sort(Result.begin(), Result.end()); } void Instruction::getAllMetadataOtherThanDebugLocImpl( SmallVectorImpl> &Result) const { Result.clear(); assert(hasMetadataHashEntry() && getContext().pImpl->MetadataStore.count(this) && "Shouldn't have called this"); const LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore.find(this)->second; assert(!Info.empty() && "Shouldn't have called this"); Result.reserve(Result.size() + Info.size()); for (auto &I : Info) Result.push_back(std::make_pair(I.first, cast(I.second.get()))); // Sort the resulting array so it is stable. if (Result.size() > 1) array_pod_sort(Result.begin(), Result.end()); } /// clearMetadataHashEntries - Clear all hashtable-based metadata from /// this instruction. void Instruction::clearMetadataHashEntries() { assert(hasMetadataHashEntry() && "Caller should check"); getContext().pImpl->MetadataStore.erase(this); setHasMetadataHashEntry(false); }