19#include "mlir/Dialect/OpenMP/OpenMPOffloadUtils.h"
22#include "clang/AST/Attrs.inc"
35#include "llvm/ADT/StringRef.h"
39#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
40#include "mlir/IR/Attributes.h"
41#include "mlir/IR/BuiltinOps.h"
42#include "mlir/IR/Location.h"
43#include "mlir/IR/MLIRContext.h"
44#include "mlir/IR/Operation.h"
45#include "mlir/IR/Verifier.h"
54 case TargetCXXABI::GenericItanium:
55 case TargetCXXABI::GenericAArch64:
56 case TargetCXXABI::AppleARM64:
59 case TargetCXXABI::Fuchsia:
60 case TargetCXXABI::GenericARM:
61 case TargetCXXABI::iOS:
62 case TargetCXXABI::WatchOS:
63 case TargetCXXABI::GenericMIPS:
64 case TargetCXXABI::WebAssembly:
65 case TargetCXXABI::XL:
66 case TargetCXXABI::Microsoft:
67 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
71 llvm_unreachable(
"invalid C++ ABI kind");
74CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
78 : builder(mlirContext, *this), astContext(astContext),
79 langOpts(astContext.
getLangOpts()), codeGenOpts(cgo),
80 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
81 diags(diags), target(astContext.getTargetInfo()),
82 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
110 .toCharUnitsFromBits(
114 const unsigned charSize = astContext.getTargetInfo().getCharWidth();
118 const unsigned sizeTypeSize =
119 astContext.getTypeSize(astContext.getSignedSizeType());
120 SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity();
127 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
130 cir::CIRDialect::getSourceLanguageAttrName(),
131 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
132 theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
133 builder.getStringAttr(
getTriple().str()));
135 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
136 theModule->setAttr(cir::CIRDialect::getOptInfoAttrName(),
137 cir::OptInfoAttr::get(&mlirContext,
138 cgo.OptimizationLevel,
141 if (langOpts.OpenMP) {
142 mlir::omp::OffloadModuleOpts ompOpts(
143 langOpts.OpenMPTargetDebug, langOpts.OpenMPTeamSubscription,
144 langOpts.OpenMPThreadSubscription, langOpts.OpenMPNoThreadState,
145 langOpts.OpenMPNoNestedParallelism, langOpts.OpenMPIsTargetDevice,
146 getTriple().isGPU(), langOpts.OpenMPForceUSM, langOpts.OpenMP,
147 langOpts.OMPHostIRFile, langOpts.OMPTargetTriples, langOpts.NoGPULib);
148 mlir::omp::setOffloadModuleInterfaceAttributes(theModule, ompOpts);
157 FileID mainFileId = astContext.getSourceManager().getMainFileID();
159 *astContext.getSourceManager().getFileEntryForID(mainFileId);
162 theModule.setSymName(path);
163 theModule->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
170 llvm::StringRef cudaBinaryName = codeGenOpts.CudaGpuBinaryFileName;
171 if (!cudaBinaryName.empty()) {
172 theModule->setAttr(cir::CIRDialect::getCUDABinaryHandleAttrName(),
173 cir::CUDABinaryHandleAttr::get(
174 &mlirContext, mlir::StringAttr::get(
175 &mlirContext, cudaBinaryName)));
182void CIRGenModule::createCUDARuntime() {
194 auto &layout = astContext.getASTRecordLayout(rd);
199 return layout.getAlignment();
202 return layout.getNonVirtualAlignment();
207 bool forPointeeType) {
217 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
220 return astContext.toCharUnitsFromBits(align);
228 t = astContext.getBaseElementType(t);
249 }
else if (forPointeeType && !alignForArray &&
253 alignment = astContext.getTypeAlignInChars(t);
258 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
260 !astContext.isAlignmentRequired(t))
274 if (theTargetCIRGenInfo)
275 return *theTargetCIRGenInfo;
278 switch (triple.getArch()) {
285 case llvm::Triple::x86_64: {
286 switch (triple.getOS()) {
293 case llvm::Triple::Linux:
295 return *theTargetCIRGenInfo;
298 case llvm::Triple::nvptx:
299 case llvm::Triple::nvptx64:
301 return *theTargetCIRGenInfo;
302 case llvm::Triple::amdgcn: {
304 return *theTargetCIRGenInfo;
310 assert(cLoc.
isValid() &&
"expected valid source location");
314 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
319 assert(cRange.
isValid() &&
"expected a valid source range");
322 mlir::Attribute metadata;
323 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
332 false, isForDefinition);
366 assert(op &&
"expected a valid global op");
374 mlir::Operation *globalValueOp = op;
375 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op))
377 mlir::SymbolTable::lookupSymbolIn(
getModule(), gv.getNameAttr());
379 if (
auto cirGlobalValue =
380 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
381 if (!cirGlobalValue.isDeclaration())
402 assert(deferredVTables.empty());
412 std::vector<GlobalDecl> curDeclsToEmit;
431 if (
auto *
attr =
decl->getAttr<AttrT>())
432 return attr->isImplicit();
433 return decl->isImplicit();
438 assert(langOpts.CUDA &&
"Should not be called by non-CUDA languages");
443 return !langOpts.CUDAIsDevice || global->
hasAttr<CUDADeviceAttr>() ||
444 global->
hasAttr<CUDAConstantAttr>() ||
445 global->
hasAttr<CUDASharedAttr>() ||
451 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
469 "Expected Variable or Function");
470 if (
const auto *
varDecl = dyn_cast<VarDecl>(global)) {
474 }
else if (langOpts.CUDAIsDevice) {
475 const auto *
functionDecl = dyn_cast<FunctionDecl>(global);
476 if ((!global->hasAttr<CUDADeviceAttr>() ||
477 (langOpts.OffloadImplicitHostDeviceTemplates &&
482 !
getASTContext().CUDAImplicitHostDeviceFunUsedByDevice.count(
484 !global->hasAttr<CUDAGlobalAttr>() &&
486 !global->hasAttr<CUDAHostAttr>()))
489 }
else if (!global->hasAttr<CUDAHostAttr>() &&
490 global->hasAttr<CUDADeviceAttr>())
494 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
497 if (fd->hasAttr<AnnotateAttr>())
498 errorNYI(fd->getSourceRange(),
"deferredAnnotations");
499 if (!fd->doesThisDeclarationHaveABody()) {
500 if (!fd->doesDeclarationForceExternallyVisibleDefinition())
504 "function declaration that forces code gen");
509 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
511 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
515 if (astContext.getInlineVariableDefinitionKind(vd) ==
554 mlir::Operation *op) {
558 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
559 if (!funcOp || funcOp.getFunctionType() != funcType) {
565 if (!funcOp.isDeclaration())
577 mlir::OpBuilder::InsertionGuard guard(builder);
582 setNonAliasAttributes(gd, funcOp);
585 auto getPriority = [
this](
const auto *
attr) ->
int {
589 return attr->DefaultPriority;
592 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
594 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
597 if (funcDecl->getAttr<AnnotateAttr>())
598 errorNYI(funcDecl->getSourceRange(),
"deferredAnnotations");
603 std::optional<int> priority) {
612 ctor.setGlobalCtorPriority(priority);
617 std::optional<int> priority) {
618 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
620 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
623 dtor.setGlobalDtorPriority(priority);
641 return mlir::SymbolTable::lookupSymbolIn(theModule, name);
646 StringRef name, mlir::Type t,
bool isConstant,
647 mlir::ptr::MemorySpaceAttrInterface addrSpace,
648 mlir::Operation *insertPoint) {
653 mlir::OpBuilder::InsertionGuard guard(builder);
659 builder.setInsertionPoint(insertPoint);
665 builder.setInsertionPointToStart(cgm.
getModule().getBody());
668 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
674 mlir::SymbolTable::setSymbolVisibility(
675 g, mlir::SymbolTable::Visibility::Private);
682 if (isa_and_nonnull<NamedDecl>(d))
686 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(gv)) {
687 if (d && d->
hasAttr<UsedAttr>())
690 if (
const auto *vd = dyn_cast_if_present<VarDecl>(d);
691 vd && ((codeGenOpts.KeepPersistentStorageVariables &&
692 (vd->getStorageDuration() ==
SD_Static ||
693 vd->getStorageDuration() ==
SD_Thread)) ||
694 (codeGenOpts.KeepStaticConsts &&
696 vd->getType().isConstQualified())))
701void CIRGenModule::setNonAliasAttributes(
GlobalDecl gd, mlir::Operation *op) {
706 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
707 if (
const auto *sa = d->
getAttr<SectionAttr>())
708 gvi.setSection(builder.getStringAttr(sa->getName()));
720std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
721 using ClangStd = clang::LangStandard;
722 using CIRLang = cir::SourceLanguage;
727 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
728 opts.LangStd == ClangStd::lang_c89 ||
729 opts.LangStd == ClangStd::lang_gnu89)
734 errorNYI(
"CIR does not yet support the given source language");
738LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
739 if (langOpts.OpenCL) {
747 if (langOpts.SYCLIsDevice &&
749 errorNYI(
"SYCL global address space");
751 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
753 if (d->
hasAttr<CUDAConstantAttr>())
755 if (d->
hasAttr<CUDASharedAttr>())
757 if (d->
hasAttr<CUDADeviceAttr>())
766 errorNYI(
"OpenMP global address space");
779 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
784 for (mlir::Attribute i : indexes) {
785 auto ind = mlir::cast<mlir::IntegerAttr>(i);
786 inds.push_back(ind.getValue().getSExtValue());
792 return view.getSymbol().getValue() == glob.getSymName();
796 cir::GlobalOp newGlob,
797 cir::GlobalViewAttr
attr,
808 mlir::Type newTy = newGlob.getSymType();
813 cir::PointerType newPtrTy;
816 newPtrTy = cir::PointerType::get(newTy);
825 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
831 mlir::Attribute oldInit) {
832 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
835 auto getNewInitElements =
836 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
838 for (mlir::Attribute elt : oldElements) {
839 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
841 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
844 newElements.push_back(elt);
846 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
849 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
850 mlir::Attribute newElements =
851 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldArray.getElts()));
853 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
855 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
856 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
857 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
859 newMembers, recordTy.getPacked(), recordTy.getPadded(), recordTy);
864 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
872 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
874 mlir::Type oldTy = oldGV.getSymType();
875 mlir::Type newTy = newGV.getSymType();
880 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
883 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
884 oldGV.getSymbolUses(theModule);
885 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
886 mlir::Operation *userOp = use.getUser();
888 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
889 "Unexpected user for global op");
891 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
892 mlir::Value useOpResultValue = getGlobalOp.getAddr();
893 useOpResultValue.setType(cir::PointerType::get(newTy));
895 mlir::OpBuilder::InsertionGuard guard(builder);
896 builder.setInsertionPointAfter(getGlobalOp);
897 mlir::Type ptrTy = builder.getPointerTo(oldTy);
899 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
900 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
901 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
902 if (
auto init = glob.getInitialValue()) {
903 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
904 glob.setInitialValueAttr(nw);
906 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
908 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
909 mlir::OpBuilder::InsertionGuard guard(builder);
910 builder.setInsertionPointAfter(
c);
911 auto newUser = cir::ConstantOp::create(builder,
c.getLoc(), typedAttr);
912 c.replaceAllUsesWith(newUser.getOperation());
944 "getOrCreateCIRGlobal: global with non-GlobalOp type");
949 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
955 if (entry.getSymType() == ty &&
965 if (isForDefinition && !entry.isDeclaration()) {
967 "getOrCreateCIRGlobal: global with conflicting type");
975 if (!isForDefinition)
984 bool isConstant =
false;
989 astContext,
true, !needsDtor);
992 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
998 *
this, loc, mangledName, ty, isConstant, declCIRAS,
999 entry.getOperation());
1019 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
1021 "getOrCreateCIRGlobal: OpenMP target global variable");
1023 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1037 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1039 "getOrCreateCIRGlobal: MS static data member inline definition");
1043 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1044 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1049 if (
getTriple().getArch() == llvm::Triple::xcore)
1051 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1061 "getOrCreateCIRGlobal: external const declaration with initializer");
1073 "getOrCreateCIRGlobal: HIP managed attribute");
1108 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1109 return cir::GetGlobalOp::create(
1112 g.getStaticLocalGuard().has_value());
1120 cir::PointerType ptrTy =
1121 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1122 return builder.getGlobalViewAttr(ptrTy, globalOp);
1126 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1127 !gv.isDeclarationForLinker()) &&
1128 "Only globals with definition can force usage.");
1133 assert(!gv.isDeclarationForLinker() &&
1134 "Only globals with definition can force usage.");
1139 cir::CIRGlobalValueInterface gv) {
1140 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1141 !gv.isDeclarationForLinker()) &&
1142 "Only globals with definition can force usage.");
1150 std::vector<cir::CIRGlobalValueInterface> &list) {
1155 mlir::Location loc = builder.getUnknownLoc();
1157 usedArray.resize(list.size());
1158 for (
auto [i, op] : llvm::enumerate(list)) {
1159 usedArray[i] = cir::GlobalViewAttr::get(
1160 cgm.
voidPtrTy, mlir::FlatSymbolRefAttr::get(op.getNameAttr()));
1163 cir::ArrayType arrayTy = cir::ArrayType::get(cgm.
voidPtrTy, usedArray.size());
1165 cir::ConstArrayAttr initAttr = cir::ConstArrayAttr::get(
1166 arrayTy, mlir::ArrayAttr::get(&cgm.
getMLIRContext(), usedArray));
1170 gv.setLinkage(cir::GlobalLinkageKind::AppendingLinkage);
1171 gv.setInitialValueAttr(initAttr);
1172 gv.setSectionAttr(builder.getStringAttr(
"llvm.metadata"));
1184 "emitGlobalVarDefinition: emit OpenCL/OpenMP global variable");
1191 bool isDefinitionAvailableExternally =
1196 if (isDefinitionAvailableExternally &&
1204 mlir::Attribute init;
1205 bool needsGlobalCtor =
false;
1206 bool needsGlobalDtor =
1207 !isDefinitionAvailableExternally &&
1212 std::optional<ConstantEmitter> emitter;
1217 bool isCUDASharedVar =
1222 bool isCUDAShadowVar =
1224 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1225 vd->
hasAttr<CUDASharedAttr>());
1226 bool isCUDADeviceShadowVar =
1232 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1234 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1236 "emitGlobalVarDefinition: loader uninitialized attribute");
1237 }
else if (!initExpr) {
1250 emitter.emplace(*
this);
1251 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1260 "emitGlobalVarDefinition: flexible array initializer");
1262 if (!isDefinitionAvailableExternally)
1263 needsGlobalCtor =
true;
1266 "emitGlobalVarDefinition: static initializer");
1277 mlir::Type initType;
1278 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1281 "emitGlobalVarDefinition: global initializer is a symbol reference");
1284 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1285 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1286 initType = typedInitAttr.getType();
1288 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1294 if (!gv || gv.getSymType() != initType) {
1296 "emitGlobalVarDefinition: global initializer with type mismatch");
1302 if (vd->
hasAttr<AnnotateAttr>()) {
1304 "emitGlobalVarDefinition: annotate global variable");
1308 cir::GlobalLinkageKind linkage =
1318 if (langOpts.CUDA) {
1319 if (langOpts.CUDAIsDevice) {
1322 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1324 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1327 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1343 emitter->finalize(gv);
1347 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1348 (!needsGlobalCtor && !needsGlobalDtor &&
1353 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1356 gv.setConstant(
true);
1360 gv.setLinkage(linkage);
1364 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1366 gv.setConstant(
false);
1371 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1372 if (initializer && !
getBuilder().isNullValue(*initializer))
1373 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1376 setNonAliasAttributes(vd, gv);
1383 if (needsGlobalCtor || needsGlobalDtor)
1388 mlir::Operation *op) {
1390 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1394 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1398 abi->emitCXXStructor(gd);
1399 else if (fd->isMultiVersion())
1400 errorNYI(method->getSourceRange(),
"multiversion functions");
1404 if (method->isVirtual())
1410 if (fd->isMultiVersion())
1411 errorNYI(fd->getSourceRange(),
"multiversion functions");
1416 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1419 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1433 astContext.getAsConstantArrayType(e->
getType());
1434 uint64_t finalSize = cat->getZExtSize();
1435 str.resize(finalSize);
1437 mlir::Type eltTy =
convertType(cat->getElementType());
1438 return builder.getString(str, eltTy, finalSize,
false);
1443 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1445 uint64_t arraySize = arrayTy.getSize();
1447 assert(arraySize == literalSize + 1 &&
1448 "wide string literal array size must be literal length plus null "
1453 bool isAllZero =
true;
1454 for (
unsigned i = 0; i < literalSize; ++i) {
1462 return cir::ZeroAttr::get(arrayTy);
1466 elements.reserve(arraySize);
1467 for (
unsigned i = 0; i < literalSize; ++i)
1468 elements.push_back(cir::IntAttr::get(arrayEltTy, e->
getCodeUnit(i)));
1470 elements.push_back(cir::IntAttr::get(arrayEltTy, 0));
1472 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1473 return builder.getConstArray(elementsAttr, arrayTy);
1484 if (d.
hasAttr<SelectAnyAttr>())
1488 if (
auto *vd = dyn_cast<VarDecl>(&d))
1503 llvm_unreachable(
"No such linkage");
1509 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1510 globalOp.setComdat(
true);
1513 funcOp.setComdat(
true);
1519 genTypes.updateCompletedType(td);
1523 replacements[name] = op;
1529 std::optional<mlir::SymbolTable::UseRange> optionalUseRange =
1530 oldF.getSymbolUses(modOp);
1531 if (!optionalUseRange)
1534 for (
const mlir::SymbolTable::SymbolUse &u : *optionalUseRange) {
1535 auto call = mlir::dyn_cast<cir::CallOp>(u.getUser());
1539 for (
auto [argOp, fnArgType] :
1540 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1541 if (argOp.getType() != fnArgType)
1550void CIRGenModule::applyReplacements() {
1551 for (
auto &i : replacements) {
1552 StringRef mangledName = i.first;
1553 mlir::Operation *replacement = i.second;
1559 auto newF = dyn_cast<cir::FuncOp>(replacement);
1562 errorNYI(replacement->getLoc(),
"replacement is not a function");
1567 "call argument types do not match replacement function");
1570 if (oldF.replaceAllSymbolUses(newF.getSymNameAttr(), theModule).failed())
1571 llvm_unreachable(
"internal error, cannot RAUW symbol");
1573 newF->moveBefore(oldF);
1580 mlir::Location loc, StringRef name, mlir::Type ty,
1582 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
1583 mlir::SymbolTable::lookupSymbolIn(theModule, name));
1587 if (gv.getSymType() == ty)
1593 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1595 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1606 mlir::SymbolTable::setSymbolVisibility(gv,
1610 !gv.hasAvailableExternallyLinkage()) {
1614 gv.setAlignmentAttr(
getSize(alignment));
1625 if ((noCommon || vd->
hasAttr<NoCommonAttr>()) && !vd->
hasAttr<CommonAttr>())
1636 if (vd->
hasAttr<SectionAttr>())
1642 if (vd->
hasAttr<PragmaClangBSSSectionAttr>() ||
1643 vd->
hasAttr<PragmaClangDataSectionAttr>() ||
1644 vd->
hasAttr<PragmaClangRelroSectionAttr>() ||
1645 vd->
hasAttr<PragmaClangRodataSectionAttr>())
1653 if (vd->
hasAttr<WeakImportAttr>())
1663 if (vd->
hasAttr<AlignedAttr>())
1670 for (
const FieldDecl *fd : rd->fields()) {
1671 if (fd->isBitField())
1673 if (fd->hasAttr<AlignedAttr>())
1698 return cir::GlobalLinkageKind::InternalLinkage;
1700 if (dd->
hasAttr<WeakAttr>()) {
1701 if (isConstantVariable)
1702 return cir::GlobalLinkageKind::WeakODRLinkage;
1703 return cir::GlobalLinkageKind::WeakAnyLinkage;
1708 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
1713 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
1727 return !astContext.getLangOpts().AppleKext
1728 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
1729 : cir::GlobalLinkageKind::InternalLinkage;
1743 return cir::GlobalLinkageKind::ExternalLinkage;
1746 return dd->
hasAttr<CUDAGlobalAttr>()
1747 ? cir::GlobalLinkageKind::ExternalLinkage
1748 : cir::GlobalLinkageKind::InternalLinkage;
1749 return cir::GlobalLinkageKind::WeakODRLinkage;
1757 return cir::GlobalLinkageKind::CommonLinkage;
1763 if (dd->
hasAttr<SelectAnyAttr>())
1764 return cir::GlobalLinkageKind::WeakODRLinkage;
1768 return cir::GlobalLinkageKind::ExternalLinkage;
1780 mlir::Operation *old, cir::FuncOp newFn) {
1782 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
1790 if (oldFn->getAttrs().size() <= 1)
1792 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
1795 newFn.setNoProto(oldFn.getNoProto());
1798 std::optional<mlir::SymbolTable::UseRange> symUses =
1799 oldFn.getSymbolUses(oldFn->getParentOp());
1800 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
1801 mlir::OpBuilder::InsertionGuard guard(builder);
1803 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
1804 builder.setInsertionPoint(noProtoCallOp);
1807 cir::CallOp realCallOp = builder.createCallOp(
1808 noProtoCallOp.getLoc(), newFn, noProtoCallOp.getOperands());
1811 noProtoCallOp.replaceAllUsesWith(realCallOp);
1812 noProtoCallOp.erase();
1813 }
else if (
auto getGlobalOp =
1814 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1816 getGlobalOp.getAddr().setType(
1817 cir::PointerType::get(newFn.getFunctionType()));
1818 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
1824 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
1829cir::GlobalLinkageKind
1831 assert(!isConstant &&
"constant variables NYI");
1832 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
1839 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
1841 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
1850 StringRef globalName,
CharUnits alignment) {
1856 cgm, loc, globalName,
c.getType(), !cgm.
getLangOpts().WritableStrings);
1859 gv.setAlignmentAttr(cgm.
getSize(alignment));
1861 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
1865 if (gv.isWeakForLinker()) {
1866 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
1869 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
1890 std::string result =
1893 assert(!mlir::SymbolTable::lookupSymbolIn(theModule, result));
1901 astContext.getAlignOfGlobalVarInChars(
s->getType(),
nullptr);
1909 if (!gv.getAlignment() ||
1910 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
1911 gv.setAlignmentAttr(
getSize(alignment));
1916 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(
s) &&
1919 "getGlobalForStringLiteral: mangle string literals");
1927 mlir::Location loc =
s->getBeginLoc().isValid()
1929 : builder.getUnknownLoc();
1930 auto typedC = llvm::cast<mlir::TypedAttr>(
c);
1932 cir::GlobalLinkageKind::PrivateLinkage, *
this,
1933 uniqueName, alignment);
1947 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
1948 assert(arrayTy &&
"String literal must be array");
1952 return builder.getGlobalViewAttr(ptrTy, gv);
1968 errorNYI(
"SYCL or OpenMP temp address space");
1978 "emitExplicitCastExprType");
1984 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
1985 return builder.getNullMethodAttr(ty);
1988 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
1989 return builder.getNullDataMemberAttr(ty);
2000 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
2002 if (methodDecl->isVirtual())
2003 return cir::ConstantOp::create(
2004 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
2010 return cir::ConstantOp::create(builder, loc,
2011 builder.getMethodAttr(ty, methodFuncOp));
2017 return cir::ConstantOp::create(
2018 builder, loc, builder.getDataMemberAttr(ty,
fieldDecl->getFieldIndex()));
2028 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
2029 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
2039 if (
decl->isTemplated())
2042 switch (
decl->getKind()) {
2045 decl->getDeclKindName());
2048 case Decl::CXXConversion:
2049 case Decl::CXXMethod:
2050 case Decl::Function: {
2053 if (!fd->isConsteval())
2062 case Decl::Decomposition:
2063 case Decl::VarTemplateSpecialization: {
2065 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
2066 for (
auto *binding : decomp->flat_bindings())
2067 if (
auto *holdingVar = binding->getHoldingVar())
2071 case Decl::OpenACCRoutine:
2074 case Decl::OpenACCDeclare:
2077 case Decl::OMPThreadPrivate:
2080 case Decl::OMPGroupPrivate:
2083 case Decl::OMPAllocate:
2086 case Decl::OMPCapturedExpr:
2089 case Decl::OMPDeclareReduction:
2092 case Decl::OMPDeclareMapper:
2095 case Decl::OMPRequires:
2100 case Decl::UsingDirective:
2101 case Decl::UsingEnum:
2102 case Decl::NamespaceAlias:
2104 case Decl::TypeAlias:
2110 case Decl::ClassTemplate:
2112 case Decl::CXXDeductionGuide:
2114 case Decl::FunctionTemplate:
2115 case Decl::StaticAssert:
2116 case Decl::TypeAliasTemplate:
2117 case Decl::UsingShadow:
2118 case Decl::VarTemplate:
2119 case Decl::VarTemplatePartialSpecialization:
2122 case Decl::CXXConstructor:
2125 case Decl::CXXDestructor:
2130 case Decl::LinkageSpec:
2131 case Decl::Namespace:
2135 case Decl::ClassTemplateSpecialization:
2136 case Decl::CXXRecord: {
2139 for (
auto *childDecl : crd->
decls())
2145 case Decl::FileScopeAsm:
2147 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2150 if (langOpts.OpenMPIsTargetDevice)
2153 if (langOpts.SYCLIsDevice)
2156 std::string line = file_asm->getAsmString();
2157 globalScopeAsm.push_back(builder.getStringAttr(line));
2164 op.setInitialValueAttr(value);
2178 md->getParent()->getNumVBases() == 0)
2180 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2191 false, isForDefinition);
2193 return {fnType, fn};
2197 mlir::Type funcType,
bool forVTable,
2201 "consteval function should never be emitted");
2211 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2214 dd->getParent()->getNumVBases() == 0)
2216 "getAddrOfFunction: MS ABI complete destructor");
2222 false, isForDefinition);
2224 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2230 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2231 if (isForDefinition || isHIPHandle)
2233 return mlir::dyn_cast<cir::FuncOp>(*handle);
2242 llvm::raw_svector_ostream
out(buffer);
2251 assert(ii &&
"Attempt to mangle unnamed decl.");
2253 const auto *fd = dyn_cast<FunctionDecl>(nd);
2257 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2261 DeviceKernelAttr::isOpenCLSpelling(
2262 fd->getAttr<DeviceKernelAttr>()) &&
2279 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2280 if (fd->isMultiVersion()) {
2282 "getMangledName: multi-version functions");
2287 "getMangledName: GPU relocatable device code");
2290 return std::string(
out.str());
2293static FunctionDecl *
2308 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2309 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2311 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2314 fpt->getExtProtoInfo());
2325 params.reserve(fpt->getNumParams());
2328 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2332 nullptr, fpt->getParamType(i),
nullptr,
2335 params.push_back(parm);
2338 tempFunc->setParams(params);
2363 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2366 "getMangledName: C++ constructor without variants");
2375 auto result = manglings.insert(std::make_pair(mangledName, gd));
2376 return mangledDeclNames[canonicalGd] = result.first->first();
2380 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2388 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
2404 if (langOpts.EmitAllDecls)
2407 const auto *vd = dyn_cast<VarDecl>(global);
2409 ((codeGenOpts.KeepPersistentStorageVariables &&
2410 (vd->getStorageDuration() ==
SD_Static ||
2411 vd->getStorageDuration() ==
SD_Thread)) ||
2412 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
2413 vd->getType().isConstQualified())))
2426 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
2427 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
2428 OMPDeclareTargetDeclAttr::getActiveAttr(global);
2429 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
2433 const auto *fd = dyn_cast<FunctionDecl>(global);
2440 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
2442 if (langOpts.SYCLIsDevice) {
2443 errorNYI(fd->getSourceRange(),
"mayBeEmittedEagerly: SYCL");
2447 const auto *vd = dyn_cast<VarDecl>(global);
2449 if (astContext.getInlineVariableDefinitionKind(vd) ==
2457 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
2458 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
2460 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
2463 assert((fd || vd) &&
2464 "Only FunctionDecl and VarDecl should hit this path so far.");
2469 cir::CIRGlobalValueInterface gv) {
2470 if (gv.hasLocalLinkage())
2473 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
2481 const llvm::Triple &tt = cgm.
getTriple();
2483 if (tt.isOSCygMing()) {
2492 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
2498 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
2506 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
2510 if (!tt.isOSBinFormatELF())
2515 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
2523 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
2527 if (!gv.isDeclarationForLinker())
2533 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
2540 if (cgOpts.DirectAccessExternalData) {
2546 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
2579 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
2598 auto res = manglings.find(mangledName);
2599 if (res == manglings.end())
2601 result = res->getValue();
2608 return cir::TLS_Model::GeneralDynamic;
2610 return cir::TLS_Model::LocalDynamic;
2612 return cir::TLS_Model::InitialExec;
2614 return cir::TLS_Model::LocalExec;
2616 llvm_unreachable(
"Invalid TLS model!");
2620 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
2625 if (d.
getAttr<TLSModelAttr>())
2629 global.setTlsModel(tlm);
2634 cir::FuncOp func,
bool isThunk) {
2636 cir::CallingConv callingConv;
2637 cir::SideEffect sideEffect;
2644 mlir::NamedAttrList pal{};
2645 std::vector<mlir::NamedAttrList> argAttrs(info.
arguments().size());
2646 mlir::NamedAttrList retAttrs{};
2648 retAttrs, callingConv, sideEffect,
2651 for (mlir::NamedAttribute
attr : pal)
2652 func->setAttr(
attr.getName(),
attr.getValue());
2654 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
2655 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
2656 idx_arg_pair.value());
2658 if (!retAttrs.empty())
2659 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
2672 bool isIncompleteFunction,
2680 if (!isIncompleteFunction)
2682 getTypes().arrangeGlobalDeclaration(globalDecl),
2685 if (!isIncompleteFunction && func.isDeclaration())
2698 if (funcDecl->isInlineBuiltinDeclaration()) {
2700 bool hasBody = funcDecl->
hasBody(fdBody);
2702 assert(hasBody &&
"Inline builtin declarations should always have an "
2707 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
2710 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
2722 if (!langOpts.Exceptions)
2725 if (langOpts.CXXExceptions)
2728 if (langOpts.ObjCExceptions)
2739 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
2742 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
2744 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
2745 bool isAlwaysInline = existingInlineKind &&
2746 *existingInlineKind == cir::InlineKind::AlwaysInline;
2750 if (!isAlwaysInline &&
2755 f.setInlineKind(cir::InlineKind::NoInline);
2770 if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
2772 f.setInlineKind(cir::InlineKind::NoInline);
2773 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
2776 f.setInlineKind(cir::InlineKind::AlwaysInline);
2780 if (!isAlwaysInline)
2781 f.setInlineKind(cir::InlineKind::NoInline);
2786 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
2791 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
2792 return redecl->isInlineSpecified();
2794 if (any_of(
decl->redecls(), checkRedeclForInline))
2799 return any_of(pattern->
redecls(), checkRedeclForInline);
2801 if (checkForInline(fd)) {
2802 f.setInlineKind(cir::InlineKind::InlineHint);
2803 }
else if (codeGenOpts.getInlining() ==
2805 !fd->isInlined() && !isAlwaysInline) {
2806 f.setInlineKind(cir::InlineKind::NoInline);
2815 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
2817 mlir::NamedAttrList extraAttrs) {
2820 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
2822 if (
getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
2825 "getOrCreateCIRFunction: OpenMP target function");
2829 if (fd->isMultiVersion())
2830 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
2836 assert(mlir::isa<cir::FuncOp>(entry));
2841 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
2849 if (isForDefinition && fn && !fn.isDeclaration()) {
2856 diagnosedConflictingDefinitions.insert(gd).second) {
2860 diag::note_previous_definition);
2864 if (fn && fn.getFunctionType() == funcType) {
2868 if (!isForDefinition) {
2876 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
2877 bool invalidLoc = !funcDecl ||
2878 funcDecl->getSourceRange().getBegin().isInvalid() ||
2879 funcDecl->getSourceRange().getEnd().isInvalid();
2881 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
2882 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
2893 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
2901 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
2910 if (!extraAttrs.empty()) {
2911 extraAttrs.append(funcOp->getAttrs());
2912 funcOp->setAttrs(extraAttrs);
2919 assert(funcOp.getFunctionType() == funcType);
2926 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
2956 fd = fd->getPreviousDecl()) {
2958 if (fd->doesThisDeclarationHaveABody()) {
2971 cir::FuncType funcType,
2975 mlir::OpBuilder::InsertionGuard guard(builder);
2983 builder.setInsertionPoint(cgf->
curFn);
2985 func = cir::FuncOp::create(builder, loc, name, funcType);
2990 func.setNoProto(
true);
2992 assert(func.isDeclaration() &&
"expected empty body");
2996 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
2998 mlir::SymbolTable::setSymbolVisibility(
2999 func, mlir::SymbolTable::Visibility::Private);
3007 theModule.push_back(func);
3012 for (
const auto *
attr :
3026 fnOp.setBuiltin(
true);
3032 return cir::CtorKind::Default;
3034 return cir::CtorKind::Copy;
3036 return cir::CtorKind::Move;
3037 return cir::CtorKind::Custom;
3042 return cir::AssignKind::Copy;
3044 return cir::AssignKind::Move;
3045 llvm_unreachable(
"not a copy or move assignment operator");
3053 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
3054 auto cxxDtor = cir::CXXDtorAttr::get(
3057 funcOp.setCxxSpecialMemberAttr(cxxDtor);
3061 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
3063 auto cxxCtor = cir::CXXCtorAttr::get(
3065 kind, ctor->isTrivial());
3066 funcOp.setCxxSpecialMemberAttr(cxxCtor);
3070 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
3071 if (method && (method->isCopyAssignmentOperator() ||
3072 method->isMoveAssignmentOperator())) {
3074 auto cxxAssign = cir::CXXAssignAttr::get(
3076 assignKind, method->isTrivial());
3077 funcOp.setCxxSpecialMemberAttr(cxxAssign);
3083 cir::FuncOp funcOp, StringRef name) {
3099 mlir::NamedAttrList extraAttrs,
3101 bool assumeConvergent) {
3102 if (assumeConvergent)
3103 errorNYI(
"createRuntimeFunction: assumeConvergent");
3113 entry.setDSOLocal(
true);
3119mlir::SymbolTable::Visibility
3123 if (op.isDeclaration())
3124 return mlir::SymbolTable::Visibility::Private;
3128mlir::SymbolTable::Visibility
3131 case cir::GlobalLinkageKind::InternalLinkage:
3132 case cir::GlobalLinkageKind::PrivateLinkage:
3133 return mlir::SymbolTable::Visibility::Private;
3134 case cir::GlobalLinkageKind::ExternalLinkage:
3135 case cir::GlobalLinkageKind::ExternalWeakLinkage:
3136 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
3137 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
3138 case cir::GlobalLinkageKind::CommonLinkage:
3139 case cir::GlobalLinkageKind::WeakAnyLinkage:
3140 case cir::GlobalLinkageKind::WeakODRLinkage:
3141 return mlir::SymbolTable::Visibility::Public;
3143 llvm::errs() <<
"visibility not implemented for '"
3144 << stringifyGlobalLinkageKind(glk) <<
"'\n";
3145 assert(0 &&
"not implemented");
3148 llvm_unreachable(
"linkage should be handled above!");
3152 clang::VisibilityAttr::VisibilityType visibility) {
3153 switch (visibility) {
3154 case clang::VisibilityAttr::VisibilityType::Default:
3155 return cir::VisibilityKind::Default;
3156 case clang::VisibilityAttr::VisibilityType::Hidden:
3157 return cir::VisibilityKind::Hidden;
3158 case clang::VisibilityAttr::VisibilityType::Protected:
3159 return cir::VisibilityKind::Protected;
3161 llvm_unreachable(
"unexpected visibility value");
3166 const clang::VisibilityAttr *va =
decl->getAttr<clang::VisibilityAttr>();
3167 cir::VisibilityAttr cirVisibility =
3170 cirVisibility = cir::VisibilityAttr::get(
3174 return cirVisibility;
3180 applyReplacements();
3182 theModule->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
3183 builder.getArrayAttr(globalScopeAsm));
3185 if (!recordLayoutEntries.empty())
3187 cir::CIRDialect::getRecordLayoutsAttrName(),
3188 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
3197 std::string cuidName =
3200 auto loc = builder.getUnknownLoc();
3201 mlir::ptr::MemorySpaceAttrInterface addrSpace =
3203 getGlobalVarAddressSpace(
nullptr));
3207 gv.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
3209 auto zeroAttr = cir::IntAttr::get(int8Ty, 0);
3210 gv.setInitialValueAttr(zeroAttr);
3212 mlir::SymbolTable::setSymbolVisibility(
3213 gv, mlir::SymbolTable::Visibility::Public);
3226 cir::FuncOp aliasee,
3227 cir::GlobalLinkageKind linkage) {
3229 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
3230 assert(aliasFD &&
"expected FunctionDecl");
3241 mangledName, fnType, aliasFD);
3242 alias.setAliasee(aliasee.getName());
3243 alias.setLinkage(linkage);
3247 mlir::SymbolTable::setSymbolVisibility(
3248 alias, mlir::SymbolTable::Visibility::Private);
3260 "declaration exists with different type");
3271 return genTypes.convertType(
type);
3278 return mlir::verify(theModule).succeeded();
3287 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
3290 langOpts.ObjCRuntime.isGNUFamily()) {
3291 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
3301 llvm::iterator_range<CastExpr::path_const_iterator> path) {
3308 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
3313 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
3325 llvm::StringRef feature) {
3326 unsigned diagID = diags.getCustomDiagID(
3328 return diags.Report(loc, diagID) << feature;
3332 llvm::StringRef feature) {
3344 "cannot compile this %0 yet");
3345 diags.Report(astContext.getFullLoc(
s->getBeginLoc()), diagId)
3346 <<
type <<
s->getSourceRange();
3352 "cannot compile this %0 yet");
3353 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
3357 cir::LabelOp label) {
3358 [[maybe_unused]]
auto result =
3360 assert(result.second &&
3361 "attempting to map a blockaddress info that is already mapped");
3366 assert(result.second &&
3367 "attempting to map a blockaddress operation that is already mapped");
3371 cir::LabelOp label) {
3373 assert(result.second &&
3374 "attempting to map a blockaddress operation that is already mapped");
3378 cir::LabelOp newLabel) {
3381 "trying to update a blockaddress not previously mapped");
3382 assert(!it->second &&
"blockaddress already has a resolved label");
3384 it->second = newLabel;
3397 "not a global temporary");
3409 materializedType = mte->
getType();
3413 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
3414 if (!insertResult.second)
3421 llvm::raw_svector_ostream
out(name);
3439 value = &evalResult.
Val;
3443 std::optional<ConstantEmitter> emitter;
3444 mlir::Attribute initialValue =
nullptr;
3445 bool isConstant =
false;
3449 emitter.emplace(*
this);
3450 initialValue = emitter->emitForInitializer(*value, materializedType);
3455 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
3463 cir::GlobalLinkageKind linkage =
3465 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
3467 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
3475 linkage = cir::GlobalLinkageKind::InternalLinkage;
3480 gv.setInitialValueAttr(initialValue);
3483 emitter->finalize(gv);
3485 if (!gv.hasLocalLinkage()) {
3490 gv.setAlignment(align.getAsAlign().value());
3493 "Global temporary with comdat/weak linkage");
3496 "Global temporary with thread local storage");
3497 mlir::Operation *cv = gv;
3503 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
3505 entry->replaceAllUsesWith(cv);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static bool shouldAssumeDSOLocal(const CIRGenModule &cgm, cir::CIRGlobalValueInterface gv)
static cir::AssignKind getAssignKindFromDecl(const CXXMethodDecl *method)
static FunctionDecl * createOpenACCBindTempFunction(ASTContext &ctx, const IdentifierInfo *bindName, const FunctionDecl *protoFunc)
static bool shouldBeInCOMDAT(CIRGenModule &cgm, const Decl &d)
static mlir::Attribute getNewInitValue(CIRGenModule &cgm, cir::GlobalOp newGlob, mlir::Type oldTy, mlir::Attribute oldInit)
static bool hasUnwindExceptions(const LangOptions &langOpts)
Determines whether the language options require us to model unwind exceptions.
static void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal, cir::FuncOp funcOp, StringRef name)
static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, const NamedDecl *nd)
static llvm::SmallVector< int64_t > indexesOfArrayAttr(mlir::ArrayAttr indexes)
static bool isViewOnGlobal(cir::GlobalOp glob, cir::GlobalViewAttr view)
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
static bool hasImplicitAttr(const ValueDecl *decl)
static CIRGenCXXABI * createCXXABI(CIRGenModule &cgm)
static bool isVarDeclStrongDefinition(const ASTContext &astContext, CIRGenModule &cgm, const VarDecl *vd, bool noCommon)
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd)
static cir::CtorKind getCtorKindFromDecl(const CXXConstructorDecl *ctor)
static void emitUsed(CIRGenModule &cgm, StringRef name, std::vector< cir::CIRGlobalValueInterface > &list)
static bool verifyPointerTypeArgs(mlir::ModuleOp modOp, cir::FuncOp oldF, cir::FuncOp newF)
static cir::GlobalViewAttr createNewGlobalView(CIRGenModule &cgm, cir::GlobalOp newGlob, cir::GlobalViewAttr attr, mlir::Type oldTy)
This file defines OpenACC nodes for declarative directives.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the SourceManager interface.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
cir::GlobalViewAttr getGlobalViewAttr(cir::GlobalOp globalOp, mlir::ArrayAttr indices={})
Get constant address of a global variable as an MLIR attribute.
cir::PointerType getPointerTo(mlir::Type ty)
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
@ Strong
Strong definition.
@ WeakUnknown
Weak for now, might become strong later in this TU.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
StringRef getCUIDHash() const
void Deallocate(void *Ptr) const
GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
GVALinkage GetGVALinkageForVariable(const VarDecl *VD) const
unsigned getTypeAlignIfKnown(QualType T, bool NeedsPreferredAlignment=false) const
Return the alignment of a type, in bits, or 0 if the type is incomplete and we cannot determine the a...
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
const TargetInfo & getTargetInfo() const
TargetCXXABI::Kind getCXXABIKind() const
Return the C++ ABI kind that should be used.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, bool packed=false, bool padded=false, mlir::Type type={})
uint64_t computeOffsetFromGlobalViewIndices(const cir::CIRDataLayout &layout, mlir::Type ty, llvm::ArrayRef< int64_t > indices)
void computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, cir::CIRDataLayout layout, llvm::SmallVectorImpl< int64_t > &indices)
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
Implements C++ ABI-specific code generation functions.
virtual mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty)=0
virtual void emitCXXConstructors(const clang::CXXConstructorDecl *d)=0
Emit constructor variants required by this ABI.
virtual void emitCXXDestructors(const clang::CXXDestructorDecl *d)=0
Emit dtor variants required by this ABI.
clang::MangleContext & getMangleContext()
Gets the mangle context.
virtual cir::GlobalLinkageKind getCXXDestructorLinkage(GVALinkage linkage, const CXXDestructorDecl *dtor, CXXDtorType dt) const
llvm::ArrayRef< CanQualType > arguments() const
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
mlir::Operation * curFn
The current function or global initializer that is generated code for.
This class organizes the cross-function state that is used while generating CIR code.
void updateResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp newLabel)
void addUsedOrCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global to a list to be added to the llvm.compiler.used metadata.
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
static cir::GlobalOp createGlobalOp(CIRGenModule &cgm, mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
llvm::StringRef getMangledName(clang::GlobalDecl gd)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
void setGlobalVisibility(mlir::Operation *op, const NamedDecl *d) const
Set the visibility for the given global.
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
void emitDeferred()
Emit any needed decls for which code generation was deferred.
clang::ASTContext & getASTContext() const
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
CIRGenCUDARuntime & getCUDARuntime()
llvm::DenseMap< cir::BlockAddrInfoAttr, cir::LabelOp > blockAddressInfoToLabel
Map BlockAddrInfoAttr (function name, label name) to the corresponding CIR LabelOp.
void emitTopLevelDecl(clang::Decl *decl)
void emitOMPDeclareMapper(const OMPDeclareMapperDecl *d)
void addReplacement(llvm::StringRef name, mlir::Operation *op)
mlir::Type convertType(clang::QualType type)
bool shouldEmitRTTI(bool forEH=false)
cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
std::vector< cir::CIRGlobalValueInterface > llvmUsed
List of global values which are required to be present in the object file; This is used for forcing v...
void emitOMPCapturedExpr(const OMPCapturedExprDecl *d)
void mapUnresolvedBlockAddress(cir::BlockAddressOp op)
bool mustBeEmitted(const clang::ValueDecl *d)
Determine whether the definition must be emitted; if this returns false, the definition can be emitte...
void emitGlobalOpenACCDeclareDecl(const clang::OpenACCDeclareDecl *cd)
mlir::IntegerAttr getSize(CharUnits size)
CIRGenBuilderTy & getBuilder()
void setDSOLocal(mlir::Operation *op) const
std::string getUniqueGlobalName(const std::string &baseName)
std::pair< cir::FuncType, cir::FuncOp > getAddrAndTypeOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
cir::GlobalOp getOrCreateCIRGlobal(llvm::StringRef mangledName, mlir::Type ty, LangAS langAS, const VarDecl *d, ForDefinition_t isForDefinition)
If the specified mangled name is not in the module, create and return an mlir::GlobalOp value.
cir::FuncOp createCIRBuiltinFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType ty, const clang::FunctionDecl *fd)
Create a CIR function with builtin attribute set.
void emitGlobalOpenACCRoutineDecl(const clang::OpenACCRoutineDecl *cd)
clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd)
Return the best known alignment for an unknown pointer to a particular class.
void handleCXXStaticMemberVarInstantiation(VarDecl *vd)
Tell the consumer that this variable has been instantiated.
std::vector< cir::CIRGlobalValueInterface > llvmCompilerUsed
void emitOMPRequiresDecl(const OMPRequiresDecl *d)
void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
void mapResolvedBlockAddress(cir::BlockAddressOp op, cir::LabelOp)
clang::DiagnosticsEngine & getDiags() const
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f, bool isIncompleteFunction, bool isThunk)
Set function attributes for a function declaration.
static mlir::SymbolTable::Visibility getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK)
const clang::TargetInfo & getTarget() const
void setCIRFunctionAttributes(GlobalDecl gd, const CIRGenFunctionInfo &info, cir::FuncOp func, bool isThunk)
Set the CIR function attributes (Sext, zext, etc).
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
void emitTentativeDefinition(const VarDecl *d)
void addUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global value to the llvmUsed list.
cir::GlobalOp createOrReplaceCXXRuntimeVariable(mlir::Location loc, llvm::StringRef name, mlir::Type ty, cir::GlobalLinkageKind linkage, clang::CharUnits alignment)
Will return a global variable of the given type.
void emitOMPAllocateDecl(const OMPAllocateDecl *d)
void error(SourceLocation loc, llvm::StringRef error)
Emit a general error that something can't be done.
void emitGlobalDecl(const clang::GlobalDecl &d)
Helper for emitDeferred to apply actual codegen.
void emitGlobalVarDefinition(const clang::VarDecl *vd, bool isTentative=false)
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
void setTLSMode(mlir::Operation *op, const VarDecl &d)
Set TLS mode for the given operation based on the given variable declaration.
cir::FuncOp getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType=nullptr, bool forVTable=false, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
Return the address of the given function.
void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op, GlobalDecl aliasGD, cir::FuncOp aliasee, cir::GlobalLinkageKind linkage)
void emitLLVMUsed()
Emit llvm.used and llvm.compiler.used globals.
mlir::Value emitMemberPointerConstant(const UnaryOperator *e)
void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd)
bool verifyModule() const
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
const cir::CIRDataLayout getDataLayout() const
mlir::Operation * getAddrOfGlobalTemporary(const MaterializeTemporaryExpr *mte, const Expr *init)
Returns a pointer to a global variable representing a temporary with static or thread storage duratio...
std::map< llvm::StringRef, clang::GlobalDecl > deferredDecls
This contains all the decls which have definitions but which are deferred for emission and therefore ...
void errorUnsupported(const Stmt *s, llvm::StringRef type)
Print out an error that codegen doesn't support the specified stmt yet.
mlir::Value getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty={}, ForDefinition_t isForDefinition=NotForDefinition)
Return the mlir::Value for the address of the given global variable.
static void setInitializer(cir::GlobalOp &op, mlir::Attribute value)
cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d)
Return the mlir::GlobalViewAttr for the address of the given global.
void addGlobalCtor(cir::FuncOp ctor, std::optional< int > priority=std::nullopt)
Add a global constructor or destructor to the module.
cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd)
void updateCompletedType(const clang::TagDecl *td)
const clang::CodeGenOptions & getCodeGenOpts() const
void emitDeferredVTables()
Emit any vtables which we deferred and still have a use for.
const clang::LangOptions & getLangOpts() const
void constructAttributeList(llvm::StringRef name, const CIRGenFunctionInfo &info, CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs, llvm::MutableArrayRef< mlir::NamedAttrList > argAttrs, mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv, cir::SideEffect &sideEffect, bool attrOnCallSite, bool isThunk)
Get the CIR attributes and calling convention to use for a particular function type.
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, bool dontDefer=false, bool isThunk=false, ForDefinition_t isForDefinition=NotForDefinition, mlir::NamedAttrList extraAttrs={})
void emitOpenACCRoutineDecl(const clang::FunctionDecl *funcDecl, cir::FuncOp func, SourceLocation pragmaLoc, ArrayRef< const OpenACCClause * > clauses)
void emitVTablesOpportunistically()
Try to emit external vtables as available_externally if they have emitted all inlined virtual functio...
cir::TLS_Model getDefaultCIRTLSModel() const
Get TLS mode from CodeGenOptions.
void addGlobalDtor(cir::FuncOp dtor, std::optional< int > priority=std::nullopt)
Add a function to the list that will be called when the module is unloaded.
void addDeferredDeclToEmit(clang::GlobalDecl GD)
bool shouldEmitCUDAGlobalVar(const VarDecl *global) const
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType funcType, const clang::FunctionDecl *funcDecl)
const TargetCIRGenInfo & getTargetCIRGenInfo()
void emitCXXGlobalVarDeclInitFunc(const VarDecl *vd, cir::GlobalOp addr, bool performInit)
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
llvm::DenseSet< cir::BlockAddressOp > unresolvedBlockAddressToLabel
Track CIR BlockAddressOps that cannot be resolved immediately because their LabelOp has not yet been ...
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
llvm::DenseMap< mlir::Attribute, cir::GlobalOp > constantStringMap
mlir::Operation * lastGlobalOp
void replaceGlobal(cir::GlobalOp oldGV, cir::GlobalOp newGV)
Replace all uses of the old global with the new global, updating types and references as needed.
static cir::VisibilityKind getGlobalVisibilityKindFromClangVisibility(clang::VisibilityAttr::VisibilityType visibility)
llvm::StringMap< unsigned > cgGlobalNames
void setCXXSpecialMemberAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl)
Mark the function as a special member (e.g. constructor, destructor)
mlir::TypedAttr emitNullMemberAttr(QualType t, const MemberPointerType *mpt)
Returns a null attribute to represent either a null method or null data member, depending on the type...
mlir::Operation * getGlobalValue(llvm::StringRef ref)
void emitOMPDeclareReduction(const OMPDeclareReductionDecl *d)
mlir::ModuleOp getModule() const
bool supportsCOMDAT() const
void addCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global value to the llvmCompilerUsed list.
clang::CharUnits getNaturalTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr, bool forPointeeType=false)
FIXME: this could likely be a common helper and not necessarily related with codegen.
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage, bool isConstantVariable)
mlir::MLIRContext & getMLIRContext()
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
CIRGenCXXABI & getCXXABI() const
cir::GlobalViewAttr getAddrOfConstantStringFromLiteral(const StringLiteral *s, llvm::StringRef name=".str")
Return a global symbol reference to a constant array for the given string literal.
llvm::MapVector< cir::BlockAddressOp, cir::LabelOp > blockAddressToLabel
Map CIR BlockAddressOps directly to their resolved LabelOps.
bool lookupRepresentativeDecl(llvm::StringRef mangledName, clang::GlobalDecl &gd) const
void emitDeclContext(const DeclContext *dc)
clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr)
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
cir::LabelOp lookupBlockAddressInfo(cir::BlockAddrInfoAttr blockInfo)
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd, bool isConstant)
void mapBlockAddress(cir::BlockAddrInfoAttr blockInfo, cir::LabelOp label)
void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
std::string getOpenACCBindMangledName(const IdentifierInfo *bindName, const FunctionDecl *attachedFunction)
void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op)
CIRGenVTables & getVTables()
void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f)
std::vector< clang::GlobalDecl > deferredDeclsToEmit
void emitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *d)
void emitAMDGPUMetadata()
Emits AMDGPU specific Metadata.
void emitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *d)
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e)
Return a constant array for the given string.
cir::VisibilityAttr getGlobalVisibilityAttrFromDecl(const Decl *decl)
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
const CIRGenFunctionInfo & arrangeGlobalDeclaration(GlobalDecl gd)
const CIRGenFunctionInfo & arrangeCXXMethodDeclaration(const clang::CXXMethodDecl *md)
C++ methods have some special rules and also have implicit parameters.
const CIRGenFunctionInfo & arrangeCXXStructorDeclaration(clang::GlobalDecl gd)
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
void emitThunks(GlobalDecl gd)
Emit the associated thunks for the given global decl.
virtual clang::LangAS getGlobalVarAddressSpace(CIRGenModule &cgm, const clang::VarDecl *d) const
Get target favored AST address space of a global variable for languages other than OpenCL and CUDA.
virtual mlir::ptr::MemorySpaceAttrInterface getCIRAllocaAddressSpace() const
Get the address space for alloca.
virtual void setTargetAttributes(const clang::Decl *decl, mlir::Operation *global, CIRGenModule &module) const
Provides a convenient hook to handle extra target-specific attributes for the given global.
Represents a base class of a C++ class.
Represents a C++ constructor within a class.
bool isMoveConstructor(unsigned &TypeQuals) const
Determine whether this constructor is a move constructor (C++11 [class.copy]p3), which can be used to...
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a static or instance method of a struct/union/class.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool hasDefinition() const
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::Reloc::Model RelocationModel
The name of the relocation model to use.
Represents the canonical version of C arrays with a specified constant size.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
static DeclContext * castToDeclContext(const Decl *)
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Represents a ValueDecl that came out of a declarator.
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Represents a member of a struct/union/class.
Cached information about one file (either on disk or in the virtual file system).
StringRef tryGetRealPathName() const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Represents a function declaration or definition.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
GlobalDecl - represents a global declaration.
GlobalDecl getCanonicalDecl() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
CXXDtorType getDtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
clang::ObjCRuntime ObjCRuntime
void setLinkage(Linkage L)
Linkage getLinkage() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
bool shouldMangleDeclName(const NamedDecl *D)
void mangleName(GlobalDecl GD, raw_ostream &)
virtual void mangleReferenceTemporary(const VarDecl *D, unsigned ManglingNumber, raw_ostream &)=0
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
APValue * getOrCreateValue(bool MayCreate) const
Get the storage for the constant value of a materialized temporary of static storage duration.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
unsigned getManglingNumber() const
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
LinkageInfo getLinkageAndVisibility() const
Determines the linkage and visibility of this entity.
bool hasUnwindExceptions() const
Does this runtime use zero-cost exceptions?
Represents a parameter to a function.
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
A (possibly-)qualified type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isConstQualified() const
Determine whether this type is const-qualified.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
bool hasUnaligned() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
StringLiteral - This represents a string literal expression, e.g.
unsigned getLength() const
uint32_t getCodeUnit(size_t i) const
StringRef getString() const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isPointerType() const
bool isReferenceType() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isObjCObjectPointerType() const
bool isMemberFunctionPointerType() const
const T * getAs() const
Member-template getAs<specific type>'.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
TLSKind getTLSKind() const
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasFlexibleArrayInit(const ASTContext &Ctx) const
Whether this variable has a flexible array member initialized with one or more elements.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
const Expr * getInit() const
bool hasExternalStorage() const
Returns true if a variable has extern or private_extern storage.
@ TLS_Dynamic
TLS with a dynamic initializer.
@ TLS_None
Not a TLS variable.
@ DeclarationOnly
This declaration is only a declaration.
@ Definition
This declaration is definitely a definition.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
bool isMatchingAddressSpace(mlir::ptr::MemorySpaceAttrInterface cirAS, clang::LangAS as)
mlir::ptr::MemorySpaceAttrInterface toCIRAddressSpaceAttr(mlir::MLIRContext &ctx, clang::LangAS langAS)
Convert an AST LangAS to the appropriate CIR address space attribute interface.
static bool isWeakForLinker(GlobalLinkageKind linkage)
Whether the definition of this global may be replaced at link time.
@ AttributedType
The l-value was considered opaque, so the alignment was determined from a type, but that type was an ...
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
std::unique_ptr< TargetCIRGenInfo > createAMDGPUTargetCIRGenInfo(CIRGenTypes &cgt)
std::unique_ptr< TargetCIRGenInfo > createNVPTXTargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCXXABI * CreateCIRGenItaniumCXXABI(CIRGenModule &cgm)
Creates and Itanium-family ABI.
std::unique_ptr< TargetCIRGenInfo > createX8664TargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCUDARuntime * createNVCUDARuntime(CIRGenModule &cgm)
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
GVALinkage
A more specific kind of linkage than enum Linkage.
@ GVA_AvailableExternally
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ FirstTargetAddressSpace
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
U cast(CodeGen::Address addr)
bool isExternallyVisible(Linkage L)
static bool globalCtorLexOrder()
static bool opFuncArmNewAttr()
static bool getRuntimeFunctionDecl()
static bool weakRefReference()
static bool opFuncOptNoneAttr()
static bool addressSpace()
static bool opFuncMinSizeAttr()
static bool opGlobalUnnamedAddr()
static bool opGlobalThreadLocal()
static bool sourceLanguageCases()
static bool opFuncAstDeclAttr()
static bool opFuncNoDuplicateAttr()
static bool stackProtector()
static bool moduleNameHash()
static bool opGlobalVisibility()
static bool setDLLStorageClass()
static bool opFuncUnwindTablesAttr()
static bool opFuncParameterAttributes()
static bool targetCIRGenInfoArch()
static bool opFuncExtraAttrs()
static bool opFuncNakedAttr()
static bool attributeNoBuiltin()
static bool opGlobalDLLImportExport()
static bool opGlobalPartition()
static bool opGlobalPragmaClangSection()
static bool opGlobalWeakRef()
static bool deferredCXXGlobalInit()
static bool opFuncOperandBundles()
static bool opFuncCallingConv()
static bool globalCtorAssociatedData()
static bool defaultVisibility()
static bool opFuncColdHotAttr()
static bool opFuncExceptions()
static bool opFuncArmStreamingAttr()
static bool cudaSupport()
static bool opFuncMaybeHandleStaticInExternC()
static bool generateDebugInfo()
static bool targetCIRGenInfoOS()
static bool opFuncCPUAndFeaturesAttributes()
static bool maybeHandleStaticInExternC()
static bool setLLVMFunctionFEnvAttributes()
mlir::Type uCharTy
ClangIR char.
unsigned char SizeSizeInBytes
unsigned char PointerAlignInBytes
cir::PointerType allocaInt8PtrTy
void* in alloca address space
cir::PointerType uInt8PtrTy
mlir::ptr::MemorySpaceAttrInterface cirAllocaAddressSpace
cir::PointerType voidPtrTy
void* in address space 0
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool hasSideEffects() const
Return true if the evaluated expression has side effects.