aboutsummaryrefslogtreecommitdiffstats
path: root/lib/IR/Metadata.cpp
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
committerStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
commitebe69fe11e48d322045d5949c83283927a0d790b (patch)
treec92f1907a6b8006628a4b01615f38264d29834ea /lib/IR/Metadata.cpp
parentb7d2e72b02a4cb8034f32f8247a2558d2434e121 (diff)
downloadexternal_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.zip
external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.gz
external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.bz2
Update aosp/master LLVM for rebase to r230699.
Change-Id: I2b5be30509658cb8266be782de0ab24f9099f9b9
Diffstat (limited to 'lib/IR/Metadata.cpp')
-rw-r--r--lib/IR/Metadata.cpp1061
1 files changed, 724 insertions, 337 deletions
diff --git a/lib/IR/Metadata.cpp b/lib/IR/Metadata.cpp
index 27ba9f7..0ad3c5c 100644
--- a/lib/IR/Metadata.cpp
+++ b/lib/IR/Metadata.cpp
@@ -1,4 +1,4 @@
-//===-- Metadata.cpp - Implement Metadata classes -------------------------===//
+//===- Metadata.cpp - Implement Metadata classes --------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,6 +13,7 @@
#include "llvm/IR/Metadata.h"
#include "LLVMContextImpl.h"
+#include "MetadataImpl.h"
#include "SymbolTableListTraitsImpl.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
@@ -20,23 +21,342 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/ConstantRange.h"
+#include "llvm/IR/DebugInfoMetadata.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;
-Metadata::Metadata(LLVMContext &Context, unsigned ID)
- : Value(Type::getMetadataTy(Context), ID) {}
+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<MDNode>(MD);
+ if (!N || N->getNumOperands() != 1)
+ return MD;
+
+ if (!N->getOperand(0))
+ // !{}
+ return MDNode::get(Context, None);
+
+ if (auto *C = dyn_cast<ConstantAsMetadata>(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;
+ return Store.lookup(MD);
+}
+
+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, std::make_pair(Owner, NextIndex)))
+ .second;
+ (void)WasInserted;
+ assert(WasInserted && "Expected to add a reference");
+
+ ++NextIndex;
+ assert(NextIndex != 0 && "Unexpected overflow");
+}
+
+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");
+ auto OwnerAndIndex = I->second;
+ UseMap.erase(I);
+ bool WasInserted = UseMap.insert(std::make_pair(New, OwnerAndIndex)).second;
+ (void)WasInserted;
+ assert(WasInserted && "Expected to add a reference");
+
+ // Check that the references are direct if there's no owner.
+ (void)MD;
+ assert((OwnerAndIndex.first || *static_cast<Metadata **>(Ref) == &MD) &&
+ "Reference without owner must be direct");
+ assert((OwnerAndIndex.first || *static_cast<Metadata **>(New) == &MD) &&
+ "Reference without owner must be direct");
+}
+
+void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
+ assert(!(MD && isa<MDNode>(MD) && cast<MDNode>(MD)->isTemporary()) &&
+ "Expected non-temp node");
+
+ if (UseMap.empty())
+ return;
+
+ // Copy out uses since UseMap will get touched below.
+ typedef std::pair<void *, std::pair<OwnerTy, uint64_t>> UseTy;
+ SmallVector<UseTy, 8> Uses(UseMap.begin(), UseMap.end());
+ std::sort(Uses.begin(), Uses.end(), [](const UseTy &L, const UseTy &R) {
+ return L.second.second < R.second.second;
+ });
+ for (const auto &Pair : Uses) {
+ // Check that this Ref hasn't disappeared after RAUW (when updating a
+ // previous Ref).
+ if (!UseMap.count(Pair.first))
+ continue;
+
+ OwnerTy Owner = Pair.second.first;
+ if (!Owner) {
+ // Update unowned tracking references directly.
+ Metadata *&Ref = *static_cast<Metadata **>(Pair.first);
+ Ref = MD;
+ if (MD)
+ MetadataTracking::track(Ref);
+ UseMap.erase(Pair.first);
+ continue;
+ }
+
+ // Check for MetadataAsValue.
+ if (Owner.is<MetadataAsValue *>()) {
+ Owner.get<MetadataAsValue *>()->handleChangedMetadata(MD);
+ continue;
+ }
+
+ // There's a Metadata owner -- dispatch.
+ Metadata *OwnerMD = Owner.get<Metadata *>();
+ switch (OwnerMD->getMetadataID()) {
+#define HANDLE_METADATA_LEAF(CLASS) \
+ case Metadata::CLASS##Kind: \
+ cast<CLASS>(OwnerMD)->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.
+ typedef std::pair<void *, std::pair<OwnerTy, uint64_t>> UseTy;
+ SmallVector<UseTy, 8> Uses(UseMap.begin(), UseMap.end());
+ std::sort(Uses.begin(), Uses.end(), [](const UseTy &L, const UseTy &R) {
+ return L.second.second < R.second.second;
+ });
+ UseMap.clear();
+ for (const auto &Pair : Uses) {
+ auto Owner = Pair.second.first;
+ if (!Owner)
+ continue;
+ if (Owner.is<MetadataAsValue *>())
+ continue;
+
+ // Resolve MDNodes that point at this.
+ auto *OwnerMD = dyn_cast<MDNode>(Owner.get<Metadata *>());
+ if (!OwnerMD)
+ continue;
+ if (OwnerMD->isResolved())
+ continue;
+ OwnerMD->decrementUnresolvedOperandCount();
+ }
+}
+
+static Function *getLocalFunction(Value *V) {
+ assert(V && "Expected value");
+ if (auto *A = dyn_cast<Argument>(V))
+ return A->getParent();
+ if (BasicBlock *BB = cast<Instruction>(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<Constant>(V) || isa<Argument>(V) || isa<Instruction>(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<Constant>(V))
+ Entry = new ConstantAsMetadata(C);
+ else
+ Entry = new LocalAsMetadata(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<LocalAsMetadata>(MD)) {
+ if (auto *C = dyn_cast<Constant>(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<Constant>(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.
//
-void MDString::anchor() { }
-
MDString *MDString::get(LLVMContext &Context, StringRef Str) {
auto &Store = Context.pImpl->MDStringCache;
auto I = Store.find(Str);
@@ -44,353 +364,398 @@ MDString *MDString::get(LLVMContext &Context, StringRef Str) {
return &I->second;
auto *Entry =
- StringMapEntry<MDString>::Create(Str, Store.getAllocator(), Context);
+ StringMapEntry<MDString>::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 {
- return StringMapEntry<MDString>::GetStringMapEntryFromValue(*this).first();
+ assert(Entry && "Expected to find string map entry");
+ return Entry->first();
}
//===----------------------------------------------------------------------===//
-// MDNodeOperand implementation.
+// MDNode implementation.
//
-// Use CallbackVH to hold MDNode operands.
-namespace llvm {
-class MDNodeOperand : public CallbackVH {
- MDNode *getParent() {
- MDNodeOperand *Cur = this;
+void *MDNode::operator new(size_t Size, unsigned NumOps) {
+ void *Ptr = ::operator new(Size + NumOps * sizeof(MDOperand));
+ MDOperand *O = static_cast<MDOperand *>(Ptr);
+ for (MDOperand *E = O + NumOps; O != E; ++O)
+ (void)new (O) MDOperand;
+ return O;
+}
+
+void MDNode::operator delete(void *Mem) {
+ MDNode *N = static_cast<MDNode *>(Mem);
+ MDOperand *O = static_cast<MDOperand *>(Mem);
+ for (MDOperand *E = O - N->NumOperands; O != E; --O)
+ (O - 1)->~MDOperand();
+ ::operator delete(O);
+}
- while (Cur->getValPtrInt() != 1)
- ++Cur;
+MDNode::MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
+ ArrayRef<Metadata *> Ops1, ArrayRef<Metadata *> Ops2)
+ : Metadata(ID, Storage), NumOperands(Ops1.size() + Ops2.size()),
+ NumUnresolved(0), Context(Context) {
+ unsigned Op = 0;
+ for (Metadata *MD : Ops1)
+ setOperand(Op++, MD);
+ for (Metadata *MD : Ops2)
+ setOperand(Op++, MD);
+
+ if (isDistinct())
+ return;
- assert(Cur->getValPtrInt() == 1 &&
- "Couldn't find the end of the operand list!");
- return reinterpret_cast<MDNode *>(Cur + 1);
- }
+ if (isUniqued())
+ // Check whether any operands are unresolved, requiring re-uniquing. If
+ // not, don't support RAUW.
+ if (!countUnresolvedOperands())
+ return;
-public:
- MDNodeOperand() {}
- virtual ~MDNodeOperand();
+ this->Context.makeReplaceable(make_unique<ReplaceableMetadataImpl>(Context));
+}
- void set(Value *V) {
- unsigned IsLast = this->getValPtrInt();
- this->setValPtr(V);
- this->setAsLastOperand(IsLast);
+TempMDNode MDNode::clone() const {
+ switch (getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid MDNode subclass");
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case CLASS##Kind: \
+ return cast<CLASS>(this)->cloneImpl();
+#include "llvm/IR/Metadata.def"
}
+}
- /// \brief Accessor method to mark the operand as the first in the list.
- void setAsLastOperand(unsigned I) { this->setValPtrInt(I); }
+static bool isOperandUnresolved(Metadata *Op) {
+ if (auto *N = dyn_cast_or_null<MDNode>(Op))
+ return !N->isResolved();
+ return false;
+}
- void deleted() override;
- void allUsesReplacedWith(Value *NV) override;
-};
-} // end namespace llvm.
+unsigned MDNode::countUnresolvedOperands() {
+ assert(NumUnresolved == 0 && "Expected unresolved ops to be uncounted");
+ NumUnresolved = std::count_if(op_begin(), op_end(), isOperandUnresolved);
+ return NumUnresolved;
+}
-// Provide out-of-line definition to prevent weak vtable.
-MDNodeOperand::~MDNodeOperand() {}
+void MDNode::makeUniqued() {
+ assert(isTemporary() && "Expected this to be temporary");
+ assert(!isResolved() && "Expected this to be unresolved");
-void MDNodeOperand::deleted() {
- getParent()->replaceOperand(this, nullptr);
-}
+ // Make this 'uniqued'.
+ Storage = Uniqued;
+ if (!countUnresolvedOperands())
+ resolve();
-void MDNodeOperand::allUsesReplacedWith(Value *NV) {
- getParent()->replaceOperand(this, NV);
+ assert(isUniqued() && "Expected this to be uniqued");
}
-//===----------------------------------------------------------------------===//
-// MDNode implementation.
-//
+void MDNode::makeDistinct() {
+ assert(isTemporary() && "Expected this to be temporary");
+ assert(!isResolved() && "Expected this to be unresolved");
+
+ // Pretend to be uniqued, resolve the node, and then store in distinct table.
+ Storage = Uniqued;
+ resolve();
+ storeDistinctInContext();
-/// \brief Get the MDNodeOperand's coallocated on the end of the MDNode.
-static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) {
- // Use <= instead of < to permit a one-past-the-end address.
- assert(Op <= N->getNumOperands() && "Invalid operand number");
- return reinterpret_cast<MDNodeOperand *>(N) - N->getNumOperands() + Op;
+ assert(isDistinct() && "Expected this to be distinct");
+ assert(isResolved() && "Expected this to be resolved");
}
-void MDNode::replaceOperandWith(unsigned i, Value *Val) {
- MDNodeOperand *Op = getOperandPtr(this, i);
- replaceOperand(Op, Val);
+void MDNode::resolve() {
+ assert(isUniqued() && "Expected this to be uniqued");
+ assert(!isResolved() && "Expected this to be unresolved");
+
+ // Move the map, so that this immediately looks resolved.
+ auto Uses = Context.takeReplaceableUses();
+ NumUnresolved = 0;
+ assert(isResolved() && "Expected this to be resolved");
+
+ // Drop RAUW support.
+ Uses->resolveAllUses();
}
-void *MDNode::operator new(size_t Size, unsigned NumOps) {
- void *Ptr = ::operator new(Size + NumOps * sizeof(MDNodeOperand));
- MDNodeOperand *Op = static_cast<MDNodeOperand *>(Ptr);
- if (NumOps) {
- MDNodeOperand *Last = Op + NumOps;
- for (; Op != Last; ++Op)
- new (Op) MDNodeOperand();
- (Op - 1)->setAsLastOperand(1);
- }
- return Op;
+void MDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {
+ assert(NumUnresolved != 0 && "Expected unresolved operands");
+
+ // Check if an operand was resolved.
+ if (!isOperandUnresolved(Old)) {
+ if (isOperandUnresolved(New))
+ // An operand was un-resolved!
+ ++NumUnresolved;
+ } else if (!isOperandUnresolved(New))
+ decrementUnresolvedOperandCount();
}
-void MDNode::operator delete(void *Mem) {
- MDNode *N = static_cast<MDNode *>(Mem);
- MDNodeOperand *Op = static_cast<MDNodeOperand *>(Mem);
- for (unsigned I = 0, E = N->NumOperands; I != E; ++I)
- (--Op)->~MDNodeOperand();
- ::operator delete(Op);
+void MDNode::decrementUnresolvedOperandCount() {
+ if (!--NumUnresolved)
+ // Last unresolved operand has just been resolved.
+ resolve();
}
-MDNode::MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,
- bool isFunctionLocal)
- : Metadata(C, ID) {
- NumOperands = Vals.size();
+void MDNode::resolveCycles() {
+ if (isResolved())
+ return;
- if (isFunctionLocal)
- setValueSubclassData(getSubclassDataFromValue() | FunctionLocalBit);
+ // Resolve this node immediately.
+ resolve();
- // Initialize the operand list.
- unsigned i = 0;
- for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op + NumOperands;
- Op != E; ++Op, ++i)
- Op->set(Vals[i]);
-}
+ // Resolve all operands.
+ for (const auto &Op : operands()) {
+ auto *N = dyn_cast_or_null<MDNode>(Op);
+ if (!N)
+ continue;
-GenericMDNode::~GenericMDNode() {
- LLVMContextImpl *pImpl = getType()->getContext().pImpl;
- if (isNotUniqued()) {
- pImpl->NonUniquedMDNodes.erase(this);
- } else {
- pImpl->MDNodeSet.erase(this);
+ assert(!N->isTemporary() &&
+ "Expected all forward declarations to be resolved");
+ if (!N->isResolved())
+ N->resolveCycles();
}
}
-void GenericMDNode::dropAllReferences() {
- for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op + NumOperands;
- Op != E; ++Op)
- Op->set(nullptr);
+static bool hasSelfReference(MDNode *N) {
+ for (Metadata *MD : N->operands())
+ if (MD == N)
+ return true;
+ return false;
+}
+
+MDNode *MDNode::replaceWithPermanentImpl() {
+ if (hasSelfReference(this))
+ return replaceWithDistinctImpl();
+ return replaceWithUniquedImpl();
}
-static const Function *getFunctionForValue(Value *V) {
- if (!V) return nullptr;
- if (Instruction *I = dyn_cast<Instruction>(V)) {
- BasicBlock *BB = I->getParent();
- return BB ? BB->getParent() : nullptr;
+MDNode *MDNode::replaceWithUniquedImpl() {
+ // Try to uniquify in place.
+ MDNode *UniquedNode = uniquify();
+
+ if (UniquedNode == this) {
+ makeUniqued();
+ return this;
}
- if (Argument *A = dyn_cast<Argument>(V))
- return A->getParent();
- if (BasicBlock *BB = dyn_cast<BasicBlock>(V))
- return BB->getParent();
- if (MDNode *MD = dyn_cast<MDNode>(V))
- return MD->getFunction();
- return nullptr;
+
+ // Collision, so RAUW instead.
+ replaceAllUsesWith(UniquedNode);
+ deleteAsSubclass();
+ return UniquedNode;
}
-#ifndef NDEBUG
-static const Function *assertLocalFunction(const MDNode *N) {
- if (!N->isFunctionLocal()) return nullptr;
+MDNode *MDNode::replaceWithDistinctImpl() {
+ makeDistinct();
+ return this;
+}
- // FIXME: This does not handle cyclic function local metadata.
- const Function *F = nullptr, *NewF = nullptr;
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) {
- if (Value *V = N->getOperand(i)) {
- if (MDNode *MD = dyn_cast<MDNode>(V))
- NewF = assertLocalFunction(MD);
- else
- NewF = getFunctionForValue(V);
- }
- if (!F)
- F = NewF;
- else
- assert((NewF == nullptr || F == NewF) &&
- "inconsistent function-local metadata");
- }
- return F;
-}
-#endif
-
-// getFunction - If this metadata is function-local and recursively has a
-// function-local operand, return the first such operand's parent function.
-// Otherwise, return null. getFunction() should not be used for performance-
-// critical code because it recursively visits all the MDNode's operands.
-const Function *MDNode::getFunction() const {
-#ifndef NDEBUG
- return assertLocalFunction(this);
-#else
- if (!isFunctionLocal()) return nullptr;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- if (const Function *F = getFunctionForValue(getOperand(i)))
- return F;
- return nullptr;
-#endif
+void MDTuple::recalculateHash() {
+ setHash(MDTupleInfo::KeyTy::calculateHash(this));
}
-/// \brief Check if the Value would require a function-local MDNode.
-static bool isFunctionLocalValue(Value *V) {
- return isa<Instruction>(V) || isa<Argument>(V) || isa<BasicBlock>(V) ||
- (isa<MDNode>(V) && cast<MDNode>(V)->isFunctionLocal());
+void MDNode::dropAllReferences() {
+ for (unsigned I = 0, E = NumOperands; I != E; ++I)
+ setOperand(I, nullptr);
+ if (!isResolved()) {
+ Context.getReplaceableUses()->resolveAllUses(/* ResolveUsers */ false);
+ (void)Context.takeReplaceableUses();
+ }
}
-MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Value*> Vals,
- FunctionLocalness FL, bool Insert) {
- auto &Store = Context.pImpl->MDNodeSet;
+void MDNode::handleChangedOperand(void *Ref, Metadata *New) {
+ unsigned Op = static_cast<MDOperand *>(Ref) - op_begin();
+ assert(Op < getNumOperands() && "Expected valid operand");
- GenericMDNodeInfo::KeyTy Key(Vals);
- auto I = Store.find_as(Key);
- if (I != Store.end())
- return *I;
- if (!Insert)
- return nullptr;
+ if (!isUniqued()) {
+ // This node is not uniqued. Just set the operand and be done with it.
+ setOperand(Op, New);
+ return;
+ }
- bool isFunctionLocal = false;
- switch (FL) {
- case FL_Unknown:
- for (Value *V : Vals) {
- if (!V) continue;
- if (isFunctionLocalValue(V)) {
- isFunctionLocal = true;
- break;
- }
- }
- break;
- case FL_No:
- isFunctionLocal = false;
- break;
- case FL_Yes:
- isFunctionLocal = true;
+ // This node is uniqued.
+ eraseFromStore();
+
+ Metadata *Old = getOperand(Op);
+ setOperand(Op, New);
+
+ // Drop uniquing for self-reference cycles.
+ if (New == this) {
+ if (!isResolved())
+ resolve();
+ storeDistinctInContext();
+ return;
+ }
+
+ // Re-unique the node.
+ auto *Uniqued = uniquify();
+ if (Uniqued == this) {
+ if (!isResolved())
+ resolveAfterOperandChange(Old, New);
+ return;
+ }
+
+ // Collision.
+ if (!isResolved()) {
+ // Still unresolved, so RAUW.
+ //
+ // First, clear out all operands to prevent any recursion (similar to
+ // dropAllReferences(), but we still need the use-list).
+ for (unsigned O = 0, E = getNumOperands(); O != E; ++O)
+ setOperand(O, nullptr);
+ Context.getReplaceableUses()->replaceAllUsesWith(Uniqued);
+ deleteAsSubclass();
+ return;
+ }
+
+ // Store in non-uniqued form if RAUW isn't possible.
+ storeDistinctInContext();
+}
+
+void MDNode::deleteAsSubclass() {
+ switch (getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid subclass of MDNode");
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case CLASS##Kind: \
+ delete cast<CLASS>(this); \
break;
+#include "llvm/IR/Metadata.def"
}
+}
- // Coallocate space for the node and Operands together, then placement new.
- GenericMDNode *N =
- new (Vals.size()) GenericMDNode(Context, Vals, isFunctionLocal);
+template <class T, class InfoT>
+static T *uniquifyImpl(T *N, DenseSet<T *, InfoT> &Store) {
+ if (T *U = getUniqued(Store, N))
+ return U;
- N->Hash = Key.Hash;
Store.insert(N);
return N;
}
-MDNode *MDNode::get(LLVMContext &Context, ArrayRef<Value*> Vals) {
- return getMDNode(Context, Vals, FL_Unknown);
-}
+template <class NodeTy> struct MDNode::HasCachedHash {
+ typedef char Yes[1];
+ typedef char No[2];
+ template <class U, U Val> struct SFINAE {};
-MDNode *MDNode::getWhenValsUnresolved(LLVMContext &Context,
- ArrayRef<Value*> Vals,
- bool isFunctionLocal) {
- return getMDNode(Context, Vals, isFunctionLocal ? FL_Yes : FL_No);
-}
+ template <class U>
+ static Yes &check(SFINAE<void (U::*)(unsigned), &U::setHash> *);
+ template <class U> static No &check(...);
-MDNode *MDNode::getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals) {
- return getMDNode(Context, Vals, FL_Unknown, false);
-}
+ static const bool value = sizeof(check<NodeTy>(nullptr)) == sizeof(Yes);
+};
-MDNode *MDNode::getTemporary(LLVMContext &Context, ArrayRef<Value*> Vals) {
- MDNode *N = new (Vals.size()) MDNodeFwdDecl(Context, Vals, FL_No);
- N->setValueSubclassData(N->getSubclassDataFromValue() | NotUniquedBit);
- LeakDetector::addGarbageObject(N);
- return N;
+MDNode *MDNode::uniquify() {
+ assert(!hasSelfReference(this) && "Cannot uniquify a self-referencing node");
+
+ // Try to insert into uniquing store.
+ switch (getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid subclass of MDNode");
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case CLASS##Kind: { \
+ CLASS *SubclassThis = cast<CLASS>(this); \
+ std::integral_constant<bool, HasCachedHash<CLASS>::value> \
+ ShouldRecalculateHash; \
+ dispatchRecalculateHash(SubclassThis, ShouldRecalculateHash); \
+ return uniquifyImpl(SubclassThis, getContext().pImpl->CLASS##s); \
+ }
+#include "llvm/IR/Metadata.def"
+ }
}
-void MDNode::deleteTemporary(MDNode *N) {
- assert(N->use_empty() && "Temporary MDNode has uses!");
- assert(isa<MDNodeFwdDecl>(N) && "Expected forward declaration");
- assert((N->getSubclassDataFromValue() & NotUniquedBit) &&
- "Temporary MDNode does not have NotUniquedBit set!");
- LeakDetector::removeGarbageObject(N);
- delete cast<MDNodeFwdDecl>(N);
-}
-
-/// \brief Return specified operand.
-Value *MDNode::getOperand(unsigned i) const {
- assert(i < getNumOperands() && "Invalid operand number");
- return *getOperandPtr(const_cast<MDNode*>(this), i);
-}
-
-void MDNode::setIsNotUniqued() {
- setValueSubclassData(getSubclassDataFromValue() | NotUniquedBit);
- LLVMContextImpl *pImpl = getType()->getContext().pImpl;
- auto *G = cast<GenericMDNode>(this);
- G->Hash = 0;
- pImpl->NonUniquedMDNodes.insert(G);
-}
-
-// Replace value from this node's operand list.
-void MDNode::replaceOperand(MDNodeOperand *Op, Value *To) {
- Value *From = *Op;
-
- // If is possible that someone did GV->RAUW(inst), replacing a global variable
- // with an instruction or some other function-local object. If this is a
- // non-function-local MDNode, it can't point to a function-local object.
- // Handle this case by implicitly dropping the MDNode reference to null.
- // Likewise if the MDNode is function-local but for a different function.
- if (To && isFunctionLocalValue(To)) {
- if (!isFunctionLocal())
- To = nullptr;
- else {
- const Function *F = getFunction();
- const Function *FV = getFunctionForValue(To);
- // Metadata can be function-local without having an associated function.
- // So only consider functions to have changed if non-null.
- if (F && FV && F != FV)
- To = nullptr;
- }
+void MDNode::eraseFromStore() {
+ switch (getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid subclass of MDNode");
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case CLASS##Kind: \
+ getContext().pImpl->CLASS##s.erase(cast<CLASS>(this)); \
+ break;
+#include "llvm/IR/Metadata.def"
}
-
- if (From == To)
- return;
+}
- // If this node is already not being uniqued (because one of the operands
- // already went to null), then there is nothing else to do here.
- if (isNotUniqued()) {
- Op->set(To);
- return;
+MDTuple *MDTuple::getImpl(LLVMContext &Context, ArrayRef<Metadata *> MDs,
+ StorageType Storage, bool ShouldCreate) {
+ unsigned Hash = 0;
+ if (Storage == Uniqued) {
+ MDTupleInfo::KeyTy Key(MDs);
+ if (auto *N = getUniqued(Context.pImpl->MDTuples, Key))
+ return N;
+ if (!ShouldCreate)
+ return nullptr;
+ Hash = Key.getHash();
+ } else {
+ assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
}
- auto &Store = getContext().pImpl->MDNodeSet;
- auto *N = cast<GenericMDNode>(this);
+ return storeImpl(new (MDs.size()) MDTuple(Context, Storage, Hash, MDs),
+ Storage, Context.pImpl->MDTuples);
+}
+
+void MDNode::deleteTemporary(MDNode *N) {
+ assert(N->isTemporary() && "Expected temporary node");
+ N->replaceAllUsesWith(nullptr);
+ N->deleteAsSubclass();
+}
- // Remove "this" from the context map.
- Store.erase(N);
+void MDNode::storeDistinctInContext() {
+ assert(isResolved() && "Expected resolved nodes");
+ Storage = Distinct;
+
+ // Reset the hash.
+ switch (getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid subclass of MDNode");
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case CLASS##Kind: { \
+ std::integral_constant<bool, HasCachedHash<CLASS>::value> ShouldResetHash; \
+ dispatchResetHash(cast<CLASS>(this), ShouldResetHash); \
+ break; \
+ }
+#include "llvm/IR/Metadata.def"
+ }
- // Update the operand.
- Op->set(To);
+ getContext().pImpl->DistinctMDNodes.insert(this);
+}
- // If we are dropping an argument to null, we choose to not unique the MDNode
- // anymore. This commonly occurs during destruction, and uniquing these
- // brings little reuse. Also, this means we don't need to include
- // isFunctionLocal bits in the hash for MDNodes.
- if (!To) {
- setIsNotUniqued();
+void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
+ if (getOperand(I) == New)
return;
- }
- // Now that the node is out of the table, get ready to reinsert it. First,
- // check to see if another node with the same operands already exists in the
- // set. If so, then this node is redundant.
- SmallVector<Value *, 8> Vals;
- GenericMDNodeInfo::KeyTy Key(N, Vals);
- auto I = Store.find_as(Key);
- if (I != Store.end()) {
- N->replaceAllUsesWith(*I);
- delete N;
+ if (!isUniqued()) {
+ setOperand(I, New);
return;
}
- N->Hash = Key.Hash;
- Store.insert(N);
+ handleChangedOperand(mutable_begin() + I, New);
+}
- // If this MDValue was previously function-local but no longer is, clear
- // its function-local flag.
- if (isFunctionLocal() && !isFunctionLocalValue(To)) {
- bool isStillFunctionLocal = false;
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
- Value *V = getOperand(i);
- if (!V) continue;
- if (isFunctionLocalValue(V)) {
- isStillFunctionLocal = true;
- break;
+void MDNode::setOperand(unsigned I, Metadata *New) {
+ assert(I < NumOperands);
+ mutable_begin()[I].reset(New, isUniqued() ? this : nullptr);
+}
+
+/// \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<Metadata *> Ops) {
+ if (!Ops.empty())
+ if (MDNode *N = dyn_cast_or_null<MDNode>(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;
}
- }
- if (!isStillFunctionLocal)
- setValueSubclassData(getSubclassDataFromValue() & ~FunctionLocalBit);
- }
+
+ return MDNode::get(Context, Ops);
}
MDNode *MDNode::concatenate(MDNode *A, MDNode *B) {
@@ -399,41 +764,50 @@ MDNode *MDNode::concatenate(MDNode *A, MDNode *B) {
if (!B)
return A;
- SmallVector<Value *, 4> Vals(A->getNumOperands() +
- B->getNumOperands());
-
- unsigned j = 0;
- for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i)
- Vals[j++] = A->getOperand(i);
- for (unsigned i = 0, ie = B->getNumOperands(); i != ie; ++i)
- Vals[j++] = B->getOperand(i);
+ SmallVector<Metadata *, 4> MDs;
+ MDs.reserve(A->getNumOperands() + B->getNumOperands());
+ MDs.append(A->op_begin(), A->op_end());
+ MDs.append(B->op_begin(), B->op_end());
- return MDNode::get(A->getContext(), Vals);
+ // 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<Value *, 4> Vals;
- for (unsigned i = 0, ie = A->getNumOperands(); i != ie; ++i) {
- Value *V = A->getOperand(i);
- for (unsigned j = 0, je = B->getNumOperands(); j != je; ++j)
- if (V == B->getOperand(j)) {
- Vals.push_back(V);
- break;
- }
- }
+ SmallVector<Metadata *, 4> MDs;
+ for (Metadata *MD : A->operands())
+ if (std::find(B->op_begin(), B->op_end(), MD) != B->op_end())
+ MDs.push_back(MD);
+
+ // 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::getMostGenericAliasScope(MDNode *A, MDNode *B) {
+ if (!A || !B)
+ return nullptr;
+
+ SmallVector<Metadata *, 4> MDs(B->op_begin(), B->op_end());
+ for (Metadata *MD : A->operands())
+ if (std::find(B->op_begin(), B->op_end(), MD) == B->op_end())
+ MDs.push_back(MD);
- return MDNode::get(A->getContext(), Vals);
+ // 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 = cast<ConstantFP>(A->getOperand(0))->getValueAPF();
- APFloat BVal = cast<ConstantFP>(B->getOperand(0))->getValueAPF();
+ APFloat AVal = mdconst::extract<ConstantFP>(A->getOperand(0))->getValueAPF();
+ APFloat BVal = mdconst::extract<ConstantFP>(B->getOperand(0))->getValueAPF();
if (AVal.compare(BVal) == APFloat::cmpLessThan)
return A;
return B;
@@ -447,25 +821,27 @@ static bool canBeMerged(const ConstantRange &A, const ConstantRange &B) {
return !A.intersectWith(B).isEmptySet() || isContiguous(A, B);
}
-static bool tryMergeRange(SmallVectorImpl<Value *> &EndPoints, ConstantInt *Low,
- ConstantInt *High) {
+static bool tryMergeRange(SmallVectorImpl<ConstantInt *> &EndPoints,
+ ConstantInt *Low, ConstantInt *High) {
ConstantRange NewRange(Low->getValue(), High->getValue());
unsigned Size = EndPoints.size();
- APInt LB = cast<ConstantInt>(EndPoints[Size - 2])->getValue();
- APInt LE = cast<ConstantInt>(EndPoints[Size - 1])->getValue();
+ 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] = ConstantInt::get(Ty, Union.getLower());
- EndPoints[Size - 1] = ConstantInt::get(Ty, Union.getUpper());
+ EndPoints[Size - 2] =
+ cast<ConstantInt>(ConstantInt::get(Ty, Union.getLower()));
+ EndPoints[Size - 1] =
+ cast<ConstantInt>(ConstantInt::get(Ty, Union.getUpper()));
return true;
}
return false;
}
-static void addRange(SmallVectorImpl<Value *> &EndPoints, ConstantInt *Low,
- ConstantInt *High) {
+static void addRange(SmallVectorImpl<ConstantInt *> &EndPoints,
+ ConstantInt *Low, ConstantInt *High) {
if (!EndPoints.empty())
if (tryMergeRange(EndPoints, Low, High))
return;
@@ -487,31 +863,33 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
// 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<Value*, 4> EndPoints;
+ SmallVector<ConstantInt *, 4> EndPoints;
int AI = 0;
int BI = 0;
int AN = A->getNumOperands() / 2;
int BN = B->getNumOperands() / 2;
while (AI < AN && BI < BN) {
- ConstantInt *ALow = cast<ConstantInt>(A->getOperand(2 * AI));
- ConstantInt *BLow = cast<ConstantInt>(B->getOperand(2 * BI));
+ ConstantInt *ALow = mdconst::extract<ConstantInt>(A->getOperand(2 * AI));
+ ConstantInt *BLow = mdconst::extract<ConstantInt>(B->getOperand(2 * BI));
if (ALow->getValue().slt(BLow->getValue())) {
- addRange(EndPoints, ALow, cast<ConstantInt>(A->getOperand(2 * AI + 1)));
+ addRange(EndPoints, ALow,
+ mdconst::extract<ConstantInt>(A->getOperand(2 * AI + 1)));
++AI;
} else {
- addRange(EndPoints, BLow, cast<ConstantInt>(B->getOperand(2 * BI + 1)));
+ addRange(EndPoints, BLow,
+ mdconst::extract<ConstantInt>(B->getOperand(2 * BI + 1)));
++BI;
}
}
while (AI < AN) {
- addRange(EndPoints, cast<ConstantInt>(A->getOperand(2 * AI)),
- cast<ConstantInt>(A->getOperand(2 * AI + 1)));
+ addRange(EndPoints, mdconst::extract<ConstantInt>(A->getOperand(2 * AI)),
+ mdconst::extract<ConstantInt>(A->getOperand(2 * AI + 1)));
++AI;
}
while (BI < BN) {
- addRange(EndPoints, cast<ConstantInt>(B->getOperand(2 * BI)),
- cast<ConstantInt>(B->getOperand(2 * BI + 1)));
+ addRange(EndPoints, mdconst::extract<ConstantInt>(B->getOperand(2 * BI)),
+ mdconst::extract<ConstantInt>(B->getOperand(2 * BI + 1)));
++BI;
}
@@ -519,8 +897,8 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
// the last and first ones.
unsigned Size = EndPoints.size();
if (Size > 4) {
- ConstantInt *FB = cast<ConstantInt>(EndPoints[0]);
- ConstantInt *FE = cast<ConstantInt>(EndPoints[1]);
+ 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];
@@ -532,26 +910,29 @@ MDNode *MDNode::getMostGenericRange(MDNode *A, MDNode *B) {
// 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(cast<ConstantInt>(EndPoints[0])->getValue(),
- cast<ConstantInt>(EndPoints[1])->getValue());
+ ConstantRange Range(EndPoints[0]->getValue(), EndPoints[1]->getValue());
if (Range.isFullSet())
return nullptr;
}
- return MDNode::get(A->getContext(), EndPoints);
+ SmallVector<Metadata *, 4> 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<TrackingVH<MDNode>, 4> &getNMDOps(void *Operands) {
- return *(SmallVector<TrackingVH<MDNode>, 4> *)Operands;
+static SmallVector<TrackingMDRef, 4> &getNMDOps(void *Operands) {
+ return *(SmallVector<TrackingMDRef, 4> *)Operands;
}
NamedMDNode::NamedMDNode(const Twine &N)
: Name(N.str()), Parent(nullptr),
- Operands(new SmallVector<TrackingVH<MDNode>, 4>()) {}
+ Operands(new SmallVector<TrackingMDRef, 4>()) {}
NamedMDNode::~NamedMDNode() {
dropAllReferences();
@@ -564,13 +945,15 @@ unsigned NamedMDNode::getNumOperands() const {
MDNode *NamedMDNode::getOperand(unsigned i) const {
assert(i < getNumOperands() && "Invalid Operand number!");
- return &*getNMDOps(Operands)[i];
+ auto *N = getNMDOps(Operands)[i].get();
+ return cast_or_null<MDNode>(N);
}
-void NamedMDNode::addOperand(MDNode *M) {
- assert(!M->isFunctionLocal() &&
- "NamedMDNode operands must not be function-local!");
- getNMDOps(Operands).push_back(TrackingVH<MDNode>(M));
+void NamedMDNode::addOperand(MDNode *M) { getNMDOps(Operands).emplace_back(M); }
+
+void NamedMDNode::setOperand(unsigned I, MDNode *New) {
+ assert(I < getNumOperands() && "Invalid operand number");
+ getNMDOps(Operands)[I].reset(New);
}
void NamedMDNode::eraseFromParent() {
@@ -630,7 +1013,7 @@ void Instruction::dropUnknownMetadata(ArrayRef<unsigned> KnownIDs) {
continue;
}
- Info[I] = Info.back();
+ Info[I] = std::move(Info.back());
Info.pop_back();
--E;
}
@@ -667,13 +1050,14 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
// Handle replacement of an existing value.
for (auto &P : Info)
if (P.first == KindID) {
- P.second = Node;
+ P.second.reset(Node);
return;
}
}
// No replacement, just add it to the list.
- Info.push_back(std::make_pair(KindID, Node));
+ Info.emplace_back(std::piecewise_construct, std::make_tuple(KindID),
+ std::make_tuple(Node));
return;
}
@@ -695,7 +1079,7 @@ void Instruction::setMetadata(unsigned KindID, MDNode *Node) {
// Handle removal of an existing value.
for (unsigned i = 0, e = Info.size(); i != e; ++i)
if (Info[i].first == KindID) {
- Info[i] = Info.back();
+ Info[i] = std::move(Info.back());
Info.pop_back();
assert(!Info.empty() && "Removing last entry should be handled above");
return;
@@ -712,8 +1096,8 @@ void Instruction::setAAMetadata(const AAMDNodes &N) {
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(getContext());
-
+ return DbgLoc.getAsMDNode();
+
if (!hasMetadataHashEntry()) return nullptr;
LLVMContextImpl::MDMapTy &Info = getContext().pImpl->MetadataStore[this];
@@ -731,8 +1115,8 @@ void Instruction::getAllMetadataImpl(
// 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(getContext())));
+ Result.push_back(
+ std::make_pair((unsigned)LLVMContext::MD_dbg, DbgLoc.getAsMDNode()));
if (!hasMetadataHashEntry()) return;
}
@@ -743,7 +1127,9 @@ void Instruction::getAllMetadataImpl(
getContext().pImpl->MetadataStore.find(this)->second;
assert(!Info.empty() && "Shouldn't have called this");
- Result.append(Info.begin(), Info.end());
+ Result.reserve(Result.size() + Info.size());
+ for (auto &I : Info)
+ Result.push_back(std::make_pair(I.first, cast<MDNode>(I.second.get())));
// Sort the resulting array so it is stable.
if (Result.size() > 1)
@@ -759,7 +1145,9 @@ void Instruction::getAllMetadataOtherThanDebugLocImpl(
const LLVMContextImpl::MDMapTy &Info =
getContext().pImpl->MetadataStore.find(this)->second;
assert(!Info.empty() && "Shouldn't have called this");
- Result.append(Info.begin(), Info.end());
+ Result.reserve(Result.size() + Info.size());
+ for (auto &I : Info)
+ Result.push_back(std::make_pair(I.first, cast<MDNode>(I.second.get())));
// Sort the resulting array so it is stable.
if (Result.size() > 1)
@@ -773,4 +1161,3 @@ void Instruction::clearMetadataHashEntries() {
getContext().pImpl->MetadataStore.erase(this);
setHasMetadataHashEntry(false);
}
-