Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
Show First 20 Lines • Show All 790 Lines • ▼ Show 20 Lines | |||||
/// If whole program visibility asserted, then upgrade all public vcall | /// If whole program visibility asserted, then upgrade all public vcall | ||||
/// visibility metadata on vtable definitions to linkage unit visibility in | /// visibility metadata on vtable definitions to linkage unit visibility in | ||||
/// Module IR (for regular or hybrid LTO). | /// Module IR (for regular or hybrid LTO). | ||||
void updateVCallVisibilityInModule( | void updateVCallVisibilityInModule( | ||||
Module &M, bool WholeProgramVisibilityEnabledInLTO, | Module &M, bool WholeProgramVisibilityEnabledInLTO, | ||||
const DenseSet<GlobalValue::GUID> &DynamicExportSymbols) { | const DenseSet<GlobalValue::GUID> &DynamicExportSymbols) { | ||||
if (!hasWholeProgramVisibility(WholeProgramVisibilityEnabledInLTO)) | if (!hasWholeProgramVisibility(WholeProgramVisibilityEnabledInLTO)) | ||||
return; | return; | ||||
for (GlobalVariable &GV : M.globals()) | for (GlobalVariable &GV : M.globals()) { | ||||
// Add linkage unit visibility to any variable with type metadata, which are | // Add linkage unit visibility to any variable with type metadata, which are | ||||
// the vtable definitions. We won't have an existing vcall_visibility | // the vtable definitions. We won't have an existing vcall_visibility | ||||
// metadata on vtable definitions with public visibility. | // metadata on vtable definitions with public visibility. | ||||
if (GV.hasMetadata(LLVMContext::MD_type) && | GlobalObject::VCallVisibilityList List = GV.getVCallVisibility(); | ||||
GV.getVCallVisibility() == GlobalObject::VCallVisibilityPublic && | if (GV.hasMetadata(LLVMContext::MD_type) && !List.empty()) { | ||||
// Don't upgrade the visibility for symbols exported to the dynamic | for (auto &Entry : List) { | ||||
// linker, as we have no information on their eventual use. | if (Entry.Visibility == GlobalObject::VCallVisibilityPublic && | ||||
!DynamicExportSymbols.count(GV.getGUID())) | !DynamicExportSymbols.count(GV.getGUID())) { | ||||
GV.setVCallVisibilityMetadata(GlobalObject::VCallVisibilityLinkageUnit); | Entry.Visibility = GlobalObject::VCallVisibilityLinkageUnit; | ||||
} | |||||
} | |||||
GV.setVCallVisibility(List); | |||||
} | |||||
} | |||||
} | } | ||||
/// If whole program visibility asserted, then upgrade all public vcall | /// If whole program visibility asserted, then upgrade all public vcall | ||||
/// visibility metadata on vtable definition summaries to linkage unit | /// visibility metadata on vtable definition summaries to linkage unit | ||||
/// visibility in Module summary index (for ThinLTO). | /// visibility in Module summary index (for ThinLTO). | ||||
void updateVCallVisibilityInIndex( | void updateVCallVisibilityInIndex( | ||||
ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, | ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, | ||||
const DenseSet<GlobalValue::GUID> &DynamicExportSymbols) { | const DenseSet<GlobalValue::GUID> &DynamicExportSymbols) { | ||||
▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | |||||
bool DevirtModule::tryFindVirtualCallTargets( | bool DevirtModule::tryFindVirtualCallTargets( | ||||
std::vector<VirtualCallTarget> &TargetsForSlot, | std::vector<VirtualCallTarget> &TargetsForSlot, | ||||
const std::set<TypeMemberInfo> &TypeMemberInfos, uint64_t ByteOffset) { | const std::set<TypeMemberInfo> &TypeMemberInfos, uint64_t ByteOffset) { | ||||
for (const TypeMemberInfo &TM : TypeMemberInfos) { | for (const TypeMemberInfo &TM : TypeMemberInfos) { | ||||
if (!TM.Bits->GV->isConstant()) | if (!TM.Bits->GV->isConstant()) | ||||
return false; | return false; | ||||
GlobalObject::VCallVisibilityList List = TM.Bits->GV->getVCallVisibility(); | |||||
// Find the maximum visibility from all !vcall_visibility | |||||
GlobalObject::VCallVisibility TypeVis = | |||||
GlobalObject::VCallVisibilityTranslationUnit; | |||||
for (auto Entry : List) { | |||||
TypeVis = std::min(TypeVis, Entry.Visibility); | |||||
} | |||||
if (List.empty()) | |||||
TypeVis = GlobalObject::VCallVisibilityPublic; | |||||
// We cannot perform whole program devirtualization analysis on a vtable | // We cannot perform whole program devirtualization analysis on a vtable | ||||
// with public LTO visibility. | // with public LTO visibility. | ||||
if (TM.Bits->GV->getVCallVisibility() == | if (TypeVis == GlobalObject::VCallVisibilityPublic) | ||||
GlobalObject::VCallVisibilityPublic) | |||||
return false; | return false; | ||||
Constant *Ptr = getPointerAtOffset(TM.Bits->GV->getInitializer(), | Constant *Ptr = getPointerAtOffset(TM.Bits->GV->getInitializer(), | ||||
TM.Offset + ByteOffset, M); | TM.Offset + ByteOffset, M); | ||||
if (!Ptr) | if (!Ptr) | ||||
return false; | return false; | ||||
auto Fn = dyn_cast<Function>(Ptr->stripPointerCasts()); | auto Fn = dyn_cast<Function>(Ptr->stripPointerCasts()); | ||||
▲ Show 20 Lines • Show All 1,291 Lines • Show Last 20 Lines |