aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen/CIRGenModule.cpp
diff options
context:
space:
mode:
authorAndy Kaylor <akaylor@nvidia.com>2025-04-25 12:08:52 -0700
committerGitHub <noreply@github.com>2025-04-25 12:08:52 -0700
commit8b9861291000b6f593185752620008f7b6fd6149 (patch)
tree7efb7a6114f8143cbe7fb0b44611c543606b2f32 /clang/lib/CIR/CodeGen/CIRGenModule.cpp
parent77f8335a07e65f88a2c2925f175f48c458911cee (diff)
downloadllvm-8b9861291000b6f593185752620008f7b6fd6149.zip
llvm-8b9861291000b6f593185752620008f7b6fd6149.tar.gz
llvm-8b9861291000b6f593185752620008f7b6fd6149.tar.bz2
[CIR] Fix calling defined functions (#137271)
Until now our function symbol lookup has been assuming that the function did not exist and creating a definition for it. This caused us to create a duplicate definition if we ever tried to call a function that was already defined. This change fixes that by adding handling for trying to look up existing global definitions before creating a new one.
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenModule.cpp')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenModule.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 0f4193b..8aa57d1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -773,6 +773,58 @@ cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable,
bool dontDefer, bool isThunk, ForDefinition_t isForDefinition,
mlir::ArrayAttr extraAttrs) {
+ const Decl *d = gd.getDecl();
+
+ if (isThunk)
+ errorNYI(d->getSourceRange(), "getOrCreateCIRFunction: thunk");
+
+ // In what follows, we continue past 'errorNYI' as if nothing happened because
+ // the rest of the implementation is better than doing nothing.
+
+ if (const auto *fd = cast_or_null<FunctionDecl>(d)) {
+ // For the device mark the function as one that should be emitted.
+ if (getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
+ !isForDefinition)
+ errorNYI(fd->getSourceRange(),
+ "getOrCreateCIRFunction: OpenMP target function");
+
+ // Any attempts to use a MultiVersion function should result in retrieving
+ // the iFunc instead. Name mangling will handle the rest of the changes.
+ if (fd->isMultiVersion())
+ errorNYI(fd->getSourceRange(), "getOrCreateCIRFunction: multi-version");
+ }
+
+ // Lookup the entry, lazily creating it if necessary.
+ mlir::Operation *entry = getGlobalValue(mangledName);
+ if (entry) {
+ if (!isa<cir::FuncOp>(entry))
+ errorNYI(d->getSourceRange(), "getOrCreateCIRFunction: non-FuncOp");
+
+ assert(!cir::MissingFeatures::weakRefReference());
+
+ // Handle dropped DLL attributes.
+ if (d && !d->hasAttr<DLLImportAttr>() && !d->hasAttr<DLLExportAttr>()) {
+ assert(!cir::MissingFeatures::setDLLStorageClass());
+ assert(!cir::MissingFeatures::setDSOLocal());
+ }
+
+ // If there are two attempts to define the same mangled name, issue an
+ // error.
+ auto fn = cast<cir::FuncOp>(entry);
+ assert((!isForDefinition || !fn || !fn.isDeclaration()) &&
+ "Duplicate function definition");
+ if (fn && fn.getFunctionType() == funcType) {
+ return fn;
+ }
+
+ if (!isForDefinition) {
+ return fn;
+ }
+
+ // TODO(cir): classic codegen checks here if this is a llvm::GlobalAlias.
+ // How will we support this?
+ }
+
auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.getDecl());
bool invalidLoc = !funcDecl ||
funcDecl->getSourceRange().getBegin().isInvalid() ||