llvm.org GIT mirror llvm / e025bc2
[ThinLTO] only emit used or referenced CFI records to index Summary: We emit CFI_FUNCTION_DEFS and CFI_FUNCTION_DECLS to distributed ThinLTO indices to implement indirect function call checking. This change causes us to only emit entries for functions that are either defined or used by the module we're writing the index for (instead of all functions in the combined index), which can make the indices substantially smaller. Fixes PR42378. Reviewers: pcc, vitalybuka, eugenis Subscribers: mehdi_amini, hiraditya, dexonsmith, arphaman, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63887 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365537 91177308-0d34-0410-b5e6-96231b3b80d8 Bob Haarman a month ago
3 changed file(s) with 104 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
39723972 NameVals.clear();
39733973 };
39743974
3975 std::set DefOrUseGUIDs;
39753976 forEachSummary([&](GVInfo I, bool IsAliasee) {
39763977 GlobalValueSummary *S = I.second;
39773978 assert(S);
3979 DefOrUseGUIDs.insert(I.first);
3980 for (const ValueInfo &VI : S->refs())
3981 DefOrUseGUIDs.insert(VI.getGUID());
39783982
39793983 auto ValueId = getValueId(I.first);
39803984 assert(ValueId);
41194123
41204124 if (!Index.cfiFunctionDefs().empty()) {
41214125 for (auto &S : Index.cfiFunctionDefs()) {
4122 NameVals.push_back(StrtabBuilder.add(S));
4123 NameVals.push_back(S.size());
4124 }
4125 Stream.EmitRecord(bitc::FS_CFI_FUNCTION_DEFS, NameVals);
4126 NameVals.clear();
4126 if (DefOrUseGUIDs.count(
4127 GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S)))) {
4128 NameVals.push_back(StrtabBuilder.add(S));
4129 NameVals.push_back(S.size());
4130 }
4131 }
4132 if (!NameVals.empty()) {
4133 Stream.EmitRecord(bitc::FS_CFI_FUNCTION_DEFS, NameVals);
4134 NameVals.clear();
4135 }
41274136 }
41284137
41294138 if (!Index.cfiFunctionDecls().empty()) {
41304139 for (auto &S : Index.cfiFunctionDecls()) {
4131 NameVals.push_back(StrtabBuilder.add(S));
4132 NameVals.push_back(S.size());
4133 }
4134 Stream.EmitRecord(bitc::FS_CFI_FUNCTION_DECLS, NameVals);
4135 NameVals.clear();
4140 if (DefOrUseGUIDs.count(
4141 GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S)))) {
4142 NameVals.push_back(StrtabBuilder.add(S));
4143 NameVals.push_back(S.size());
4144 }
4145 }
4146 if (!NameVals.empty()) {
4147 Stream.EmitRecord(bitc::FS_CFI_FUNCTION_DECLS, NameVals);
4148 NameVals.clear();
4149 }
41364150 }
41374151
41384152 // Walk the GUIDs that were referenced, and write the
0 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
1 target triple = "x86_64-unknown-linux-gnu"
2
3 declare !type !0 i8 @bar(i8*)
4 declare i1 @llvm.type.test(i8* %ptr, metadata %type) nounwind readnone
5
6 define i8 @baz(i8* %p) !type !0 {
7 %x = call i1 @llvm.type.test(i8* %p, metadata !"t1")
8 %1 = select i1 %x, i8 0, i8 3
9 ret i8 %1
10 }
11
12 define i8 @qux(i8* %p) !type !0 {
13 %x = call i1 @llvm.type.test(i8* %p, metadata !"t1")
14 ret i8 4
15 }
16
17 define i8 @g(i1 %i, i8* %p) {
18 %1 = select i1 %i, i8(i8*)* @bar, i8(i8*)* @qux
19 %2 = call i8 %1(i8* %p)
20 ret i8 %2
21 }
22
23 !0 = !{i64 0, !"t1"}
0 ; Verifies that only functions defined or used by each module make it into the
1 ; CFI functions sets in that module's distributed index.
2 ; RUN: opt -thinlto-bc -thinlto-split-lto-unit %s -o %t1.bc
3 ; RUN: opt -thinlto-bc -thinlto-split-lto-unit %S/Inputs/cfi-icall-only-bazqux.ll -o %t2.bc
4 ; RUN: llvm-lto2 run -thinlto-distributed-indexes %t1.bc %t2.bc -o %t.out \
5 ; RUN: -r %t1.bc,bar,plx \
6 ; RUN: -r %t1.bc,baz,x \
7 ; RUN: -r %t1.bc,f,plx \
8 ; RUN: -r %t1.bc,foo,plx \
9 ; RUN: -r %t2.bc,bar,x \
10 ; RUN: -r %t2.bc,baz,plx \
11 ; RUN: -r %t2.bc,g,plx \
12 ; RUN: -r %t2.bc,qux,plx
13 ; RUN: llvm-bcanalyzer -dump %t1.bc.thinlto.bc | FileCheck %s --check-prefix=FOOBAZ
14 ; RUN: llvm-bcanalyzer -dump %t2.bc.thinlto.bc | FileCheck %s --check-prefix=BARQUX
15
16 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
17 target triple = "x86_64-unknown-linux-gnu"
18
19 declare !type !0 i8 @baz(i8*)
20 declare i1 @llvm.type.test(i8* %ptr, metadata %type) nounwind readnone
21
22 define i8 @foo(i8* %p) !type !0 {
23 %x = call i1 @llvm.type.test(i8* %p, metadata !"t1")
24 %1 = select i1 %x, i8 0, i8 1
25 ret i8 %1
26 }
27
28 define i8 @bar(i8* %p) !type !0 {
29 %x = call i1 @llvm.type.test(i8* %p, metadata !"t1")
30 ret i8 2
31 }
32
33 define i8 @f(i1 %i, i8* %p) {
34 %1 = select i1 %i, i8(i8*)* @foo, i8(i8*)* @baz
35 %2 = call i8 %1(i8* %p)
36 ret i8 %2
37 }
38
39 !0 = !{i64 0, !"t1"}
40
41 ; FOOBAZ:
42 ; FOOBAZ:
43 ; FOOBAZ:
44 ; FOOBAZ:
45 ; FOOBAZ:
46 ; FOOBAZ-NEXT: blob data = 'barbazfoot1'
47 ; FOOBAZ-NEXT:
48
49 ; BARQUX:
50 ; BARQUX:
51 ; BARQUX:
52 ; BARQUX:
53 ; BARQUX:
54 ; BARQUX-NEXT: blob data = 'barbazquxt1'
55 ; BARQUX-NEXT: