llvm.org GIT mirror llvm / 8b2dee8
Make it illegal for two Functions to point to the same DISubprogram As recently discussed on llvm-dev [1], this patch makes it illegal for two Functions to point to the same DISubprogram and updates FunctionCloner to also clone the debug info of a function to conform to the new requirement. To simplify the implementation it also factors out the creation of inlineAt locations from the Inliner into a general-purpose utility in DILocation. [1] http://lists.llvm.org/pipermail/llvm-dev/2017-May/112661.html <rdar://problem/31926379> Differential Revision: https://reviews.llvm.org/D32975 This reapplies r302469 with a fix for a bot failure (reparentDebugInfo now checks for the case the orig and new function are identical). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302576 91177308-0d34-0410-b5e6-96231b3b80d8 Adrian Prantl 3 years ago
7 changed file(s) with 221 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
7979 static DebugLoc get(unsigned Line, unsigned Col, const MDNode *Scope,
8080 const MDNode *InlinedAt = nullptr);
8181
82 enum { ReplaceLastInlinedAt = true };
83 /// Rebuild the entire inlined-at chain for this instruction so that the top of
84 /// the chain now is inlined-at the new call site.
85 /// \param InlinedAt The new outermost inlined-at in the chain.
86 /// \param ReplaceLast Replace the last location in the inlined-at chain.
87 static DebugLoc appendInlinedAt(DebugLoc DL, DILocation *InlinedAt,
88 LLVMContext &Ctx,
89 DenseMap &Cache,
90 bool ReplaceLast = false);
91
92 /// Reparent all debug locations referenced by \c I that belong to \c OrigSP
93 /// to become (possibly indirect) children of \c NewSP.
94 static void reparentDebugInfo(Instruction &I, DISubprogram *OrigSP,
95 DISubprogram *NewSP,
96 DenseMap &Cache);
97
8298 unsigned getLine() const;
8399 unsigned getCol() const;
84100 MDNode *getScope() const;
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/IR/DebugLoc.h"
10 #include "llvm/IR/IntrinsicInst.h"
1011 #include "LLVMContextImpl.h"
1112 #include "llvm/IR/DebugInfo.h"
1213 using namespace llvm;
6465 const_cast(Scope),
6566 const_cast(InlinedAt));
6667 }
68
69 DebugLoc DebugLoc::appendInlinedAt(DebugLoc DL, DILocation *InlinedAt,
70 LLVMContext &Ctx,
71 DenseMap &Cache,
72 bool ReplaceLast) {
73 SmallVector InlinedAtLocations;
74 DILocation *Last = InlinedAt;
75 DILocation *CurInlinedAt = DL;
76
77 // Gather all the inlined-at nodes.
78 while (DILocation *IA = CurInlinedAt->getInlinedAt()) {
79 // Skip any we've already built nodes for.
80 if (auto *Found = Cache[IA]) {
81 Last = cast(Found);
82 break;
83 }
84
85 if (ReplaceLast && !IA->getInlinedAt())
86 break;
87 InlinedAtLocations.push_back(IA);
88 CurInlinedAt = IA;
89 }
90
91 // Starting from the top, rebuild the nodes to point to the new inlined-at
92 // location (then rebuilding the rest of the chain behind it) and update the
93 // map of already-constructed inlined-at nodes.
94 for (const DILocation *MD : reverse(InlinedAtLocations))
95 Cache[MD] = Last = DILocation::getDistinct(
96 Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last);
97
98 return Last;
99 }
100
101 /// Reparent \c Scope from \c OrigSP to \c NewSP.
102 static DIScope *reparentScope(LLVMContext &Ctx, DIScope *Scope,
103 DISubprogram *OrigSP, DISubprogram *NewSP,
104 DenseMap &Cache) {
105 SmallVector ScopeChain;
106 DIScope *Last = NewSP;
107 DIScope *CurScope = Scope;
108 do {
109 if (auto *SP = dyn_cast(CurScope)) {
110 // Don't rewrite this scope chain if it doesn't lead to the replaced SP.
111 if (SP != OrigSP)
112 return Scope;
113 Cache.insert({OrigSP, NewSP});
114 break;
115 }
116 if (auto *Found = Cache[CurScope]) {
117 Last = cast(Found);
118 break;
119 }
120 ScopeChain.push_back(CurScope);
121 } while ((CurScope = CurScope->getScope().resolve()));
122
123 // Starting from the top, rebuild the nodes to point to the new inlined-at
124 // location (then rebuilding the rest of the chain behind it) and update the
125 // map of already-constructed inlined-at nodes.
126 for (const DIScope *MD : reverse(ScopeChain)) {
127 if (auto *LB = dyn_cast(MD))
128 Cache[MD] = Last = DILexicalBlock::getDistinct(
129 Ctx, Last, LB->getFile(), LB->getLine(), LB->getColumn());
130 else if (auto *LB = dyn_cast(MD))
131 Cache[MD] = Last = DILexicalBlockFile::getDistinct(
132 Ctx, Last, LB->getFile(), LB->getDiscriminator());
133 else
134 llvm_unreachable("illegal parent scope");
135 }
136 return Last;
137 }
138
139 void DebugLoc::reparentDebugInfo(Instruction &I, DISubprogram *OrigSP,
140 DISubprogram *NewSP,
141 DenseMap &Cache) {
142 auto DL = I.getDebugLoc();
143 if (!OrigSP || !NewSP || OrigSP == NewSP || !DL)
144 return;
145
146 // Reparent the debug location.
147 auto &Ctx = I.getContext();
148 DILocation *InlinedAt = DL->getInlinedAt();
149 if (InlinedAt) {
150 while (auto *IA = InlinedAt->getInlinedAt())
151 InlinedAt = IA;
152 auto NewScope =
153 reparentScope(Ctx, InlinedAt->getScope(), OrigSP, NewSP, Cache);
154 InlinedAt =
155 DebugLoc::get(InlinedAt->getLine(), InlinedAt->getColumn(), NewScope);
156 }
157 I.setDebugLoc(
158 DebugLoc::get(DL.getLine(), DL.getCol(),
159 reparentScope(Ctx, DL->getScope(), OrigSP, NewSP, Cache),
160 DebugLoc::appendInlinedAt(DL, InlinedAt, Ctx, Cache,
161 ReplaceLastInlinedAt)));
162
163 // Fix up debug variables to point to NewSP.
164 auto reparentVar = [&](DILocalVariable *Var) {
165 return DILocalVariable::getDistinct(
166 Ctx,
167 cast(
168 reparentScope(Ctx, Var->getScope(), OrigSP, NewSP, Cache)),
169 Var->getName(), Var->getFile(), Var->getLine(), Var->getType(),
170 Var->getArg(), Var->getFlags(), Var->getAlignInBits());
171 };
172 if (auto *DbgValue = dyn_cast(&I)) {
173 auto *Var = DbgValue->getVariable();
174 I.setOperand(2, MetadataAsValue::get(Ctx, reparentVar(Var)));
175 } else if (auto *DbgDeclare = dyn_cast(&I)) {
176 auto *Var = DbgDeclare->getVariable();
177 I.setOperand(1, MetadataAsValue::get(Ctx, reparentVar(Var)));
178 }
179 }
180
67181
68182 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
69183 LLVM_DUMP_METHOD void DebugLoc::dump() const {
266266 /// \brief Keep track of the metadata nodes that have been checked already.
267267 SmallPtrSet MDNodes;
268268
269 /// Keep track which DISubprogram is attached to which function.
270 DenseMap DISubprogramAttachments;
271
269272 /// Track all DICompileUnits visited.
270273 SmallPtrSet CUVisited;
271274
385388 verifyCompileUnits();
386389
387390 verifyDeoptimizeCallingConvs();
388
391 DISubprogramAttachments.clear();
389392 return !Broken;
390393 }
391394
20842087 switch (I.first) {
20852088 default:
20862089 break;
2087 case LLVMContext::MD_dbg:
2090 case LLVMContext::MD_dbg: {
20882091 ++NumDebugAttachments;
20892092 AssertDI(NumDebugAttachments == 1,
20902093 "function must have a single !dbg attachment", &F, I.second);
20912094 AssertDI(isa(I.second),
20922095 "function !dbg attachment must be a subprogram", &F, I.second);
2096 auto *SP = cast(I.second);
2097 const Function *&AttachedTo = DISubprogramAttachments[SP];
2098 AssertDI(!AttachedTo || AttachedTo == &F,
2099 "DISubprogram attached to more than one function", SP, &F);
2100 AttachedTo = &F;
20932101 break;
2102 }
20942103 case LLVMContext::MD_prof:
20952104 ++NumProfAttachments;
20962105 Assert(NumProfAttachments == 1,
4040 ValueToValueMapTy &VMap,
4141 const Twine &NameSuffix, Function *F,
4242 ClonedCodeInfo *CodeInfo) {
43 DenseMap Cache;
4344 BasicBlock *NewBB = BasicBlock::Create(BB->getContext(), "", F);
4445 if (BB->hasName()) NewBB->setName(BB->getName()+NameSuffix);
4546
4950 for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
5051 II != IE; ++II) {
5152 Instruction *NewInst = II->clone();
53 if (F && F->getSubprogram())
54 DebugLoc::reparentDebugInfo(*NewInst, BB->getParent()->getSubprogram(),
55 F->getSubprogram(), Cache);
5256 if (II->hasName())
5357 NewInst->setName(II->getName()+NameSuffix);
5458 NewBB->getInstList().push_back(NewInst);
119123
120124 SmallVector, 1> MDs;
121125 OldFunc->getAllMetadata(MDs);
122 for (auto MD : MDs)
123 NewFunc->addMetadata(
124 MD.first,
125 *MapMetadata(MD.second, VMap,
126 ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
127 TypeMapper, Materializer));
126 for (auto MD : MDs) {
127 MDNode *NewMD;
128 bool MustCloneSP =
129 (MD.first == LLVMContext::MD_dbg && OldFunc->getParent() &&
130 OldFunc->getParent() == NewFunc->getParent());
131 if (MustCloneSP) {
132 auto *SP = cast(MD.second);
133 NewMD = DISubprogram::getDistinct(
134 NewFunc->getContext(), SP->getScope(), SP->getName(),
135 NewFunc->getName(), SP->getFile(), SP->getLine(), SP->getType(),
136 SP->isLocalToUnit(), SP->isDefinition(), SP->getScopeLine(),
137 SP->getContainingType(), SP->getVirtuality(), SP->getVirtualIndex(),
138 SP->getThisAdjustment(), SP->getFlags(), SP->isOptimized(),
139 SP->getUnit(), SP->getTemplateParams(), SP->getDeclaration(),
140 SP->getVariables(), SP->getThrownTypes());
141 } else
142 NewMD =
143 MapMetadata(MD.second, VMap,
144 ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
145 TypeMapper, Materializer);
146 NewFunc->addMetadata(MD.first, *NewMD);
147 }
128148
129149 // Loop over all of the basic blocks in the function, cloning them as
130150 // appropriate. Note that we save BE this way in order to handle cloning of
13011301 return false;
13021302 }
13031303
1304 /// Rebuild the entire inlined-at chain for this instruction so that the top of
1305 /// the chain now is inlined-at the new call site.
1306 static DebugLoc
1307 updateInlinedAtInfo(const DebugLoc &DL, DILocation *InlinedAtNode,
1308 LLVMContext &Ctx,
1309 DenseMap &IANodes) {
1310 SmallVector InlinedAtLocations;
1311 DILocation *Last = InlinedAtNode;
1312 DILocation *CurInlinedAt = DL;
1313
1314 // Gather all the inlined-at nodes
1315 while (DILocation *IA = CurInlinedAt->getInlinedAt()) {
1316 // Skip any we've already built nodes for
1317 if (DILocation *Found = IANodes[IA]) {
1318 Last = Found;
1319 break;
1320 }
1321
1322 InlinedAtLocations.push_back(IA);
1323 CurInlinedAt = IA;
1324 }
1325
1326 // Starting from the top, rebuild the nodes to point to the new inlined-at
1327 // location (then rebuilding the rest of the chain behind it) and update the
1328 // map of already-constructed inlined-at nodes.
1329 for (const DILocation *MD : reverse(InlinedAtLocations)) {
1330 Last = IANodes[MD] = DILocation::getDistinct(
1331 Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last);
1332 }
1333
1334 // And finally create the normal location for this instruction, referring to
1335 // the new inlined-at chain.
1336 return DebugLoc::get(DL.getLine(), DL.getCol(), DL.getScope(), Last);
1337 }
1338
13391304 /// Return the result of AI->isStaticAlloca() if AI were moved to the entry
13401305 /// block. Allocas used in inalloca calls and allocas of dynamic array size
13411306 /// cannot be static.
13631328 // Cache the inlined-at nodes as they're built so they are reused, without
13641329 // this every instruction's inlined-at chain would become distinct from each
13651330 // other.
1366 DenseMapDILocation *, DILocation *> IANodes;
1331 DenseMapMDNode *, MDNode *> IANodes;
13671332
13681333 for (; FI != Fn->end(); ++FI) {
13691334 for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
13701335 BI != BE; ++BI) {
13711336 if (DebugLoc DL = BI->getDebugLoc()) {
1372 BI->setDebugLoc(
1373 updateInlinedAtInfo(DL, InlinedAtNode, BI->getContext(), IANodes));
1337 auto IA = DebugLoc::appendInlinedAt(DL, InlinedAtNode, BI->getContext(),
1338 IANodes);
1339 auto IDL = DebugLoc::get(DL.getLine(), DL.getCol(), DL.getScope(), IA);
1340 BI->setDebugLoc(IDL);
13741341 continue;
13751342 }
13761343
22 ; CHECK: function declaration may not have a !dbg attachment
33 declare !dbg !4 void @f1()
44
5 define void @f2() !dbg !4 {
5 ; CHECK: function must have a single !dbg attachment
6 define void @f2() !dbg !4 !dbg !4 {
67 unreachable
78 }
89
9 ; CHECK: function must have a single !dbg attachment
10 define void @f3() !dbg !4 !dbg !4 {
10 ; CHECK: DISubprogram attached to more than one function
11 define void @f3() !dbg !4 {
12 unreachable
13 }
14
15 ; CHECK: DISubprogram attached to more than one function
16 define void @f4() !dbg !4 {
1117 unreachable
1218 }
1319
1521 ; CHECK: function !dbg attachment must be a subprogram
1622 ; CHECK-NEXT: void ()* @bar
1723 ; CHECK-NEXT: !{{[0-9]+}} = !{}
18 define void @bar() !dbg !6 {
24 define void @bar() !dbg !3 {
1925 unreachable
2026 }
2127
2531 !llvm.dbg.cu = !{!1}
2632 !1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2)
2733 !2 = !DIFile(filename: "t.c", directory: "/path/to/dir")
34 !3 = !{}
2835 !4 = distinct !DISubprogram(name: "foo", scope: !1, file: !2, unit: !1)
29 !6 = !{}
295295 Value* AllocaContent = IBuilder.getInt32(1);
296296 Instruction* Store = IBuilder.CreateStore(AllocaContent, Alloca);
297297 IBuilder.SetCurrentDebugLocation(DebugLoc::get(5, 2, Subprogram));
298 Instruction* Terminator = IBuilder.CreateRetVoid();
299298
300299 // Create a local variable around the alloca
301300 auto *IntType = DBuilder.createBasicType("int", 32, dwarf::DW_ATE_signed);
305304 auto *DL = DILocation::get(Subprogram->getContext(), 5, 0, Subprogram);
306305 DBuilder.insertDeclare(Alloca, Variable, E, DL, Store);
307306 DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, E, DL,
308 Terminator);
309 // Finalize the debug info
307 Entry);
308 // Also create an inlined variable.
309 auto *InlinedSP =
310 DBuilder.createFunction(CU, "inlined", "inlined", File, 8, FuncType,
311 true, true, 9, DINode::FlagZero, false);
312 auto *InlinedVar =
313 DBuilder.createAutoVariable(InlinedSP, "inlined", File, 5, IntType, true);
314 auto *Scope = DBuilder.createLexicalBlock(
315 DBuilder.createLexicalBlockFile(InlinedSP, File), File, 1, 1);
316 auto InlinedDL =
317 DebugLoc::get(9, 4, Scope, DebugLoc::get(5, 2, Subprogram));
318 IBuilder.SetCurrentDebugLocation(InlinedDL);
319 DBuilder.insertDeclare(Alloca, InlinedVar, E, InlinedDL, Store);
320 IBuilder.CreateStore(IBuilder.getInt32(2), Alloca);
321 // Finalize the debug info.
310322 DBuilder.finalize();
311
312
313 // Create another, empty, compile unit
323 IBuilder.CreateRetVoid();
324
325 // Create another, empty, compile unit.
314326 DIBuilder DBuilder2(*M);
315327 DBuilder2.createCompileUnit(dwarf::DW_LANG_C99,
316328 DBuilder.createFile("extra.c", "/file/dir"),
344356 // function, while the original subprogram still points to the old one.
345357 TEST_F(CloneFunc, Subprogram) {
346358 EXPECT_FALSE(verifyModule(*M));
347
348 unsigned SubprogramCount = Finder->subprogram_count();
349 EXPECT_EQ(1U, SubprogramCount);
350
351 auto Iter = Finder->subprograms().begin();
352 auto *Sub = cast(*Iter);
353
354 EXPECT_TRUE(Sub == OldFunc->getSubprogram());
355 EXPECT_TRUE(Sub == NewFunc->getSubprogram());
359 EXPECT_EQ(3U, Finder->subprogram_count());
360 EXPECT_NE(NewFunc->getSubprogram(), OldFunc->getSubprogram());
356361 }
357362
358363 // Test that instructions in the old function still belong to it in the
379384 EXPECT_EQ(OldDL.getCol(), NewDL.getCol());
380385
381386 // But that they belong to different functions
382 auto *OldSubprogram = cast(OldDL.getScope());
383 auto *NewSubprogram = cast(NewDL.getScope());
387 auto *OldSubprogram = cast(OldDL.getInlinedAtScope());
388 auto *NewSubprogram = cast(NewDL.getInlinedAtScope());
384389 EXPECT_EQ(OldFunc->getSubprogram(), OldSubprogram);
385390 EXPECT_EQ(NewFunc->getSubprogram(), NewSubprogram);
386391 }
415420 EXPECT_EQ(NewFunc, cast(NewIntrin->getAddress())->
416421 getParent()->getParent());
417422
418 // Old variable must belong to the old function
419 EXPECT_EQ(OldFunc->getSubprogram(),
420 cast(OldIntrin->getVariable()->getScope()));
421 // New variable must belong to the New function
422 EXPECT_EQ(NewFunc->getSubprogram(),
423 cast(NewIntrin->getVariable()->getScope()));
423 if (!OldIntrin->getDebugLoc()->getInlinedAt()) {
424 // Old variable must belong to the old function.
425 EXPECT_EQ(OldFunc->getSubprogram(),
426 cast(OldIntrin->getVariable()->getScope()));
427 // New variable must belong to the new function.
428 EXPECT_EQ(NewFunc->getSubprogram(),
429 cast(NewIntrin->getVariable()->getScope()));
430 }
424431 } else if (DbgValueInst* OldIntrin = dyn_cast(&OldI)) {
425432 DbgValueInst* NewIntrin = dyn_cast(&NewI);
426433 EXPECT_TRUE(NewIntrin);
427434
428 // Old variable must belong to the old function
429 EXPECT_EQ(OldFunc->getSubprogram(),
430 cast(OldIntrin->getVariable()->getScope()));
431 // New variable must belong to the New function
432 EXPECT_EQ(NewFunc->getSubprogram(),
433 cast(NewIntrin->getVariable()->getScope()));
435 if (!OldIntrin->getDebugLoc()->getInlinedAt()) {
436 // Old variable must belong to the old function.
437 EXPECT_EQ(OldFunc->getSubprogram(),
438 cast(OldIntrin->getVariable()->getScope()));
439 // New variable must belong to the new function.
440 EXPECT_EQ(NewFunc->getSubprogram(),
441 cast(NewIntrin->getVariable()->getScope()));
442 }
434443 }
435444
436445 ++OldIter;