llvm.org GIT mirror llvm / d8d85ac
IR: Allow multiple global metadata attachments with the same type. This will be necessary to allow the global merge pass to attach multiple debug info metadata nodes to global variables once we reverse the edge from DIGlobalVariable to GlobalVariable. Differential Revision: http://reviews.llvm.org/D20414 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271358 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 3 years ago
12 changed file(s) with 155 addition(s) and 93 deletion(s). Raw diff Collapse all Expand all
7373 /// Check if this has any metadata.
7474 bool hasMetadata() const { return hasMetadataHashEntry(); }
7575
76 /// Get the current metadata attachment, if any.
76 /// Get the current metadata attachments for the given kind, if any.
7777 ///
78 /// Returns \c nullptr if such an attachment is missing.
78 /// These functions require that the function have at most a single attachment
79 /// of the given kind, and return \c nullptr if such an attachment is missing.
7980 /// @{
8081 MDNode *getMetadata(unsigned KindID) const;
8182 MDNode *getMetadata(StringRef Kind) const;
83 /// @}
84
85 /// Appends all attachments with the given ID to \c MDs in insertion order.
86 /// If the global has no attachments with the given ID, or if ID is invalid,
87 /// leaves MDs unchanged.
88 /// @{
89 void getMetadata(unsigned KindID, SmallVectorImpl &MDs) const;
90 void getMetadata(StringRef Kind, SmallVectorImpl &MDs) const;
8291 /// @}
8392
8493 /// Set a particular kind of metadata attachment.
9099 void setMetadata(StringRef Kind, MDNode *MD);
91100 /// @}
92101
93 /// Get all current metadata attachments.
102 /// Add a metadata attachment.
103 /// @{
104 void addMetadata(unsigned KindID, MDNode &MD);
105 void addMetadata(StringRef Kind, MDNode &MD);
106 /// @}
107
108 /// Appends all attachments for the global to \c MDs, sorting by attachment
109 /// ID. Attachments with the same ID appear in insertion order.
94110 void
95111 getAllMetadata(SmallVectorImpl> &MDs) const;
96112
97 /// Drop metadata not in the given list.
98 ///
99 /// Drop all metadata from \c this not included in \c KnownIDs.
100 void dropUnknownMetadata(ArrayRef KnownIDs);
113 /// Erase all metadata attachments with the given kind.
114 void eraseMetadata(unsigned KindID);
101115
102116 void copyAttributesFrom(const GlobalValue *Src) override;
103117
107121 V->getValueID() == Value::GlobalVariableVal;
108122 }
109123
110 protected:
111124 void clearMetadata();
112125
113126 private:
17181718 if (ParseMetadataAttachment(MDK, N))
17191719 return true;
17201720
1721 GO.setMetadata(MDK, N);
1721 GO.addMetadata(MDK, *N);
17221722 return false;
17231723 }
17241724
41664166 MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]);
41674167 if (!MD)
41684168 return error("Invalid metadata attachment");
4169 GO.setMetadata(K->second, MD);
4169 GO.addMetadata(K->second, *MD);
41704170 }
41714171 return std::error_code();
41724172 }
344344
345345 SmallVector, 8> MDs;
346346 for (const GlobalVariable &GV : M.globals()) {
347 MDs.clear();
347348 GV.getAllMetadata(MDs);
348349 for (const auto &I : MDs)
349350 EnumerateMetadata(&GV, I.second);
355356 EnumerateType(A.getType());
356357
357358 // Enumerate metadata attached to this function.
359 MDs.clear();
358360 F.getAllMetadata(MDs);
359361 for (const auto &I : MDs)
360362 EnumerateMetadata(&F, I.second);
996996 }
997997 };
998998
999 /// Multimap-like storage for metadata attachments for globals. This differs
1000 /// from MDAttachmentMap in that it allows multiple attachments per metadata
1001 /// kind.
1002 class MDGlobalAttachmentMap {
1003 struct Attachment {
1004 unsigned MDKind;
1005 TrackingMDNodeRef Node;
1006 };
1007 SmallVector Attachments;
1008
1009 public:
1010 bool empty() const { return Attachments.empty(); }
1011
1012 /// Appends all attachments with the given ID to \c Result in insertion order.
1013 /// If the global has no attachments with the given ID, or if ID is invalid,
1014 /// leaves Result unchanged.
1015 void get(unsigned ID, SmallVectorImpl &Result);
1016
1017 void insert(unsigned ID, MDNode &MD);
1018 void erase(unsigned ID);
1019
1020 /// Appends all attachments for the global to \c Result, sorting by attachment
1021 /// ID. Attachments with the same ID appear in insertion order. This function
1022 /// does \em not clear \c Result.
1023 void getAll(SmallVectorImpl> &Result) const;
1024 };
1025
9991026 class LLVMContextImpl {
10001027 public:
10011028 /// OwnedModules - The set of modules instantiated in this context, and which
11071134 DenseMap InstructionMetadata;
11081135
11091136 /// Collection of per-GlobalObject metadata used in this context.
1110 DenseMapAttachmentMap> GlobalObjectMetadata;
1137 DenseMapGlobalAttachmentMap> GlobalObjectMetadata;
11111138
11121139 /// DiscriminatorTable - This table maps file:line locations to an
11131140 /// integer representing the next DWARF path discriminator to assign to
11241124 array_pod_sort(Result.begin(), Result.end());
11251125 }
11261126
1127 void MDGlobalAttachmentMap::insert(unsigned ID, MDNode &MD) {
1128 Attachments.push_back({ID, TrackingMDNodeRef(&MD)});
1129 }
1130
1131 void MDGlobalAttachmentMap::get(unsigned ID,
1132 SmallVectorImpl &Result) {
1133 for (auto A : Attachments)
1134 if (A.MDKind == ID)
1135 Result.push_back(A.Node);
1136 }
1137
1138 void MDGlobalAttachmentMap::erase(unsigned ID) {
1139 auto Follower = Attachments.begin();
1140 for (auto Leader = Attachments.begin(), E = Attachments.end(); Leader != E;
1141 ++Leader) {
1142 if (Leader->MDKind != ID) {
1143 if (Follower != Leader)
1144 *Follower = std::move(*Leader);
1145 ++Follower;
1146 }
1147 }
1148 Attachments.resize(Follower - Attachments.begin());
1149 }
1150
1151 void MDGlobalAttachmentMap::getAll(
1152 SmallVectorImpl> &Result) const {
1153 for (auto &A : Attachments)
1154 Result.emplace_back(A.MDKind, A.Node);
1155
1156 // Sort the resulting array so it is stable with respect to metadata IDs. We
1157 // need to preserve the original insertion order though.
1158 std::stable_sort(
1159 Result.begin(), Result.end(),
1160 [](const std::pair &A,
1161 const std::pair &B) { return A.first < B.first; });
1162 }
1163
11271164 void Instruction::setMetadata(StringRef Kind, MDNode *Node) {
11281165 if (!Node && !hasMetadata())
11291166 return;
12801317 setHasMetadataHashEntry(false);
12811318 }
12821319
1283 MDNode *GlobalObject::getMetadata(unsigned KindID) const {
1320 void GlobalObject::getMetadata(unsigned KindID,
1321 SmallVectorImpl &MDs) const {
1322 if (hasMetadata())
1323 getContext().pImpl->GlobalObjectMetadata[this].get(KindID, MDs);
1324 }
1325
1326 void GlobalObject::getMetadata(StringRef Kind,
1327 SmallVectorImpl &MDs) const {
1328 if (hasMetadata())
1329 getMetadata(getContext().getMDKindID(Kind), MDs);
1330 }
1331
1332 void GlobalObject::addMetadata(unsigned KindID, MDNode &MD) {
12841333 if (!hasMetadata())
1285 return nullptr;
1286 return getContext().pImpl->GlobalObjectMetadata[this].lookup(KindID);
1287 }
1288
1289 MDNode *GlobalObject::getMetadata(StringRef Kind) const {
1290 if (!hasMetadata())
1291 return nullptr;
1292 return getMetadata(getContext().getMDKindID(Kind));
1293 }
1294
1295 void GlobalObject::setMetadata(unsigned KindID, MDNode *MD) {
1296 if (MD) {
1297 if (!hasMetadata())
1298 setHasMetadataHashEntry(true);
1299
1300 getContext().pImpl->GlobalObjectMetadata[this].set(KindID, *MD);
1301 return;
1302 }
1303
1334 setHasMetadataHashEntry(true);
1335
1336 getContext().pImpl->GlobalObjectMetadata[this].insert(KindID, MD);
1337 }
1338
1339 void GlobalObject::addMetadata(StringRef Kind, MDNode &MD) {
1340 addMetadata(getContext().getMDKindID(Kind), MD);
1341 }
1342
1343 void GlobalObject::eraseMetadata(unsigned KindID) {
13041344 // Nothing to unset.
13051345 if (!hasMetadata())
13061346 return;
13111351 clearMetadata();
13121352 }
13131353
1314 void GlobalObject::setMetadata(StringRef Kind, MDNode *MD) {
1315 if (!MD && !hasMetadata())
1316 return;
1317 setMetadata(getContext().getMDKindID(Kind), MD);
1318 }
1319
13201354 void GlobalObject::getAllMetadata(
13211355 SmallVectorImpl> &MDs) const {
13221356 MDs.clear();
13271361 getContext().pImpl->GlobalObjectMetadata[this].getAll(MDs);
13281362 }
13291363
1330 void GlobalObject::dropUnknownMetadata(ArrayRef KnownIDs) {
1331 if (!hasMetadata())
1332 return;
1333 if (KnownIDs.empty()) {
1334 clearMetadata();
1335 return;
1336 }
1337
1338 SmallSet KnownSet;
1339 KnownSet.insert(KnownIDs.begin(), KnownIDs.end());
1340
1341 auto &Store = getContext().pImpl->GlobalObjectMetadata[this];
1342 assert(!Store.empty());
1343
1344 Store.remove_if([&KnownSet](const std::pair &I) {
1345 return !KnownSet.count(I.first);
1346 });
1347
1348 if (Store.empty())
1349 clearMetadata();
1350 }
1351
13521364 void GlobalObject::clearMetadata() {
13531365 if (!hasMetadata())
13541366 return;
13561368 setHasMetadataHashEntry(false);
13571369 }
13581370
1371
1372 void GlobalObject::setMetadata(unsigned KindID, MDNode *N) {
1373 eraseMetadata(KindID);
1374 if (N)
1375 addMetadata(KindID, *N);
1376 }
1377
1378 void GlobalObject::setMetadata(StringRef Kind, MDNode *N) {
1379 setMetadata(getContext().getMDKindID(Kind), N);
1380 }
1381
1382 MDNode *GlobalObject::getMetadata(unsigned KindID) const {
1383 SmallVector MDs;
1384 getMetadata(KindID, MDs);
1385 assert(MDs.size() <= 1 && "Expected at most one metadata attachment");
1386 if (MDs.empty())
1387 return nullptr;
1388 return MDs[0];
1389 }
1390
1391 MDNode *GlobalObject::getMetadata(StringRef Kind) const {
1392 return getMetadata(getContext().getMDKindID(Kind));
1393 }
1394
13591395 void Function::setSubprogram(DISubprogram *SP) {
13601396 setMetadata(LLVMContext::MD_dbg, SP);
13611397 }
19901990 "blockaddress may not be used with the entry block!", Entry);
19911991 }
19921992
1993 unsigned NumDebugAttachments = 0;
19931994 // Visit metadata attachments.
19941995 for (const auto &I : MDs) {
19951996 // Verify that the attachment is legal.
19971998 default:
19981999 break;
19992000 case LLVMContext::MD_dbg:
2001 ++NumDebugAttachments;
2002 AssertDI(NumDebugAttachments == 1,
2003 "function must have a single !dbg attachment", &F, I.second);
20002004 AssertDI(isa(I.second),
20012005 "function !dbg attachment must be a subprogram", &F, I.second);
20022006 break;
121121 SmallVector, 1> MDs;
122122 OldFunc->getAllMetadata(MDs);
123123 for (auto MD : MDs)
124 NewFunc->setMetadata(
124 NewFunc->addMetadata(
125125 MD.first,
126 MapMetadata(MD.second, VMap,
127 ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
128 TypeMapper, Materializer));
126 *MapMetadata(MD.second, VMap,
127 ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
128 TypeMapper, Materializer));
129129
130130 // Loop over all of the basic blocks in the function, cloning them as
131131 // appropriate. Note that we save BE this way in order to handle cloning of
949949 // Remap the metadata attachments.
950950 SmallVector, 8> MDs;
951951 F.getAllMetadata(MDs);
952 F.clearMetadata();
952953 for (const auto &I : MDs)
953 F.setMetadata(I.first, cast_or_null(mapMetadata(I.second)));
954 F.addMetadata(I.first, *cast(mapMetadata(I.second)));
954955
955956 // Remap the argument types.
956957 if (TypeMapper)
0 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
11 ; RUN: verify-uselistorder %s
22
3 ; CHECK: @global = global i32 0, !foo [[M2:![0-9]+]], !baz [[M3:![0-9]+]]
4 @global = global i32 0, !foo !2, !baz !3
3 ; CHECK: @global = global i32 0, !foo [[M2:![0-9]+]], !foo [[M3:![0-9]+]], !baz [[M3]]
4 @global = global i32 0, !foo !2, !foo !3, !baz !3
55
66 ; CHECK-LABEL: @test
77 ; CHECK: ret void, !foo [[M0:![0-9]+]], !bar [[M1:![0-9]+]]
0 ; RUN: not llvm-as %s -disable-output 2>&1 | FileCheck %s
11
2 define void @foo() !dbg !4 !dbg !4 {
2 define void @foo() !dbg !4 {
3 unreachable
4 }
5
6 ; CHECK: function must have a single !dbg attachment
7 define void @foo2() !dbg !4 !dbg !4 {
38 unreachable
49 }
510
22412241 EXPECT_EQ(T2, MDs[3].second);
22422242 }
22432243
2244 TEST_F(FunctionAttachmentTest, dropUnknownMetadata) {
2245 Function *F = getFunction("foo");
2246
2247 MDTuple *T1 = getTuple();
2248 MDTuple *T2 = getTuple();
2249 MDTuple *P = getTuple();
2250 DISubprogram *SP = getSubprogram();
2251
2252 F->setMetadata("other1", T1);
2253 F->setMetadata(LLVMContext::MD_dbg, SP);
2254 F->setMetadata("other2", T2);
2255 F->setMetadata(LLVMContext::MD_prof, P);
2256
2257 unsigned Known[] = {Context.getMDKindID("other2"), LLVMContext::MD_prof};
2258 F->dropUnknownMetadata(Known);
2259
2260 EXPECT_EQ(T2, F->getMetadata("other2"));
2261 EXPECT_EQ(P, F->getMetadata(LLVMContext::MD_prof));
2262 EXPECT_EQ(nullptr, F->getMetadata("other1"));
2263 EXPECT_EQ(nullptr, F->getMetadata(LLVMContext::MD_dbg));
2264
2265 F->setMetadata("other2", nullptr);
2266 F->setMetadata(LLVMContext::MD_prof, nullptr);
2267 EXPECT_FALSE(F->hasMetadata());
2268 }
2269
22702244 TEST_F(FunctionAttachmentTest, Verifier) {
22712245 Function *F = getFunction("foo");
22722246 F->setMetadata("attach", getTuple());