@@ -132,6 +132,11 @@ static cl::opt<int> ICPMaxNumVTableLastCandidate(
132132 " icp-max-num-vtable-last-candidate" , cl::init(1 ), cl::Hidden,
133133 cl::desc(" The maximum number of vtable for the last candidate." ));
134134
135+ static cl::opt<std::string> ICPKnownUnrepresentativeVTables (
136+ " icp-known-unrepresentative-vtables" , cl::init(" " ), cl::Hidden,
137+ cl::desc(" A comma-separated list of mangled vtable names for which instrumented
138+ profiles are not representative. For instance, the instantiated class is arch or micro-arch specific, while instrumented profiles are collected on one arch." ));
139+
135140namespace {
136141
137142// The key is a vtable global variable, and the value is a map.
@@ -316,6 +321,8 @@ class IndirectCallPromoter {
316321
317322 OptimizationRemarkEmitter &ORE;
318323
324+ const DenseSet<StringRef> &KnownUnrepresentativeBaseTypes;
325+
319326 // A struct that records the direct target and it's call count.
320327 struct PromotionCandidate {
321328 Function *const TargetFunction;
@@ -391,10 +398,12 @@ class IndirectCallPromoter {
391398 Function &Func, Module &M, InstrProfSymtab *Symtab, bool SamplePGO,
392399 const VirtualCallSiteTypeInfoMap &VirtualCSInfo,
393400 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal,
401+ DenseSet<StringRef> &KnownUnrepresentativeTypes,
394402 OptimizationRemarkEmitter &ORE)
395403 : F(Func), M(M), Symtab(Symtab), SamplePGO(SamplePGO),
396404 VirtualCSInfo (VirtualCSInfo),
397- VTableAddressPointOffsetVal(VTableAddressPointOffsetVal), ORE(ORE) {}
405+ VTableAddressPointOffsetVal(VTableAddressPointOffsetVal), ORE(ORE),
406+ KnownUnrepresentativeBaseTypes(KnownUnrepresentativeTypes) {}
398407 IndirectCallPromoter (const IndirectCallPromoter &) = delete;
399408 IndirectCallPromoter &operator =(const IndirectCallPromoter &) = delete ;
400409
@@ -851,8 +860,26 @@ bool IndirectCallPromoter::isProfitableToCompareVTables(
851860 LLVM_DEBUG (dbgs () << " \n " );
852861
853862 uint64_t CandidateVTableCount = 0 ;
854- for (auto &[GUID, Count] : VTableGUIDAndCounts)
863+ SmallVector<MDNode *, 2 > Types;
864+ for (auto &[GUID, Count] : VTableGUIDAndCounts) {
855865 CandidateVTableCount += Count;
866+ auto *VTableVar = Symtab->getGlobalVariable (GUID);
867+
868+ assert (VTableVar &&
869+ " VTableVar must exist for GUID in VTableGUIDAndCounts" );
870+
871+ Types.clear ();
872+ VTableVar->getMetadata (LLVMContext::MD_type, Types);
873+
874+ for (auto *Type : Types)
875+ if (auto *TypeId = dyn_cast<MDString>(Type->getOperand (1 ).get ()))
876+ if (KnownUnrepresentativeBaseTypes.contains (TypeId->getString ())) {
877+ LLVM_DEBUG (dbgs ()
878+ << " vtable profiles are known to be "
879+ " unrepresentative. Bail out vtable comparison." )
880+ return false ;
881+ }
882+ }
856883
857884 if (CandidateVTableCount < Candidate.Count * ICPVTablePercentageThreshold) {
858885 LLVM_DEBUG (
@@ -956,9 +983,19 @@ static bool promoteIndirectCalls(Module &M, ProfileSummaryInfo *PSI, bool InLTO,
956983 bool Changed = false ;
957984 VirtualCallSiteTypeInfoMap VirtualCSInfo;
958985
959- if (EnableVTableProfileUse)
986+ DenseSet<StringRef> KnownUnrepresentativeTypeSet;
987+
988+ if (EnableVTableProfileUse) {
960989 computeVirtualCallSiteTypeInfoMap (M, MAM, VirtualCSInfo);
961990
991+ SmallVector<StringRef> KnownUnrepresentativeTypes;
992+ llvm::SplitString (ICPKnownUnrepresentativeVTables,
993+ KnownUnrepresentativeTypes);
994+
995+ for (const StringRef Str : KnownUnrepresentativeTypes)
996+ KnownUnrepresentativeTypeSet.insert (Str);
997+ }
998+
962999 // VTableAddressPointOffsetVal stores the vtable address points. The vtable
9631000 // address point of a given <vtable, address point offset> is static (doesn't
9641001 // change after being computed once).
@@ -977,7 +1014,8 @@ static bool promoteIndirectCalls(Module &M, ProfileSummaryInfo *PSI, bool InLTO,
9771014 auto &ORE = FAM.getResult <OptimizationRemarkEmitterAnalysis>(F);
9781015
9791016 IndirectCallPromoter CallPromoter (F, M, &Symtab, SamplePGO, VirtualCSInfo,
980- VTableAddressPointOffsetVal, ORE);
1017+ VTableAddressPointOffsetVal,
1018+ KnownUnrepresentativeTypeSet, ORE);
9811019 bool FuncChanged = CallPromoter.processFunction (PSI);
9821020 if (ICPDUMPAFTER && FuncChanged) {
9831021 LLVM_DEBUG (dbgs () << " \n == IR Dump After ==" ; F.print (dbgs ()));
0 commit comments