forked from OSchip/llvm-project
[opaque pointer types] Pass through function types for TLS
initialization and global destructor calls. Differential Revision: https://reviews.llvm.org/D57801 llvm-svn: 353355
This commit is contained in:
parent
18f0bd78e2
commit
f7321540d5
|
@ -227,10 +227,11 @@ llvm::Function *CodeGenModule::codegenCXXStructor(const CXXMethodDecl *MD,
|
|||
return Fn;
|
||||
}
|
||||
|
||||
llvm::Constant *CodeGenModule::getAddrOfCXXStructor(
|
||||
llvm::FunctionCallee CodeGenModule::getAddrAndTypeOfCXXStructor(
|
||||
const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo,
|
||||
llvm::FunctionType *FnType, bool DontDefer,
|
||||
ForDefinition_t IsForDefinition) {
|
||||
|
||||
GlobalDecl GD;
|
||||
if (auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
|
||||
GD = GlobalDecl(CD, toCXXCtorType(Type));
|
||||
|
@ -249,9 +250,10 @@ llvm::Constant *CodeGenModule::getAddrOfCXXStructor(
|
|||
FnType = getTypes().GetFunctionType(*FnInfo);
|
||||
}
|
||||
|
||||
return GetOrCreateLLVMFunction(
|
||||
llvm::Constant *Ptr = GetOrCreateLLVMFunction(
|
||||
getMangledName(GD), FnType, GD, /*ForVTable=*/false, DontDefer,
|
||||
/*isThunk=*/false, /*ExtraAttrs=*/llvm::AttributeList(), IsForDefinition);
|
||||
return {FnType, Ptr};
|
||||
}
|
||||
|
||||
static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF,
|
||||
|
|
|
@ -556,7 +556,7 @@ public:
|
|||
/// \param Dtor - a function taking a single pointer argument
|
||||
/// \param Addr - a pointer to pass to the destructor function.
|
||||
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
|
||||
llvm::Constant *Dtor,
|
||||
llvm::FunctionCallee Dtor,
|
||||
llvm::Constant *Addr) = 0;
|
||||
|
||||
/*************************** thread_local initialization ********************/
|
||||
|
|
|
@ -97,7 +97,7 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
|
|||
return;
|
||||
}
|
||||
|
||||
llvm::Constant *Func;
|
||||
llvm::FunctionCallee Func;
|
||||
llvm::Constant *Argument;
|
||||
|
||||
// Special-case non-array C++ destructors, if they have the right signature.
|
||||
|
@ -117,7 +117,7 @@ static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
|
|||
assert(!Record->hasTrivialDestructor());
|
||||
CXXDestructorDecl *Dtor = Record->getDestructor();
|
||||
|
||||
Func = CGM.getAddrOfCXXStructor(Dtor, StructorType::Complete);
|
||||
Func = CGM.getAddrAndTypeOfCXXStructor(Dtor, StructorType::Complete);
|
||||
Argument = llvm::ConstantExpr::getBitCast(
|
||||
Addr.getPointer(), CGF.getTypes().ConvertType(Type)->getPointerTo());
|
||||
|
||||
|
@ -214,8 +214,8 @@ void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
|
|||
|
||||
/// Create a stub function, suitable for being passed to atexit,
|
||||
/// which passes the given address to the given destructor function.
|
||||
llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD,
|
||||
llvm::Constant *dtor,
|
||||
llvm::Function *CodeGenFunction::createAtExitStub(const VarDecl &VD,
|
||||
llvm::FunctionCallee dtor,
|
||||
llvm::Constant *addr) {
|
||||
// Get the destructor function type, void(*)(void).
|
||||
llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false);
|
||||
|
@ -238,7 +238,7 @@ llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD,
|
|||
|
||||
// Make sure the call and the callee agree on calling convention.
|
||||
if (llvm::Function *dtorFn =
|
||||
dyn_cast<llvm::Function>(dtor->stripPointerCasts()))
|
||||
dyn_cast<llvm::Function>(dtor.getCallee()->stripPointerCasts()))
|
||||
call->setCallingConv(dtorFn->getCallingConv());
|
||||
|
||||
CGF.FinishFunction();
|
||||
|
@ -248,7 +248,7 @@ llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD,
|
|||
|
||||
/// Register a global destructor using the C atexit runtime function.
|
||||
void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD,
|
||||
llvm::Constant *dtor,
|
||||
llvm::FunctionCallee dtor,
|
||||
llvm::Constant *addr) {
|
||||
// Create a function which calls the destructor.
|
||||
llvm::Constant *dtorStub = createAtExitStub(VD, dtor, addr);
|
||||
|
@ -681,8 +681,8 @@ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
|
|||
|
||||
void CodeGenFunction::GenerateCXXGlobalDtorsFunc(
|
||||
llvm::Function *Fn,
|
||||
const std::vector<std::pair<llvm::WeakTrackingVH, llvm::Constant *>>
|
||||
&DtorsAndObjects) {
|
||||
const std::vector<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
|
||||
llvm::Constant *>> &DtorsAndObjects) {
|
||||
{
|
||||
auto NL = ApplyDebugLocation::CreateEmpty(*this);
|
||||
StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
|
||||
|
@ -692,9 +692,11 @@ void CodeGenFunction::GenerateCXXGlobalDtorsFunc(
|
|||
|
||||
// Emit the dtors, in reverse order from construction.
|
||||
for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
|
||||
llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
|
||||
llvm::CallInst *CI = Builder.CreateCall(Callee,
|
||||
DtorsAndObjects[e - i - 1].second);
|
||||
llvm::FunctionType *CalleeTy;
|
||||
llvm::Value *Callee;
|
||||
llvm::Constant *Arg;
|
||||
std::tie(CalleeTy, Callee, Arg) = DtorsAndObjects[e - i - 1];
|
||||
llvm::CallInst *CI = Builder.CreateCall(CalleeTy, Callee, Arg);
|
||||
// Make sure the call and the callee agree on calling convention.
|
||||
if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
|
||||
CI->setCallingConv(F->getCallingConv());
|
||||
|
|
|
@ -330,7 +330,7 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
|
|||
switch (M->getStorageDuration()) {
|
||||
case SD_Static:
|
||||
case SD_Thread: {
|
||||
llvm::Constant *CleanupFn;
|
||||
llvm::FunctionCallee CleanupFn;
|
||||
llvm::Constant *CleanupArg;
|
||||
if (E->getType()->isArrayType()) {
|
||||
CleanupFn = CodeGenFunction(CGF.CGM).generateDestroyHelper(
|
||||
|
@ -339,7 +339,7 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
|
|||
dyn_cast_or_null<VarDecl>(M->getExtendingDecl()));
|
||||
CleanupArg = llvm::Constant::getNullValue(CGF.Int8PtrTy);
|
||||
} else {
|
||||
CleanupFn = CGF.CGM.getAddrOfCXXStructor(ReferenceTemporaryDtor,
|
||||
CleanupFn = CGF.CGM.getAddrAndTypeOfCXXStructor(ReferenceTemporaryDtor,
|
||||
StructorType::Complete);
|
||||
CleanupArg = cast<llvm::Constant>(ReferenceTemporary.getPointer());
|
||||
}
|
||||
|
|
|
@ -3924,12 +3924,12 @@ public:
|
|||
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr,
|
||||
bool PerformInit);
|
||||
|
||||
llvm::Constant *createAtExitStub(const VarDecl &VD, llvm::Constant *Dtor,
|
||||
llvm::Function *createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor,
|
||||
llvm::Constant *Addr);
|
||||
|
||||
/// Call atexit() with a function that passes the given argument to
|
||||
/// the given function.
|
||||
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn,
|
||||
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn,
|
||||
llvm::Constant *addr);
|
||||
|
||||
/// Call atexit() with function dtorStub.
|
||||
|
@ -3962,8 +3962,8 @@ public:
|
|||
/// variables.
|
||||
void GenerateCXXGlobalDtorsFunc(
|
||||
llvm::Function *Fn,
|
||||
const std::vector<std::pair<llvm::WeakTrackingVH, llvm::Constant *>>
|
||||
&DtorsAndObjects);
|
||||
const std::vector<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
|
||||
llvm::Constant *>> &DtorsAndObjects);
|
||||
|
||||
void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
|
||||
const VarDecl *D,
|
||||
|
|
|
@ -451,7 +451,9 @@ private:
|
|||
SmallVector<GlobalInitData, 8> PrioritizedCXXGlobalInits;
|
||||
|
||||
/// Global destructor functions and arguments that need to run on termination.
|
||||
std::vector<std::pair<llvm::WeakTrackingVH, llvm::Constant *>> CXXGlobalDtors;
|
||||
std::vector<
|
||||
std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, llvm::Constant *>>
|
||||
CXXGlobalDtors;
|
||||
|
||||
/// The complete set of modules that has been imported.
|
||||
llvm::SetVector<clang::Module *> ImportedModules;
|
||||
|
@ -958,6 +960,17 @@ public:
|
|||
const CGFunctionInfo *FnInfo = nullptr,
|
||||
llvm::FunctionType *FnType = nullptr,
|
||||
bool DontDefer = false,
|
||||
ForDefinition_t IsForDefinition = NotForDefinition) {
|
||||
return cast<llvm::Constant>(getAddrAndTypeOfCXXStructor(MD, Type, FnInfo,
|
||||
FnType, DontDefer,
|
||||
IsForDefinition)
|
||||
.getCallee());
|
||||
}
|
||||
|
||||
llvm::FunctionCallee getAddrAndTypeOfCXXStructor(
|
||||
const CXXMethodDecl *MD, StructorType Type,
|
||||
const CGFunctionInfo *FnInfo = nullptr,
|
||||
llvm::FunctionType *FnType = nullptr, bool DontDefer = false,
|
||||
ForDefinition_t IsForDefinition = NotForDefinition);
|
||||
|
||||
/// Given a builtin id for a function like "__builtin_fabsf", return a
|
||||
|
@ -998,8 +1011,9 @@ public:
|
|||
void addCompilerUsedGlobal(llvm::GlobalValue *GV);
|
||||
|
||||
/// Add a destructor and object to add to the C++ global destructor function.
|
||||
void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object) {
|
||||
CXXGlobalDtors.emplace_back(DtorFn, Object);
|
||||
void AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object) {
|
||||
CXXGlobalDtors.emplace_back(DtorFn.getFunctionType(), DtorFn.getCallee(),
|
||||
Object);
|
||||
}
|
||||
|
||||
/// Create or return a runtime function declaration with the specified type
|
||||
|
|
|
@ -328,7 +328,8 @@ public:
|
|||
llvm::GlobalVariable *DeclPtr,
|
||||
bool PerformInit) override;
|
||||
void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
|
||||
llvm::Constant *dtor, llvm::Constant *addr) override;
|
||||
llvm::FunctionCallee dtor,
|
||||
llvm::Constant *addr) override;
|
||||
|
||||
llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD,
|
||||
llvm::Value *Val);
|
||||
|
@ -2284,9 +2285,8 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
|
|||
|
||||
/// Register a global destructor using __cxa_atexit.
|
||||
static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
|
||||
llvm::Constant *dtor,
|
||||
llvm::Constant *addr,
|
||||
bool TLS) {
|
||||
llvm::FunctionCallee dtor,
|
||||
llvm::Constant *addr, bool TLS) {
|
||||
const char *Name = "__cxa_atexit";
|
||||
if (TLS) {
|
||||
const llvm::Triple &T = CGF.getTarget().getTriple();
|
||||
|
@ -2322,11 +2322,10 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
|
|||
// function.
|
||||
addr = llvm::Constant::getNullValue(CGF.Int8PtrTy);
|
||||
|
||||
llvm::Value *args[] = {
|
||||
llvm::ConstantExpr::getBitCast(dtor, dtorTy),
|
||||
llvm::Value *args[] = {llvm::ConstantExpr::getBitCast(
|
||||
cast<llvm::Constant>(dtor.getCallee()), dtorTy),
|
||||
llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy),
|
||||
handle
|
||||
};
|
||||
handle};
|
||||
CGF.EmitNounwindRuntimeCall(atexit, args);
|
||||
}
|
||||
|
||||
|
@ -2375,9 +2374,8 @@ void CodeGenModule::registerGlobalDtorsWithAtExit() {
|
|||
}
|
||||
|
||||
/// Register a global destructor as best as we know how.
|
||||
void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
|
||||
const VarDecl &D,
|
||||
llvm::Constant *dtor,
|
||||
void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
|
||||
llvm::FunctionCallee dtor,
|
||||
llvm::Constant *addr) {
|
||||
if (D.isNoDestroy(CGM.getContext()))
|
||||
return;
|
||||
|
@ -2541,6 +2539,8 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
|
|||
getMangleContext().mangleItaniumThreadLocalInit(VD, Out);
|
||||
}
|
||||
|
||||
llvm::FunctionType *InitFnTy = llvm::FunctionType::get(CGM.VoidTy, false);
|
||||
|
||||
// If we have a definition for the variable, emit the initialization
|
||||
// function as an alias to the global Init function (if any). Otherwise,
|
||||
// produce a declaration of the initialization function.
|
||||
|
@ -2559,8 +2559,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
|
|||
// This function will not exist if the TU defining the thread_local
|
||||
// variable in question does not need any dynamic initialization for
|
||||
// its thread_local variables.
|
||||
llvm::FunctionType *FnTy = llvm::FunctionType::get(CGM.VoidTy, false);
|
||||
Init = llvm::Function::Create(FnTy,
|
||||
Init = llvm::Function::Create(InitFnTy,
|
||||
llvm::GlobalVariable::ExternalWeakLinkage,
|
||||
InitFnName.str(), &CGM.getModule());
|
||||
const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
|
||||
|
@ -2578,7 +2577,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
|
|||
CGBuilderTy Builder(CGM, Entry);
|
||||
if (InitIsInitFunc) {
|
||||
if (Init) {
|
||||
llvm::CallInst *CallVal = Builder.CreateCall(Init);
|
||||
llvm::CallInst *CallVal = Builder.CreateCall(InitFnTy, Init);
|
||||
if (isThreadWrapperReplaceable(VD, CGM)) {
|
||||
CallVal->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
|
||||
llvm::Function *Fn =
|
||||
|
@ -2594,7 +2593,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
|
|||
Builder.CreateCondBr(Have, InitBB, ExitBB);
|
||||
|
||||
Builder.SetInsertPoint(InitBB);
|
||||
Builder.CreateCall(Init);
|
||||
Builder.CreateCall(InitFnTy, Init);
|
||||
Builder.CreateBr(ExitBB);
|
||||
|
||||
Builder.SetInsertPoint(ExitBB);
|
||||
|
|
|
@ -394,7 +394,8 @@ public:
|
|||
llvm::GlobalVariable *DeclPtr,
|
||||
bool PerformInit) override;
|
||||
void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
|
||||
llvm::Constant *Dtor, llvm::Constant *Addr) override;
|
||||
llvm::FunctionCallee Dtor,
|
||||
llvm::Constant *Addr) override;
|
||||
|
||||
// ==== Notes on array cookies =========
|
||||
//
|
||||
|
@ -2222,7 +2223,7 @@ Address MicrosoftCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
|
|||
}
|
||||
|
||||
static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD,
|
||||
llvm::Constant *Dtor,
|
||||
llvm::FunctionCallee Dtor,
|
||||
llvm::Constant *Addr) {
|
||||
// Create a function which calls the destructor.
|
||||
llvm::Constant *DtorStub = CGF.createAtExitStub(VD, Dtor, Addr);
|
||||
|
@ -2241,7 +2242,7 @@ static void emitGlobalDtorWithTLRegDtor(CodeGenFunction &CGF, const VarDecl &VD,
|
|||
}
|
||||
|
||||
void MicrosoftCXXABI::registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D,
|
||||
llvm::Constant *Dtor,
|
||||
llvm::FunctionCallee Dtor,
|
||||
llvm::Constant *Addr) {
|
||||
if (D.isNoDestroy(CGM.getContext()))
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue