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
213 lines
6.6 KiB
C++
213 lines
6.6 KiB
C++
#include "TargetInfo.h"
|
|
#include "ABIInfo.h"
|
|
#include "CIRGenFunction.h"
|
|
#include "CIRGenModule.h"
|
|
#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
|
|
#include "clang/Basic/AddressSpaces.h"
|
|
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
|
|
#include "clang/CIR/Dialect/IR/CIRDialect.h"
|
|
#include "clang/CIR/MissingFeatures.h"
|
|
|
|
using namespace clang;
|
|
using namespace clang::CIRGen;
|
|
|
|
bool clang::CIRGen::isEmptyRecordForLayout(const ASTContext &context,
|
|
QualType t) {
|
|
const auto *rd = t->getAsRecordDecl();
|
|
if (!rd)
|
|
return false;
|
|
|
|
// If this is a C++ record, check the bases first.
|
|
if (const CXXRecordDecl *cxxrd = dyn_cast<CXXRecordDecl>(rd)) {
|
|
if (cxxrd->isDynamicClass())
|
|
return false;
|
|
|
|
for (const auto &i : cxxrd->bases())
|
|
if (!isEmptyRecordForLayout(context, i.getType()))
|
|
return false;
|
|
}
|
|
|
|
for (const auto *i : rd->fields())
|
|
if (!isEmptyFieldForLayout(context, i))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool clang::CIRGen::isEmptyFieldForLayout(const ASTContext &context,
|
|
const FieldDecl *fd) {
|
|
if (fd->isZeroLengthBitField())
|
|
return true;
|
|
|
|
if (fd->isUnnamedBitField())
|
|
return false;
|
|
|
|
return isEmptyRecordForLayout(context, fd->getType());
|
|
}
|
|
|
|
namespace {
|
|
|
|
class AMDGPUABIInfo : public ABIInfo {
|
|
public:
|
|
AMDGPUABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
|
|
};
|
|
|
|
class AMDGPUTargetCIRGenInfo : public TargetCIRGenInfo {
|
|
public:
|
|
AMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
|
|
: TargetCIRGenInfo(std::make_unique<AMDGPUABIInfo>(cgt)) {}
|
|
|
|
bool supportsLibCall() const override { return false; }
|
|
|
|
void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global,
|
|
CIRGenModule &cgm) const override {
|
|
if (auto func = mlir::dyn_cast<cir::FuncOp>(global)) {
|
|
if (requiresAMDGPUProtectedVisibility(decl, func.getGlobalVisibility())) {
|
|
func.setGlobalVisibility(cir::VisibilityKind::Protected);
|
|
func.setDSOLocal(true);
|
|
}
|
|
setAMDGPUTargetFunctionAttributes(decl, func, cgm);
|
|
} else if (auto gv = mlir::dyn_cast<cir::GlobalOp>(global)) {
|
|
if (requiresAMDGPUProtectedVisibility(decl, gv.getGlobalVisibility())) {
|
|
gv.setGlobalVisibility(cir::VisibilityKind::Protected);
|
|
gv.setDSOLocal(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
clang::LangAS
|
|
getGlobalVarAddressSpace(CIRGenModule &cgm,
|
|
const clang::VarDecl *decl) const override {
|
|
using clang::LangAS;
|
|
assert(!cgm.getLangOpts().OpenCL &&
|
|
!(cgm.getLangOpts().CUDA && cgm.getLangOpts().CUDAIsDevice) &&
|
|
"Address space agnostic languages only");
|
|
LangAS defaultGlobalAS = LangAS::opencl_global;
|
|
if (!decl)
|
|
return defaultGlobalAS;
|
|
|
|
LangAS addrSpace = decl->getType().getAddressSpace();
|
|
if (addrSpace != LangAS::Default)
|
|
return addrSpace;
|
|
|
|
// Only promote to address space 4 if VarDecl has constant initialization.
|
|
if (decl->getType().isConstantStorage(cgm.getASTContext(), false, false) &&
|
|
decl->hasConstantInitialization())
|
|
return LangAS::opencl_constant;
|
|
|
|
return defaultGlobalAS;
|
|
}
|
|
|
|
mlir::ptr::MemorySpaceAttrInterface
|
|
getCIRAllocaAddressSpace() const override {
|
|
return cir::LangAddressSpaceAttr::get(
|
|
&getABIInfo().cgt.getMLIRContext(),
|
|
cir::LangAddressSpace::OffloadPrivate);
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
namespace {
|
|
|
|
class X8664ABIInfo : public ABIInfo {
|
|
public:
|
|
X8664ABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
|
|
};
|
|
|
|
class X8664TargetCIRGenInfo : public TargetCIRGenInfo {
|
|
public:
|
|
X8664TargetCIRGenInfo(CIRGenTypes &cgt)
|
|
: TargetCIRGenInfo(std::make_unique<X8664ABIInfo>(cgt)) {}
|
|
};
|
|
} // namespace
|
|
|
|
namespace {
|
|
|
|
class NVPTXABIInfo : public ABIInfo {
|
|
public:
|
|
NVPTXABIInfo(CIRGenTypes &cgt) : ABIInfo(cgt) {}
|
|
};
|
|
|
|
class NVPTXTargetCIRGenInfo : public TargetCIRGenInfo {
|
|
public:
|
|
NVPTXTargetCIRGenInfo(CIRGenTypes &cgt)
|
|
: TargetCIRGenInfo(std::make_unique<NVPTXABIInfo>(cgt)) {}
|
|
|
|
void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global,
|
|
CIRGenModule &cgm) const override {
|
|
auto globalValue = mlir::dyn_cast<cir::CIRGlobalValueInterface>(global);
|
|
if (globalValue && globalValue.isDeclaration())
|
|
return;
|
|
|
|
const auto *vd = dyn_cast_or_null<VarDecl>(decl);
|
|
if (vd) {
|
|
if (cgm.getLangOpts().CUDA) {
|
|
if (vd->getType()->isCUDADeviceBuiltinSurfaceType() ||
|
|
vd->getType()->isCUDADeviceBuiltinTextureType())
|
|
assert(!cir::MissingFeatures::emitNVVMMetadata());
|
|
return;
|
|
}
|
|
}
|
|
|
|
const auto *fd = dyn_cast_or_null<FunctionDecl>(decl);
|
|
if (!fd)
|
|
return;
|
|
|
|
auto func = mlir::cast<cir::FuncOp>(global);
|
|
|
|
// Perform special handling in OpenCL/CUDA mode.
|
|
if (cgm.getLangOpts().OpenCL || cgm.getLangOpts().CUDA) {
|
|
// Use function attributes to check for kernel functions. By default, all
|
|
// functions are device functions.
|
|
if (fd->hasAttr<DeviceKernelAttr>() || fd->hasAttr<CUDAGlobalAttr>()) {
|
|
// OpenCL/CUDA kernel functions get kernel metadata. Kernel functions
|
|
// are also not subject to inlining.
|
|
func.setInlineKind(cir::InlineKind::NoInline);
|
|
if (fd->hasAttr<CUDAGlobalAttr>()) {
|
|
func.setCallingConv(cir::CallingConv::PTXKernel);
|
|
assert(!cir::MissingFeatures::opFuncParameterAttributes());
|
|
}
|
|
if (fd->hasAttr<CUDALaunchBoundsAttr>())
|
|
assert(!cir::MissingFeatures::handleCUDALaunchBoundsAttr());
|
|
}
|
|
}
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
std::unique_ptr<TargetCIRGenInfo>
|
|
clang::CIRGen::createAMDGPUTargetCIRGenInfo(CIRGenTypes &cgt) {
|
|
return std::make_unique<AMDGPUTargetCIRGenInfo>(cgt);
|
|
}
|
|
|
|
std::unique_ptr<TargetCIRGenInfo>
|
|
clang::CIRGen::createNVPTXTargetCIRGenInfo(CIRGenTypes &cgt) {
|
|
return std::make_unique<NVPTXTargetCIRGenInfo>(cgt);
|
|
}
|
|
|
|
std::unique_ptr<TargetCIRGenInfo>
|
|
clang::CIRGen::createX8664TargetCIRGenInfo(CIRGenTypes &cgt) {
|
|
return std::make_unique<X8664TargetCIRGenInfo>(cgt);
|
|
}
|
|
|
|
ABIInfo::~ABIInfo() noexcept = default;
|
|
|
|
bool TargetCIRGenInfo::isNoProtoCallVariadic(
|
|
const FunctionNoProtoType *fnType) const {
|
|
// The following conventions are known to require this to be false:
|
|
// x86_stdcall
|
|
// MIPS
|
|
// For everything else, we just prefer false unless we opt out.
|
|
return false;
|
|
}
|
|
|
|
clang::LangAS
|
|
TargetCIRGenInfo::getGlobalVarAddressSpace(CIRGenModule &cgm,
|
|
const clang::VarDecl *d) const {
|
|
assert(!cgm.getLangOpts().OpenCL &&
|
|
!(cgm.getLangOpts().CUDA && cgm.getLangOpts().CUDAIsDevice) &&
|
|
"Address space agnostic languages only");
|
|
return d ? d->getType().getAddressSpace() : LangAS::Default;
|
|
}
|