[clang] [clang codegen] Add CreateRuntimeFunction overload that takes a clang type. (PR #113506)
Eli Friedman via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 23 16:16:29 PDT 2024
https://github.com/efriedma-quic created https://github.com/llvm/llvm-project/pull/113506
Correctly computing the LLVM types/attributes is complicated in general, so add a variant which does that for you.
>From 852334cad31df42463a831f9c53cc4ac4535b93c Mon Sep 17 00:00:00 2001
From: Eli Friedman <efriedma at quicinc.com>
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 41bb8d19d161eb..1661a242c80b57 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<llvm::Constant>(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<llvm::Constant>(BlockObjectAssign.getCallee()));
return BlockObjectAssign;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 2bcca5e85bdfeb..8d7f85fb445424 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<DLLImportAttr>()) {
+ F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
+ F->setLinkage(llvm::GlobalValue::ExternalLinkage);
+ }
+ }
+}
+
+llvm::FunctionCallee CodeGenModule::CreateRuntimeFunction(
+ QualType ReturnTy, ArrayRef<QualType> 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<FunctionProtoType>());
+ auto *ConvTy = getTypes().GetFunctionType(Info);
+ llvm::Constant *C = GetOrCreateLLVMFunction(
+ Name, ConvTy, GlobalDecl(), /*ForVTable=*/false,
+ /*DontDefer=*/false, /*IsThunk=*/false, ExtraAttrs);
+
+ if (auto *F = dyn_cast<llvm::Function>(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<llvm::Function>(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<DLLImportAttr>()) {
- 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 1b77490e261c21..6f410539487630 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<QualType> 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);
More information about the cfe-commits
mailing list