diff options
| author | mingmingl <mingmingl@google.com> | 2025-02-18 16:49:20 -0800 |
|---|---|---|
| committer | mingmingl <mingmingl@google.com> | 2025-02-18 16:49:20 -0800 |
| commit | 1e041a32422e8c84b37a387a9559725b9d852ea8 (patch) | |
| tree | 3257af8209f811d1ff85d96f18744b109829435f | |
| parent | 5399782508e9573b0d2f184b151997375a1dfdeb (diff) | |
[ThinLTO][WPD]Skip virtual function entries in combined index when virtual function elimination is offusers/mingmingl-llvm/spr/virtual
| -rw-r--r-- | llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 47 | ||||
| -rw-r--r-- | llvm/test/Assembler/thinlto-vtable-summary-vfe.ll | 31 | ||||
| -rw-r--r-- | llvm/test/Assembler/thinlto-vtable-summary2.ll | 3 |
3 files changed, 62 insertions, 19 deletions
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp index 611d4bfbc69e..18a65da8d1cc 100644 --- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -814,7 +814,7 @@ static void computeVTableFuncs(ModuleSummaryIndex &Index, /// Record vtable definition \p V for each type metadata it references. static void recordTypeIdCompatibleVtableReferences(ModuleSummaryIndex &Index, - const GlobalVariable &V, + const GlobalVariable &V, const bool VFE, SmallVectorImpl<MDNode *> &Types) { for (MDNode *Type : Types) { auto TypeID = Type->getOperand(1).get(); @@ -824,16 +824,21 @@ recordTypeIdCompatibleVtableReferences(ModuleSummaryIndex &Index, cast<ConstantAsMetadata>(Type->getOperand(0))->getValue()) ->getZExtValue(); - if (auto *TypeId = dyn_cast<MDString>(TypeID)) - Index.getOrInsertTypeIdCompatibleVtableSummary(TypeId->getString()) - .push_back({Offset, Index.getOrInsertValueInfo(&V)}); + if (auto *TypeId = dyn_cast<MDString>(TypeID)) { + StringRef TypeIdStr = TypeId->getString(); + // Skip virtual function entries if VFE is not enabled. + if (!VFE && TypeIdStr.ends_with(".virtual")) + continue; + Index.getOrInsertTypeIdCompatibleVtableSummary(TypeIdStr).push_back( + {Offset, Index.getOrInsertValueInfo(&V)}); + } } } static void computeVariableSummary(ModuleSummaryIndex &Index, const GlobalVariable &V, DenseSet<GlobalValue::GUID> &CantBePromoted, - const Module &M, + const Module &M, const bool VFE, SmallVectorImpl<MDNode *> &Types) { SetVector<ValueInfo, SmallVector<ValueInfo, 0>> RefEdges; SmallPtrSet<const User *, 8> Visited; @@ -858,7 +863,7 @@ static void computeVariableSummary(ModuleSummaryIndex &Index, computeVTableFuncs(Index, V, M, VTableFuncs); // Record this vtable definition for each type metadata it references. - recordTypeIdCompatibleVtableReferences(Index, V, Types); + recordTypeIdCompatibleVtableReferences(Index, V, VFE, Types); } } @@ -911,20 +916,25 @@ static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) { Summary->setLive(true); } +// If \p M has a integer module flag with \p Name, returns true if the value is +// non-zero and false if the value is zero. If the module flag does not exist, +// returns \p Default. +static bool getModuleFlag(const Module &M, StringRef Name, + bool Default = false) { + if (auto *MD = mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(Name))) + return MD->getZExtValue() != 0; + return Default; +} + ModuleSummaryIndex llvm::buildModuleSummaryIndex( const Module &M, std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback, ProfileSummaryInfo *PSI, std::function<const StackSafetyInfo *(const Function &F)> GetSSICallback) { assert(PSI); - bool EnableSplitLTOUnit = false; - bool UnifiedLTO = false; - if (auto *MD = mdconst::extract_or_null<ConstantInt>( - M.getModuleFlag("EnableSplitLTOUnit"))) - EnableSplitLTOUnit = MD->getZExtValue(); - if (auto *MD = - mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("UnifiedLTO"))) - UnifiedLTO = MD->getZExtValue(); + const bool EnableSplitLTOUnit = getModuleFlag(M, "EnableSplitLTOUnit"); + const bool UnifiedLTO = getModuleFlag(M, "UnifiedLTO"); + ModuleSummaryIndex Index(/*HaveGVs=*/true, EnableSplitLTOUnit, UnifiedLTO); // Identify the local values in the llvm.used and llvm.compiler.used sets, @@ -1014,10 +1024,7 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( }); } - bool IsThinLTO = true; - if (auto *MD = - mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("ThinLTO"))) - IsThinLTO = MD->getZExtValue(); + const bool IsThinLTO = getModuleFlag(M, "ThinLTO", /*Default=*/true); // Compute summaries for all functions defined in module, and save in the // index. @@ -1042,13 +1049,15 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex( CantBePromoted, IsThinLTO, GetSSICallback); } + const bool VFE = getModuleFlag(M, "Virtual Function Elim"); + // Compute summaries for all variables defined in module, and save in the // index. SmallVector<MDNode *, 2> Types; for (const GlobalVariable &G : M.globals()) { if (G.isDeclaration()) continue; - computeVariableSummary(Index, G, CantBePromoted, M, Types); + computeVariableSummary(Index, G, CantBePromoted, M, VFE, Types); } // Compute summaries for all aliases defined in module, and save in the diff --git a/llvm/test/Assembler/thinlto-vtable-summary-vfe.ll b/llvm/test/Assembler/thinlto-vtable-summary-vfe.ll new file mode 100644 index 000000000000..d47d9b3f29c3 --- /dev/null +++ b/llvm/test/Assembler/thinlto-vtable-summary-vfe.ll @@ -0,0 +1,31 @@ +;; Test that a virtual function has a typeidCompatibleVTable entry when virtual +;; function elimination is enabled. + +; RUN: opt %s -S -module-summary | FileCheck %s + +;; These summary entries should get numbered differently. +; CHECK: ^2 = gv: (name: "_ZTS1A" +; CHECK: ^6 = typeidCompatibleVTable: (name: "_ZTS1A" +; CHECK: typeidCompatibleVTable: (name: "_ZTSM1AFivE.virtual" + +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@_ZTV1A = dso_local unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTI1A, ptr @_ZN1A3fooEv] }, align 8, !type !0, !type !1 +@_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr] +@_ZTS1A = dso_local constant [3 x i8] c"1A\00", align 1 +@_ZTI1A = dso_local constant { ptr, ptr } { ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), ptr @_ZTS1A } + +define i32 @_ZN1A3fooEv(ptr %this) { +entry: + %this.addr = alloca ptr + store ptr %this, ptr %this.addr + %this1 = load ptr, ptr %this.addr + ret i32 1 +} + +!llvm.module.flags = !{!2} + +!0 = !{i64 16, !"_ZTS1A"} +!1 = !{i64 16, !"_ZTSM1AFivE.virtual"} +!2 = !{i32 1, !"Virtual Function Elim", i32 1} diff --git a/llvm/test/Assembler/thinlto-vtable-summary2.ll b/llvm/test/Assembler/thinlto-vtable-summary2.ll index 862b7abfcd3c..6c5d479d2966 100644 --- a/llvm/test/Assembler/thinlto-vtable-summary2.ll +++ b/llvm/test/Assembler/thinlto-vtable-summary2.ll @@ -7,8 +7,11 @@ ; RUN: opt %s -S -module-summary -o - | llvm-as -o - | llvm-dis -o - | FileCheck %s ;; These summary entries should get numbered differently. +;; When virtual function elimination is not enabled (the default case), +;; there is no need to generate typeidCompatibleVTable entries for virtual functions. ; CHECK: ^2 = gv: (name: "_ZTS1A" ; CHECK: ^6 = typeidCompatibleVTable: (name: "_ZTS1A" +; CHECK-NOT: typeidCompatibleVTable: (name: "_ZTSM1AFivE.virtual" ; ModuleID = 'thinlto-vtable-summary2.cc' source_filename = "thinlto-vtable-summary2.cc" |
