llvm.org GIT mirror llvm / d640962
IR: Add MDLocation class Add a new subclass of `UniquableMDNode`, `MDLocation`. This will be the IR version of `DebugLoc` and `DILocation`. The goal is to rename this to `DILocation` once the IR classes supersede the `DI`-prefixed wrappers. This isn't used anywhere yet. Part of PR21433. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225824 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 5 years ago
7 changed file(s) with 266 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
4949 HANDLE_METADATA_LEAF(MDNodeFwdDecl)
5050 HANDLE_UNIQUABLE_BRANCH(UniquableMDNode)
5151 HANDLE_UNIQUABLE_LEAF(MDTuple)
52 HANDLE_UNIQUABLE_LEAF(MDLocation)
5253
5354 #undef HANDLE_METADATA
5455 #undef HANDLE_METADATA_LEAF
5656 public:
5757 enum MetadataKind {
5858 MDTupleKind,
59 MDLocationKind,
5960 MDNodeFwdDeclKind,
6061 ConstantAsMetadataKind,
6162 LocalAsMetadataKind,
669670 /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:
670671 static bool classof(const Metadata *MD) {
671672 return MD->getMetadataID() == MDTupleKind ||
673 MD->getMetadataID() == MDLocationKind ||
672674 MD->getMetadataID() == MDNodeFwdDeclKind;
673675 }
674676
725727
726728 public:
727729 static bool classof(const Metadata *MD) {
728 return MD->getMetadataID() == MDTupleKind;
730 return MD->getMetadataID() == MDTupleKind ||
731 MD->getMetadataID() == MDLocationKind;
729732 }
730733
731734 /// \brief Check whether any operands are forward declarations.
810813 MDNode *MDNode::getDistinct(LLVMContext &Context, ArrayRef MDs) {
811814 return MDTuple::getDistinct(Context, MDs);
812815 }
816
817 /// \brief Debug location.
818 ///
819 /// A debug location in source code, used for debug info and otherwise.
820 class MDLocation : public UniquableMDNode {
821 friend class LLVMContextImpl;
822 friend class UniquableMDNode;
823
824 MDLocation(LLVMContext &C, unsigned Line, unsigned Column,
825 ArrayRef MDs, bool AllowRAUW);
826 ~MDLocation() { dropAllReferences(); }
827
828 static MDLocation *constructHelper(LLVMContext &Context, unsigned Line,
829 unsigned Column, Metadata *Scope,
830 Metadata *InlinedAt, bool AllowRAUW);
831
832 static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
833 unsigned Column, Metadata *Scope,
834 Metadata *InlinedAt, bool ShouldCreate);
835
836 // Disallow replacing operands.
837 void replaceOperandWith(unsigned I, Metadata *New) LLVM_DELETED_FUNCTION;
838
839 public:
840 static MDLocation *get(LLVMContext &Context, unsigned Line, unsigned Column,
841 Metadata *Scope, Metadata *InlinedAt = nullptr) {
842 return getImpl(Context, Line, Column, Scope, InlinedAt,
843 /* ShouldCreate */ true);
844 }
845 static MDLocation *getIfExists(LLVMContext &Context, unsigned Line,
846 unsigned Column, Metadata *Scope,
847 Metadata *InlinedAt = nullptr) {
848 return getImpl(Context, Line, Column, Scope, InlinedAt,
849 /* ShouldCreate */ false);
850 }
851 static MDLocation *getDistinct(LLVMContext &Context, unsigned Line,
852 unsigned Column, Metadata *Scope,
853 Metadata *InlinedAt = nullptr);
854
855 unsigned getLine() const { return MDNodeSubclassData; }
856 unsigned getColumn() const { return SubclassData16; }
857 Metadata *getScope() const { return getOperand(0); }
858 Metadata *getInlinedAt() const {
859 return getNumOperands() == 2 ? getOperand(1) : nullptr;
860 }
861
862 static bool classof(const Metadata *MD) {
863 return MD->getMetadataID() == MDLocationKind;
864 }
865
866 private:
867 MDLocation *uniquifyImpl();
868 void eraseFromStoreImpl();
869 };
813870
814871 /// \brief Forward declaration of metadata.
815872 ///
12711271 Out << "}";
12721272 }
12731273
1274 namespace {
1275 struct FieldSeparator {
1276 bool Skip;
1277 FieldSeparator() : Skip(true) {}
1278 };
1279 raw_ostream &operator<<(raw_ostream &OS, FieldSeparator &FS) {
1280 if (FS.Skip) {
1281 FS.Skip = false;
1282 return OS;
1283 }
1284 return OS << ", ";
1285 }
1286 } // end namespace
1287
1288 static void writeMDLocation(raw_ostream &Out, const MDLocation *DL,
1289 TypePrinting *TypePrinter, SlotTracker *Machine,
1290 const Module *Context) {
1291 Out << "!MDLocation(";
1292 FieldSeparator FS;
1293 if (DL->getLine())
1294 Out << FS << "line: " << DL->getLine();
1295 if (DL->getColumn())
1296 Out << FS << "column: " << DL->getColumn();
1297 Out << FS << "scope: ";
1298 WriteAsOperandInternal(Out, DL->getScope(), TypePrinter, Machine, Context);
1299 if (DL->getInlinedAt()) {
1300 Out << FS << "inlinedAt: ";
1301 WriteAsOperandInternal(Out, DL->getInlinedAt(), TypePrinter, Machine,
1302 Context);
1303 }
1304 Out << ")";
1305 }
1306
12741307 static void WriteMDNodeBodyInternal(raw_ostream &Out, const MDNode *Node,
12751308 TypePrinting *TypePrinter,
12761309 SlotTracker *Machine,
139139 I->dropAllReferences();
140140 for (auto *I : MDTuples)
141141 I->dropAllReferences();
142 for (auto *I : MDLocations)
143 I->dropAllReferences();
142144
143145 for (UniquableMDNode *I : DistinctMDNodes)
144146 I->deleteAsSubclass();
145147 for (MDTuple *I : MDTuples)
148 delete I;
149 for (MDLocation *I : MDLocations)
146150 delete I;
147151
148152 // Destroy MDStrings.
214214 }
215215 };
216216
217 /// \brief DenseMapInfo for MDLocation.
218 struct MDLocationInfo {
219 struct KeyTy {
220 unsigned Line;
221 unsigned Column;
222 Metadata *Scope;
223 Metadata *InlinedAt;
224
225 KeyTy(unsigned Line, unsigned Column, Metadata *Scope, Metadata *InlinedAt)
226 : Line(Line), Column(Column), Scope(Scope), InlinedAt(InlinedAt) {}
227
228 KeyTy(const MDLocation *L)
229 : Line(L->getLine()), Column(L->getColumn()), Scope(L->getScope()),
230 InlinedAt(L->getInlinedAt()) {}
231
232 bool operator==(const MDLocation *RHS) const {
233 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
234 return false;
235 return Line == RHS->getLine() && Column == RHS->getColumn() &&
236 Scope == RHS->getScope() && InlinedAt == RHS->getInlinedAt();
237 }
238 };
239 static inline MDLocation *getEmptyKey() {
240 return DenseMapInfo::getEmptyKey();
241 }
242 static inline MDLocation *getTombstoneKey() {
243 return DenseMapInfo::getTombstoneKey();
244 }
245 static unsigned getHashValue(const KeyTy &Key) {
246 return hash_combine(Key.Line, Key.Column, Key.Scope, Key.InlinedAt);
247 }
248 static unsigned getHashValue(const MDLocation *U) {
249 return getHashValue(KeyTy(U));
250 }
251 static bool isEqual(const KeyTy &LHS, const MDLocation *RHS) {
252 return LHS == RHS;
253 }
254 static bool isEqual(const MDLocation *LHS, const MDLocation *RHS) {
255 return LHS == RHS;
256 }
257 };
258
217259 class LLVMContextImpl {
218260 public:
219261 /// OwnedModules - The set of modules instantiated in this context, and which
245287 DenseMap MetadataAsValues;
246288
247289 DenseSet MDTuples;
290 DenseSet MDLocations;
248291
249292 // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
250293 // aren't in the MDNodeSet, but they're still shared between objects, so no
639639
640640 void MDTuple::eraseFromStoreImpl() { getContext().pImpl->MDTuples.erase(this); }
641641
642 MDLocation::MDLocation(LLVMContext &C, unsigned Line, unsigned Column,
643 ArrayRef MDs, bool AllowRAUW)
644 : UniquableMDNode(C, MDLocationKind, MDs, AllowRAUW) {
645 assert((MDs.size() == 1 || MDs.size() == 2) &&
646 "Expected a scope and optional inlined-at");
647
648 // Set line and column.
649 assert(Line < (1u << 24) && "Expected 24-bit line");
650 assert(Column < (1u << 8) && "Expected 8-bit column");
651
652 MDNodeSubclassData = Line;
653 SubclassData16 = Column;
654 }
655
656 MDLocation *MDLocation::constructHelper(LLVMContext &Context, unsigned Line,
657 unsigned Column, Metadata *Scope,
658 Metadata *InlinedAt, bool AllowRAUW) {
659 SmallVector Ops;
660 Ops.push_back(Scope);
661 if (InlinedAt)
662 Ops.push_back(InlinedAt);
663 return new (Ops.size()) MDLocation(Context, Line, Column, Ops, AllowRAUW);
664 }
665
666 static void adjustLine(unsigned &Line) {
667 // Set to unknown on overflow. Still use 24 bits for now.
668 if (Line >= (1u << 24))
669 Line = 0;
670 }
671
672 static void adjustColumn(unsigned &Column) {
673 // Set to unknown on overflow. Still use 8 bits for now.
674 if (Column >= (1u << 8))
675 Column = 0;
676 }
677
678 MDLocation *MDLocation::getImpl(LLVMContext &Context, unsigned Line,
679 unsigned Column, Metadata *Scope,
680 Metadata *InlinedAt, bool ShouldCreate) {
681 // Fixup line/column.
682 adjustLine(Line);
683 adjustColumn(Column);
684
685 MDLocationInfo::KeyTy Key(Line, Column, Scope, InlinedAt);
686
687 auto &Store = Context.pImpl->MDLocations;
688 auto I = Store.find_as(Key);
689 if (I != Store.end())
690 return *I;
691 if (!ShouldCreate)
692 return nullptr;
693
694 auto *N = constructHelper(Context, Line, Column, Scope, InlinedAt,
695 /* AllowRAUW */ true);
696 Store.insert(N);
697 return N;
698 }
699
700 MDLocation *MDLocation::getDistinct(LLVMContext &Context, unsigned Line,
701 unsigned Column, Metadata *Scope,
702 Metadata *InlinedAt) {
703 // Fixup line/column.
704 adjustLine(Line);
705 adjustColumn(Column);
706
707 auto *N = constructHelper(Context, Line, Column, Scope, InlinedAt,
708 /* AllowRAUW */ false);
709 N->storeDistinctInContext();
710 return N;
711 }
712
713 MDLocation *MDLocation::uniquifyImpl() {
714 MDLocationInfo::KeyTy Key(this);
715
716 auto &Store = getContext().pImpl->MDLocations;
717 auto I = Store.find_as(Key);
718 if (I == Store.end()) {
719 Store.insert(this);
720 return this;
721 }
722 return *I;
723 }
724
725 void MDLocation::eraseFromStoreImpl() {
726 getContext().pImpl->MDLocations.erase(this);
727 }
728
642729 MDNodeFwdDecl *MDNode::getTemporary(LLVMContext &Context,
643730 ArrayRef MDs) {
644731 return MDNodeFwdDecl::get(Context, MDs);
649736 void UniquableMDNode::storeDistinctInContext() {
650737 assert(!IsDistinctInContext && "Expected newly distinct metadata");
651738 IsDistinctInContext = true;
652 auto *T = cast(this);
653 T->setHash(0);
654 getContext().pImpl->DistinctMDNodes.insert(T);
739 if (auto *T = dyn_cast(this))
740 T->setHash(0);
741 getContext().pImpl->DistinctMDNodes.insert(this);
655742 }
656743
657744 void MDNode::replaceOperandWith(unsigned I, Metadata *New) {
386386 Temp->replaceAllUsesWith(nullptr);
387387 }
388388
389 typedef MetadataTest MDLocationTest;
390
391 TEST_F(MDLocationTest, Overflow) {
392 MDNode *N = MDNode::get(Context, None);
393 {
394 MDLocation *L = MDLocation::get(Context, 2, 7, N);
395 EXPECT_EQ(2u, L->getLine());
396 EXPECT_EQ(7u, L->getColumn());
397 }
398 unsigned U24 = 1u << 24;
399 unsigned U8 = 1u << 8;
400 {
401 MDLocation *L = MDLocation::get(Context, U24 - 1, U8 - 1, N);
402 EXPECT_EQ(U24 - 1, L->getLine());
403 EXPECT_EQ(U8 - 1, L->getColumn());
404 }
405 {
406 MDLocation *L = MDLocation::get(Context, U24, U8, N);
407 EXPECT_EQ(0u, L->getLine());
408 EXPECT_EQ(0u, L->getColumn());
409 }
410 {
411 MDLocation *L = MDLocation::get(Context, U24 + 1, U8 + 1, N);
412 EXPECT_EQ(0u, L->getLine());
413 EXPECT_EQ(0u, L->getColumn());
414 }
415 }
416
417 TEST_F(MDLocationTest, getDistinct) {
418 MDNode *N = MDNode::get(Context, None);
419 MDLocation *L0 = MDLocation::getDistinct(Context, 2, 7, N);
420 EXPECT_TRUE(L0->isDistinct());
421 MDLocation *L1 = MDLocation::get(Context, 2, 7, N);
422 EXPECT_FALSE(L1->isDistinct());
423 EXPECT_EQ(L1, MDLocation::get(Context, 2, 7, N));
424 }
425
389426 typedef MetadataTest MetadataAsValueTest;
390427
391428 TEST_F(MetadataAsValueTest, MDNode) {