================ @@ -1070,8 +1084,138 @@ void InstrProfiling::maybeSetComdat(GlobalVariable *GV, Function *Fn, GV->setLinkage(GlobalValue::InternalLinkage); } -GlobalVariable *InstrProfiling::setupProfileSection(InstrProfInstBase *Inc, - InstrProfSectKind IPSK) { +static inline bool shouldRecordVTableAddr(GlobalVariable *GV) { + if (!profDataReferencedByCode(*GV->getParent())) + return false; + + if (!GV->hasLinkOnceLinkage() && !GV->hasLocalLinkage() && + !GV->hasAvailableExternallyLinkage()) + return true; + + // This avoids the profile data from referencing internal symbols in + // COMDAT. + if (GV->hasLocalLinkage() && GV->hasComdat()) + return false; + + return true; +} + +// FIXME: Does symbollic relocation from 'getFuncAddrForProfData' matter here? +static inline Constant *getVTableAddrForProfData(GlobalVariable *GV) { + auto *Int8PtrTy = Type::getInt8PtrTy(GV->getContext()); + + // Store a nullptr in __profvt_ if a real address shouldn't be used. + if (!shouldRecordVTableAddr(GV)) + return ConstantPointerNull::get(Int8PtrTy); + + return ConstantExpr::getBitCast(GV, Int8PtrTy); +} + +/// Get the name of a profiling variable for a particular variable. +static std::string getVarName(GlobalVariable *GV, StringRef Prefix) { + StringRef Name = getPGOName(*GV); + return (Prefix + Name).str(); +} + +void InstrProfiling::getOrCreateVTableProfData(GlobalVariable *GV) { + assert(!DebugInfoCorrelate && + "Value profiling is not supported with lightweight instrumentation"); + if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) + return; + + if (GV->getName().starts_with("llvm.") || + GV->getName().starts_with("__llvm") || + GV->getName().starts_with("__prof")) + return; + + // VTableProfData already created + auto It = VTableDataMap.find(GV); + if (It != VTableDataMap.end() && It->second) + return; + + GlobalValue::LinkageTypes Linkage = GV->getLinkage(); + GlobalValue::VisibilityTypes Visibility = GV->getVisibility(); + + // This is to keep consistent with per-function profile data + // for correctness. + if (TT.isOSBinFormatXCOFF()) { + Linkage = GlobalValue::InternalLinkage; + Visibility = GlobalValue::DefaultVisibility; + } + + LLVMContext &Ctx = M->getContext(); + Type *DataTypes[] = { +#define INSTR_PROF_VTABLE_DATA(Type, LLVMType, Name, Init) LLVMType, +#include "llvm/ProfileData/InstrProfData.inc" + }; + + auto *DataTy = StructType::get(Ctx, ArrayRef(DataTypes)); + + // Used by INSTR_PROF_VTABLE_DATA MACRO + Constant *VTableAddr = getVTableAddrForProfData(GV); + StringRef VTableName = GV->getName(); + StringRef PGOVTableName = getPGOName(*GV); + // Record the length of the vtable. This is needed since vtable pointers + // loaded from C++ objects might be from the middle of a vtable definition. + uint32_t VTableSizeVal = + M->getDataLayout().getTypeAllocSize(GV->getValueType()); + + Constant *DataVals[] = { +#define INSTR_PROF_VTABLE_DATA(Type, LLVMType, Name, Init) Init, +#include "llvm/ProfileData/InstrProfData.inc" + }; + + auto *Data = + new GlobalVariable(*M, DataTy, false /* constant */, Linkage, + ConstantStruct::get(DataTy, DataVals), + getVarName(GV, getInstrProfVTableVarPrefix())); + + Data->setVisibility(Visibility); + Data->setSection(getInstrProfSectionName(IPSK_vtab, TT.getObjectFormat())); + Data->setAlignment(Align(8)); + + const bool NeedComdat = needsComdatForCounter(*GV, *M); + + // GV is the data structure to record vtable information. + // Place the global variable for per-vtable profile data in a comdat group + // if the associated vtable definition is a COMDAT. This makes sure only one + // copy of the variable for the vtable will be emitted after linking. + auto MaybeSetComdat = [&](GlobalVariable *GV, StringRef GroupName) { + bool UseComdat = (NeedComdat || TT.isOSBinFormatELF()); + if (UseComdat) { + // Create a new comdat group using the name of the global variable as + // opposed to using the comdat group of the vtable. + Comdat *C = M->getOrInsertComdat(GroupName); + // For ELF, when not using COMDAT, put the vtable profile data into a + // nodeduplicate COMDAT which is lowered to a zero-flag zero group. + // This allows -z -start-top-gc to discard the entire group when the ---------------- snehasish wrote:
s/start-top-gc/start-stop-gc https://github.com/llvm/llvm-project/pull/66825 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits