llvm.org GIT mirror llvm / 8ec0aee
IR: Remove MDNodeFwdDecl Remove `MDNodeFwdDecl` (as promised in r226481). Aside from API changes, there's no real functionality change here. `MDNode::getTemporary()` now forwards to `MDTuple::getTemporary()`, which returns a tuple with `isTemporary()` equal to true. The main point is that we can now add temporaries of other `MDNode` subclasses, needed for PR22235 (I introduced `MDNodeFwdDecl` in the first place because I didn't recognize this need, and thought they were only needed to handle forward references). A few things left out of (or highlighted by) this commit: - I've had to remove the (few) uses of `std::unique_ptr<>` to deal with temporaries, since the destructor is no longer public. `getTemporary()` should probably return the equivalent of `std::unique_ptr<T, MDNode::deleteTemporary>`. - `MDLocation::getTemporary()` doesn't exist yet (worse, it actually does exist, but does the wrong thing: `MDNode::getTemporary()` is inherited and returns an `MDTuple`). - `MDNode` now only has one subclass, `UniquableMDNode`, and the distinction between them is actually somewhat confusing. I'll fix those up next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226501 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 5 years ago
13 changed file(s) with 78 addition(s) and 96 deletion(s). Raw diff Collapse all Expand all
8585 }
8686
8787 void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef MD, LLVMMetadataRef New) {
88 auto *Node = unwrapNodeFwdDecl>(MD);
88 auto *Node = unwrapTuple>(MD);
89 assert(Node->isTemporary() && "Expected temporary node");
8990 Node->replaceAllUsesWith(unwrap(New));
9091 MDNode::deleteTemporary(Node);
9192 }
8484
8585 /// \brief Create a temporary.
8686 ///
87 /// Create an \a MDNodeFwdDecl and track it in \a UnresolvedNodes.
87 /// Create an \a temporary node and track it in \a UnresolvedNodes.
8888 void trackIfUnresolved(MDNode *N);
8989
9090 public:
4646 HANDLE_METADATA_LEAF(ConstantAsMetadata)
4747 HANDLE_METADATA_LEAF(LocalAsMetadata)
4848 HANDLE_METADATA_BRANCH(MDNode)
49 HANDLE_METADATA_LEAF(MDNodeFwdDecl)
5049 HANDLE_UNIQUABLE_BRANCH(UniquableMDNode)
5150 HANDLE_UNIQUABLE_LEAF(MDTuple)
5251 HANDLE_UNIQUABLE_LEAF(MDLocation)
6060 enum MetadataKind {
6161 MDTupleKind,
6262 MDLocationKind,
63 MDNodeFwdDeclKind,
6463 ConstantAsMetadataKind,
6564 LocalAsMetadataKind,
6665 MDStringKind
697696 ArrayRef MDs);
698697 static inline MDTuple *getDistinct(LLVMContext &Context,
699698 ArrayRef MDs);
700
701 /// \brief Return a temporary MDNode
702 ///
703 /// For use in constructing cyclic MDNode structures. A temporary MDNode is
704 /// not uniqued, may be RAUW'd, and must be manually deleted with
705 /// deleteTemporary.
706 static MDNodeFwdDecl *getTemporary(LLVMContext &Context,
707 ArrayRef MDs);
699 static inline MDTuple *getTemporary(LLVMContext &Context,
700 ArrayRef MDs);
708701
709702 /// \brief Deallocate a node created by getTemporary.
710703 ///
771764 /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
772765 static bool classof(const Metadata *MD) {
773766 return MD->getMetadataID() == MDTupleKind ||
774 MD->getMetadataID() == MDLocationKind ||
775 MD->getMetadataID() == MDNodeFwdDeclKind;
767 MD->getMetadataID() == MDLocationKind;
776768 }
777769
778770 /// \brief Check whether MDNode is a vtable access.
793785 /// for implementing sub-types of \a MDNode that can be uniqued like
794786 /// constants.
795787 ///
796 /// There is limited support for RAUW at construction time. At
797 /// construction time, if any operands are an instance of \a
798 /// MDNodeFwdDecl (or another unresolved \a UniquableMDNode, which
799 /// indicates an \a MDNodeFwdDecl in its path), the node itself will be
800 /// unresolved. As soon as all operands become resolved, it will drop
801 /// RAUW support permanently.
788 /// There is limited support for RAUW at construction time. At construction
789 /// time, if any operand is a temporary node (or an unresolved uniqued node,
790 /// which indicates a transitive temporary operand), the node itself will be
791 /// unresolved. As soon as all operands become resolved, it will drop RAUW
792 /// support permanently.
802793 ///
803794 /// If an unresolved node is part of a cycle, \a resolveCycles() needs
804 /// to be called on some member of the cycle when each \a MDNodeFwdDecl
805 /// has been removed.
795 /// to be called on some member of the cycle once all temporary nodes have been
796 /// replaced.
806797 class UniquableMDNode : public MDNode {
807798 friend class ReplaceableMetadataImpl;
808799 friend class MDNode;
833824 /// Once all forward declarations have been resolved, force cycles to be
834825 /// resolved.
835826 ///
836 /// \pre No operands (or operands' operands, etc.) are \a MDNodeFwdDecl.
827 /// \pre No operands (or operands' operands, etc.) have \a isTemporary().
837828 void resolveCycles();
838829
839830 private:
887878 return getImpl(Context, MDs, Distinct);
888879 }
889880
881 /// \brief Return a temporary node.
882 ///
883 /// For use in constructing cyclic MDNode structures. A temporary MDNode is
884 /// not uniqued, may be RAUW'd, and must be manually deleted with
885 /// deleteTemporary.
886 static MDTuple *getTemporary(LLVMContext &Context, ArrayRef MDs) {
887 return getImpl(Context, MDs, Temporary);
888 }
889
890890 static bool classof(const Metadata *MD) {
891891 return MD->getMetadataID() == MDTupleKind;
892892 }
904904 }
905905 MDTuple *MDNode::getDistinct(LLVMContext &Context, ArrayRef MDs) {
906906 return MDTuple::getDistinct(Context, MDs);
907 }
908 MDTuple *MDNode::getTemporary(LLVMContext &Context, ArrayRef MDs) {
909 return MDTuple::getTemporary(Context, MDs);
907910 }
908911
909912 /// \brief Debug location.
958961 private:
959962 MDLocation *uniquifyImpl();
960963 void eraseFromStoreImpl();
961 };
962
963 /// \brief Forward declaration of metadata.
964 ///
965 /// Forward declaration of metadata, in the form of a basic tuple. Unlike \a
966 /// MDTuple, this class has full support for RAUW, is not owned, is not
967 /// uniqued, and is suitable for forward references.
968 class MDNodeFwdDecl : public MDNode {
969 friend class Metadata;
970
971 MDNodeFwdDecl(LLVMContext &C, ArrayRef Vals)
972 : MDNode(C, MDNodeFwdDeclKind, Temporary, Vals) {}
973
974 public:
975 ~MDNodeFwdDecl() { dropAllReferences(); }
976
977 // MSVC doesn't see the alternative: "using MDNode::operator delete".
978 void operator delete(void *Mem) { MDNode::operator delete(Mem); }
979
980 static MDNodeFwdDecl *get(LLVMContext &Context, ArrayRef MDs) {
981 return new (MDs.size()) MDNodeFwdDecl(Context, MDs);
982 }
983
984 static bool classof(const Metadata *MD) {
985 return MD->getMetadataID() == MDNodeFwdDeclKind;
986 }
987964 };
988965
989966 //===----------------------------------------------------------------------===//
530530 }
531531
532532 // Otherwise, create MDNode forward reference.
533 MDNodeFwdDecl *FwdNode = MDNodeFwdDecl::get(Context, None);
533 MDTuple *FwdNode = MDTuple::getTemporary(Context, None);
534534 ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc());
535535
536536 if (NumberedMetadata.size() <= MID)
596596 // See if this was forward referenced, if so, handle it.
597597 auto FI = ForwardRefMDNodes.find(MetadataID);
598598 if (FI != ForwardRefMDNodes.end()) {
599 MDNodeFwdDecl *Temp = FI->second.first;
599 MDTuple *Temp = FI->second.first;
600600 Temp->replaceAllUsesWith(Init);
601 delete Temp;
601 MDNode::deleteTemporary(Temp);
602602 ForwardRefMDNodes.erase(FI);
603603
604604 assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work");
135135 std::vector > NumberedTypes;
136136
137137 std::vector NumberedMetadata;
138 std::mapNodeFwdDecl *, LocTy>> ForwardRefMDNodes;
138 std::mapTuple *, LocTy>> ForwardRefMDNodes;
139139
140140 // Global Value reference information.
141141 std::map > ForwardRefVals;
540540 }
541541
542542 // If there was a forward reference to this value, replace it.
543 MDNodeFwdDecl *PrevMD = cast>(OldMD.get());
543 MDTuple *PrevMD = cast>(OldMD.get());
544544 PrevMD->replaceAllUsesWith(MD);
545545 MDNode::deleteTemporary(PrevMD);
546546 --NumFwdRefs;
572572
573573 // Resolve any cycles.
574574 for (auto &MD : MDValuePtrs) {
575 assert(!(MD && isa(MD)) && "Unexpected forward reference");
576 if (auto *N = dyn_cast_or_null(MD))
577 N->resolveCycles();
575 auto *N = dyn_cast_or_null(MD);
576 if (!N)
577 continue;
578
579 assert(!N->isTemporary() && "Unexpected forward reference");
580 N->resolveCycles();
578581 }
579582 }
580583
336336 DN = MDNode::get(VMContext, Ops);
337337 }
338338
339 auto *Node = cast(const_cast(DbgNode));
339 assert(DbgNode->isTemporary() && "Expected temporary node");
340 auto *Node = const_cast(DbgNode);
340341 Node->replaceAllUsesWith(const_cast(DN));
341342 MDNode::deleteTemporary(Node);
342343 DbgNode = DN;
345346 void DIDescriptor::replaceAllUsesWith(MDNode *D) {
346347 assert(DbgNode && "Trying to replace an unverified type!");
347348 assert(DbgNode != D && "This replacement should always happen");
348 auto *Node = cast(const_cast(DbgNode));
349 assert(DbgNode->isTemporary() && "Expected temporary node");
350 auto *Node = const_cast(DbgNode);
349351 Node->replaceAllUsesWith(D);
350352 MDNode::deleteTemporary(Node);
351353 }
154154 }
155155
156156 void ReplaceableMetadataImpl::replaceAllUsesWith(Metadata *MD) {
157 assert(!(MD && isaFwdDecl>(MD)) && "Expected non-temp node");
157 assert(!(MD && isa>(MD) && cast(MD)->isTemporary()) &&
158 "Expected non-temp node");
158159
159160 if (UseMap.empty())
160161 return;
470471
471472 // Resolve all operands.
472473 for (const auto &Op : operands()) {
473 if (!Op)
474 auto *N = dyn_cast_or_null(Op);
475 if (!N)
474476 continue;
475 assert(!isa(Op) &&
477
478 assert(!N->isTemporary() &&
476479 "Expected all forward declarations to be resolved");
477 if (auto *N = dyn_cast(Op))
478 if (!N->isResolved())
479 N->resolveCycles();
480 if (!N->isResolved())
481 N->resolveCycles();
480482 }
481483 }
482484
620622 N->storeDistinctInContext();
621623 break;
622624 case Temporary:
623 llvm_unreachable("Unexpected temporary node");
625 break;
624626 }
625627 return N;
626628 }
722724 getContext().pImpl->MDLocations.erase(this);
723725 }
724726
725 MDNodeFwdDecl *MDNode::getTemporary(LLVMContext &Context,
726 ArrayRef MDs) {
727 return MDNodeFwdDecl::get(Context, MDs);
728 }
729
730 void MDNode::deleteTemporary(MDNode *N) { delete cast(N); }
727 void MDNode::deleteTemporary(MDNode *N) {
728 assert(N->isTemporary() && "Expected temporary node");
729 cast(N)->deleteAsSubclass();
730 }
731731
732732 void UniquableMDNode::storeDistinctInContext() {
733733 assert(isResolved() && "Expected resolved nodes");
616616 }
617617
618618 // Check these last, so we diagnose problems in operands first.
619 Assert1(!isa(MD), "Expected no forward declarations!", &MD);
619 Assert1(!MD.isTemporary(), "Expected no forward declarations!", &MD);
620620 Assert1(MD.isResolved(), "All nodes should be resolved!", &MD);
621621 }
622622
318318
319319 // Now we have a complete set of all metadata in the chains used to specify
320320 // the noalias scopes and the lists of those scopes.
321 SmallVectorNode *, 16> DummyNodes;
321 SmallVectorTuple *, 16> DummyNodes;
322322 DenseMap MDMap;
323323 for (SetVector::iterator I = MD.begin(), IE = MD.end();
324324 I != IE; ++I) {
325 MDNode *Dummy = MDNode::getTemporary(CalledFunc->getContext(), None);
325 MDTuple *Dummy = MDTuple::getTemporary(CalledFunc->getContext(), None);
326326 DummyNodes.push_back(Dummy);
327327 MDMap[*I].reset(Dummy);
328328 }
342342 }
343343
344344 MDNode *NewM = MDNode::get(CalledFunc->getContext(), NewOps);
345 MDNodeFwdDecl *TempM = cast>(MDMap[*I]);
345 MDTuple *TempM = cast>(MDMap[*I]);
346 assert(TempM->isTemporary() && "Expected temporary node");
346347
347348 TempM->replaceAllUsesWith(NewM);
348349 }
248248
249249 // In general we need a dummy node, since whether the operands are null can
250250 // affect the size of the node.
251 std::unique_ptr Dummy(
252 MDNode::getTemporary(Node->getContext(), None));
253 mapToMetadata(VM, Node, Dummy.get());
251 MDTuple *Dummy = MDTuple::getTemporary(Node->getContext(), None);
252 mapToMetadata(VM, Node, Dummy);
254253 Metadata *NewMD = cloneMDNode(Node, VM, Flags, TypeMapper, Materializer,
255254 /* IsDistinct */ true);
256255 Dummy->replaceAllUsesWith(NewMD);
256 MDNode::deleteTemporary(Dummy);
257257 return mapToMetadata(VM, Node, NewMD);
258258 }
259259
284284 assert(Node->isUniqued() && "Expected uniqued node");
285285
286286 // Create a dummy node in case we have a metadata cycle.
287 MDNodeFwdDecl *Dummy = MDNode::getTemporary(Node->getContext(), None);
287 MDTuple *Dummy = MDTuple::getTemporary(Node->getContext(), None);
288288 mapToMetadata(VM, Node, Dummy);
289289
290290 // Check all operands to see if any need to be remapped.
166166 delete I;
167167 }
168168
169 TEST_F(MDNodeTest, DeleteMDNodeFwdDecl) {
170 delete MDNode::getTemporary(Context, None);
171 }
172
173169 TEST_F(MDNodeTest, SelfReference) {
174170 // !0 = !{!0}
175171 // !1 = !{!0}
342338
343339 TEST_F(MDNodeTest, getDistinctWithUnresolvedOperands) {
344340 // temporary !{}
345 MDNodeFwdDecl *Temp = MDNode::getTemporary(Context, None);
341 MDTuple *Temp = MDTuple::getTemporary(Context, None);
346342 ASSERT_FALSE(Temp->isResolved());
347343
348344 // distinct !{temporary !{}}
363359 MDNode *N0 = MDNode::get(Context, None);
364360
365361 // !1 = !{!3, null}
366 std::unique_ptr Temp3(MDNode::getTemporary(Context, None));
367 Metadata *Ops1[] = {Temp3.get(), nullptr};
362 MDTuple *Temp3 = MDTuple::getTemporary(Context, None);
363 Metadata *Ops1[] = {Temp3, nullptr};
368364 MDNode *N1 = MDNode::get(Context, Ops1);
369365
370366 // !2 = !{!3, !0}
371 Metadata *Ops2[] = {Temp3.get(), N0};
367 Metadata *Ops2[] = {Temp3, N0};
372368 MDNode *N2 = MDNode::get(Context, Ops2);
373369
374370 // !3 = !{!2}
375371 Metadata *Ops3[] = {N2};
376372 MDNode *N3 = MDNode::get(Context, Ops3);
377373 Temp3->replaceAllUsesWith(N3);
374 MDNode::deleteTemporary(Temp3);
378375
379376 // !4 = !{!1}
380377 Metadata *Ops4[] = {N1};
427424 // a global value that gets RAUW'ed.
428425 //
429426 // Use a temporary node to keep N from being resolved.
430 std::unique_ptr Temp(MDNodeFwdDecl::get(Context, None));
431 Metadata *Ops[] = {nullptr, Temp.get()};
427 MDTuple *Temp = MDTuple::getTemporary(Context, None);
428 Metadata *Ops[] = {nullptr, Temp};
432429
433430 MDNode *Empty = MDTuple::get(Context, ArrayRef());
434431 MDNode *N = MDTuple::get(Context, Ops);
440437 EXPECT_EQ(Empty, N->getOperand(0));
441438
442439 // Check code for adding another unresolved operand.
443 N->replaceOperandWith(0, Temp.get());
444 EXPECT_EQ(Temp.get(), N->getOperand(0));
440 N->replaceOperandWith(0, Temp);
441 EXPECT_EQ(Temp, N->getOperand(0));
445442
446443 // Remove the references to Temp; required for teardown.
447444 Temp->replaceAllUsesWith(nullptr);
445 MDNode::deleteTemporary(Temp);
448446 }
449447
450448 typedef MetadataTest MDLocationTest;
550548 ConstantInt::get(getGlobalContext(), APInt(8, 0)));
551549
552550 // Create a temporary to prevent nodes from resolving.
553 std::unique_ptr Temp(MDNode::getTemporary(Context, None));
551 MDTuple *Temp = MDTuple::getTemporary(Context, None);
554552
555553 // When the first operand of N1 gets reset to nullptr, it'll collide with N2.
556 Metadata *Ops1[] = {CI, CI, Temp.get()};
557 Metadata *Ops2[] = {nullptr, CI, Temp.get()};
554 Metadata *Ops1[] = {CI, CI, Temp};
555 Metadata *Ops2[] = {nullptr, CI, Temp};
558556
559557 auto *N1 = MDTuple::get(Context, Ops1);
560558 auto *N2 = MDTuple::get(Context, Ops2);
566564 ValueAsMetadata::handleDeletion(CI->getValue());
567565 EXPECT_EQ(nullptr, N2->getOperand(0));
568566 EXPECT_EQ(nullptr, N2->getOperand(1));
569 EXPECT_EQ(Temp.get(), N2->getOperand(2));
567 EXPECT_EQ(Temp, N2->getOperand(2));
570568
571569 // Clean up Temp for teardown.
572570 Temp->replaceAllUsesWith(nullptr);
571 MDNode::deleteTemporary(Temp);
573572 }
574573
575574 typedef MetadataTest TrackingMDRefTest;