Skip to content

Commit 40f913c

Browse files
Propagate ExportDynamic from base type to compatible derived types in
WPD.
1 parent e9fc768 commit 40f913c

File tree

3 files changed

+133
-1
lines changed

3 files changed

+133
-1
lines changed

llvm/lib/LTO/LTO.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1905,7 +1905,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
19051905
auto IsVisibleToRegularObj = [&](StringRef name) {
19061906
auto It = GlobalResolutions->find(name);
19071907
return (It == GlobalResolutions->end() ||
1908-
It->second.VisibleOutsideSummary);
1908+
It->second.VisibleOutsideSummary || It->second.ExportDynamic);
19091909
};
19101910

19111911
getVisibleToRegularObjVtableGUIDs(ThinLTO.CombinedIndex,
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
; RUN: rm -rf %t && mkdir %t && cd %t
2+
3+
; Generate unsplit module with summary for ThinLTO index-based WPD.
4+
; RUN: opt -thinlto-bc -o summary.o %s
5+
6+
; RUN: llvm-dis -o - summary.o
7+
8+
;; TODO: Implement the fix for WPD in regular or hybrid LTO, and add test coverage.
9+
10+
; Index based WPD
11+
; For `_ZTI7Derived`, the 'llvm-lto2' resolution arguments specifies `VisibleOutsideSummary` as false
12+
; and `ExportDynamic` as false. The callsite inside @_ZN4Base8dispatchEv
13+
; got devirtualized.
14+
; RUN: llvm-lto2 run summary.o -save-temps -pass-remarks=. \
15+
; RUN: -o tmp \
16+
; RUN: --whole-program-visibility-enabled-in-lto=true \
17+
; RUN: --validate-all-vtables-have-type-infos=true \
18+
; RUN: --all-vtables-have-type-infos=true \
19+
; RUN: -r=summary.o,__cxa_pure_virtual, \
20+
; RUN: -r=summary.o,_ZN8DerivedNC2Ev,x \
21+
; RUN: -r=summary.o,_ZN4Base8dispatchEv,px \
22+
; RUN: -r=summary.o,_ZN7DerivedC2Ev, \
23+
; RUN: -r=summary.o,_ZN8DerivedN5printEv,px \
24+
; RUN: -r=summary.o,_ZTS4Base, \
25+
; RUN: -r=summary.o,_ZTV8DerivedN,p \
26+
; RUN: -r=summary.o,_ZTI8DerivedN,p \
27+
; RUN: -r=summary.o,_ZTI4Base, \
28+
; RUN: -r=summary.o,_ZTS8DerivedN,p \
29+
; RUN: -r=summary.o,_ZTI7Derived, \
30+
; RUN: -r=summary.o,_ZTV4Base 2>&1 | FileCheck --allow-empty %s --check-prefix=REMARK
31+
32+
; REMARK: single-impl: devirtualized a call to _ZN8DerivedN5printEv
33+
34+
; Index based WPD
35+
; For `_ZTI7Derived`, the 'llvm-lto2' resolution arguments specifies `VisibleOutsideSummary` as false
36+
; and `ExportDynamic` as true. The callsite inside @_ZN4Base8dispatchEv won't
37+
; get devirtualized.
38+
; RUN: llvm-lto2 run summary.o -save-temps -pass-remarks=. \
39+
; RUN: -o tmp \
40+
; RUN: --whole-program-visibility-enabled-in-lto=true \
41+
; RUN: --validate-all-vtables-have-type-infos=true \
42+
; RUN: --all-vtables-have-type-infos=true \
43+
; RUN: -r=summary.o,__cxa_pure_virtual, \
44+
; RUN: -r=summary.o,_ZN8DerivedNC2Ev,x \
45+
; RUN: -r=summary.o,_ZN4Base8dispatchEv,px \
46+
; RUN: -r=summary.o,_ZN7DerivedC2Ev, \
47+
; RUN: -r=summary.o,_ZN8DerivedN5printEv,px \
48+
; RUN: -r=summary.o,_ZTS4Base, \
49+
; RUN: -r=summary.o,_ZTV8DerivedN,p \
50+
; RUN: -r=summary.o,_ZTI8DerivedN,p \
51+
; RUN: -r=summary.o,_ZTI4Base, \
52+
; RUN: -r=summary.o,_ZTS8DerivedN,p \
53+
; RUN: -r=summary.o,_ZTI7Derived,d \
54+
; RUN: -r=summary.o,_ZTV4Base 2>&1 | FileCheck %s --allow-empty --implicit-check-not='single-impl: devirtualized a call to'
55+
56+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
57+
target triple = "x86_64-unknown-linux-gnu"
58+
59+
@_ZTV8DerivedN = linkonce_odr hidden constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTI8DerivedN, ptr @_ZN8DerivedN5printEv] }, !type !0, !type !1, !type !2, !type !3, !type !4, !type !5, !vcall_visibility !6
60+
@_ZTI8DerivedN = linkonce_odr hidden constant { ptr, ptr, ptr } { ptr null, ptr @_ZTS8DerivedN, ptr @_ZTI7Derived }
61+
@_ZTS8DerivedN = linkonce_odr hidden constant [10 x i8] c"8DerivedN\00", align 1
62+
@_ZTI7Derived = external constant ptr
63+
@_ZTV4Base = linkonce_odr hidden constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTI4Base, ptr @__cxa_pure_virtual] }, !type !0, !type !1, !vcall_visibility !6
64+
@_ZTI4Base = linkonce_odr hidden constant { ptr, ptr } { ptr null, ptr @_ZTS4Base }
65+
@_ZTS4Base = linkonce_odr hidden constant [6 x i8] c"4Base\00", align 1
66+
67+
@llvm.used = appending global [1 x ptr] [ptr @_ZN8DerivedNC2Ev], section "llvm.metadata"
68+
69+
define hidden void @_ZN4Base8dispatchEv(ptr %this) {
70+
entry:
71+
%this.addr = alloca ptr
72+
store ptr %this, ptr %this.addr
73+
%this1 = load ptr, ptr %this.addr
74+
%vtable = load ptr, ptr %this1
75+
%0 = call i1 @llvm.type.test(ptr %vtable, metadata !"_ZTS7Derived")
76+
call void @llvm.assume(i1 %0)
77+
%vfn = getelementptr inbounds ptr, ptr %vtable, i64 0
78+
%1 = load ptr, ptr %vfn
79+
call void %1(ptr %this1)
80+
ret void
81+
}
82+
83+
define linkonce_odr hidden void @_ZN8DerivedNC2Ev(ptr %this) #0 {
84+
entry:
85+
%this.addr = alloca ptr
86+
store ptr %this, ptr %this.addr
87+
%this1 = load ptr, ptr %this.addr
88+
call void @_ZN7DerivedC2Ev(ptr %this1)
89+
store ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTV8DerivedN, i32 0, i32 0, i32 2), ptr %this1
90+
ret void
91+
}
92+
93+
define linkonce_odr hidden void @_ZN8DerivedN5printEv(ptr %this) #0 {
94+
entry:
95+
ret void
96+
}
97+
98+
attributes #0 = { noinline optnone }
99+
100+
declare void @__cxa_pure_virtual()
101+
declare i1 @llvm.type.test(ptr, metadata)
102+
declare void @llvm.assume(i1)
103+
declare void @_ZN7DerivedC2Ev(ptr)
104+
105+
!0 = !{i64 16, !"_ZTS4Base"}
106+
!1 = !{i64 16, !"_ZTSM4BaseFvvE.virtual"}
107+
!2 = !{i64 16, !"_ZTS7Derived"}
108+
!3 = !{i64 16, !"_ZTSM7DerivedFvvE.virtual"}
109+
!4 = !{i64 16, !"_ZTS8DerivedN"}
110+
!5 = !{i64 16, !"_ZTSM8DerivedNFvvE.virtual"}
111+
!6 = !{i64 0}

llvm/tools/llvm-lto2/llvm-lto2.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,18 @@ static cl::opt<bool> EnableFreestanding(
187187
cl::desc("Enable Freestanding (disable builtins / TLI) during LTO"),
188188
cl::Hidden);
189189

190+
static cl::opt<bool> WholeProgramVisibilityEnabledInLTO(
191+
"whole-program-visibility-enabled-in-lto",
192+
cl::desc("Enable whole program visibility during LTO"), cl::Hidden);
193+
194+
static cl::opt<bool> ValidateAllVtablesHaveTypeInfos(
195+
"validate-all-vtables-have-type-infos",
196+
cl::desc("Validate that all vtables have type infos in LTO"), cl::Hidden);
197+
198+
static cl::opt<bool>
199+
AllVtablesHaveTypeInfos("all-vtables-have-type-infos", cl::Hidden,
200+
cl::desc("All vtables have type infos"));
201+
190202
extern cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInfoFormat;
191203
extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat;
192204

@@ -257,6 +269,8 @@ static int run(int argc, char **argv) {
257269
Res.VisibleToRegularObj = true;
258270
else if (C == 'r')
259271
Res.LinkerRedefined = true;
272+
else if (C == 'd')
273+
Res.ExportDynamic = true;
260274
else {
261275
llvm::errs() << "invalid character " << C << " in resolution: " << R
262276
<< '\n';
@@ -332,6 +346,13 @@ static int run(int argc, char **argv) {
332346
Conf.PTO.LoopVectorization = Conf.OptLevel > 1;
333347
Conf.PTO.SLPVectorization = Conf.OptLevel > 1;
334348

349+
if (WholeProgramVisibilityEnabledInLTO.getNumOccurrences() > 0)
350+
Conf.HasWholeProgramVisibility = WholeProgramVisibilityEnabledInLTO;
351+
if (ValidateAllVtablesHaveTypeInfos.getNumOccurrences() > 0)
352+
Conf.ValidateAllVtablesHaveTypeInfos = ValidateAllVtablesHaveTypeInfos;
353+
if (AllVtablesHaveTypeInfos.getNumOccurrences() > 0)
354+
Conf.AllVtablesHaveTypeInfos = AllVtablesHaveTypeInfos;
355+
335356
ThinBackend Backend;
336357
if (ThinLTODistributedIndexes)
337358
Backend = createWriteIndexesThinBackend(llvm::hardware_concurrency(Threads),

0 commit comments

Comments
 (0)