Skip to content

Commit 1a1a684

Browse files
committed
[StripDeadDebugInfo] Drop dead CUs for const global expression
Compile units are not left explicitly if they have const global expression. They should be left if that const global is used in a function that is contained in extracted module. Signed-off-by: Mikhail Lychkov <[email protected]> Differential Revision: https://reviews.llvm.org/D131179
1 parent e5a3d5b commit 1a1a684

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

llvm/lib/Transforms/IPO/StripSymbols.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,18 @@
3030
#include "llvm/IR/PassManager.h"
3131
#include "llvm/IR/TypeFinder.h"
3232
#include "llvm/IR/ValueSymbolTable.h"
33+
#include "llvm/Support/CommandLine.h"
3334
#include "llvm/Transforms/IPO.h"
3435
#include "llvm/Transforms/IPO/StripSymbols.h"
3536
#include "llvm/Transforms/Utils/Local.h"
3637

3738
using namespace llvm;
3839

40+
static cl::opt<bool>
41+
StripGlobalConstants("strip-global-constants", cl::init(false), cl::Hidden,
42+
cl::desc("Removes debug compile units which reference "
43+
"to non-existing global constants"));
44+
3945
/// OnlyUsedBy - Return true if V is only used by Usr.
4046
static bool OnlyUsedBy(Value *V, Value *Usr) {
4147
for (User *U : V->users())
@@ -216,7 +222,8 @@ static bool stripDeadDebugInfoImpl(Module &M) {
216222
// Create our live global variable list.
217223
bool GlobalVariableChange = false;
218224
for (auto *DIG : DIC->getGlobalVariables()) {
219-
if (DIG->getExpression() && DIG->getExpression()->isConstant())
225+
if (DIG->getExpression() && DIG->getExpression()->isConstant() &&
226+
!StripGlobalConstants)
220227
LiveGVs.insert(DIG);
221228

222229
// Make sure we only visit each global variable only once.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
; This test checks that strip-dead-debug-info pass deletes debug compile units
2+
; if global constants from those units are absent in the module.
3+
4+
; RUN: opt -passes='strip-dead-debug-info,verify' -strip-global-constants %s -S | FileCheck %s
5+
6+
; CHECK: !llvm.dbg.cu = !{!{{[0-9]+}}, !{{[0-9]+}}}
7+
; CHECK-COUNT-2: !DICompileUnit
8+
9+
;target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
10+
;target triple = "spir64-unknown-unknown"
11+
12+
; Function Attrs: convergent nounwind
13+
define void @dev_func1() #0 !dbg !16 {
14+
%1 = call i32 @dev_subfunc1(i32 0) #1, !dbg !19
15+
ret void, !dbg !20
16+
}
17+
18+
; Function Attrs: convergent nounwind
19+
define i32 @dev_subfunc1(i32 %0) #0 !dbg !21 {
20+
ret i32 %0, !dbg !24
21+
}
22+
23+
; Function Attrs: convergent nounwind
24+
define void @dev_func2() #0 !dbg !25 {
25+
ret void, !dbg !26
26+
}
27+
28+
attributes #0 = { convergent nounwind }
29+
attributes #1 = { convergent }
30+
31+
!llvm.dbg.cu = !{!0, !8, !10}
32+
!llvm.module.flags = !{!15}
33+
34+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, imports: !2, splitDebugInlining: false, nameTableKind: None)
35+
!1 = !DIFile(filename: "dev_func1.cpp", directory: "/home/usr/test")
36+
!2 = !{}
37+
!3 = !{!4}
38+
!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value))
39+
!5 = distinct !DIGlobalVariable(name: "ZERO", scope: !1, file: !1, line: 32, type: !6, isLocal: true, isDefinition: true)
40+
!6 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !7)
41+
!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
42+
!8 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !9, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, imports: !2, splitDebugInlining: false, nameTableKind: None)
43+
!9 = !DIFile(filename: "dev_func2.cpp", directory: "/home/usr/test")
44+
!10 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !11, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !12, imports: !2, splitDebugInlining: false, nameTableKind: None)
45+
!11 = !DIFile(filename: "file3.cpp", directory: "/home/usr/test")
46+
!12 = !{!13}
47+
!13 = !DIGlobalVariableExpression(var: !14, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value))
48+
!14 = distinct !DIGlobalVariable(name: "ZERO", scope: !11, file: !11, line: 145, type: !6, isLocal: true, isDefinition: true)
49+
!15 = !{i32 2, !"Debug Info Version", i32 3}
50+
!16 = distinct !DISubprogram(name: "dev_func1", linkageName: "dev_func1", scope: !1, file: !1, line: 22, type: !17, scopeLine: 22, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
51+
!17 = !DISubroutineType(types: !18)
52+
!18 = !{null}
53+
!19 = !DILocation(line: 12, column: 1, scope: !16)
54+
!20 = !DILocation(line: 29, column: 5, scope: !16)
55+
!21 = distinct !DISubprogram(name: "dev_subfunc1", linkageName: "dev_subfunc1", scope: !1, file: !1, line: 42, type: !22, scopeLine: 42, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
56+
!22 = !DISubroutineType(types: !23)
57+
!23 = !{!7, !7}
58+
!24 = !DILocation(line: 5, column: 1, scope: !21)
59+
!25 = distinct !DISubprogram(name: "dev_func2", linkageName: "dev_func2", scope: !9, file: !9, line: 22, type: !17, scopeLine: 22, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !8, retainedNodes: !2)
60+
!26 = !DILocation(line: 29, column: 5, scope: !25)
61+

0 commit comments

Comments
 (0)