From dae138eca8858c883bc4ae534eba1ffa2baaf6b7 Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Thu, 26 Dec 2019 09:31:43 -0800 Subject: [PATCH] [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 --- include/llvm/IR/ModuleSummaryIndex.h | 14 ++++++++++++-- lib/Analysis/ModuleSummaryAnalysis.cpp | 8 +++++--- lib/AsmParser/LLLexer.cpp | 1 + lib/AsmParser/LLParser.cpp | 8 +++++++- lib/AsmParser/LLToken.h | 1 + lib/Bitcode/Reader/BitcodeReader.cpp | 13 ++++++++----- lib/Bitcode/Writer/BitcodeWriter.cpp | 4 ++-- lib/IR/AsmWriter.cpp | 8 ++++++-- test/Assembler/thinlto-vtable-summary.ll | 4 ++-- 9 files changed, 44 insertions(+), 17 deletions(-) diff --git a/include/llvm/IR/ModuleSummaryIndex.h b/include/llvm/IR/ModuleSummaryIndex.h index 2c635742135..a34f6e38a61 100644 --- a/include/llvm/IR/ModuleSummaryIndex.h +++ b/include/llvm/IR/ModuleSummaryIndex.h @@ -757,9 +757,10 @@ private: public: struct GVarFlags { - GVarFlags(bool ReadOnly, bool WriteOnly, bool Constant) + GVarFlags(bool ReadOnly, bool WriteOnly, bool Constant, + GlobalObject::VCallVisibility Vis) : MaybeReadOnly(ReadOnly), MaybeWriteOnly(WriteOnly), - Constant(Constant) {} + Constant(Constant), VCallVisibility(Vis) {} // If true indicates that this global variable might be accessed // purely by non-volatile load instructions. This in turn means @@ -780,6 +781,9 @@ public: // opportunity to make some extra optimizations. Readonly constants // are also internalized. unsigned Constant : 1; + // Set from metadata on vtable definitions during the module summary + // analysis. + unsigned VCallVisibility : 2; } VarFlags; GlobalVarSummary(GVFlags Flags, GVarFlags VarFlags, @@ -798,6 +802,12 @@ public: bool maybeReadOnly() const { return VarFlags.MaybeReadOnly; } bool maybeWriteOnly() const { return VarFlags.MaybeWriteOnly; } 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) { assert(!VTableFuncs); diff --git a/lib/Analysis/ModuleSummaryAnalysis.cpp b/lib/Analysis/ModuleSummaryAnalysis.cpp index c7a0984ed28..3dddf4b7d60 100644 --- a/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -600,8 +600,9 @@ static void computeVariableSummary(ModuleSummaryIndex &Index, !V.hasComdat() && !V.hasAppendingLinkage() && !V.isInterposable() && !V.hasAvailableExternallyLinkage() && !V.hasDLLExportStorageClass(); bool Constant = V.isConstant(); - GlobalVarSummary::GVarFlags VarFlags( - CanBeInternalized, Constant ? false : CanBeInternalized, Constant); + GlobalVarSummary::GVarFlags VarFlags(CanBeInternalized, + Constant ? false : CanBeInternalized, + Constant, V.getVCallVisibility()); auto GVarSummary = std::make_unique(Flags, VarFlags, RefEdges.takeVector()); if (NonRenamableLocal) @@ -722,7 +723,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( std::make_unique( GVFlags, GlobalVarSummary::GVarFlags( - false, false, cast(GV)->isConstant()), + false, false, cast(GV)->isConstant(), + GlobalObject::VCallVisibilityPublic), ArrayRef{}); Index.addGlobalValueSummary(*GV, std::move(Summary)); } diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index d96b5e0bff5..f7857f4c6d7 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -788,6 +788,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(sizeM1); KEYWORD(bitMask); KEYWORD(inlineBits); + KEYWORD(vcall_visibility); KEYWORD(wpdResolutions); KEYWORD(wpdRes); KEYWORD(indir); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 902b3ec0cfe..4446a9f5e53 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -8154,7 +8154,8 @@ bool LLParser::ParseVariableSummary(std::string Name, GlobalValue::GUID GUID, /*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false); GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false, /* WriteOnly */ false, - /* Constant */ false); + /* Constant */ false, + GlobalObject::VCallVisibilityPublic); std::vector Refs; VTableFuncList VTableFuncs; if (ParseToken(lltok::colon, "expected ':' here") || @@ -8861,6 +8862,11 @@ bool LLParser::ParseGVarFlags(GlobalVarSummary::GVarFlags &GVarFlags) { return true; GVarFlags.Constant = Flag; break; + case lltok::kw_vcall_visibility: + if (ParseRest(Flag)) + return true; + GVarFlags.VCallVisibility = Flag; + break; default: return Error(Lex.getLoc(), "expected gvar flag type"); } diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index e430e0f6faa..1d88c2972f3 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -421,6 +421,7 @@ enum Kind { kw_sizeM1, kw_bitMask, kw_inlineBits, + kw_vcall_visibility, kw_wpdResolutions, kw_wpdRes, kw_indir, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index e89560be5d3..6baa64a465c 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -985,9 +985,10 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, // Decode the flags for GlobalVariable in the summary static GlobalVarSummary::GVarFlags getDecodedGVarFlags(uint64_t RawFlags) { - return GlobalVarSummary::GVarFlags((RawFlags & 0x1) ? true : false, - (RawFlags & 0x2) ? true : false, - (RawFlags & 0x4) ? true : false); + return GlobalVarSummary::GVarFlags( + (RawFlags & 0x1) ? true : false, (RawFlags & 0x2) ? true : false, + (RawFlags & 0x4) ? true : false, + (GlobalObject::VCallVisibility)(RawFlags >> 3)); } static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) { @@ -5969,7 +5970,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { unsigned RefArrayStart = 2; GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false, /* WriteOnly */ false, - /* Constant */ false); + /* Constant */ false, + GlobalObject::VCallVisibilityPublic); auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); if (Version >= 5) { GVF = getDecodedGVarFlags(Record[2]); @@ -6106,7 +6108,8 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { unsigned RefArrayStart = 3; GlobalVarSummary::GVarFlags GVF(/* ReadOnly */ false, /* WriteOnly */ false, - /* Constant */ false); + /* Constant */ false, + GlobalObject::VCallVisibilityPublic); auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); if (Version >= 5) { GVF = getDecodedGVarFlags(Record[3]); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 956bbcd0c43..3f45dfe4f84 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1028,8 +1028,8 @@ static uint64_t getEncodedGVSummaryFlags(GlobalValueSummary::GVFlags Flags) { } static uint64_t getEncodedGVarFlags(GlobalVarSummary::GVarFlags Flags) { - uint64_t RawFlags = - Flags.MaybeReadOnly | (Flags.MaybeWriteOnly << 1) | (Flags.Constant << 2); + uint64_t RawFlags = Flags.MaybeReadOnly | (Flags.MaybeWriteOnly << 1) | + (Flags.Constant << 2) | Flags.VCallVisibility << 3; return RawFlags; } diff --git a/lib/IR/AsmWriter.cpp b/lib/IR/AsmWriter.cpp index 1c57508b586..f0a32407909 100644 --- a/lib/IR/AsmWriter.cpp +++ b/lib/IR/AsmWriter.cpp @@ -2900,11 +2900,15 @@ void AssemblyWriter::printAliasSummary(const AliasSummary *AS) { } void AssemblyWriter::printGlobalVarSummary(const GlobalVarSummary *GS) { + auto VTableFuncs = GS->vTableFuncs(); Out << ", varFlags: (readonly: " << GS->VarFlags.MaybeReadOnly << ", " << "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()) { Out << ", vTableFuncs: ("; FieldSeparator FS; diff --git a/test/Assembler/thinlto-vtable-summary.ll b/test/Assembler/thinlto-vtable-summary.ll index 014955d8ad9..67e7a2f1c93 100644 --- a/test/Assembler/thinlto-vtable-summary.ll +++ b/test/Assembler/thinlto-vtable-summary.ll @@ -29,9 +29,9 @@ declare i32 @_ZN1C1fEi(%struct.C*, i32) ^0 = module: (path: "", hash: (0, 0, 0, 0, 0)) ^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 -^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 ^6 = typeidCompatibleVTable: (name: "_ZTS1A", summary: ((offset: 16, ^2), (offset: 16, ^4))) ; guid = 7004155349499253778 ^7 = typeidCompatibleVTable: (name: "_ZTS1B", summary: ((offset: 16, ^2))) ; guid = 6203814149063363976