From 852334cad31df42463a831f9c53cc4ac4535b93c Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 23 Oct 2024 16:12:27 -0700 Subject: [PATCH] [clang codegen] Add CreateRuntimeFunction overload that takes a clang type. Correctly computing the LLVM types/attributes is complicated in general, so add a variant which does that for you. --- clang/lib/CodeGen/CGBlocks.cpp | 14 +++---- clang/lib/CodeGen/CodeGenModule.cpp | 61 ++++++++++++++++++++++------- clang/lib/CodeGen/CodeGenModule.h | 6 +++ 3 files changed, 59 insertions(+), 22 deletions(-) diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 41bb8d19d161ebb..1661a242c80b578 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -2839,10 +2839,9 @@ llvm::FunctionCallee CodeGenModule::getBlockObjectDispose() { if (BlockObjectDispose) return BlockObjectDispose; - llvm::Type *args[] = { Int8PtrTy, Int32Ty }; - llvm::FunctionType *fty - = llvm::FunctionType::get(VoidTy, args, false); - BlockObjectDispose = CreateRuntimeFunction(fty, "_Block_object_dispose"); + QualType args[] = {Context.VoidPtrTy, Context.IntTy}; + BlockObjectDispose = + CreateRuntimeFunction(Context.VoidTy, args, "_Block_object_dispose"); configureBlocksRuntimeObject( *this, cast(BlockObjectDispose.getCallee())); return BlockObjectDispose; @@ -2852,10 +2851,9 @@ llvm::FunctionCallee CodeGenModule::getBlockObjectAssign() { if (BlockObjectAssign) return BlockObjectAssign; - llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty }; - llvm::FunctionType *fty - = llvm::FunctionType::get(VoidTy, args, false); - BlockObjectAssign = CreateRuntimeFunction(fty, "_Block_object_assign"); + QualType args[] = {Context.VoidPtrTy, Context.VoidPtrTy, Context.IntTy}; + BlockObjectAssign = + CreateRuntimeFunction(Context.VoidTy, args, "_Block_object_assign"); configureBlocksRuntimeObject( *this, cast(BlockObjectAssign.getCallee())); return BlockObjectAssign; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 2bcca5e85bdfeb9..8d7f85fb445424c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4903,6 +4903,52 @@ GetRuntimeFunctionDecl(ASTContext &C, StringRef Name) { return nullptr; } +static void setWindowsItaniumDLLImport(CodeGenModule &CGM, bool Local, + llvm::Function *F, StringRef Name) { + // In Windows Itanium environments, try to mark runtime functions + // dllimport. For Mingw and MSVC, don't. We don't really know if the user + // will link their standard library statically or dynamically. Marking + // functions imported when they are not imported can cause linker errors + // and warnings. + if (!Local && CGM.getTriple().isWindowsItaniumEnvironment() && + !CGM.getCodeGenOpts().LTOVisibilityPublicStd) { + const FunctionDecl *FD = GetRuntimeFunctionDecl(CGM.getContext(), Name); + if (!FD || FD->hasAttr()) { + F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + F->setLinkage(llvm::GlobalValue::ExternalLinkage); + } + } +} + +llvm::FunctionCallee CodeGenModule::CreateRuntimeFunction( + QualType ReturnTy, ArrayRef ArgTys, StringRef Name, + llvm::AttributeList ExtraAttrs, bool Local, bool AssumeConvergent) { + if (AssumeConvergent) { + ExtraAttrs = + ExtraAttrs.addFnAttribute(VMContext, llvm::Attribute::Convergent); + } + + QualType FTy = Context.getFunctionType(Context.VoidTy, ArgTys, + FunctionProtoType::ExtProtoInfo()); + const CGFunctionInfo &Info = getTypes().arrangeFreeFunctionType( + Context.getCanonicalType(FTy).castAs()); + auto *ConvTy = getTypes().GetFunctionType(Info); + llvm::Constant *C = GetOrCreateLLVMFunction( + Name, ConvTy, GlobalDecl(), /*ForVTable=*/false, + /*DontDefer=*/false, /*IsThunk=*/false, ExtraAttrs); + + if (auto *F = dyn_cast(C)) { + if (F->empty()) { + SetLLVMFunctionAttributes(GlobalDecl(), Info, F, /*IsThunk*/ false); + // FIXME: Set calling-conv properly in ExtProtoInfo + F->setCallingConv(getRuntimeCC()); + setWindowsItaniumDLLImport(*this, Local, F, Name); + setDSOLocal(F); + } + } + return {ConvTy, C}; +} + /// CreateRuntimeFunction - Create a new runtime function with the specified /// type and name. llvm::FunctionCallee @@ -4922,20 +4968,7 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name, if (auto *F = dyn_cast(C)) { if (F->empty()) { F->setCallingConv(getRuntimeCC()); - - // In Windows Itanium environments, try to mark runtime functions - // dllimport. For Mingw and MSVC, don't. We don't really know if the user - // will link their standard library statically or dynamically. Marking - // functions imported when they are not imported can cause linker errors - // and warnings. - if (!Local && getTriple().isWindowsItaniumEnvironment() && - !getCodeGenOpts().LTOVisibilityPublicStd) { - const FunctionDecl *FD = GetRuntimeFunctionDecl(Context, Name); - if (!FD || FD->hasAttr()) { - F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - F->setLinkage(llvm::GlobalValue::ExternalLinkage); - } - } + setWindowsItaniumDLLImport(*this, Local, F, Name); setDSOLocal(F); // FIXME: We should use CodeGenModule::SetLLVMFunctionAttributes() instead // of trying to approximate the attributes using the LLVM function diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 1b77490e261c210..6f4105394876307 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1254,6 +1254,12 @@ class CodeGenModule : public CodeGenTypeCache { llvm::AttributeList ExtraAttrs = llvm::AttributeList(), bool Local = false, bool AssumeConvergent = false); + llvm::FunctionCallee + CreateRuntimeFunction(QualType ReturnTy, ArrayRef ArgTys, + StringRef Name, + llvm::AttributeList ExtraAttrs = llvm::AttributeList(), + bool Local = false, bool AssumeConvergent = false); + /// Create a new runtime global variable with the specified type and name. llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty, StringRef Name);