1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[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
This commit is contained in:
Teresa Johnson 2019-12-26 09:31:43 -08:00
parent af435f4dd3
commit dae138eca8
9 changed files with 44 additions and 17 deletions

View File

@ -757,9 +757,10 @@ private:
public: public:
struct GVarFlags { struct GVarFlags {
GVarFlags(bool ReadOnly, bool WriteOnly, bool Constant) GVarFlags(bool ReadOnly, bool WriteOnly, bool Constant,
GlobalObject::VCallVisibility Vis)
: MaybeReadOnly(ReadOnly), MaybeWriteOnly(WriteOnly), : MaybeReadOnly(ReadOnly), MaybeWriteOnly(WriteOnly),
Constant(Constant) {} Constant(Constant), VCallVisibility(Vis) {}
// If true indicates that this global variable might be accessed // If true indicates that this global variable might be accessed
// purely by non-volatile load instructions. This in turn means // purely by non-volatile load instructions. This in turn means
@ -780,6 +781,9 @@ public:
// opportunity to make some extra optimizations. Readonly constants // opportunity to make some extra optimizations. Readonly constants
// are also internalized. // are also internalized.
unsigned Constant : 1; unsigned Constant : 1;
// Set from metadata on vtable definitions during the module summary
// analysis.
unsigned VCallVisibility : 2;
} VarFlags; } VarFlags;
GlobalVarSummary(GVFlags Flags, GVarFlags VarFlags, GlobalVarSummary(GVFlags Flags, GVarFlags VarFlags,
@ -798,6 +802,12 @@ public:
bool maybeReadOnly() const { return VarFlags.MaybeReadOnly; } bool maybeReadOnly() const { return VarFlags.MaybeReadOnly; }
bool maybeWriteOnly() const { return VarFlags.MaybeWriteOnly; } bool maybeWriteOnly() const { return VarFlags.MaybeWriteOnly; }
bool isConstant() const { return VarFlags.Constant; } bool isConstant() const { return VarFlags.Constant; }
void setVCallVisibility(GlobalObject::VCallVisibility Vis) {
VarFlags.VCallVisibility = Vis;
}
GlobalObject::VCallVisibility getVCallVisibility() const {
return (GlobalObject::VCallVisibility)VarFlags.VCallVisibility;
}
void setVTableFuncs(VTableFuncList Funcs) { void setVTableFuncs(VTableFuncList Funcs) {
assert(!VTableFuncs); assert(!VTableFuncs);

View File

@ -600,8 +600,9 @@ static void computeVariableSummary(ModuleSummaryIndex &Index,
!V.hasComdat() && !V.hasAppendingLinkage() && !V.isInterposable() && !V.hasComdat() && !V.hasAppendingLinkage() && !V.isInterposable() &&
!V.hasAvailableExternallyLinkage() && !V.hasDLLExportStorageClass(); !V.hasAvailableExternallyLinkage() && !V.hasDLLExportStorageClass();
bool Constant = V.isConstant(); bool Constant = V.isConstant();
GlobalVarSummary::GVarFlags VarFlags( GlobalVarSummary::GVarFlags VarFlags(CanBeInternalized,
CanBeInternalized, Constant ? false : CanBeInternalized, Constant); Constant ? false : CanBeInternalized,
Constant, V.getVCallVisibility());
auto GVarSummary = std::make_unique<GlobalVarSummary>(Flags, VarFlags, auto GVarSummary = std::make_unique<GlobalVarSummary>(Flags, VarFlags,
RefEdges.takeVector()); RefEdges.takeVector());
if (NonRenamableLocal) if (NonRenamableLocal)
@ -722,7 +723,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
std::make_unique<GlobalVarSummary>( std::make_unique<GlobalVarSummary>(
GVFlags, GVFlags,
GlobalVarSummary::GVarFlags( GlobalVarSummary::GVarFlags(
false, false, cast<GlobalVariable>(GV)->isConstant()), false, false, cast<GlobalVariable>(GV)->isConstant(),
GlobalObject::VCallVisibilityPublic),
ArrayRef<ValueInfo>{}); ArrayRef<ValueInfo>{});
Index.addGlobalValueSummary(*GV, std::move(Summary)); Index.addGlobalValueSummary(*GV, std::move(Summary));
} }

View File

@ -788,6 +788,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(sizeM1); KEYWORD(sizeM1);
KEYWORD(bitMask); KEYWORD(bitMask);
KEYWORD(inlineBits); KEYWORD(inlineBits);
KEYWORD(vcall_visibility);
KEYWORD(wpdResolutions); KEYWORD(wpdResolutions);
KEYWORD(wpdRes); KEYWORD(wpdRes);
KEYWORD(indir); KEYWORD(indir);

View File

@ -8154,7 +8154,8 @@ bool LLParser::ParseVariableSummary(std::string Name, GlobalValue::GUID GUID,
/*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false); /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false, GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false,
/* WriteOnly */ false, /* WriteOnly */ false,
/* Constant */ false); /* Constant */ false,
GlobalObject::VCallVisibilityPublic);
std::vector<ValueInfo> Refs; std::vector<ValueInfo> Refs;
VTableFuncList VTableFuncs; VTableFuncList VTableFuncs;
if (ParseToken(lltok::colon, "expected ':' here") || if (ParseToken(lltok::colon, "expected ':' here") ||
@ -8861,6 +8862,11 @@ bool LLParser::ParseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) {
return true; return true;
GVarFlags.Constant = Flag; GVarFlags.Constant = Flag;
break; break;
case lltok::kw_vcall_visibility:
if (ParseRest(Flag))
return true;
GVarFlags.VCallVisibility = Flag;
break;
default: default:
return Error(Lex.getLoc(), "expected gvar flag type"); return Error(Lex.getLoc(), "expected gvar flag type");
} }

View File

@ -421,6 +421,7 @@ enum Kind {
kw_sizeM1, kw_sizeM1,
kw_bitMask, kw_bitMask,
kw_inlineBits, kw_inlineBits,
kw_vcall_visibility,
kw_wpdResolutions, kw_wpdResolutions,
kw_wpdRes, kw_wpdRes,
kw_indir, kw_indir,

View File

@ -985,9 +985,10 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags,
// Decode the flags for GlobalVariable in the summary // Decode the flags for GlobalVariable in the summary
static GlobalVarSummary::GVarFlags getDecodedGVarFlags(uint64_t RawFlags) { static GlobalVarSummary::GVarFlags getDecodedGVarFlags(uint64_t RawFlags) {
return GlobalVarSummary::GVarFlags((RawFlags & 0x1) ? true : false, return GlobalVarSummary::GVarFlags(
(RawFlags & 0x2) ? true : false, (RawFlags & 0x1) ? true : false, (RawFlags & 0x2) ? true : false,
(RawFlags & 0x4) ? true : false); (RawFlags & 0x4) ? true : false,
(GlobalObject::VCallVisibility)(RawFlags >> 3));
} }
static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) { static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) {
@ -5969,7 +5970,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
unsigned RefArrayStart = 2; unsigned RefArrayStart = 2;
GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false, GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false,
/* WriteOnly */ false, /* WriteOnly */ false,
/* Constant */ false); /* Constant */ false,
GlobalObject::VCallVisibilityPublic);
auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
if (Version >= 5) { if (Version >= 5) {
GVF = getDecodedGVarFlags(Record[2]); GVF = getDecodedGVarFlags(Record[2]);
@ -6106,7 +6108,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
unsigned RefArrayStart = 3; unsigned RefArrayStart = 3;
GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false, GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false,
/* WriteOnly */ false, /* WriteOnly */ false,
/* Constant */ false); /* Constant */ false,
GlobalObject::VCallVisibilityPublic);
auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); auto Flags = getDecodedGVSummaryFlags(RawFlags, Version);
if (Version >= 5) { if (Version >= 5) {
GVF = getDecodedGVarFlags(Record[3]); GVF = getDecodedGVarFlags(Record[3]);

View File

@ -1028,8 +1028,8 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) {
} }
static uint64_t getEncodedGVarFlags(GlobalVarSummary::GVarFlags Flags) { static uint64_t getEncodedGVarFlags(GlobalVarSummary::GVarFlags Flags) {
uint64_t RawFlags = uint64_t RawFlags = Flags.MaybeReadOnly | (Flags.MaybeWriteOnly << 1) |
Flags.MaybeReadOnly | (Flags.MaybeWriteOnly << 1) | (Flags.Constant << 2); (Flags.Constant << 2) | Flags.VCallVisibility << 3;
return RawFlags; return RawFlags;
} }

View File

@ -2900,11 +2900,15 @@ void AssemblyWriter::printAliasSummary(const AliasSummary *AS) {
} }
void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) { void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) {
auto VTableFuncs = GS->vTableFuncs();
Out << ", varFlags: (readonly: " << GS->VarFlags.MaybeReadOnly << ", " Out << ", varFlags: (readonly: " << GS->VarFlags.MaybeReadOnly << ", "
<< "writeonly: " << GS->VarFlags.MaybeWriteOnly << ", " << "writeonly: " << GS->VarFlags.MaybeWriteOnly << ", "
<< "constant: " << GS->VarFlags.Constant << ")"; << "constant: " << GS->VarFlags.Constant;
if (!VTableFuncs.empty())
Out << ", "
<< "vcall_visibility: " << GS->VarFlags.VCallVisibility;
Out << ")";
auto VTableFuncs = GS->vTableFuncs();
if (!VTableFuncs.empty()) { if (!VTableFuncs.empty()) {
Out << ", vTableFuncs: ("; Out << ", vTableFuncs: (";
FieldSeparator FS; FieldSeparator FS;

View File

@ -29,9 +29,9 @@ declare i32 @_ZN1C1fEi(%struct.C*, i32)
^0 = module: (path: "<stdin>", hash: (0, 0, 0, 0, 0)) ^0 = module: (path: "<stdin>", hash: (0, 0, 0, 0, 0))
^1 = gv: (name: "_ZN1A1nEi") ; guid = 1621563287929432257 ^1 = gv: (name: "_ZN1A1nEi") ; guid = 1621563287929432257
^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 ^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
^3 = gv: (name: "_ZN1B1fEi") ; guid = 7162046368816414394 ^3 = gv: (name: "_ZN1B1fEi") ; guid = 7162046368816414394
^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 ^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
^5 = gv: (name: "_ZN1C1fEi") ; guid = 14876272565662207556 ^5 = gv: (name: "_ZN1C1fEi") ; guid = 14876272565662207556
^6 = typeidCompatibleVTable: (name: "_ZTS1A", summary: ((offset: 16, ^2), (offset: 16, ^4))) ; guid = 7004155349499253778 ^6 = typeidCompatibleVTable: (name: "_ZTS1A", summary: ((offset: 16, ^2), (offset: 16, ^4))) ; guid = 7004155349499253778
^7 = typeidCompatibleVTable: (name: "_ZTS1B", summary: ((offset: 16, ^2))) ; guid = 6203814149063363976 ^7 = typeidCompatibleVTable: (name: "_ZTS1B", summary: ((offset: 16, ^2))) ; guid = 6203814149063363976