llvm.org GIT mirror llvm / 26d1429
Debugging infomration is encoded in llvm IR using metadata. This is designed such a way that debug info for symbols preserved even if symbols are optimized away by the optimizer. Add new special pass to remove debug info for such symbols. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107416 91177308-0d34-0410-b5e6-96231b3b80d8 Devang Patel 10 years ago
4 changed file(s) with 154 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
112112 (void) llvm::createSingleLoopExtractorPass();
113113 (void) llvm::createStripSymbolsPass();
114114 (void) llvm::createStripNonDebugSymbolsPass();
115 (void) llvm::createStripDeadDebugInfoPass();
115116 (void) llvm::createStripDeadPrototypesPass();
116117 (void) llvm::createTailCallEliminationPass();
117118 (void) llvm::createTailDuplicationPass();
4242 //
4343 // These pass removes llvm.dbg.declare intrinsics.
4444 ModulePass *createStripDebugDeclarePass();
45
46 //===----------------------------------------------------------------------===//
47 //
48 // These pass removes unused symbols' debug info.
49 ModulePass *createStripDeadDebugInfoPass();
4550
4651 //===----------------------------------------------------------------------===//
4752 /// createLowerSetJmpPass - This function lowers the setjmp/longjmp intrinsics
7272 AU.setPreservesAll();
7373 }
7474 };
75
76 class StripDeadDebugInfo : public ModulePass {
77 public:
78 static char ID; // Pass identification, replacement for typeid
79 explicit StripDeadDebugInfo()
80 : ModulePass(&ID) {}
81
82 virtual bool runOnModule(Module &M);
83
84 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
85 AU.setPreservesAll();
86 }
87 };
7588 }
7689
7790 char StripSymbols::ID = 0;
96109
97110 ModulePass *llvm::createStripDebugDeclarePass() {
98111 return new StripDebugDeclare();
112 }
113
114 char StripDeadDebugInfo::ID = 0;
115 static RegisterPass
116 A("strip-dead-debug-info", "Strip debug info for unused symbols");
117
118 ModulePass *llvm::createStripDeadDebugInfoPass() {
119 return new StripDeadDebugInfo();
99120 }
100121
101122 /// OnlyUsedBy - Return true if V is only used by Usr.
294315
295316 return true;
296317 }
318
319 /// getRealLinkageName - If special LLVM prefix that is used to inform the asm
320 /// printer to not emit usual symbol prefix before the symbol name is used then
321 /// return linkage name after skipping this special LLVM prefix.
322 static StringRef getRealLinkageName(StringRef LinkageName) {
323 char One = '\1';
324 if (LinkageName.startswith(StringRef(&One, 1)))
325 return LinkageName.substr(1);
326 return LinkageName;
327 }
328
329 bool StripDeadDebugInfo::runOnModule(Module &M) {
330 bool Changed = false;
331
332 // Debugging infomration is encoded in llvm IR using metadata. This is designed
333 // such a way that debug info for symbols preserved even if symbols are
334 // optimized away by the optimizer. This special pass removes debug info for
335 // such symbols.
336
337 // llvm.dbg.gv keeps track of debug info for global variables.
338 if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv")) {
339 SmallVector MDs;
340 for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
341 if (DIGlobalVariable(NMD->getOperand(i)).Verify())
342 MDs.push_back(NMD->getOperand(i));
343 else
344 Changed = true;
345 NMD->eraseFromParent();
346 NMD = NULL;
347
348 for (SmallVector::iterator I = MDs.begin(),
349 E = MDs.end(); I != E; ++I) {
350 if (M.getGlobalVariable(DIGlobalVariable(*I).getGlobal()->getName(),
351 true)) {
352 if (!NMD)
353 NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv");
354 NMD->addOperand(*I);
355 }
356 else
357 Changed = true;
358 }
359 }
360
361 // llvm.dbg.sp keeps track of debug info for subprograms.
362 if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) {
363 SmallVector MDs;
364 for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i)
365 if (DISubprogram(NMD->getOperand(i)).Verify())
366 MDs.push_back(NMD->getOperand(i));
367 else
368 Changed = true;
369 NMD->eraseFromParent();
370 NMD = NULL;
371
372 for (SmallVector::iterator I = MDs.begin(),
373 E = MDs.end(); I != E; ++I) {
374 bool FnIsLive = false;
375 if (Function *F = DISubprogram(*I).getFunction())
376 if (M.getFunction(F->getName()))
377 FnIsLive = true;
378 if (FnIsLive) {
379 if (!NMD)
380 NMD = M.getOrInsertNamedMetadata("llvm.dbg.sp");
381 NMD->addOperand(*I);
382 } else {
383 // Remove llvm.dbg.lv.fnname named mdnode which may have been used
384 // to hold debug info for dead function's local variables.
385 StringRef FName = DISubprogram(*I).getLinkageName();
386 if (FName.empty())
387 FName = DISubprogram(*I).getName();
388 if (NamedMDNode *LVNMD =
389 M.getNamedMetadata(Twine("llvm.dbg.lv.",
390 getRealLinkageName(FName))))
391 LVNMD->eraseFromParent();
392 }
393 }
394 }
395
396 return Changed;
397 }
0 ; RUN: opt -strip-dead-debug-info | llvm-dis -o %t.ll
1 ; RUN: grep -v bar %t.ll
2 ; RUN: grep -v abcd %t.ll
3
4 @xyz = global i32 2 ; [#uses=1]
5
6 declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone
7
8 define i32 @fn() nounwind readnone ssp {
9 entry:
10 ret i32 0, !dbg !17
11 }
12
13 define i32 @foo(i32 %i) nounwind readonly ssp {
14 entry:
15 tail call void @llvm.dbg.value(metadata !{i32 %i}, i64 0, metadata !14), !dbg !19
16 %.0 = load i32* @xyz, align 4 ; [#uses=1]
17 ret i32 %.0, !dbg !20
18 }
19
20 !llvm.dbg.sp = !{!0, !5, !9}
21 !llvm.dbg.lv.bar = !{!12}
22 !llvm.dbg.lv.foo = !{!14}
23 !llvm.dbg.gv = !{!15, !16}
24
25 !0 = metadata !{i32 524334, i32 0, metadata !1, metadata !"bar", metadata !"bar", metadata !"", metadata !1, i32 5, metadata !3, i1 true, i1 true, i32 0, i32 0, null, i1 false, i1 true, null} ; [ DW_TAG_subprogram ]
26 !1 = metadata !{i32 524329, metadata !"g.c", metadata !"/tmp/", metadata !2} ; [ DW_TAG_file_type ]
27 !2 = metadata !{i32 524305, i32 0, i32 1, metadata !"g.c", metadata !"/tmp/", metadata !"4.2.1 (Based on Apple Inc. build 5658) (LLVM build)", i1 true, i1 true, metadata !"", i32 0} ; [ DW_TAG_compile_unit ]
28 !3 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !4, i32 0, null} ; [ DW_TAG_subroutine_type ]
29 !4 = metadata !{null}
30 !5 = metadata !{i32 524334, i32 0, metadata !1, metadata !"fn", metadata !"fn", metadata !"fn", metadata !1, i32 6, metadata !6, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i32 ()* @fn} ; [ DW_TAG_subprogram ]
31 !6 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !7, i32 0, null} ; [ DW_TAG_subroutine_type ]
32 !7 = metadata !{metadata !8}
33 !8 = metadata !{i32 524324, metadata !1, metadata !"int", metadata !1, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
34 !9 = metadata !{i32 524334, i32 0, metadata !1, metadata !"foo", metadata !"foo", metadata !"foo", metadata !1, i32 7, metadata !10, i1 false, i1 true, i32 0, i32 0, null, i1 false, i1 true, i32 (i32)* @foo} ; [ DW_TAG_subprogram ]
35 !10 = metadata !{i32 524309, metadata !1, metadata !"", metadata !1, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null} ; [ DW_TAG_subroutine_type ]
36 !11 = metadata !{metadata !8, metadata !8}
37 !12 = metadata !{i32 524544, metadata !13, metadata !"bb", metadata !1, i32 5, metadata !8} ; [ DW_TAG_auto_variable ]
38 !13 = metadata !{i32 524299, metadata !0, i32 5, i32 0} ; [ DW_TAG_lexical_block ]
39 !14 = metadata !{i32 524545, metadata !9, metadata !"i", metadata !1, i32 7, metadata !8} ; [ DW_TAG_arg_variable ]
40 !15 = metadata !{i32 524340, i32 0, metadata !1, metadata !"abcd", metadata !"abcd", metadata !"", metadata !1, i32 2, metadata !8, i1 true, i1 true, null} ; [ DW_TAG_variable ]
41 !16 = metadata !{i32 524340, i32 0, metadata !1, metadata !"xyz", metadata !"xyz", metadata !"", metadata !1, i32 3, metadata !8, i1 false, i1 true, i32* @xyz} ; [ DW_TAG_variable ]
42 !17 = metadata !{i32 6, i32 0, metadata !18, null}
43 !18 = metadata !{i32 524299, metadata !5, i32 6, i32 0} ; [ DW_TAG_lexical_block ]
44 !19 = metadata !{i32 7, i32 0, metadata !9, null}
45 !20 = metadata !{i32 10, i32 0, metadata !21, null}
46 !21 = metadata !{i32 524299, metadata !9, i32 7, i32 0} ; [ DW_TAG_lexical_block ]