CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
122 lines
4.9 KiB
C++
122 lines
4.9 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This contains code dealing with code generation of C++ declarations
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "CIRGenCXXABI.h"
|
|
#include "CIRGenFunction.h"
|
|
#include "CIRGenModule.h"
|
|
#include "clang/AST/Attr.h"
|
|
#include "clang/AST/Mangle.h"
|
|
#include "clang/Basic/LangOptions.h"
|
|
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
|
|
|
|
using namespace clang;
|
|
using namespace clang::CIRGen;
|
|
|
|
void CIRGenFunction::emitCXXGuardedInit(const VarDecl &varDecl,
|
|
cir::GlobalOp globalOp,
|
|
bool performInit) {
|
|
// If we've been asked to forbid guard variables, emit an error now.
|
|
// This diagnostic is hard-coded for Darwin's use case; we can find
|
|
// better phrasing if someone else needs it.
|
|
if (cgm.getCodeGenOpts().ForbidGuardVariables)
|
|
cgm.error(varDecl.getLocation(), "guard variables are forbidden");
|
|
|
|
// Compute the mangled guard variable name and set the static_local attribute
|
|
// BEFORE emitting initialization. This ensures that GetGlobalOps created
|
|
// during initialization (e.g., in the ctor region) will see the attribute
|
|
// and be marked with static_local accordingly.
|
|
llvm::SmallString<256> guardName;
|
|
{
|
|
llvm::raw_svector_ostream out(guardName);
|
|
cgm.getCXXABI().getMangleContext().mangleStaticGuardVariable(&varDecl, out);
|
|
}
|
|
|
|
// Mark the global as static local with the guard name. The emission of the
|
|
// guard/acquire is done during LoweringPrepare.
|
|
auto guardAttr = mlir::StringAttr::get(&cgm.getMLIRContext(), guardName);
|
|
if (!varDecl.isStaticLocal())
|
|
cgm.errorNYI(
|
|
varDecl.getSourceRange(),
|
|
"Static local guard attr only valid on static local variables");
|
|
globalOp.setStaticLocalGuardAttr(
|
|
cir::StaticLocalGuardAttr::get(&cgm.getMLIRContext(), guardAttr));
|
|
|
|
// Emit the initializer and add a global destructor if appropriate.
|
|
// TODO(cir): classic codegen calls emitCXXGlobalVarDeclInit for this as well,
|
|
// and this is meant to handle cases with weak linkage (see comment in
|
|
// emitCXXGlobalVarDeclInitFunc). At one point we'll have to do some level of
|
|
// split here depending on whether this is a global (which should/can have
|
|
// ctor/dtor regions), or should have in-function initialization.
|
|
cgm.emitCXXStaticLocalVarDeclInit(&varDecl, globalOp, performInit);
|
|
}
|
|
|
|
void CIRGenModule::setGlobalTlsReferences(const VarDecl &vd,
|
|
cir::GlobalOp globalOp) {
|
|
assert(!vd.isStaticLocal() && vd.getTLSKind());
|
|
|
|
// C doesn't need guarded thread-local init, because it can't have
|
|
// non-constant init.
|
|
if (!getLangOpts().CPlusPlus)
|
|
return;
|
|
|
|
if (globalOp.getTlsModel() != cir::TLS_Model::GeneralDynamic)
|
|
return;
|
|
|
|
llvm::SmallString<256> wrapperFuncName;
|
|
llvm::SmallString<256> initFuncName;
|
|
llvm::SmallString<256> guardName;
|
|
|
|
if (getCXXABI().getMangleContext().getKind() == MangleContext::MK_Itanium) {
|
|
llvm::raw_svector_ostream wrapperOut(wrapperFuncName);
|
|
llvm::raw_svector_ostream initOut(initFuncName);
|
|
llvm::raw_svector_ostream guardStream(guardName);
|
|
|
|
auto &mc = cast<ItaniumMangleContext>(getCXXABI().getMangleContext());
|
|
mc.mangleItaniumThreadLocalWrapper(&vd, wrapperOut);
|
|
mc.mangleItaniumThreadLocalInit(&vd, initOut);
|
|
if (globalOp.hasWeakLinkage() || globalOp.hasLinkOnceLinkage() ||
|
|
isTemplateInstantiation(vd.getTemplateSpecializationKind())) {
|
|
getCXXABI().getMangleContext().mangleStaticGuardVariable(&vd,
|
|
guardStream);
|
|
}
|
|
|
|
} else {
|
|
errorNYI(vd.getSourceRange(),
|
|
"setGlobalTlsReferences: non-itanium mangler");
|
|
return;
|
|
}
|
|
globalOp.setDynTlsRefsAttr(cir::ThreadLocalGlobalWrapperInitAttr::get(
|
|
&getMLIRContext(), wrapperFuncName, initFuncName, guardName));
|
|
}
|
|
|
|
void CIRGenModule::emitCXXGlobalVarDeclInitFunc(const VarDecl *vd,
|
|
cir::GlobalOp addr,
|
|
bool performInit) {
|
|
assert(!cir::MissingFeatures::cudaSupport());
|
|
|
|
assert(!cir::MissingFeatures::deferredCXXGlobalInit());
|
|
|
|
// TODO(cir): Classic codegen calls emitCXXGuardedInit in the following case:
|
|
// template<typename T> struct Templ {
|
|
// static T f;
|
|
// };
|
|
// template<typename T> T Templ<T>::f = get_i();
|
|
// auto func() {
|
|
// Templ<int> t;
|
|
// return decltype(t)::f;
|
|
// }
|
|
//
|
|
// However, at the moment it is only suitable for static-local variables, so
|
|
// we will have to modify it to work for this case as well.
|
|
emitCXXGlobalVarDeclInit(vd, addr, performInit);
|
|
}
|