Skip to content

Commit 9c2eb22

Browse files
committed
[ThinLTO] Summarize vcall_visibility metadata
Summary: Second patch in series to support Safe Whole Program Devirtualization Enablement, see RFC here: http://lists.llvm.org/pipermail/llvm-dev/2019-December/137543.html Summarize vcall_visibility metadata in ThinLTO global variable summary. Depends on D71907. Reviewers: pcc, evgeny777, steven_wu Subscribers: mehdi_amini, Prazek, inglorion, hiraditya, dexonsmith, arphaman, ostannard, llvm-commits, cfe-commits, davidxl Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D71911
1 parent cc14de8 commit 9c2eb22

File tree

10 files changed

+55
-17
lines changed

10 files changed

+55
-17
lines changed

clang/test/CodeGenCXX/vcall-visibility-metadata.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -emit-llvm -fvirtual-function-elimination -fwhole-program-vtables -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VFE
22
// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -emit-llvm -fwhole-program-vtables -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOVFE
33

4+
// Check that in ThinLTO we also get vcall_visibility summary entries in the bitcode
5+
// RUN: %clang_cc1 -flto=thin -flto-unit -triple x86_64-unknown-linux -emit-llvm-bc -fwhole-program-vtables -o - %s | llvm-dis -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOVFE --check-prefix=CHECK-SUMMARY
6+
47

58
// Anonymous namespace.
69
namespace {
@@ -88,3 +91,11 @@ void *construct_G() {
8891
// CHECK-DAG: [[VIS_TU]] = !{i64 2}
8992
// CHECK-VFE-DAG: !{i32 1, !"Virtual Function Elim", i32 1}
9093
// CHECK-NOVFE-DAG: !{i32 1, !"Virtual Function Elim", i32 0}
94+
95+
// CHECK-SUMMARY-DAG: gv: (name: "_ZTV1B", {{.*}} vcall_visibility: 1
96+
// CHECK-SUMMARY-DAG: gv: (name: "_ZTVN12_GLOBAL__N_11FE", {{.*}} vcall_visibility: 0
97+
// CHECK-SUMMARY-DAG: gv: (name: "_ZTV1D", {{.*}} vcall_visibility: 0
98+
// CHECK-SUMMARY-DAG: gv: (name: "_ZTV1C", {{.*}} vcall_visibility: 0
99+
// CHECK-SUMMARY-DAG: gv: (name: "_ZTV1E", {{.*}} vcall_visibility: 0
100+
// CHECK-SUMMARY-DAG: gv: (name: "_ZTVN12_GLOBAL__N_11AE", {{.*}} vcall_visibility: 2
101+
// CHECK-SUMMARY-DAG: gv: (name: "_ZTVN12_GLOBAL__N_11GE", {{.*}} vcall_visibility: 1

llvm/include/llvm/IR/ModuleSummaryIndex.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -757,9 +757,10 @@ class GlobalVarSummary : public GlobalValueSummary {
757757

758758
public:
759759
struct GVarFlags {
760-
GVarFlags(bool ReadOnly, bool WriteOnly, bool Constant)
760+
GVarFlags(bool ReadOnly, bool WriteOnly, bool Constant,
761+
GlobalObject::VCallVisibility Vis)
761762
: MaybeReadOnly(ReadOnly), MaybeWriteOnly(WriteOnly),
762-
Constant(Constant) {}
763+
Constant(Constant), VCallVisibility(Vis) {}
763764

764765
// If true indicates that this global variable might be accessed
765766
// purely by non-volatile load instructions. This in turn means
@@ -780,6 +781,9 @@ class GlobalVarSummary : public GlobalValueSummary {
780781
// opportunity to make some extra optimizations. Readonly constants
781782
// are also internalized.
782783
unsigned Constant : 1;
784+
// Set from metadata on vtable definitions during the module summary
785+
// analysis.
786+
unsigned VCallVisibility : 2;
783787
} VarFlags;
784788

785789
GlobalVarSummary(GVFlags Flags, GVarFlags VarFlags,
@@ -798,6 +802,12 @@ class GlobalVarSummary : public GlobalValueSummary {
798802
bool maybeReadOnly() const { return VarFlags.MaybeReadOnly; }
799803
bool maybeWriteOnly() const { return VarFlags.MaybeWriteOnly; }
800804
bool isConstant() const { return VarFlags.Constant; }
805+
void setVCallVisibility(GlobalObject::VCallVisibility Vis) {
806+
VarFlags.VCallVisibility = Vis;
807+
}
808+
GlobalObject::VCallVisibility getVCallVisibility() const {
809+
return (GlobalObject::VCallVisibility)VarFlags.VCallVisibility;
810+
}
801811

802812
void setVTableFuncs(VTableFuncList Funcs) {
803813
assert(!VTableFuncs);

llvm/lib/Analysis/ModuleSummaryAnalysis.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,8 +600,9 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
600600
!V.hasComdat() && !V.hasAppendingLinkage() && !V.isInterposable() &&
601601
!V.hasAvailableExternallyLinkage() && !V.hasDLLExportStorageClass();
602602
bool Constant = V.isConstant();
603-
GlobalVarSummary::GVarFlags VarFlags(
604-
CanBeInternalized, Constant ? false : CanBeInternalized, Constant);
603+
GlobalVarSummary::GVarFlags VarFlags(CanBeInternalized,
604+
Constant ? false : CanBeInternalized,
605+
Constant, V.getVCallVisibility());
605606
auto GVarSummary = std::make_unique<GlobalVarSummary>(Flags, VarFlags,
606607
RefEdges.takeVector());
607608
if (NonRenamableLocal)
@@ -722,7 +723,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
722723
std::make_unique<GlobalVarSummary>(
723724
GVFlags,
724725
GlobalVarSummary::GVarFlags(
725-
false, false, cast<GlobalVariable>(GV)->isConstant()),
726+
false, false, cast<GlobalVariable>(GV)->isConstant(),
727+
GlobalObject::VCallVisibilityPublic),
726728
ArrayRef<ValueInfo>{});
727729
Index.addGlobalValueSummary(*GV, std::move(Summary));
728730
}

llvm/lib/AsmParser/LLLexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,7 @@ lltok::Kind LLLexer::LexIdentifier() {
788788
KEYWORD(sizeM1);
789789
KEYWORD(bitMask);
790790
KEYWORD(inlineBits);
791+
KEYWORD(vcall_visibility);
791792
KEYWORD(wpdResolutions);
792793
KEYWORD(wpdRes);
793794
KEYWORD(indir);

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8154,7 +8154,8 @@ bool LLParser::ParseVariableSummary(std::string Name, GlobalValue::GUID GUID,
81548154
/*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
81558155
GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false,
81568156
/* WriteOnly */ false,
8157-
/* Constant */ false);
8157+
/* Constant */ false,
8158+
GlobalObject::VCallVisibilityPublic);
81588159
std::vector<ValueInfo> Refs;
81598160
VTableFuncList VTableFuncs;
81608161
if (ParseToken(lltok::colon, "expected ':' here") ||
@@ -8861,6 +8862,11 @@ bool LLParser::ParseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) {
88618862
return true;
88628863
GVarFlags.Constant = Flag;
88638864
break;
8865+
case lltok::kw_vcall_visibility:
8866+
if (ParseRest(Flag))
8867+
return true;
8868+
GVarFlags.VCallVisibility = Flag;
8869+
break;
88648870
default:
88658871
return Error(Lex.getLoc(), "expected gvar flag type");
88668872
}

llvm/lib/AsmParser/LLToken.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ enum Kind {
421421
kw_sizeM1,
422422
kw_bitMask,
423423
kw_inlineBits,
424+
kw_vcall_visibility,
424425
kw_wpdResolutions,
425426
kw_wpdRes,
426427
kw_indir,

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -985,9 +985,10 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
985985

986986
// Decode the flags for GlobalVariable in the summary
987987
static GlobalVarSummary::GVarFlags getDecodedGVarFlags(uint64_t RawFlags) {
988-
return GlobalVarSummary::GVarFlags((RawFlags & 0x1) ? true : false,
989-
(RawFlags & 0x2) ? true : false,
990-
(RawFlags & 0x4) ? true : false);
988+
return GlobalVarSummary::GVarFlags(
989+
(RawFlags & 0x1) ? true : false, (RawFlags & 0x2) ? true : false,
990+
(RawFlags & 0x4) ? true : false,
991+
(GlobalObject::VCallVisibility)(RawFlags >> 3));
991992
}
992993

993994
static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) {
@@ -5969,7 +5970,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
59695970
unsigned RefArrayStart = 2;
59705971
GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false,
59715972
/* WriteOnly */ false,
5972-
/* Constant */ false);
5973+
/* Constant */ false,
5974+
GlobalObject::VCallVisibilityPublic);
59735975
auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
59745976
if (Version >= 5) {
59755977
GVF = getDecodedGVarFlags(Record[2]);
@@ -6106,7 +6108,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
61066108
unsigned RefArrayStart = 3;
61076109
GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false,
61086110
/* WriteOnly */ false,
6109-
/* Constant */ false);
6111+
/* Constant */ false,
6112+
GlobalObject::VCallVisibilityPublic);
61106113
auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
61116114
if (Version >= 5) {
61126115
GVF = getDecodedGVarFlags(Record[3]);

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,8 +1028,8 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
10281028
}
10291029

10301030
static uint64_t getEncodedGVarFlags(GlobalVarSummary::GVarFlags Flags) {
1031-
uint64_t RawFlags =
1032-
Flags.MaybeReadOnly | (Flags.MaybeWriteOnly << 1) | (Flags.Constant << 2);
1031+
uint64_t RawFlags = Flags.MaybeReadOnly | (Flags.MaybeWriteOnly << 1) |
1032+
(Flags.Constant << 2) | Flags.VCallVisibility << 3;
10331033
return RawFlags;
10341034
}
10351035

llvm/lib/IR/AsmWriter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2900,11 +2900,15 @@ void AssemblyWriter::printAliasSummary(const AliasSummary *AS) {
29002900
}
29012901

29022902
void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) {
2903+
auto VTableFuncs = GS->vTableFuncs();
29032904
Out << ", varFlags: (readonly: " << GS->VarFlags.MaybeReadOnly << ", "
29042905
<< "writeonly: " << GS->VarFlags.MaybeWriteOnly << ", "
2905-
<< "constant: " << GS->VarFlags.Constant << ")";
2906+
<< "constant: " << GS->VarFlags.Constant;
2907+
if (!VTableFuncs.empty())
2908+
Out << ", "
2909+
<< "vcall_visibility: " << GS->VarFlags.VCallVisibility;
2910+
Out << ")";
29062911

2907-
auto VTableFuncs = GS->vTableFuncs();
29082912
if (!VTableFuncs.empty()) {
29092913
Out << ", vTableFuncs: (";
29102914
FieldSeparator FS;

llvm/test/Assembler/thinlto-vtable-summary.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ declare i32 @_ZN1C1fEi(%struct.C*, i32)
2929

3030
^0 = module: (path: "<stdin>", hash: (0, 0, 0, 0, 0))
3131
^1 = gv: (name: "_ZN1A1nEi") ; guid = 1621563287929432257
32-
^2 = gv: (name: "_ZTV1B", summaries: (variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0, constant: 0), vTableFuncs: ((virtFunc: ^3, offset: 16), (virtFunc: ^1, offset: 24)), refs: (^3, ^1)))) ; guid = 5283576821522790367
32+
^2 = gv: (name: "_ZTV1B", summaries: (variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0, constant: 0, vcall_visibility: 0), vTableFuncs: ((virtFunc: ^3, offset: 16), (virtFunc: ^1, offset: 24)), refs: (^3, ^1)))) ; guid = 5283576821522790367
3333
^3 = gv: (name: "_ZN1B1fEi") ; guid = 7162046368816414394
34-
^4 = gv: (name: "_ZTV1C", summaries: (variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0, constant: 0), vTableFuncs: ((virtFunc: ^5, offset: 16), (virtFunc: ^1, offset: 24)), refs: (^1, ^5)))) ; guid = 13624023785555846296
34+
^4 = gv: (name: "_ZTV1C", summaries: (variable: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0, constant: 0, vcall_visibility: 0), vTableFuncs: ((virtFunc: ^5, offset: 16), (virtFunc: ^1, offset: 24)), refs: (^1, ^5)))) ; guid = 13624023785555846296
3535
^5 = gv: (name: "_ZN1C1fEi") ; guid = 14876272565662207556
3636
^6 = typeidCompatibleVTable: (name: "_ZTS1A", summary: ((offset: 16, ^2), (offset: 16, ^4))) ; guid = 7004155349499253778
3737
^7 = typeidCompatibleVTable: (name: "_ZTS1B", summary: ((offset: 16, ^2))) ; guid = 6203814149063363976

0 commit comments

Comments
 (0)