mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-09 13:55:22 +00:00
[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 llvm-svn: 365537
This commit is contained in:
parent
8fea1df72a
commit
f4fcc00e4d
@ -3973,9 +3973,13 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
||||
NameVals.clear();
|
||||
};
|
||||
|
||||
std::set<GlobalValue::GUID> DefOrUseGUIDs;
|
||||
forEachSummary([&](GVInfo I, bool IsAliasee) {
|
||||
GlobalValueSummary *S = I.second;
|
||||
assert(S);
|
||||
DefOrUseGUIDs.insert(I.first);
|
||||
for (const ValueInfo &VI : S->refs())
|
||||
DefOrUseGUIDs.insert(VI.getGUID());
|
||||
|
||||
auto ValueId = getValueId(I.first);
|
||||
assert(ValueId);
|
||||
@ -4120,20 +4124,30 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() {
|
||||
|
||||
if (!Index.cfiFunctionDefs().empty()) {
|
||||
for (auto &S : Index.cfiFunctionDefs()) {
|
||||
NameVals.push_back(StrtabBuilder.add(S));
|
||||
NameVals.push_back(S.size());
|
||||
if (DefOrUseGUIDs.count(
|
||||
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S)))) {
|
||||
NameVals.push_back(StrtabBuilder.add(S));
|
||||
NameVals.push_back(S.size());
|
||||
}
|
||||
}
|
||||
if (!NameVals.empty()) {
|
||||
Stream.EmitRecord(bitc::FS_CFI_FUNCTION_DEFS, NameVals);
|
||||
NameVals.clear();
|
||||
}
|
||||
Stream.EmitRecord(bitc::FS_CFI_FUNCTION_DEFS, NameVals);
|
||||
NameVals.clear();
|
||||
}
|
||||
|
||||
if (!Index.cfiFunctionDecls().empty()) {
|
||||
for (auto &S : Index.cfiFunctionDecls()) {
|
||||
NameVals.push_back(StrtabBuilder.add(S));
|
||||
NameVals.push_back(S.size());
|
||||
if (DefOrUseGUIDs.count(
|
||||
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(S)))) {
|
||||
NameVals.push_back(StrtabBuilder.add(S));
|
||||
NameVals.push_back(S.size());
|
||||
}
|
||||
}
|
||||
if (!NameVals.empty()) {
|
||||
Stream.EmitRecord(bitc::FS_CFI_FUNCTION_DECLS, NameVals);
|
||||
NameVals.clear();
|
||||
}
|
||||
Stream.EmitRecord(bitc::FS_CFI_FUNCTION_DECLS, NameVals);
|
||||
NameVals.clear();
|
||||
}
|
||||
|
||||
// Walk the GUIDs that were referenced, and write the
|
||||
|
24
test/ThinLTO/X86/Inputs/cfi-icall-only-bazqux.ll
Normal file
24
test/ThinLTO/X86/Inputs/cfi-icall-only-bazqux.ll
Normal file
@ -0,0 +1,24 @@
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
declare !type !0 i8 @bar(i8*)
|
||||
declare i1 @llvm.type.test(i8* %ptr, metadata %type) nounwind readnone
|
||||
|
||||
define i8 @baz(i8* %p) !type !0 {
|
||||
%x = call i1 @llvm.type.test(i8* %p, metadata !"t1")
|
||||
%1 = select i1 %x, i8 0, i8 3
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
define i8 @qux(i8* %p) !type !0 {
|
||||
%x = call i1 @llvm.type.test(i8* %p, metadata !"t1")
|
||||
ret i8 4
|
||||
}
|
||||
|
||||
define i8 @g(i1 %i, i8* %p) {
|
||||
%1 = select i1 %i, i8(i8*)* @bar, i8(i8*)* @qux
|
||||
%2 = call i8 %1(i8* %p)
|
||||
ret i8 %2
|
||||
}
|
||||
|
||||
!0 = !{i64 0, !"t1"}
|
56
test/ThinLTO/X86/cfi-icall-only-defuse.ll
Normal file
56
test/ThinLTO/X86/cfi-icall-only-defuse.ll
Normal file
@ -0,0 +1,56 @@
|
||||
; Verifies that only functions defined or used by each module make it into the
|
||||
; CFI functions sets in that module's distributed index.
|
||||
; RUN: opt -thinlto-bc -thinlto-split-lto-unit %s -o %t1.bc
|
||||
; RUN: opt -thinlto-bc -thinlto-split-lto-unit %S/Inputs/cfi-icall-only-bazqux.ll -o %t2.bc
|
||||
; RUN: llvm-lto2 run -thinlto-distributed-indexes %t1.bc %t2.bc -o %t.out \
|
||||
; RUN: -r %t1.bc,bar,plx \
|
||||
; RUN: -r %t1.bc,baz,x \
|
||||
; RUN: -r %t1.bc,f,plx \
|
||||
; RUN: -r %t1.bc,foo,plx \
|
||||
; RUN: -r %t2.bc,bar,x \
|
||||
; RUN: -r %t2.bc,baz,plx \
|
||||
; RUN: -r %t2.bc,g,plx \
|
||||
; RUN: -r %t2.bc,qux,plx
|
||||
; RUN: llvm-bcanalyzer -dump %t1.bc.thinlto.bc | FileCheck %s --check-prefix=FOOBAZ
|
||||
; RUN: llvm-bcanalyzer -dump %t2.bc.thinlto.bc | FileCheck %s --check-prefix=BARQUX
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
declare !type !0 i8 @baz(i8*)
|
||||
declare i1 @llvm.type.test(i8* %ptr, metadata %type) nounwind readnone
|
||||
|
||||
define i8 @foo(i8* %p) !type !0 {
|
||||
%x = call i1 @llvm.type.test(i8* %p, metadata !"t1")
|
||||
%1 = select i1 %x, i8 0, i8 1
|
||||
ret i8 %1
|
||||
}
|
||||
|
||||
define i8 @bar(i8* %p) !type !0 {
|
||||
%x = call i1 @llvm.type.test(i8* %p, metadata !"t1")
|
||||
ret i8 2
|
||||
}
|
||||
|
||||
define i8 @f(i1 %i, i8* %p) {
|
||||
%1 = select i1 %i, i8(i8*)* @foo, i8(i8*)* @baz
|
||||
%2 = call i8 %1(i8* %p)
|
||||
ret i8 %2
|
||||
}
|
||||
|
||||
!0 = !{i64 0, !"t1"}
|
||||
|
||||
; FOOBAZ: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; FOOBAZ: <CFI_FUNCTION_DEFS op0=0 op1=3 op2=3 op3=3 op4=6 op5=3/>
|
||||
; FOOBAZ: <TYPE_ID op0=9 op1=2 op2=4 op3=7 op4=0 op5=0 op6=0 op7=0/>
|
||||
; FOOBAZ: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
; FOOBAZ: <STRTAB_BLOCK
|
||||
; FOOBAZ-NEXT: <BLOB abbrevid=4/> blob data = 'barbazfoot1'
|
||||
; FOOBAZ-NEXT: </STRTAB_BLOCK>
|
||||
|
||||
; BARQUX: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; BARQUX: <CFI_FUNCTION_DEFS op0=0 op1=3 op2=3 op3=3 op4=6 op5=3/>
|
||||
; BARQUX: <TYPE_ID op0=9 op1=2 op2=4 op3=7 op4=0 op5=0 op6=0 op7=0/>
|
||||
; BARQUX: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
; BARQUX: <STRTAB_BLOCK
|
||||
; BARQUX-NEXT: <BLOB abbrevid=4/> blob data = 'barbazquxt1'
|
||||
; BARQUX-NEXT: </STRTAB_BLOCK>
|
Loading…
x
Reference in New Issue
Block a user