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.
::operator delete(O);
}
-MDNode::MDNode(LLVMContext &Context, unsigned ID, ArrayRef<Metadata *> MDs)
- : Metadata(ID), Context(Context), NumOperands(MDs.size()),
+MDNode::MDNode(LLVMContext &Context, unsigned ID, StorageType Storage,
+ ArrayRef<Metadata *> MDs)
+ : Metadata(ID, Storage), 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<MDNodeFwdDecl>(this))
- return false;
- return cast<UniquableMDNode>(this)->isResolved();
+ if (Storage == Temporary)
+ this->Context.makeReplaceable(
+ make_unique<ReplaceableMetadataImpl>(Context));
}
static bool isOperandUnresolved(Metadata *Op) {
}
UniquableMDNode::UniquableMDNode(LLVMContext &C, unsigned ID,
- ArrayRef<Metadata *> Vals, bool AllowRAUW)
- : MDNode(C, ID, Vals) {
- if (!AllowRAUW)
+ StorageType Storage, ArrayRef<Metadata *> Vals)
+ : MDNode(C, ID, Storage, Vals) {
+ if (Storage != Uniqued)
return;
// Check whether any operands are unresolved, requiring re-uniquing.
if (!NumUnresolved)
return;
- ReplaceableUses.reset(new ReplaceableMetadataImpl);
+ this->Context.makeReplaceable(make_unique<ReplaceableMetadataImpl>(C));
SubclassData32 = NumUnresolved;
}
void UniquableMDNode::resolve() {
+ assert(Storage == Uniqued && "Expected this to be uniqued");
assert(!isResolved() && "Expected this to be unresolved");
// Move the map, so that this immediately looks resolved.
- auto Uses = std::move(ReplaceableUses);
+ auto Uses = Context.takeReplaceableUses();
SubclassData32 = 0;
assert(isResolved() && "Expected this to be resolved");
setOperand(I, nullptr);
if (auto *N = dyn_cast<UniquableMDNode>(this))
if (!N->isResolved()) {
- N->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false);
- N->ReplaceableUses.reset();
+ N->Context.getReplaceableUses()->resolveAllUses(/* ResolveUsers */ false);
+ (void)N->Context.takeReplaceableUses();
}
}
// Drop uniquing for self-reference cycles.
if (New == this) {
- storeDistinctInContext();
if (!isResolved())
resolve();
+ storeDistinctInContext();
return;
}
// dropAllReferences(), but we still need the use-list).
for (unsigned O = 0, E = getNumOperands(); O != E; ++O)
setOperand(O, nullptr);
- ReplaceableUses->replaceAllUsesWith(Uniqued);
+ Context.getReplaceableUses()->replaceAllUsesWith(Uniqued);
deleteAsSubclass();
return;
}
return nullptr;
// Coallocate space for the node and Operands together, then placement new.
- auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ true);
+ auto *N = new (MDs.size()) MDTuple(Context, Uniqued, MDs);
N->setHash(Key.Hash);
Store.insert(N);
return N;
}
MDTuple *MDTuple::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
- auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ false);
+ auto *N = new (MDs.size()) MDTuple(Context, Distinct, MDs);
N->storeDistinctInContext();
return N;
}
void MDTuple::eraseFromStoreImpl() { getContext().pImpl->MDTuples.erase(this); }
-MDLocation::MDLocation(LLVMContext &C, unsigned Line, unsigned Column,
- ArrayRef<Metadata *> MDs, bool AllowRAUW)
- : UniquableMDNode(C, MDLocationKind, MDs, AllowRAUW) {
+MDLocation::MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned Column, ArrayRef<Metadata *> MDs)
+ : UniquableMDNode(C, MDLocationKind, Storage, MDs) {
assert((MDs.size() == 1 || MDs.size() == 2) &&
"Expected a scope and optional inlined-at");
// Set line and column.
assert(Line < (1u << 24) && "Expected 24-bit line");
- assert(Column < (1u << 8) && "Expected 8-bit column");
+ assert(Column < (1u << 16) && "Expected 16-bit column");
MDNodeSubclassData = Line;
SubclassData16 = Column;
}
-MDLocation *MDLocation::constructHelper(LLVMContext &Context, unsigned Line,
+MDLocation *MDLocation::constructHelper(LLVMContext &Context,
+ StorageType Storage, unsigned Line,
unsigned Column, Metadata *Scope,
- Metadata *InlinedAt, bool AllowRAUW) {
+ Metadata *InlinedAt) {
SmallVector<Metadata *, 2> Ops;
Ops.push_back(Scope);
if (InlinedAt)
Ops.push_back(InlinedAt);
- return new (Ops.size()) MDLocation(Context, Line, Column, Ops, AllowRAUW);
+ return new (Ops.size()) MDLocation(Context, Storage, Line, Column, Ops);
}
static void adjustLine(unsigned &Line) {
}
static void adjustColumn(unsigned &Column) {
- // Set to unknown on overflow. Still use 8 bits for now.
- if (Column >= (1u << 8))
+ // Set to unknown on overflow. We only have 16 bits to play with here.
+ if (Column >= (1u << 16))
Column = 0;
}
if (!ShouldCreate)
return nullptr;
- auto *N = constructHelper(Context, Line, Column, Scope, InlinedAt,
- /* AllowRAUW */ true);
+ auto *N = constructHelper(Context, Uniqued, Line, Column, Scope, InlinedAt);
Store.insert(N);
return N;
}
adjustLine(Line);
adjustColumn(Column);
- auto *N = constructHelper(Context, Line, Column, Scope, InlinedAt,
- /* AllowRAUW */ false);
+ auto *N = constructHelper(Context, Distinct, Line, Column, Scope, InlinedAt);
N->storeDistinctInContext();
return N;
}
void MDNode::deleteTemporary(MDNode *N) { delete cast<MDNodeFwdDecl>(N); }
void UniquableMDNode::storeDistinctInContext() {
- assert(!IsDistinctInContext && "Expected newly distinct metadata");
- IsDistinctInContext = true;
+ assert(isResolved() && "Expected resolved nodes");
+ Storage = Distinct;
if (auto *T = dyn_cast<MDTuple>(this))
T->setHash(0);
getContext().pImpl->DistinctMDNodes.insert(this);
if (getOperand(I) == New)
return;
- if (isDistinct()) {
+ if (!isUniqued()) {
setOperand(I, New);
return;
}