diff options
author | Andy Kaylor <akaylor@nvidia.com> | 2025-04-25 12:08:52 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-25 12:08:52 -0700 |
commit | 8b9861291000b6f593185752620008f7b6fd6149 (patch) | |
tree | 7efb7a6114f8143cbe7fb0b44611c543606b2f32 /clang/lib/CIR/CodeGen/CIRGenModule.cpp | |
parent | 77f8335a07e65f88a2c2925f175f48c458911cee (diff) | |
download | llvm-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.cpp | 52 |
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() || |