aeubanks created this revision.
Herald added subscribers: ormris, steven_wu, hiraditya.
Herald added a project: All.
aeubanks requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, jdoerfert.
Herald added projects: clang, LLVM.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D128955
Files:
clang/lib/CodeGen/CGClass.cpp
llvm/include/llvm/IR/Intrinsics.td
llvm/include/llvm/Transforms/IPO/WholeProgramDevirt.h
llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
llvm/lib/Analysis/TypeMetadataUtils.cpp
llvm/lib/LTO/LTOBackend.cpp
llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
Index: llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
===================================================================
--- llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -860,7 +860,7 @@
const DenseSet<GlobalValue::GUID> &DynamicExportSymbols) {
if (!hasWholeProgramVisibility(WholeProgramVisibilityEnabledInLTO))
return;
- for (GlobalVariable &GV : M.globals())
+ for (GlobalVariable &GV : M.globals()) {
// Add linkage unit visibility to any variable with type metadata, which are
// the vtable definitions. We won't have an existing vcall_visibility
// metadata on vtable definitions with public visibility.
@@ -870,6 +870,34 @@
// linker, as we have no information on their eventual use.
!DynamicExportSymbols.count(GV.getGUID()))
GV.setVCallVisibilityMetadata(GlobalObject::VCallVisibilityLinkageUnit);
+ }
+}
+
+void updatePublicTypeTestCalls(Module &M,
+ bool WholeProgramVisibilityEnabledInLTO) {
+ Function *PublicTypeTestFunc =
+ M.getFunction(Intrinsic::getName(Intrinsic::public_type_test));
+ if (!PublicTypeTestFunc)
+ return;
+ if (hasWholeProgramVisibility(WholeProgramVisibilityEnabledInLTO)) {
+ Function *TypeTestFunc =
+ Intrinsic::getDeclaration(&M, Intrinsic::type_test);
+ for (Use &U : make_early_inc_range(PublicTypeTestFunc->uses())) {
+ auto *CI = cast<CallInst>(U.getUser());
+ auto *NewCI = CallInst::Create(
+ TypeTestFunc, {CI->getArgOperand(0), CI->getArgOperand(1)}, None, "",
+ CI);
+ CI->replaceAllUsesWith(NewCI);
+ CI->eraseFromParent();
+ }
+ } else {
+ auto *True = ConstantInt::getTrue(M.getContext());
+ for (Use &U : make_early_inc_range(PublicTypeTestFunc->uses())) {
+ auto *CI = cast<CallInst>(U.getUser());
+ CI->replaceAllUsesWith(True);
+ CI->eraseFromParent();
+ }
+ }
}
/// If whole program visibility asserted, then upgrade all public vcall
Index: llvm/lib/LTO/LTOBackend.cpp
===================================================================
--- llvm/lib/LTO/LTOBackend.cpp
+++ llvm/lib/LTO/LTOBackend.cpp
@@ -40,6 +40,7 @@
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/IPO/WholeProgramDevirt.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Utils/FunctionImportUtils.h"
#include "llvm/Transforms/Utils/SplitModule.h"
@@ -330,6 +331,7 @@
/*EmbedBitcode*/ true, /*EmbedCmdline*/ true,
/*Cmdline*/ CmdArgs);
}
+ updatePublicTypeTestCalls(Mod, Conf.HasWholeProgramVisibility);
// FIXME: Plumb the combined index into the new pass manager.
runNewPMPasses(Conf, Mod, TM, Conf.OptLevel, IsThinLTO, ExportSummary,
ImportSummary);
Index: llvm/lib/Analysis/TypeMetadataUtils.cpp
===================================================================
--- llvm/lib/Analysis/TypeMetadataUtils.cpp
+++ llvm/lib/Analysis/TypeMetadataUtils.cpp
@@ -75,7 +75,9 @@
SmallVectorImpl<DevirtCallSite> &DevirtCalls,
SmallVectorImpl<CallInst *> &Assumes, const CallInst *CI,
DominatorTree &DT) {
- assert(CI->getCalledFunction()->getIntrinsicID() == Intrinsic::type_test);
+ assert(CI->getCalledFunction()->getIntrinsicID() == Intrinsic::type_test ||
+ CI->getCalledFunction()->getIntrinsicID() ==
+ Intrinsic::public_type_test);
const Module *M = CI->getParent()->getParent()->getParent();
Index: llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
===================================================================
--- llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -164,7 +164,8 @@
SetVector<FunctionSummary::ConstVCall> &TypeCheckedLoadConstVCalls,
DominatorTree &DT) {
switch (CI->getCalledFunction()->getIntrinsicID()) {
- case Intrinsic::type_test: {
+ case Intrinsic::type_test:
+ case Intrinsic::public_type_test: {
auto *TypeMDVal = cast<MetadataAsValue>(CI->getArgOperand(1));
auto *TypeId = dyn_cast<MDString>(TypeMDVal->getMetadata());
if (!TypeId)
Index: llvm/include/llvm/Transforms/IPO/WholeProgramDevirt.h
===================================================================
--- llvm/include/llvm/Transforms/IPO/WholeProgramDevirt.h
+++ llvm/include/llvm/Transforms/IPO/WholeProgramDevirt.h
@@ -240,6 +240,8 @@
uint64_t ByteOffset;
};
+void updatePublicTypeTestCalls(Module &M,
+ bool WholeProgramVisibilityEnabledInLTO);
void updateVCallVisibilityInModule(
Module &M, bool WholeProgramVisibilityEnabledInLTO,
const DenseSet<GlobalValue::GUID> &DynamicExportSymbols);
Index: llvm/include/llvm/IR/Intrinsics.td
===================================================================
--- llvm/include/llvm/IR/Intrinsics.td
+++ llvm/include/llvm/IR/Intrinsics.td
@@ -1757,6 +1757,10 @@
[llvm_ptr_ty, llvm_i32_ty, llvm_metadata_ty],
[IntrNoMem, IntrWillReturn]>;
+// Test whether a pointer is associated with a type metadata identifier.
+def int_public_type_test : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_metadata_ty],
+ [IntrNoMem, IntrWillReturn, IntrSpeculatable]>;
+
// Create a branch funnel that implements an indirect call to a limited set of
// callees. This needs to be a musttail call.
def int_icall_branch_funnel : DefaultAttrsIntrinsic<[], [llvm_vararg_ty], []>;
Index: clang/lib/CodeGen/CGClass.cpp
===================================================================
--- clang/lib/CodeGen/CGClass.cpp
+++ clang/lib/CodeGen/CGClass.cpp
@@ -2698,15 +2698,19 @@
// Don't insert type test assumes if we are forcing public
// visibility.
!CGM.AlwaysHasLTOVisibilityPublic(RD)) {
- llvm::Metadata *MD =
- CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
+ QualType Ty = QualType(RD->getTypeForDecl(), 0);
+ llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(Ty);
llvm::Value *TypeId =
llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy);
+ // isExternallyVisible(Ty->getLinkage())?
+ llvm::Intrinsic::ID IID =
+ Ty->getVisibility() == Visibility::HiddenVisibility
+ ? llvm::Intrinsic::type_test
+ : llvm::Intrinsic::public_type_test;
llvm::Value *TypeTest =
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
- {CastedVTable, TypeId});
+ Builder.CreateCall(CGM.getIntrinsic(IID), {CastedVTable, TypeId});
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest);
}
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits