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:
parent
af435f4dd3
commit
dae138eca8
@ -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);
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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]);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user