IR: Return unique_ptr from MDNode::getTemporary()

Change `MDTuple::getTemporary()` and `MDLocation::getTemporary()` to
return (effectively) `std::unique_ptr<T, MDNode::deleteTemporary>`, and
clean up call sites.  (For now, `DIBuilder` call sites just call
`release()` immediately.)

There's an accompanying change in each of clang and polly to use the new
API.

llvm-svn: 226504
This commit is contained in:
Duncan P. N. Exon Smith 2015-01-19 21:30:18 +00:00
parent 2658554aec
commit 7d82313bcd
10 changed files with 77 additions and 81 deletions

View File

@ -66,8 +66,9 @@ LLVMMetadataRef LLVMMDNode2(LLVMContextRef C, LLVMMetadataRef *MDs,
LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef C, LLVMMetadataRef *MDs, LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef C, LLVMMetadataRef *MDs,
unsigned Count) { unsigned Count) {
return wrap(MDNode::getTemporary(*unwrap(C), return wrap(MDTuple::getTemporary(*unwrap(C),
ArrayRef<Metadata *>(unwrap(MDs), Count))); ArrayRef<Metadata *>(unwrap(MDs), Count))
.release());
} }
void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name, void LLVMAddNamedMetadataOperand2(LLVMModuleRef M, const char *name,

View File

@ -651,6 +651,15 @@ public:
} }
}; };
template <class T>
struct TempMDNodeDeleter {
inline void operator()(T *Node) const;
};
#define HANDLE_UNIQUABLE_LEAF(CLASS) \
typedef std::unique_ptr<CLASS, TempMDNodeDeleter<CLASS>> Temp##CLASS;
#include "llvm/IR/Metadata.def"
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// \brief Tuple of metadata. /// \brief Tuple of metadata.
class MDNode : public Metadata { class MDNode : public Metadata {
@ -697,8 +706,8 @@ public:
ArrayRef<Metadata *> MDs); ArrayRef<Metadata *> MDs);
static inline MDTuple *getDistinct(LLVMContext &Context, static inline MDTuple *getDistinct(LLVMContext &Context,
ArrayRef<Metadata *> MDs); ArrayRef<Metadata *> MDs);
static inline MDTuple *getTemporary(LLVMContext &Context, static inline TempMDTuple getTemporary(LLVMContext &Context,
ArrayRef<Metadata *> MDs); ArrayRef<Metadata *> MDs);
/// \brief Deallocate a node created by getTemporary. /// \brief Deallocate a node created by getTemporary.
/// ///
@ -884,8 +893,9 @@ public:
/// For use in constructing cyclic MDNode structures. A temporary MDNode is /// For use in constructing cyclic MDNode structures. A temporary MDNode is
/// not uniqued, may be RAUW'd, and must be manually deleted with /// not uniqued, may be RAUW'd, and must be manually deleted with
/// deleteTemporary. /// deleteTemporary.
static MDTuple *getTemporary(LLVMContext &Context, ArrayRef<Metadata *> MDs) { static TempMDTuple getTemporary(LLVMContext &Context,
return getImpl(Context, MDs, Temporary); ArrayRef<Metadata *> MDs) {
return TempMDTuple(getImpl(Context, MDs, Temporary));
} }
static bool classof(const Metadata *MD) { static bool classof(const Metadata *MD) {
@ -906,9 +916,14 @@ MDTuple *MDNode::getIfExists(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
MDTuple *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) { MDTuple *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {
return MDTuple::getDistinct(Context, MDs); return MDTuple::getDistinct(Context, MDs);
} }
MDTuple *MDNode::getTemporary(LLVMContext &Context, ArrayRef<Metadata *> MDs) { TempMDTuple MDNode::getTemporary(LLVMContext &Context,
ArrayRef<Metadata *> MDs) {
return MDTuple::getTemporary(Context, MDs); return MDTuple::getTemporary(Context, MDs);
} }
template <class T>
void TempMDNodeDeleter<T>::operator()(T *Node) const {
MDNode::deleteTemporary(Node);
}
/// \brief Debug location. /// \brief Debug location.
/// ///
@ -945,10 +960,11 @@ public:
Metadata *InlinedAt = nullptr) { Metadata *InlinedAt = nullptr) {
return getImpl(Context, Line, Column, Scope, InlinedAt, Distinct); return getImpl(Context, Line, Column, Scope, InlinedAt, Distinct);
} }
static MDLocation *getTemporary(LLVMContext &Context, unsigned Line, static TempMDLocation getTemporary(LLVMContext &Context, unsigned Line,
unsigned Column, Metadata *Scope, unsigned Column, Metadata *Scope,
Metadata *InlinedAt = nullptr) { Metadata *InlinedAt = nullptr) {
return getImpl(Context, Line, Column, Scope, InlinedAt, Temporary); return TempMDLocation(
getImpl(Context, Line, Column, Scope, InlinedAt, Temporary));
} }
unsigned getLine() const { return MDNodeSubclassData; } unsigned getLine() const { return MDNodeSubclassData; }

View File

@ -531,13 +531,13 @@ bool LLParser::ParseMDNodeID(MDNode *&Result) {
} }
// Otherwise, create MDNode forward reference. // Otherwise, create MDNode forward reference.
MDTuple *FwdNode = MDTuple::getTemporary(Context, None); auto &FwdRef = ForwardRefMDNodes[MID];
ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc()); FwdRef = std::make_pair(MDTuple::getTemporary(Context, None), Lex.getLoc());
if (NumberedMetadata.size() <= MID) if (NumberedMetadata.size() <= MID)
NumberedMetadata.resize(MID+1); NumberedMetadata.resize(MID+1);
NumberedMetadata[MID].reset(FwdNode); Result = FwdRef.first.get();
Result = FwdNode; NumberedMetadata[MID].reset(Result);
return false; return false;
} }
@ -597,9 +597,7 @@ bool LLParser::ParseStandaloneMetadata() {
// See if this was forward referenced, if so, handle it. // See if this was forward referenced, if so, handle it.
auto FI = ForwardRefMDNodes.find(MetadataID); auto FI = ForwardRefMDNodes.find(MetadataID);
if (FI != ForwardRefMDNodes.end()) { if (FI != ForwardRefMDNodes.end()) {
MDTuple *Temp = FI->second.first; FI->second.first->replaceAllUsesWith(Init);
Temp->replaceAllUsesWith(Init);
MDNode::deleteTemporary(Temp);
ForwardRefMDNodes.erase(FI); ForwardRefMDNodes.erase(FI);
assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work"); assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work");

View File

@ -136,7 +136,7 @@ namespace llvm {
std::vector<std::pair<Type*, LocTy> > NumberedTypes; std::vector<std::pair<Type*, LocTy> > NumberedTypes;
std::vector<TrackingMDNodeRef> NumberedMetadata; std::vector<TrackingMDNodeRef> NumberedMetadata;
std::map<unsigned, std::pair<MDTuple *, LocTy>> ForwardRefMDNodes; std::map<unsigned, std::pair<TempMDTuple, LocTy>> ForwardRefMDNodes;
// Global Value reference information. // Global Value reference information.
std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals; std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals;

View File

@ -541,9 +541,8 @@ void BitcodeReaderMDValueList::AssignValue(Metadata *MD, unsigned Idx) {
} }
// If there was a forward reference to this value, replace it. // If there was a forward reference to this value, replace it.
MDTuple *PrevMD = cast<MDTuple>(OldMD.get()); TempMDTuple PrevMD(cast<MDTuple>(OldMD.get()));
PrevMD->replaceAllUsesWith(MD); PrevMD->replaceAllUsesWith(MD);
MDNode::deleteTemporary(PrevMD);
--NumFwdRefs; --NumFwdRefs;
} }
@ -557,7 +556,7 @@ Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) {
// Create and return a placeholder, which will later be RAUW'd. // Create and return a placeholder, which will later be RAUW'd.
AnyFwdRefs = true; AnyFwdRefs = true;
++NumFwdRefs; ++NumFwdRefs;
Metadata *MD = MDNode::getTemporary(Context, None); Metadata *MD = MDNode::getTemporary(Context, None).release();
MDValuePtrs[Idx].reset(MD); MDValuePtrs[Idx].reset(MD);
return MD; return MD;
} }

View File

@ -142,15 +142,15 @@ DICompileUnit DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
assert(!Filename.empty() && assert(!Filename.empty() &&
"Unable to create compile unit without filename"); "Unable to create compile unit without filename");
Metadata *TElts[] = {HeaderBuilder::get(DW_TAG_base_type).get(VMContext)}; Metadata *TElts[] = {HeaderBuilder::get(DW_TAG_base_type).get(VMContext)};
TempEnumTypes = MDNode::getTemporary(VMContext, TElts); TempEnumTypes = MDNode::getTemporary(VMContext, TElts).release();
TempRetainTypes = MDNode::getTemporary(VMContext, TElts); TempRetainTypes = MDNode::getTemporary(VMContext, TElts).release();
TempSubprograms = MDNode::getTemporary(VMContext, TElts); TempSubprograms = MDNode::getTemporary(VMContext, TElts).release();
TempGVs = MDNode::getTemporary(VMContext, TElts); TempGVs = MDNode::getTemporary(VMContext, TElts).release();
TempImportedModules = MDNode::getTemporary(VMContext, TElts); TempImportedModules = MDNode::getTemporary(VMContext, TElts).release();
Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_compile_unit) Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_compile_unit)
.concat(Lang) .concat(Lang)
@ -825,7 +825,7 @@ DICompositeType DIBuilder::createReplaceableForwardDecl(
nullptr, // TemplateParams nullptr, // TemplateParams
UniqueIdentifier.empty() ? nullptr UniqueIdentifier.empty() ? nullptr
: MDString::get(VMContext, UniqueIdentifier)}; : MDString::get(VMContext, UniqueIdentifier)};
DICompositeType RetTy(MDNode::getTemporary(VMContext, Elts)); DICompositeType RetTy(MDNode::getTemporary(VMContext, Elts).release());
assert(RetTy.isCompositeType() && assert(RetTy.isCompositeType() &&
"createReplaceableForwardDecl result should be a DIType"); "createReplaceableForwardDecl result should be a DIType");
if (!UniqueIdentifier.empty()) if (!UniqueIdentifier.empty())
@ -903,7 +903,7 @@ DIGlobalVariable DIBuilder::createTempGlobalVariableFwdDecl(
return createGlobalVariableHelper(VMContext, Context, Name, LinkageName, F, return createGlobalVariableHelper(VMContext, Context, Name, LinkageName, F,
LineNumber, Ty, isLocalToUnit, Val, Decl, LineNumber, Ty, isLocalToUnit, Val, Decl,
false, [&](ArrayRef<Metadata *> Elts) { false, [&](ArrayRef<Metadata *> Elts) {
return MDNode::getTemporary(VMContext, Elts); return MDNode::getTemporary(VMContext, Elts).release();
}); });
} }
@ -1007,7 +1007,7 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name,
return createFunctionHelper(VMContext, Context, Name, LinkageName, File, return createFunctionHelper(VMContext, Context, Name, LinkageName, File,
LineNo, Ty, isLocalToUnit, isDefinition, LineNo, Ty, isLocalToUnit, isDefinition,
ScopeLine, Flags, isOptimized, Fn, TParams, Decl, ScopeLine, Flags, isOptimized, Fn, TParams, Decl,
MDNode::getTemporary(VMContext, None), MDNode::getTemporary(VMContext, None).release(),
[&](ArrayRef<Metadata *> Elts) -> MDNode *{ [&](ArrayRef<Metadata *> Elts) -> MDNode *{
MDNode *Node = MDNode::get(VMContext, Elts); MDNode *Node = MDNode::get(VMContext, Elts);
// Create a named metadata so that we // Create a named metadata so that we
@ -1030,7 +1030,7 @@ DIBuilder::createTempFunctionFwdDecl(DIDescriptor Context, StringRef Name,
LineNo, Ty, isLocalToUnit, isDefinition, LineNo, Ty, isLocalToUnit, isDefinition,
ScopeLine, Flags, isOptimized, Fn, TParams, Decl, ScopeLine, Flags, isOptimized, Fn, TParams, Decl,
nullptr, [&](ArrayRef<Metadata *> Elts) { nullptr, [&](ArrayRef<Metadata *> Elts) {
return MDNode::getTemporary(VMContext, Elts); return MDNode::getTemporary(VMContext, Elts).release();
}); });
} }

View File

@ -68,9 +68,9 @@ MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) {
MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) { MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
// To ensure uniqueness the root node is self-referential. // To ensure uniqueness the root node is self-referential.
MDNode *Dummy = MDNode::getTemporary(Context, None); auto Dummy = MDNode::getTemporary(Context, None);
SmallVector<Metadata *, 3> Args(1, Dummy); SmallVector<Metadata *, 3> Args(1, Dummy.get());
if (Extra) if (Extra)
Args.push_back(Extra); Args.push_back(Extra);
if (!Name.empty()) if (!Name.empty())
@ -82,7 +82,7 @@ MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
// !1 = metadata !{metadata !0} <- root // !1 = metadata !{metadata !0} <- root
// Replace the dummy operand with the root node itself and delete the dummy. // Replace the dummy operand with the root node itself and delete the dummy.
Root->replaceOperandWith(0, Root); Root->replaceOperandWith(0, Root);
MDNode::deleteTemporary(Dummy);
// We now have // We now have
// !1 = metadata !{metadata !1} <- self-referential root // !1 = metadata !{metadata !1} <- self-referential root
return Root; return Root;

View File

@ -319,13 +319,12 @@ static void CloneAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap) {
// Now we have a complete set of all metadata in the chains used to specify // Now we have a complete set of all metadata in the chains used to specify
// the noalias scopes and the lists of those scopes. // the noalias scopes and the lists of those scopes.
SmallVector<MDTuple *, 16> DummyNodes; SmallVector<TempMDTuple, 16> DummyNodes;
DenseMap<const MDNode *, TrackingMDNodeRef> MDMap; DenseMap<const MDNode *, TrackingMDNodeRef> MDMap;
for (SetVector<const MDNode *>::iterator I = MD.begin(), IE = MD.end(); for (SetVector<const MDNode *>::iterator I = MD.begin(), IE = MD.end();
I != IE; ++I) { I != IE; ++I) {
MDTuple *Dummy = MDTuple::getTemporary(CalledFunc->getContext(), None); DummyNodes.push_back(MDTuple::getTemporary(CalledFunc->getContext(), None));
DummyNodes.push_back(Dummy); MDMap[*I].reset(DummyNodes.back().get());
MDMap[*I].reset(Dummy);
} }
// Create new metadata nodes to replace the dummy nodes, replacing old // Create new metadata nodes to replace the dummy nodes, replacing old
@ -389,10 +388,6 @@ static void CloneAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap) {
NI->setMetadata(LLVMContext::MD_noalias, M); NI->setMetadata(LLVMContext::MD_noalias, M);
} }
} }
// Now that everything has been replaced, delete the dummy nodes.
for (unsigned i = 0, ie = DummyNodes.size(); i != ie; ++i)
MDNode::deleteTemporary(DummyNodes[i]);
} }
/// AddAliasScopeMetadata - If the inlined function has noalias arguments, then /// AddAliasScopeMetadata - If the inlined function has noalias arguments, then

View File

@ -249,12 +249,11 @@ static Metadata *mapDistinctNode(const UniquableMDNode *Node,
// In general we need a dummy node, since whether the operands are null can // In general we need a dummy node, since whether the operands are null can
// affect the size of the node. // affect the size of the node.
MDTuple *Dummy = MDTuple::getTemporary(Node->getContext(), None); auto Dummy = MDTuple::getTemporary(Node->getContext(), None);
mapToMetadata(VM, Node, Dummy); mapToMetadata(VM, Node, Dummy.get());
Metadata *NewMD = cloneMDNode(Node, VM, Flags, TypeMapper, Materializer, Metadata *NewMD = cloneMDNode(Node, VM, Flags, TypeMapper, Materializer,
/* IsDistinct */ true); /* IsDistinct */ true);
Dummy->replaceAllUsesWith(NewMD); Dummy->replaceAllUsesWith(NewMD);
MDNode::deleteTemporary(Dummy);
return mapToMetadata(VM, Node, NewMD); return mapToMetadata(VM, Node, NewMD);
} }
@ -285,14 +284,13 @@ static Metadata *mapUniquedNode(const UniquableMDNode *Node,
assert(Node->isUniqued() && "Expected uniqued node"); assert(Node->isUniqued() && "Expected uniqued node");
// Create a dummy node in case we have a metadata cycle. // Create a dummy node in case we have a metadata cycle.
MDTuple *Dummy = MDTuple::getTemporary(Node->getContext(), None); auto Dummy = MDTuple::getTemporary(Node->getContext(), None);
mapToMetadata(VM, Node, Dummy); mapToMetadata(VM, Node, Dummy.get());
// Check all operands to see if any need to be remapped. // Check all operands to see if any need to be remapped.
if (!shouldRemapUniquedNode(Node, VM, Flags, TypeMapper, Materializer)) { if (!shouldRemapUniquedNode(Node, VM, Flags, TypeMapper, Materializer)) {
// Use an identity mapping. // Use an identity mapping.
mapToSelf(VM, Node); mapToSelf(VM, Node);
MDNode::deleteTemporary(Dummy);
return const_cast<Metadata *>(static_cast<const Metadata *>(Node)); return const_cast<Metadata *>(static_cast<const Metadata *>(Node));
} }
@ -300,7 +298,6 @@ static Metadata *mapUniquedNode(const UniquableMDNode *Node,
Metadata *NewMD = cloneMDNode(Node, VM, Flags, TypeMapper, Materializer, Metadata *NewMD = cloneMDNode(Node, VM, Flags, TypeMapper, Materializer,
/* IsDistinct */ false); /* IsDistinct */ false);
Dummy->replaceAllUsesWith(NewMD); Dummy->replaceAllUsesWith(NewMD);
MDNode::deleteTemporary(Dummy);
return mapToMetadata(VM, Node, NewMD); return mapToMetadata(VM, Node, NewMD);
} }

View File

@ -171,11 +171,10 @@ TEST_F(MDNodeTest, SelfReference) {
// !0 = !{!0} // !0 = !{!0}
// !1 = !{!0} // !1 = !{!0}
{ {
MDNode *Temp = MDNode::getTemporary(Context, None); auto Temp = MDNode::getTemporary(Context, None);
Metadata *Args[] = {Temp}; Metadata *Args[] = {Temp.get()};
MDNode *Self = MDNode::get(Context, Args); MDNode *Self = MDNode::get(Context, Args);
Self->replaceOperandWith(0, Self); Self->replaceOperandWith(0, Self);
MDNode::deleteTemporary(Temp);
ASSERT_EQ(Self, Self->getOperand(0)); ASSERT_EQ(Self, Self->getOperand(0));
// Self-references should be distinct, so MDNode::get() should grab a // Self-references should be distinct, so MDNode::get() should grab a
@ -190,11 +189,10 @@ TEST_F(MDNodeTest, SelfReference) {
// !0 = !{!0, !{}} // !0 = !{!0, !{}}
// !1 = !{!0, !{}} // !1 = !{!0, !{}}
{ {
MDNode *Temp = MDNode::getTemporary(Context, None); auto Temp = MDNode::getTemporary(Context, None);
Metadata *Args[] = {Temp, MDNode::get(Context, None)}; Metadata *Args[] = {Temp.get(), MDNode::get(Context, None)};
MDNode *Self = MDNode::get(Context, Args); MDNode *Self = MDNode::get(Context, Args);
Self->replaceOperandWith(0, Self); Self->replaceOperandWith(0, Self);
MDNode::deleteTemporary(Temp);
ASSERT_EQ(Self, Self->getOperand(0)); ASSERT_EQ(Self, Self->getOperand(0));
// Self-references should be distinct, so MDNode::get() should grab a // Self-references should be distinct, so MDNode::get() should grab a
@ -310,48 +308,44 @@ TEST_F(MDNodeTest, getDistinct) {
TEST_F(MDNodeTest, isUniqued) { TEST_F(MDNodeTest, isUniqued) {
MDNode *U = MDTuple::get(Context, None); MDNode *U = MDTuple::get(Context, None);
MDNode *D = MDTuple::getDistinct(Context, None); MDNode *D = MDTuple::getDistinct(Context, None);
MDNode *T = MDTuple::getTemporary(Context, None); auto T = MDTuple::getTemporary(Context, None);
EXPECT_TRUE(U->isUniqued()); EXPECT_TRUE(U->isUniqued());
EXPECT_FALSE(D->isUniqued()); EXPECT_FALSE(D->isUniqued());
EXPECT_FALSE(T->isUniqued()); EXPECT_FALSE(T->isUniqued());
MDNode::deleteTemporary(T);
} }
TEST_F(MDNodeTest, isDistinct) { TEST_F(MDNodeTest, isDistinct) {
MDNode *U = MDTuple::get(Context, None); MDNode *U = MDTuple::get(Context, None);
MDNode *D = MDTuple::getDistinct(Context, None); MDNode *D = MDTuple::getDistinct(Context, None);
MDNode *T = MDTuple::getTemporary(Context, None); auto T = MDTuple::getTemporary(Context, None);
EXPECT_FALSE(U->isDistinct()); EXPECT_FALSE(U->isDistinct());
EXPECT_TRUE(D->isDistinct()); EXPECT_TRUE(D->isDistinct());
EXPECT_FALSE(T->isDistinct()); EXPECT_FALSE(T->isDistinct());
MDNode::deleteTemporary(T);
} }
TEST_F(MDNodeTest, isTemporary) { TEST_F(MDNodeTest, isTemporary) {
MDNode *U = MDTuple::get(Context, None); MDNode *U = MDTuple::get(Context, None);
MDNode *D = MDTuple::getDistinct(Context, None); MDNode *D = MDTuple::getDistinct(Context, None);
MDNode *T = MDTuple::getTemporary(Context, None); auto T = MDTuple::getTemporary(Context, None);
EXPECT_FALSE(U->isTemporary()); EXPECT_FALSE(U->isTemporary());
EXPECT_FALSE(D->isTemporary()); EXPECT_FALSE(D->isTemporary());
EXPECT_TRUE(T->isTemporary()); EXPECT_TRUE(T->isTemporary());
MDNode::deleteTemporary(T);
} }
TEST_F(MDNodeTest, getDistinctWithUnresolvedOperands) { TEST_F(MDNodeTest, getDistinctWithUnresolvedOperands) {
// temporary !{} // temporary !{}
MDTuple *Temp = MDTuple::getTemporary(Context, None); auto Temp = MDTuple::getTemporary(Context, None);
ASSERT_FALSE(Temp->isResolved()); ASSERT_FALSE(Temp->isResolved());
// distinct !{temporary !{}} // distinct !{temporary !{}}
Metadata *Ops[] = {Temp}; Metadata *Ops[] = {Temp.get()};
MDNode *Distinct = MDNode::getDistinct(Context, Ops); MDNode *Distinct = MDNode::getDistinct(Context, Ops);
EXPECT_TRUE(Distinct->isResolved()); EXPECT_TRUE(Distinct->isResolved());
EXPECT_EQ(Temp, Distinct->getOperand(0)); EXPECT_EQ(Temp.get(), Distinct->getOperand(0));
// temporary !{} => !{} // temporary !{} => !{}
MDNode *Empty = MDNode::get(Context, None); MDNode *Empty = MDNode::get(Context, None);
Temp->replaceAllUsesWith(Empty); Temp->replaceAllUsesWith(Empty);
MDNode::deleteTemporary(Temp);
EXPECT_EQ(Empty, Distinct->getOperand(0)); EXPECT_EQ(Empty, Distinct->getOperand(0));
} }
@ -360,19 +354,18 @@ TEST_F(MDNodeTest, handleChangedOperandRecursion) {
MDNode *N0 = MDNode::get(Context, None); MDNode *N0 = MDNode::get(Context, None);
// !1 = !{!3, null} // !1 = !{!3, null}
MDTuple *Temp3 = MDTuple::getTemporary(Context, None); auto Temp3 = MDTuple::getTemporary(Context, None);
Metadata *Ops1[] = {Temp3, nullptr}; Metadata *Ops1[] = {Temp3.get(), nullptr};
MDNode *N1 = MDNode::get(Context, Ops1); MDNode *N1 = MDNode::get(Context, Ops1);
// !2 = !{!3, !0} // !2 = !{!3, !0}
Metadata *Ops2[] = {Temp3, N0}; Metadata *Ops2[] = {Temp3.get(), N0};
MDNode *N2 = MDNode::get(Context, Ops2); MDNode *N2 = MDNode::get(Context, Ops2);
// !3 = !{!2} // !3 = !{!2}
Metadata *Ops3[] = {N2}; Metadata *Ops3[] = {N2};
MDNode *N3 = MDNode::get(Context, Ops3); MDNode *N3 = MDNode::get(Context, Ops3);
Temp3->replaceAllUsesWith(N3); Temp3->replaceAllUsesWith(N3);
MDNode::deleteTemporary(Temp3);
// !4 = !{!1} // !4 = !{!1}
Metadata *Ops4[] = {N1}; Metadata *Ops4[] = {N1};
@ -425,8 +418,8 @@ TEST_F(MDNodeTest, replaceResolvedOperand) {
// a global value that gets RAUW'ed. // a global value that gets RAUW'ed.
// //
// Use a temporary node to keep N from being resolved. // Use a temporary node to keep N from being resolved.
MDTuple *Temp = MDTuple::getTemporary(Context, None); auto Temp = MDTuple::getTemporary(Context, None);
Metadata *Ops[] = {nullptr, Temp}; Metadata *Ops[] = {nullptr, Temp.get()};
MDNode *Empty = MDTuple::get(Context, ArrayRef<Metadata *>()); MDNode *Empty = MDTuple::get(Context, ArrayRef<Metadata *>());
MDNode *N = MDTuple::get(Context, Ops); MDNode *N = MDTuple::get(Context, Ops);
@ -438,12 +431,11 @@ TEST_F(MDNodeTest, replaceResolvedOperand) {
EXPECT_EQ(Empty, N->getOperand(0)); EXPECT_EQ(Empty, N->getOperand(0));
// Check code for adding another unresolved operand. // Check code for adding another unresolved operand.
N->replaceOperandWith(0, Temp); N->replaceOperandWith(0, Temp.get());
EXPECT_EQ(Temp, N->getOperand(0)); EXPECT_EQ(Temp.get(), N->getOperand(0));
// Remove the references to Temp; required for teardown. // Remove the references to Temp; required for teardown.
Temp->replaceAllUsesWith(nullptr); Temp->replaceAllUsesWith(nullptr);
MDNode::deleteTemporary(Temp);
} }
typedef MetadataTest MDLocationTest; typedef MetadataTest MDLocationTest;
@ -485,10 +477,9 @@ TEST_F(MDLocationTest, getDistinct) {
TEST_F(MDLocationTest, getTemporary) { TEST_F(MDLocationTest, getTemporary) {
MDNode *N = MDNode::get(Context, None); MDNode *N = MDNode::get(Context, None);
MDLocation *L = MDLocation::getTemporary(Context, 2, 7, N); auto L = MDLocation::getTemporary(Context, 2, 7, N);
EXPECT_TRUE(L->isTemporary()); EXPECT_TRUE(L->isTemporary());
EXPECT_FALSE(L->isResolved()); EXPECT_FALSE(L->isResolved());
MDNode::deleteTemporary(L);
} }
typedef MetadataTest MetadataAsValueTest; typedef MetadataTest MetadataAsValueTest;
@ -557,11 +548,11 @@ TEST_F(ValueAsMetadataTest, CollidingDoubleUpdates) {
ConstantInt::get(getGlobalContext(), APInt(8, 0))); ConstantInt::get(getGlobalContext(), APInt(8, 0)));
// Create a temporary to prevent nodes from resolving. // Create a temporary to prevent nodes from resolving.
MDTuple *Temp = MDTuple::getTemporary(Context, None); auto Temp = MDTuple::getTemporary(Context, None);
// When the first operand of N1 gets reset to nullptr, it'll collide with N2. // When the first operand of N1 gets reset to nullptr, it'll collide with N2.
Metadata *Ops1[] = {CI, CI, Temp}; Metadata *Ops1[] = {CI, CI, Temp.get()};
Metadata *Ops2[] = {nullptr, CI, Temp}; Metadata *Ops2[] = {nullptr, CI, Temp.get()};
auto *N1 = MDTuple::get(Context, Ops1); auto *N1 = MDTuple::get(Context, Ops1);
auto *N2 = MDTuple::get(Context, Ops2); auto *N2 = MDTuple::get(Context, Ops2);
@ -573,11 +564,10 @@ TEST_F(ValueAsMetadataTest, CollidingDoubleUpdates) {
ValueAsMetadata::handleDeletion(CI->getValue()); ValueAsMetadata::handleDeletion(CI->getValue());
EXPECT_EQ(nullptr, N2->getOperand(0)); EXPECT_EQ(nullptr, N2->getOperand(0));
EXPECT_EQ(nullptr, N2->getOperand(1)); EXPECT_EQ(nullptr, N2->getOperand(1));
EXPECT_EQ(Temp, N2->getOperand(2)); EXPECT_EQ(Temp.get(), N2->getOperand(2));
// Clean up Temp for teardown. // Clean up Temp for teardown.
Temp->replaceAllUsesWith(nullptr); Temp->replaceAllUsesWith(nullptr);
MDNode::deleteTemporary(Temp);
} }
typedef MetadataTest TrackingMDRefTest; typedef MetadataTest TrackingMDRefTest;