19#include "mlir/Dialect/OpenMP/Utils/Utils.h"
20#include "mlir/IR/SymbolTable.h"
23#include "clang/AST/Attrs.inc"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringExtras.h"
43#include "llvm/ADT/StringRef.h"
44#include "llvm/ADT/StringSwitch.h"
45#include "llvm/Support/raw_ostream.h"
49#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
50#include "mlir/IR/Attributes.h"
51#include "mlir/IR/BuiltinOps.h"
52#include "mlir/IR/Location.h"
53#include "mlir/IR/MLIRContext.h"
54#include "mlir/IR/Operation.h"
55#include "mlir/IR/Verifier.h"
64 case TargetCXXABI::GenericItanium:
65 case TargetCXXABI::GenericAArch64:
66 case TargetCXXABI::AppleARM64:
67 case TargetCXXABI::GenericARM:
69 case TargetCXXABI::Microsoft:
72 case TargetCXXABI::Fuchsia:
73 case TargetCXXABI::iOS:
74 case TargetCXXABI::WatchOS:
75 case TargetCXXABI::GenericMIPS:
76 case TargetCXXABI::WebAssembly:
77 case TargetCXXABI::XL:
78 cgm.
errorNYI(
"createCXXABI: C++ ABI kind");
82 llvm_unreachable(
"invalid C++ ABI kind");
85CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
89 : builder(mlirContext, *this), astContext(astContext),
92 theModule{
mlir::ModuleOp::create(
mlir::UnknownLoc::get(&mlirContext))},
93 diags(diags), target(astContext.getTargetInfo()),
94 abi(
createCXXABI(*this)), genTypes(*this), vtables(*this) {
101 langOpts.CPlusPlusModules &&
130 .toCharUnitsFromBits(
134 const unsigned charSize = target.getCharWidth();
137 const unsigned sizeTypeSize = target.getTypeWidth(target.getSizeType());
145 std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
148 cir::CIRDialect::getSourceLanguageAttrName(),
149 cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
150 if (langOpts.OpenCL || (langOpts.CUDAIsDevice &&
getTriple().isSPIRV())) {
153 langOpts.OpenCL ? langOpts.getOpenCLCompatibleVersion() : 200;
154 setOpenCLVersionAttr(cir::CIRDialect::getOpenCLVersionAttrName(), version);
155 if (langOpts.OpenCLCPlusPlus)
156 setOpenCLVersionAttr(cir::CIRDialect::getOpenCLCXXVersionAttrName(),
157 langOpts.OpenCLCPlusPlusVersion);
160 unsigned spirMajor = version / 100;
161 getModule()->setAttr(cir::CIRDialect::getOpenCLSPIRVersionAttrName(),
164 spirMajor > 1 ? 0 : 2));
167 getModule()->setAttr(cir::CIRDialect::getTripleAttrName(),
168 builder.getStringAttr(
getTriple().str()));
169 getModule()->setAttr(cir::CIRDialect::getTargetABIAttrName(),
170 builder.getStringAttr(
getTarget().getABI()));
175 cir::CIRDialect::getCXXABIAttrName(),
178 if (llvm::VersionTuple sdkVersion =
getTarget().getSDKVersion();
180 getModule()->setAttr(cir::CIRDialect::getSDKVersionAttrName(),
181 builder.getStringAttr(sdkVersion.getAsString()));
182 if (langOpts.CUDA && !langOpts.CUID.empty())
183 getModule()->setAttr(cir::CIRDialect::getCUIDHashAttrName(),
184 builder.getStringAttr(astContext.getCUIDHash()));
187 getModule()->setAttr(cir::CIRDialect::getSizeTypeWidthAttrName(),
188 builder.getI32IntegerAttr(sizeTypeSize));
189 getModule()->setAttr(cir::CIRDialect::getIntTypeWidthAttrName(),
190 builder.getI32IntegerAttr(target.getIntWidth()));
196 cir::CIRDialect::getLoweringOptionsAttrName(),
197 cir::LoweringOptionsAttr::get(
200 langOpts.ThreadsafeStatics,
202 langOpts.CUDAIsDevice,
205 langOpts.GPURelocatableDeviceCode,
206 langOpts.OpenMP != 0,
207 langOpts.OpenMPIsTargetDevice,
209 static_cast<int32_t
>(langOpts.getClangABICompat()),
210 static_cast<int32_t
>(langOpts.LongDoubleSize),
211 cgo.EnableNoundefAttrs));
213 if (cgo.OptimizationLevel > 0 || cgo.OptimizeSize > 0)
214 getModule()->setAttr(cir::CIRDialect::getOptInfoAttrName(),
215 cir::OptInfoAttr::get(&mlirContext,
216 cgo.OptimizationLevel,
220 cir::CIRDialect::getDefaultTlsModelAttrName(),
223 if (langOpts.OpenMP) {
224 mlir::omp::OffloadModuleOpts ompOpts(
225 langOpts.OpenMPTargetDebug, langOpts.OpenMPTeamSubscription,
226 langOpts.OpenMPThreadSubscription, langOpts.OpenMPNoThreadState,
227 langOpts.OpenMPNoNestedParallelism, langOpts.OpenMPIsTargetDevice,
228 getTriple().isGPU(), langOpts.OpenMPForceUSM, langOpts.OpenMP,
229 langOpts.OMPHostIRFile, langOpts.OMPTargetTriples, langOpts.NoGPULib);
230 mlir::omp::setOffloadModuleInterfaceAttributes(
getModule(), ompOpts);
231 mlir::omp::setOpenMPVersionAttribute(
getModule(), langOpts.OpenMP);
237 createOpenMPRuntime();
242 FileID mainFileId = astContext.getSourceManager().getMainFileID();
244 *astContext.getSourceManager().getFileEntryForID(mainFileId);
248 getModule()->setLoc(mlir::FileLineColLoc::get(&mlirContext, path,
256void CIRGenModule::setOpenCLVersionAttr(StringRef attrName,
unsigned version) {
258 attrName, cir::OpenCLVersionAttr::get(&
getMLIRContext(), version / 100,
259 (version % 100) / 10));
262void CIRGenModule::createCUDARuntime() {
266void CIRGenModule::createOpenMPRuntime() {
267 openMPRuntime = std::make_unique<CIRGenOpenMPRuntime>(*
this);
278 auto &layout = astContext.getASTRecordLayout(rd);
283 return layout.getAlignment();
286 return layout.getNonVirtualAlignment();
291 bool forPointeeType) {
301 if (
unsigned align = tt->getDecl()->getMaxAlignment()) {
304 return astContext.toCharUnitsFromBits(align);
312 t = astContext.getBaseElementType(t);
333 }
else if (forPointeeType && !alignForArray &&
337 alignment = astContext.getTypeAlignInChars(t);
342 if (
unsigned maxAlign = astContext.getLangOpts().MaxTypeAlign) {
344 !astContext.isAlignmentRequired(t))
358 if (theTargetCIRGenInfo)
359 return *theTargetCIRGenInfo;
362 switch (triple.getArch()) {
369 case llvm::Triple::x86_64: {
370 switch (triple.getOS()) {
377 case llvm::Triple::Linux:
379 return *theTargetCIRGenInfo;
382 case llvm::Triple::aarch64:
383 case llvm::Triple::aarch64_32:
384 case llvm::Triple::aarch64_be: {
386 return *theTargetCIRGenInfo;
388 case llvm::Triple::nvptx:
389 case llvm::Triple::nvptx64:
391 return *theTargetCIRGenInfo;
392 case llvm::Triple::amdgpu: {
394 return *theTargetCIRGenInfo;
396 case llvm::Triple::spir:
397 case llvm::Triple::spir64:
398 case llvm::Triple::spirv:
399 case llvm::Triple::spirv32:
400 case llvm::Triple::spirv64:
402 return *theTargetCIRGenInfo;
407 assert(cLoc.
isValid() &&
"expected valid source location");
411 return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
416 assert(cRange.
isValid() &&
"expected a valid source range");
419 mlir::Attribute metadata;
420 return mlir::FusedLoc::get({begin, end}, metadata, builder.getContext());
429 false, isForDefinition);
463 assert(op &&
"expected a valid global op");
471 mlir::Operation *globalValueOp = op;
472 if (
auto gv = dyn_cast<cir::GetGlobalOp>(op)) {
474 assert(globalValueOp &&
"expected a valid global op");
477 if (
auto cirGlobalValue =
478 dyn_cast<cir::CIRGlobalValueInterface>(globalValueOp))
479 if (!cirGlobalValue.isDeclaration())
500 assert(deferredVTables.empty());
510 std::vector<GlobalDecl> curDeclsToEmit;
518 if (
const auto *fd = d.getDecl()->getAsFunction()) {
519 if (langOpts.SYCLIsDevice && fd->hasAttr<SYCLKernelEntryPointAttr>() &&
523 if (!fd->getAttr<SYCLKernelEntryPointAttr>()->isInvalidAttr()) {
552 os << (isa<VarDecl>(d) ?
".static." :
".intern.");
554 os << (isa<VarDecl>(d) ?
"__static__" :
"__intern__");
561 "printPostfixForExternalizedDecl: CUID is not specified");
570 if (!langOpts.OpenMPIsTargetDevice && !langOpts.CUDA)
573 const auto *aa = global->
getAttr<AliasAttr>();
581 const auto *aliaseeDecl = dyn_cast<ValueDecl>(aliaseeGD.getDecl());
582 if (langOpts.OpenMPIsTargetDevice)
583 return !aliaseeDecl ||
584 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(aliaseeDecl);
587 const bool hasDeviceAttr = global->
hasAttr<CUDADeviceAttr>();
588 const bool aliaseeHasDeviceAttr =
589 aliaseeDecl && aliaseeDecl->hasAttr<CUDADeviceAttr>();
591 if (langOpts.CUDAIsDevice)
592 return !hasDeviceAttr || !aliaseeHasDeviceAttr;
600 if (
const auto *cd = dyn_cast<clang::OpenACCConstructDecl>(gd.
getDecl())) {
608 if (global->hasAttr<WeakRefAttr>())
613 if (global->hasAttr<AliasAttr>()) {
621 if (langOpts.CUDA && !
getASTContext().shouldEmitCUDADecl(global))
624 if (langOpts.OpenMP) {
626 if (openMPRuntime && openMPRuntime->emitTargetGlobal(gd))
628 if (
auto *drd = dyn_cast<OMPDeclareReductionDecl>(global)) {
633 if (
auto *dmd = dyn_cast<OMPDeclareMapperDecl>(global)) {
640 if (
const auto *fd = dyn_cast<FunctionDecl>(global)) {
643 if (fd->hasAttr<AnnotateAttr>()) {
646 deferredAnnotations[mangledName] = fd;
648 if (!fd->doesThisDeclarationHaveABody()) {
649 if (!fd->doesDeclarationForceExternallyVisibleDefinition() &&
660 assert(vd->isFileVarDecl() &&
"Cannot emit local var decl as global.");
662 !astContext.isMSStaticDataMemberInlineDefinition(vd)) {
666 if (astContext.getInlineVariableDefinitionKind(vd) ==
681 if (
auto existing = dyn_cast_if_present<cir::CIRGlobalValueInterface>(
683 existing && !existing.isDeclaration())
711 mlir::Operation *op) {
715 cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
716 if (!funcOp || funcOp.getFunctionType() != funcType) {
722 if (!funcOp.isDeclaration())
734 mlir::OpBuilder::InsertionGuard guard(builder);
739 setNonAliasAttributes(gd, funcOp);
742 auto getPriority = [
this](
const auto *
attr) ->
int {
746 return attr->DefaultPriority;
749 if (
const ConstructorAttr *ca = funcDecl->getAttr<ConstructorAttr>())
751 if (
const DestructorAttr *da = funcDecl->getAttr<DestructorAttr>())
754 if (funcDecl->getAttr<AnnotateAttr>())
757 if (
getLangOpts().OpenMP && funcDecl->hasAttr<OMPDeclareTargetDeclAttr>())
763 std::optional<int> priority) {
772 ctor.setGlobalCtorPriority(priority);
777 std::optional<int> priority) {
778 if (codeGenOpts.RegisterGlobalDtorsWithAtExit &&
780 errorNYI(dtor.getLoc(),
"registerGlobalDtorsWithAtExit");
783 dtor.setGlobalDtorPriority(priority);
809 mlir::ptr::MemorySpaceAttrInterface addrSpace,
810 mlir::Operation *insertPoint) {
815 mlir::OpBuilder::InsertionGuard guard(builder);
821 builder.setInsertionPoint(insertPoint);
827 builder.setInsertionPointToStart(
getModule().getBody());
830 g = cir::GlobalOp::create(builder, loc, name, t, isConstant, addrSpace);
836 mlir::SymbolTable::setSymbolVisibility(
837 g, mlir::SymbolTable::Visibility::Private);
845 if (isa_and_nonnull<NamedDecl>(d))
849 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(gv)) {
850 if (d && d->
hasAttr<UsedAttr>())
853 if (
const auto *vd = dyn_cast_if_present<VarDecl>(d);
854 vd && ((codeGenOpts.KeepPersistentStorageVariables &&
855 (vd->getStorageDuration() ==
SD_Static ||
856 vd->getStorageDuration() ==
SD_Thread)) ||
857 (codeGenOpts.KeepStaticConsts &&
859 vd->getType().isConstQualified())))
865static std::vector<std::string>
867 llvm::StringMap<bool> &featureMap) {
868 llvm::StringMap<bool> defaultFeatureMap;
872 std::vector<std::string> delta;
873 for (
const auto &[k, v] : featureMap) {
874 auto defaultIt = defaultFeatureMap.find(k);
875 if (defaultIt == defaultFeatureMap.end() || defaultIt->getValue() != v)
876 delta.push_back((v ?
"+" :
"-") + k.str());
882bool CIRGenModule::getCPUAndFeaturesAttributes(
883 GlobalDecl gd, llvm::StringMap<std::string> &attrs,
884 bool setTargetFeatures) {
890 std::vector<std::string> features;
894 const auto *fd = dyn_cast_or_null<FunctionDecl>(gd.
getDecl());
895 fd = fd ? fd->getMostRecentDecl() : fd;
896 const auto *td = fd ? fd->getAttr<TargetAttr>() :
nullptr;
897 const auto *tv = fd ? fd->getAttr<TargetVersionAttr>() :
nullptr;
898 assert((!td || !tv) &&
"both target_version and target specified");
899 const auto *sd = fd ? fd->getAttr<CPUSpecificAttr>() :
nullptr;
900 const auto *tc = fd ? fd->getAttr<TargetClonesAttr>() :
nullptr;
901 bool addedAttr =
false;
902 if (td || tv || sd || tc) {
903 llvm::StringMap<bool> featureMap;
904 astContext.getFunctionFeatureMap(featureMap, gd);
910 llvm::StringRef featureStr = td ? td->getFeaturesStr() : llvm::StringRef();
913 if (!featureStr.empty()) {
914 clang::ParsedTargetAttr parsedAttr =
916 if (!parsedAttr.
CPU.empty() &&
918 targetCPU = parsedAttr.
CPU;
921 if (!parsedAttr.
Tune.empty() &&
923 tuneCPU = parsedAttr.
Tune;
939 features.reserve(features.size() + featureMap.size());
940 for (
const auto &entry : featureMap)
941 features.push_back((entry.getValue() ?
"+" :
"-") +
942 entry.getKey().str());
947 llvm::StringMap<bool> featureMap;
949 astContext.getFunctionFeatureMap(featureMap, gd);
960 if (!targetCPU.empty()) {
961 attrs[cir::CIRDialect::getTargetCPUAttrName()] = targetCPU.str();
964 if (!tuneCPU.empty()) {
965 attrs[cir::CIRDialect::getTuneCPUAttrName()] = tuneCPU.str();
968 if (!features.empty() && setTargetFeatures) {
969 llvm::erase_if(features, [&](
const std::string &f) {
970 assert(!f.empty() && (f[0] ==
'+' || f[0] ==
'-') &&
971 "feature string must start with '+' or '-'");
974 llvm::sort(features);
975 attrs[cir::CIRDialect::getTargetFeaturesAttrName()] =
976 llvm::join(features,
",");
984void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
989 if (
auto gvi = mlir::dyn_cast<cir::CIRGlobalValueInterface>(op)) {
990 if (
const auto *sa = d->
getAttr<SectionAttr>())
991 gvi.setSection(builder.getStringAttr(sa->getName()));
995 if (
auto func = dyn_cast<cir::FuncOp>(op)) {
996 llvm::StringMap<std::string> attrs;
997 if (getCPUAndFeaturesAttributes(gd, attrs)) {
1004 for (llvm::StringRef name :
1005 {cir::CIRDialect::getTargetCPUAttrName(),
1006 cir::CIRDialect::getTuneCPUAttrName(),
1007 cir::CIRDialect::getTargetFeaturesAttrName()})
1008 func->removeAttr(name);
1009 for (
const auto &[key, val] : attrs)
1010 func->setAttr(key, builder.getStringAttr(val));
1020std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage()
const {
1021 using ClangStd = clang::LangStandard;
1022 using CIRLang = cir::SourceLanguage;
1025 if (opts.OpenCLCPlusPlus)
1026 return CIRLang::OpenCLCXX;
1028 return CIRLang::OpenCLC;
1030 return CIRLang::CXX;
1031 if (opts.C99 || opts.C11 || opts.C17 || opts.C23 || opts.C2y ||
1032 opts.LangStd == ClangStd::lang_c89 ||
1033 opts.LangStd == ClangStd::lang_gnu89)
1038 errorNYI(
"CIR does not yet support the given source language");
1039 return std::nullopt;
1042LangAS CIRGenModule::getGlobalVarAddressSpace(
const VarDecl *d) {
1043 if (langOpts.OpenCL) {
1051 if (langOpts.SYCLIsDevice &&
1055 if (langOpts.CUDA && langOpts.CUDAIsDevice) {
1057 if (d->
hasAttr<CUDAConstantAttr>())
1059 if (d->
hasAttr<CUDASharedAttr>())
1061 if (d->
hasAttr<CUDADeviceAttr>())
1069 if (langOpts.OpenMP && d && d->
hasAttr<OMPAllocateDeclAttr>())
1083 gv.
setLinkage(cir::GlobalLinkageKind::ExternalWeakLinkage);
1092 auto linkage = cir::GlobalLinkageKind::ExternalWeakLinkage;
1093 func.setLinkage(linkage);
1094 func.setLinkageAttr(
1095 cir::GlobalLinkageKindAttr::get(&cgm.
getMLIRContext(), linkage));
1097 if (!func.isDeclaration())
1098 mlir::SymbolTable::setSymbolVisibility(
1105 for (mlir::Attribute i : indexes) {
1106 auto ind = mlir::cast<mlir::IntegerAttr>(i);
1107 inds.push_back(ind.getValue().getSExtValue());
1113 return view.getSymbol().getValue() == glob.getSymName();
1117 cir::GlobalOp newGlob,
1118 cir::GlobalViewAttr
attr,
1129 mlir::Type newTy = newGlob.getSymType();
1135 return cir::GlobalOffsetAttr::get(
attr.getType(),
attr.getSymbol(),
1136 static_cast<int64_t>(offset));
1138 cir::PointerType newPtrTy;
1141 newPtrTy = cir::PointerType::get(newTy);
1147 attr.getAddressPoint());
1151 cgm.
errorNYI(
"Unhandled type in createNewGlobalView");
1157 mlir::Attribute oldInit) {
1158 if (
auto oldView = mlir::dyn_cast<cir::GlobalViewAttr>(oldInit))
1163 if (mlir::isa<cir::GlobalOffsetAttr>(oldInit))
1166 auto getNewInitElements =
1167 [&](mlir::ArrayAttr oldElements) -> mlir::ArrayAttr {
1169 for (mlir::Attribute elt : oldElements) {
1170 if (
auto view = mlir::dyn_cast<cir::GlobalViewAttr>(elt))
1172 else if (mlir::isa<cir::ConstArrayAttr, cir::ConstRecordAttr>(elt))
1175 newElements.push_back(elt);
1177 return mlir::ArrayAttr::get(cgm.
getBuilder().getContext(), newElements);
1180 if (
auto oldArray = mlir::dyn_cast<cir::ConstArrayAttr>(oldInit)) {
1186 mlir::Attribute oldElts = oldArray.getElts();
1187 if (mlir::isa<mlir::StringAttr>(oldElts))
1189 mlir::Attribute newElements =
1190 getNewInitElements(mlir::cast<mlir::ArrayAttr>(oldElts));
1192 newElements, mlir::cast<cir::ArrayType>(oldArray.getType()));
1194 if (
auto oldRecord = mlir::dyn_cast<cir::ConstRecordAttr>(oldInit)) {
1195 mlir::ArrayAttr newMembers = getNewInitElements(oldRecord.getMembers());
1196 auto recordTy = mlir::cast<cir::RecordType>(oldRecord.getType());
1202 cgm.
errorNYI(
"Unhandled type in getNewInitValue");
1210 assert(oldGV.getSymName() == newGV.getSymName() &&
"symbol names must match");
1212 mlir::Type oldTy = oldGV.getSymType();
1213 mlir::Type newTy = newGV.getSymType();
1218 assert(oldTy != newTy &&
"expected type change in replaceGlobal");
1221 std::optional<mlir::SymbolTable::UseRange> oldSymUses =
1223 for (mlir::SymbolTable::SymbolUse use : *oldSymUses) {
1224 mlir::Operation *userOp = use.getUser();
1226 (mlir::isa<cir::GetGlobalOp, cir::GlobalOp, cir::ConstantOp>(userOp)) &&
1227 "Unexpected user for global op");
1229 if (
auto getGlobalOp = dyn_cast<cir::GetGlobalOp>(use.getUser())) {
1230 mlir::Value useOpResultValue = getGlobalOp.getAddr();
1231 useOpResultValue.setType(cir::PointerType::get(newTy));
1233 mlir::OpBuilder::InsertionGuard guard(builder);
1234 builder.setInsertionPointAfter(getGlobalOp);
1235 mlir::Type ptrTy = builder.getPointerTo(oldTy);
1237 builder.createBitcast(getGlobalOp->getLoc(), useOpResultValue, ptrTy);
1238 useOpResultValue.replaceAllUsesExcept(
cast,
cast.getDefiningOp());
1239 }
else if (
auto glob = dyn_cast<cir::GlobalOp>(userOp)) {
1240 if (
auto init = glob.getInitialValue()) {
1241 mlir::Attribute nw =
getNewInitValue(*
this, newGV, oldTy, init.value());
1242 glob.setInitialValueAttr(nw);
1244 }
else if (
auto c = dyn_cast<cir::ConstantOp>(userOp)) {
1245 mlir::Attribute init =
getNewInitValue(*
this, newGV, oldTy, c.getValue());
1246 auto typedAttr = mlir::cast<mlir::TypedAttr>(init);
1247 mlir::OpBuilder::InsertionGuard guard(builder);
1248 builder.setInsertionPointAfter(c);
1249 auto newUser = cir::ConstantOp::create(builder, c.getLoc(), typedAttr);
1250 c.replaceAllUsesWith(newUser.getOperation());
1286 cir::GlobalOp entry;
1290 "getOrCreateCIRGlobal: global with non-GlobalOp type");
1295 mlir::ptr::MemorySpaceAttrInterface entryCIRAS = entry.getAddrSpaceAttr();
1301 if (entry.getSymType() == ty &&
1312 if (isForDefinition && !entry.isDeclaration()) {
1314 "getOrCreateCIRGlobal: global with conflicting type");
1322 if (!isForDefinition)
1331 bool isConstant =
false;
1333 QualType declType = d->
getType();
1348 mlir::ptr::MemorySpaceAttrInterface declCIRAS =
1353 cir::GlobalOp gv =
createGlobalOp(loc, mangledName, ty, isConstant, declCIRAS,
1354 entry.getOperation());
1374 if (langOpts.OpenMP && !langOpts.OpenMPSimd)
1376 "getOrCreateCIRGlobal: OpenMP target global variable");
1378 gv.setAlignmentAttr(
getSize(astContext.getDeclAlign(d)));
1389 if (astContext.isMSStaticDataMemberInlineDefinition(d))
1391 "getOrCreateCIRGlobal: MS static data member inline definition");
1395 if (
const SectionAttr *sa = d->
getAttr<SectionAttr>())
1396 gv.setSectionAttr(builder.getStringAttr(sa->getName()));
1400 if (
getTriple().getArch() == llvm::Triple::xcore)
1402 "getOrCreateCIRGlobal: XCore specific ABI requirements");
1412 "getOrCreateCIRGlobal: external const declaration with initializer");
1458 mlir::Type ptrTy = builder.getPointerTo(g.getSymType(), g.getAddrSpaceAttr());
1459 mlir::Value addr = cir::GetGlobalOp::create(
1462 g.getDynamicInitGuard().has_value() &&
1472 auto ptrTy = mlir::cast<cir::PointerType>(addr.getType());
1473 mlir::ptr::MemorySpaceAttrInterface declAS =
1475 if (ptrTy.getAddrSpace() == declAS)
1477 return builder.createAddrSpaceCast(
1478 addr, builder.getPointerTo(ptrTy.getPointee(), declAS));
1486 cir::PointerType ptrTy =
1487 builder.getPointerTo(globalOp.getSymType(), globalOp.getAddrSpaceAttr());
1488 return builder.getGlobalViewAttr(ptrTy, globalOp);
1492 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1493 !gv.isDeclarationForLinker()) &&
1494 "Only globals with definition can force usage.");
1499 assert(!gv.isDeclarationForLinker() &&
1500 "Only globals with definition can force usage.");
1505 cir::CIRGlobalValueInterface gv) {
1506 assert((mlir::isa<cir::FuncOp>(gv.getOperation()) ||
1507 !gv.isDeclarationForLinker()) &&
1508 "Only globals with definition can force usage.");
1516 std::vector<cir::CIRGlobalValueInterface> &list) {
1521 mlir::Location loc = builder.getUnknownLoc();
1526 usedArray.resize(list.size());
1527 for (
auto [i, op] : llvm::enumerate(list)) {
1528 usedArray[i] = cir::GlobalViewAttr::get(
1529 voidPtrTy, mlir::FlatSymbolRefAttr::get(op.getNameAttr()));
1532 cir::ArrayType arrayTy = cir::ArrayType::get(voidPtrTy, usedArray.size());
1534 cir::ConstArrayAttr initAttr = cir::ConstArrayAttr::get(
1535 arrayTy, mlir::ArrayAttr::get(&cgm.
getMLIRContext(), usedArray));
1538 loc, name, arrayTy,
false,
1540 gv.setLinkage(cir::GlobalLinkageKind::AppendingLinkage);
1541 gv.setInitialValueAttr(initAttr);
1542 gv.setSectionAttr(builder.getStringAttr(
"llvm.metadata"));
1559 "emitGlobalVarDefinition: emit OpenMP global variable");
1566 bool isDefinitionAvailableExternally =
1571 if (isDefinitionAvailableExternally &&
1579 mlir::Attribute init;
1580 bool needsGlobalCtor =
false;
1581 bool needsGlobalDtor =
1582 !isDefinitionAvailableExternally &&
1587 std::optional<ConstantEmitter> emitter;
1592 bool isCUDASharedVar =
1597 bool isCUDAShadowVar =
1599 (vd->
hasAttr<CUDAConstantAttr>() || vd->
hasAttr<CUDADeviceAttr>() ||
1600 vd->
hasAttr<CUDASharedAttr>());
1601 bool isCUDADeviceShadowVar =
1607 (isCUDASharedVar || isCUDAShadowVar || isCUDADeviceShadowVar)) {
1609 }
else if (vd->
hasAttr<LoaderUninitializedAttr>()) {
1611 "emitGlobalVarDefinition: loader uninitialized attribute");
1612 }
else if (!initExpr) {
1625 emitter.emplace(*
this);
1626 mlir::Attribute initializer = emitter->tryEmitForInitializer(*initDecl);
1635 "emitGlobalVarDefinition: flexible array initializer");
1637 if (!isDefinitionAvailableExternally)
1638 needsGlobalCtor =
true;
1641 "emitGlobalVarDefinition: static initializer");
1652 mlir::Type initType;
1653 if (mlir::isa<mlir::SymbolRefAttr>(init)) {
1656 "emitGlobalVarDefinition: global initializer is a symbol reference");
1659 assert(mlir::isa<mlir::TypedAttr>(init) &&
"This should have a type");
1660 auto typedInitAttr = mlir::cast<mlir::TypedAttr>(init);
1661 initType = typedInitAttr.getType();
1663 assert(!mlir::isa<mlir::NoneType>(initType) &&
"Should have a type by now");
1669 if (!gv || gv.getSymType() != initType) {
1671 "emitGlobalVarDefinition: global initializer with type mismatch");
1677 if (vd->
hasAttr<AnnotateAttr>())
1690 if (langOpts.CUDA) {
1691 if (langOpts.CUDAIsDevice) {
1694 if (linkage != cir::GlobalLinkageKind::InternalLinkage &&
1696 (vd->
hasAttr<CUDADeviceAttr>() || vd->
hasAttr<CUDAConstantAttr>() ||
1699 gv->setAttr(cir::CUDAExternallyInitializedAttr::getMnemonic(),
1712 emitter->finalize(gv);
1716 gv.setConstant((vd->
hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
1717 (!needsGlobalCtor && !needsGlobalDtor &&
1722 if (
const SectionAttr *sa = vd->
getAttr<SectionAttr>()) {
1725 gv.setConstant(
true);
1729 gv.setLinkage(linkage);
1733 if (linkage == cir::GlobalLinkageKind::CommonLinkage) {
1735 gv.setConstant(
false);
1740 std::optional<mlir::Attribute> initializer = gv.getInitialValue();
1741 if (initializer && !
getBuilder().isNullValue(*initializer))
1742 gv.setLinkage(cir::GlobalLinkageKind::WeakAnyLinkage);
1745 setNonAliasAttributes(vd, gv);
1753 if (needsGlobalCtor || needsGlobalDtor) {
1776 cir::GlobalLinkageKind::AvailableExternallyLinkage)
1782 if (fd->isInlineBuiltinDeclaration())
1785 if (codeGenOpts.OptimizationLevel == 0 && !fd->hasAttr<AlwaysInlineAttr>())
1790 if (
const Module *m = fd->getOwningModule();
1792 getASTContext().getCurrentNamedModule() != m->getTopLevelModule()) {
1793 errorNYI(fd->getSourceRange(),
"should emit function in a named module");
1796 if (fd->hasAttr<NoInlineAttr>())
1807 mlir::Operation *op) {
1809 if (
const auto *fd = dyn_cast<FunctionDecl>(
decl)) {
1813 if (
const auto *method = dyn_cast<CXXMethodDecl>(
decl)) {
1817 abi->emitCXXStructor(gd);
1818 else if (fd->isMultiVersion())
1819 errorNYI(method->getSourceRange(),
"multiversion functions");
1823 if (method->isVirtual())
1829 if (fd->isMultiVersion())
1830 errorNYI(fd->getSourceRange(),
"multiversion functions");
1835 if (
const auto *vd = dyn_cast<VarDecl>(
decl))
1838 llvm_unreachable(
"Invalid argument to CIRGenModule::emitGlobalDefinition");
1852 astContext.getAsConstantArrayType(e->
getType());
1853 uint64_t finalSize = cat->getZExtSize();
1854 str.resize(finalSize);
1856 mlir::Type eltTy =
convertType(cat->getElementType());
1857 return builder.getString(str, eltTy, finalSize,
false);
1862 auto arrayEltTy = mlir::cast<cir::IntType>(arrayTy.getElementType());
1864 uint64_t arraySize = arrayTy.getSize();
1866 assert(arraySize > literalSize &&
1867 "wide string literal array size must have room for null terminator?");
1871 bool isAllZero =
true;
1872 for (
unsigned i = 0; i < literalSize; ++i) {
1880 return cir::ZeroAttr::get(arrayTy);
1884 elements.reserve(arraySize);
1885 for (
unsigned i = 0; i < literalSize; ++i)
1886 elements.push_back(cir::IntAttr::get(
1887 arrayEltTy, llvm::APInt(arrayEltTy.getWidth(), e->
getCodeUnit(i))));
1889 auto elementsAttr = mlir::ArrayAttr::get(&
getMLIRContext(), elements);
1890 return builder.getConstArray(elementsAttr, arrayTy);
1900 if (
auto globalOp = dyn_cast_or_null<cir::GlobalOp>(op)) {
1901 globalOp.setSelfComdat();
1904 funcOp.setSelfComdat();
1910 genTypes.updateCompletedType(td);
1914 replacements[name] = op;
1919 mlir::SymbolUserMap &userMap) {
1920 for (mlir::Operation *user : userMap.getUsers(oldF)) {
1921 auto call = mlir::dyn_cast<cir::CallOp>(user);
1925 for (
auto [argOp, fnArgType] :
1926 llvm::zip(call.getArgs(), newF.getFunctionType().getInputs())) {
1927 if (argOp.getType() != fnArgType)
1936void CIRGenModule::applyReplacements() {
1937 if (replacements.empty())
1943 mlir::SymbolTableCollection symbolTableCollection;
1944 mlir::SymbolUserMap userMap(symbolTableCollection,
getModule());
1946 for (
auto &i : replacements) {
1947 StringRef mangledName = i.first;
1948 mlir::Operation *replacement = i.second;
1954 auto newF = dyn_cast<cir::FuncOp>(replacement);
1957 errorNYI(replacement->getLoc(),
"replacement is not a function");
1962 "call argument types do not match replacement function");
1966 userMap.replaceAllUsesWith(oldF, newF.getSymNameAttr());
1967 newF->moveBefore(oldF);
1974 mlir::Location loc, StringRef name, mlir::Type ty,
1976 auto gv = mlir::dyn_cast_or_null<cir::GlobalOp>(
getGlobalValue(name));
1980 if (gv.getSymType() == ty)
1986 assert(gv.isDeclaration() &&
"Declaration has wrong type!");
1988 errorNYI(loc,
"createOrReplaceCXXRuntimeVariable: declaration exists with "
1999 mlir::SymbolTable::setSymbolVisibility(gv,
2003 !gv.hasAvailableExternallyLinkage()) {
2007 gv.setAlignmentAttr(
getSize(alignment));
2012cir::GlobalLinkageKind
2016 return cir::GlobalLinkageKind::InternalLinkage;
2019 return cir::GlobalLinkageKind::WeakAnyLinkage;
2023 return cir::GlobalLinkageKind::LinkOnceAnyLinkage;
2028 return cir::GlobalLinkageKind::AvailableExternallyLinkage;
2042 return !astContext.getLangOpts().AppleKext
2043 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
2044 : cir::GlobalLinkageKind::InternalLinkage;
2058 return cir::GlobalLinkageKind::ExternalLinkage;
2061 return dd->
hasAttr<CUDAGlobalAttr>()
2062 ? cir::GlobalLinkageKind::ExternalLinkage
2063 : cir::GlobalLinkageKind::InternalLinkage;
2064 return cir::GlobalLinkageKind::WeakODRLinkage;
2072 return cir::GlobalLinkageKind::CommonLinkage;
2078 if (dd->
hasAttr<SelectAnyAttr>())
2079 return cir::GlobalLinkageKind::WeakODRLinkage;
2083 return cir::GlobalLinkageKind::ExternalLinkage;
2095 mlir::Operation *old, cir::FuncOp newFn) {
2097 auto oldFn = mlir::dyn_cast<cir::FuncOp>(old);
2105 unsigned numInherentAttrs = 0;
2106 oldFn->getName().walkInherentAttrs(
2107 oldFn, [&](llvm::StringRef, mlir::Attribute &
attr) {
2110 if (numInherentAttrs <= 1)
2112 "replaceUsesOfNonProtoTypeWithRealFunction: Attribute forwarding");
2115 newFn.setNoProto(oldFn.getNoProto());
2118 std::optional<mlir::SymbolTable::UseRange> symUses =
2119 oldFn.getSymbolUses(oldFn->getParentOp());
2124 for (
const mlir::SymbolTable::SymbolUse &use : symUses.value()) {
2125 mlir::OpBuilder::InsertionGuard guard(builder);
2127 if (
auto noProtoCallOp = mlir::dyn_cast<cir::CallOp>(use.getUser())) {
2128 builder.setInsertionPoint(noProtoCallOp);
2131 cir::FuncType newFnType = newFn.getFunctionType();
2132 mlir::OperandRange callOperands = noProtoCallOp.getOperands();
2133 bool returnTypeMatches =
2134 newFnType.hasVoidReturn()
2135 ? noProtoCallOp.getNumResults() == 0
2136 : noProtoCallOp.getNumResults() == 1 &&
2137 noProtoCallOp.getResultTypes().front() ==
2138 newFnType.getReturnType();
2139 bool typesMatch = !newFn.getNoProto() && returnTypeMatches &&
2140 callOperands.size() == newFnType.getNumInputs();
2141 for (
unsigned i = 0, e = newFnType.getNumInputs(); typesMatch && i != e;
2143 if (callOperands[i].
getType() != newFnType.getInput(i))
2147 cir::CallOp realCallOp;
2151 builder.createCallOp(noProtoCallOp.getLoc(), newFn, callOperands);
2159 cir::FuncType origFnType = oldFn.getFunctionType();
2160 cir::FuncType callFnType =
2162 ? cir::FuncType::get(llvm::to_vector(callOperands.getTypes()),
2163 origFnType.getReturnType(),
2166 mlir::Value addr = cir::GetGlobalOp::create(
2167 builder, noProtoCallOp.getLoc(), cir::PointerType::get(newFnType),
2168 newFn.getSymName());
2169 mlir::Value casted =
2170 builder.createBitcast(addr, cir::PointerType::get(callFnType));
2171 realCallOp = builder.createIndirectCallOp(
2172 noProtoCallOp.getLoc(), casted, callFnType, callOperands);
2174 realCallOp.setCallingConv(noProtoCallOp.getCallingConv());
2177 noProtoCallOp.replaceAllUsesWith(realCallOp);
2178 noProtoCallOp.erase();
2179 }
else if (
auto getGlobalOp =
2180 mlir::dyn_cast<cir::GetGlobalOp>(use.getUser())) {
2187 mlir::Value res = getGlobalOp.getAddr();
2188 const mlir::Type oldResTy = res.getType();
2189 const auto newPtrTy = cir::PointerType::get(newFn.getFunctionType());
2190 if (oldResTy != newPtrTy) {
2191 res.setType(newPtrTy);
2192 builder.setInsertionPointAfter(getGlobalOp.getOperation());
2193 mlir::Value castRes =
2194 cir::CastOp::create(builder, getGlobalOp.getLoc(), oldResTy,
2195 cir::CastKind::bitcast, res);
2196 res.replaceAllUsesExcept(castRes, castRes.getDefiningOp());
2198 }
else if (mlir::isa<cir::GlobalOp>(use.getUser())) {
2204 "replaceUsesOfNonProtoTypeWithRealFunction: unexpected use type");
2209cir::GlobalLinkageKind
2211 GVALinkage linkage = astContext.GetGVALinkageForVariable(vd);
2218 GVALinkage linkage = astContext.GetGVALinkageForFunction(d);
2220 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(d))
2229 StringRef globalName,
CharUnits alignment) {
2232 mlir::ptr::MemorySpaceAttrInterface addrSpace =
2242 gv.setAlignmentAttr(cgm.
getSize(alignment));
2244 cir::GlobalLinkageKindAttr::get(cgm.
getBuilder().getContext(), lt));
2248 if (gv.isWeakForLinker()) {
2249 assert(cgm.
supportsCOMDAT() &&
"Only COFF uses weak string literals");
2252 cgm.
setDSOLocal(
static_cast<mlir::Operation *
>(gv));
2273 std::string result =
2284 astContext.getAlignOfGlobalVarInChars(s->
getType(),
nullptr);
2292 if (!gv.getAlignment() ||
2293 uint64_t(alignment.
getQuantity()) > *gv.getAlignment())
2294 gv.setAlignmentAttr(
getSize(alignment));
2299 if (
getCXXABI().getMangleContext().shouldMangleStringLiteral(s) &&
2302 "getGlobalForStringLiteral: mangle string literals");
2312 : builder.getUnknownLoc();
2313 auto typedC = llvm::cast<mlir::TypedAttr>(c);
2315 cir::GlobalLinkageKind::PrivateLinkage, *
this,
2316 uniqueName, alignment);
2330 auto arrayTy = mlir::dyn_cast<cir::ArrayType>(gv.getSymType());
2331 assert(arrayTy &&
"String literal must be array");
2333 arrayTy.getElementType(),
2336 return builder.getGlobalViewAttr(ptrTy, gv);
2340 StringRef str, StringRef name) {
2341 mlir::Attribute init = builder.getString(str,
convertType(astContext.CharTy),
2347 cir::GlobalLinkageKind::PrivateLinkage, *
this,
2352mlir::ptr::MemorySpaceAttrInterface
2383 "emitExplicitCastExprType");
2389 auto ty = mlir::cast<cir::MethodType>(
convertType(destTy));
2390 return builder.getNullMethodAttr(ty);
2393 auto ty = mlir::cast<cir::DataMemberType>(
convertType(destTy));
2394 return builder.getNullDataMemberAttr(ty);
2405 if (
const auto *methodDecl = dyn_cast<CXXMethodDecl>(
decl)) {
2407 if (methodDecl->isVirtual())
2408 return cir::ConstantOp::create(
2409 builder, loc,
getCXXABI().buildVirtualMethodAttr(ty, methodDecl));
2415 return cir::ConstantOp::create(builder, loc,
2416 builder.getMethodAttr(ty, methodFuncOp));
2431 assert(
fieldDecl->getParent() == destClass &&
2432 "scalar member pointer should be relative to the declaring class");
2434 astContext.toCharUnitsFromBits(astContext.getFieldOffset(
fieldDecl))
2436 return cir::ConstantOp::create(builder, loc,
2437 cir::DataMemberOffsetAttr::get(ty, offset));
2440 std::optional<llvm::SmallVector<int32_t>> path =
2444 return cir::ConstantOp::create(builder, loc,
2445 builder.getDataMemberAttr(ty, *path));
2448std::optional<llvm::SmallVector<int32_t>>
2456 if (
const auto *indirectField = dyn_cast<IndirectFieldDecl>(
decl)) {
2458 for (
const NamedDecl *nd : indirectField->chain()) {
2460 if (!findFieldMemberPath(currentClass, field, path))
2461 return std::nullopt;
2462 currentClass = field->getType()->getAsCXXRecordDecl();
2468 return std::nullopt;
2472bool CIRGenModule::findFieldMemberPath(
const CXXRecordDecl *currentClass,
2482 if (currentClass->
isUnion()) {
2488 "data member pointer for non-zero-initializable union");
2495 path.push_back(fieldIdx);
2503 for (
const CXXBaseSpecifier &base : currentClass->
bases()) {
2504 const auto *baseDecl =
2507 if (base.isVirtual()) {
2512 llvm::SmallVector<int32_t> discardedPath;
2513 if (findFieldMemberPath(baseDecl, field, discardedPath)) {
2515 "data member pointer through virtual base");
2528 path.push_back(baseFieldIdx);
2529 if (findFieldMemberPath(baseDecl, field, path))
2557 if (
auto *oid = dyn_cast<ObjCImplDecl>(
decl))
2558 errorNYI(oid->getSourceRange(),
"emitDeclConext: ObjCImplDecl");
2568 if (
decl->isTemplated())
2571 switch (
decl->getKind()) {
2574 decl->getDeclKindName());
2577 case Decl::CXXConversion:
2578 case Decl::CXXMethod:
2579 case Decl::Function: {
2582 if (!fd->isConsteval())
2587 case Decl::Import: {
2596 if (!importedModules.insert(mod))
2598 moduleImportLocs[mod] = importDecl->getLocation();
2615 visited.insert(mod);
2616 stack.push_back(mod);
2618 while (!stack.empty()) {
2620 if (!emittedModuleInitializers.insert(cur).second)
2623 for (
Decl *initializer : astContext.getModuleInitializers(cur))
2630 if (submodule->IsExplicit)
2633 if (visited.insert(submodule).second)
2634 stack.push_back(submodule);
2645 case Decl::Decomposition:
2646 case Decl::VarTemplateSpecialization: {
2648 if (
auto *decomp = dyn_cast<DecompositionDecl>(
decl))
2649 for (
auto *binding : decomp->flat_bindings())
2650 if (
auto *holdingVar = binding->getHoldingVar())
2654 case Decl::OpenACCRoutine:
2657 case Decl::OpenACCDeclare:
2660 case Decl::OMPThreadPrivate:
2663 case Decl::OMPGroupPrivate:
2666 case Decl::OMPAllocate:
2669 case Decl::OMPCapturedExpr:
2672 case Decl::OMPDeclareReduction:
2675 case Decl::OMPDeclareMapper:
2678 case Decl::OMPRequires:
2683 case Decl::UsingDirective:
2684 case Decl::UsingEnum:
2685 case Decl::NamespaceAlias:
2687 case Decl::TypeAlias:
2694 case Decl::IndirectField:
2698 case Decl::ClassTemplate:
2700 case Decl::CXXDeductionGuide:
2702 case Decl::ExplicitInstantiation:
2703 case Decl::FunctionTemplate:
2704 case Decl::StaticAssert:
2705 case Decl::TypeAliasTemplate:
2706 case Decl::UsingShadow:
2707 case Decl::VarTemplate:
2708 case Decl::VarTemplatePartialSpecialization:
2711 case Decl::CXXConstructor:
2714 case Decl::CXXDestructor:
2719 case Decl::LinkageSpec:
2720 case Decl::Namespace:
2724 case Decl::ClassTemplateSpecialization:
2725 case Decl::CXXRecord: {
2728 for (
auto *childDecl : crd->
decls())
2734 case Decl::FileScopeAsm:
2736 if (langOpts.CUDA && langOpts.CUDAIsDevice)
2739 if (langOpts.OpenMPIsTargetDevice)
2742 if (langOpts.SYCLIsDevice)
2745 std::string line = file_asm->getAsmString();
2746 globalScopeAsm.push_back(builder.getStringAttr(line));
2753 op.setInitialValueAttr(value);
2767 md->getParent()->getNumVBases() == 0)
2769 "getAddrAndTypeOfCXXStructor: MS ABI complete destructor");
2780 false, isForDefinition);
2782 return {fnType, fn};
2786 mlir::Type funcType,
bool forVTable,
2790 "consteval function should never be emitted");
2800 if (
const auto *dd = dyn_cast<CXXDestructorDecl>(gd.
getDecl())) {
2803 dd->getParent()->getNumVBases() == 0)
2805 "getAddrOfFunction: MS ABI complete destructor");
2811 false, isForDefinition);
2813 if (langOpts.CUDA && !langOpts.CUDAIsDevice &&
2819 bool isHIPHandle = mlir::isa<cir::GlobalOp>(*handle);
2820 if (isForDefinition || isHIPHandle)
2822 return mlir::dyn_cast<cir::FuncOp>(*handle);
2831 llvm::raw_svector_ostream
out(buffer);
2840 assert(ii &&
"Attempt to mangle unnamed decl.");
2842 const auto *fd = dyn_cast<FunctionDecl>(nd);
2846 }
else if (fd && fd->hasAttr<CUDAGlobalAttr>() &&
2850 DeviceKernelAttr::isOpenCLSpelling(
2851 fd->getAttr<DeviceKernelAttr>()) &&
2868 if (
const auto *fd = dyn_cast<FunctionDecl>(nd)) {
2869 if (fd->isMultiVersion()) {
2871 "getMangledName: multi-version functions");
2879 "getMangledName: GPU relocatable device code");
2881 return std::string(
out.str());
2884static FunctionDecl *
2899 if (
auto *methodDecl = dyn_cast<CXXMethodDecl>(protoFunc);
2900 methodDecl && methodDecl->isImplicitObjectMemberFunction()) {
2902 paramTypes.insert(paramTypes.begin(), methodDecl->getThisType());
2905 fpt->getExtProtoInfo());
2916 params.reserve(fpt->getNumParams());
2919 for (
unsigned i = 0, e = fpt->getNumParams(); i != e; ++i) {
2923 nullptr, fpt->getParamType(i),
nullptr,
2926 params.push_back(parm);
2929 tempFunc->setParams(params);
2954 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.
getDecl())) {
2957 "getMangledName: C++ constructor without variants");
2966 if (!langOpts.CUDAIsDevice || !astContext.mayExternalize(gd.
getDecl())) {
2967 auto foundName = mangledDeclNames.find(canonicalGd);
2968 if (foundName != mangledDeclNames.end())
2969 return foundName->second;
2976 auto result = manglings.insert(std::make_pair(mangledName, gd));
2977 return mangledDeclNames[canonicalGd] = result.first->first();
2981 assert(!d->
getInit() &&
"Cannot emit definite definitions here!");
2989 if (gv && !mlir::cast<cir::GlobalOp>(gv).isDeclaration())
3005 if (langOpts.EmitAllDecls)
3008 const auto *vd = dyn_cast<VarDecl>(global);
3010 ((codeGenOpts.KeepPersistentStorageVariables &&
3011 (vd->getStorageDuration() ==
SD_Static ||
3012 vd->getStorageDuration() ==
SD_Thread)) ||
3013 (codeGenOpts.KeepStaticConsts && vd->getStorageDuration() ==
SD_Static &&
3014 vd->getType().isConstQualified())))
3027 if (langOpts.OpenMP >= 50 && !langOpts.OpenMPSimd) {
3028 std::optional<OMPDeclareTargetDeclAttr *> activeAttr =
3029 OMPDeclareTargetDeclAttr::getActiveAttr(global);
3030 if (!activeAttr || (*activeAttr)->getLevel() != (
unsigned)-1)
3034 const auto *fd = dyn_cast<FunctionDecl>(global);
3041 if (fd->hasAttr<TargetVersionAttr>() && !fd->isMultiVersion())
3045 if (langOpts.SYCLIsDevice && fd->hasAttr<SYCLKernelEntryPointAttr>())
3048 const auto *vd = dyn_cast<VarDecl>(global);
3050 if (astContext.getInlineVariableDefinitionKind(vd) ==
3058 if (langOpts.OpenMP && langOpts.OpenMPUseTLS &&
3059 astContext.getTargetInfo().isTLSSupported() &&
isa<VarDecl>(global) &&
3061 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(global))
3064 assert((fd || vd) &&
3065 "Only FunctionDecl and VarDecl should hit this path so far.");
3070 cir::CIRGlobalValueInterface gv) {
3071 if (gv.hasLocalLinkage())
3074 if (!gv.hasDefaultVisibility() && !gv.hasExternalWeakLinkage())
3082 const llvm::Triple &tt = cgm.
getTriple();
3084 if (tt.isOSCygMing()) {
3093 cgm.
errorNYI(
"shouldAssumeDSOLocal: MinGW");
3099 if (tt.isOSBinFormatCOFF() && gv.hasExternalWeakLinkage())
3107 if (tt.isOSBinFormatCOFF() || (tt.isOSWindows() && tt.isOSBinFormatMachO()))
3111 if (!tt.isOSBinFormatELF())
3116 if (rm != llvm::Reloc::Static && !lOpts.PIE) {
3124 return !(lOpts.SemanticInterposition || lOpts.HalfNoSemanticInterposition);
3128 if (!gv.isDeclarationForLinker())
3134 if (rm == llvm::Reloc::PIC_ && gv.hasExternalWeakLinkage())
3141 if (cgOpts.DirectAccessExternalData) {
3147 if (
auto globalOp = dyn_cast<cir::GlobalOp>(gv.getOperation())) {
3173 if (gv.hasLocalLinkage()) {
3174 gv.setGlobalVisibility(cir::VisibilityKind::Default);
3189 d->
hasAttr<OMPDeclareTargetDeclAttr>() &&
3190 d->
getAttr<OMPDeclareTargetDeclAttr>()->getDevType() !=
3191 OMPDeclareTargetDeclAttr::DT_NoHost &&
3193 llvm_unreachable(
"setGlobalVisibility: OpenMP is NYI");
3202 !d->
hasAttr<OMPDeclareTargetDeclAttr>()) {
3203 bool needsProtected =
false;
3207 }
else if (
const auto *vd = dyn_cast<VarDecl>(d)) {
3208 needsProtected = vd->hasAttr<CUDADeviceAttr>() ||
3209 vd->hasAttr<CUDAConstantAttr>() ||
3210 vd->getType()->isCUDADeviceBuiltinSurfaceType() ||
3211 vd->getType()->isCUDADeviceBuiltinTextureType();
3213 if (needsProtected) {
3214 gv.setGlobalVisibility(cir::VisibilityKind::Protected);
3220 gv.setGlobalVisibility(cir::VisibilityKind::Hidden);
3227 !gv.isDeclarationForLinker())
3236 if (
auto globalValue = dyn_cast<cir::CIRGlobalValueInterface>(op))
3255 auto res = manglings.find(mangledName);
3256 if (res == manglings.end())
3258 result = res->getValue();
3263 return llvm::StringSwitch<cir::TLSModel>(S)
3264 .Case(
"global-dynamic", cir::TLSModel::GeneralDynamic)
3265 .Case(
"local-dynamic", cir::TLSModel::LocalDynamic)
3266 .Case(
"initial-exec", cir::TLSModel::InitialExec)
3267 .Case(
"local-exec", cir::TLSModel::LocalExec);
3273 return cir::TLSModel::GeneralDynamic;
3275 return cir::TLSModel::LocalDynamic;
3277 return cir::TLSModel::InitialExec;
3279 return cir::TLSModel::LocalExec;
3281 llvm_unreachable(
"Invalid TLS model!");
3285 bool isExtendingDecl) {
3286 assert(d.
getTLSKind() &&
"setting TLS mode on non-TLS var!");
3295 global.setTlsModel(tlm);
3305 if (isExtendingDecl)
3313 cir::FuncOp func,
bool isThunk) {
3315 cir::CallingConv callingConv;
3322 mlir::NamedAttrList pal{};
3323 std::vector<mlir::NamedAttrList> argAttrs(info.arguments().size());
3324 mlir::NamedAttrList retAttrs{};
3326 retAttrs, callingConv,
3329 for (mlir::NamedAttribute
attr : pal)
3330 func->setAttr(
attr.getName(),
attr.getValue());
3332 llvm::for_each(llvm::enumerate(argAttrs), [func](
auto idx_arg_pair) {
3333 mlir::function_interface_impl::setArgAttrs(func, idx_arg_pair.index(),
3334 idx_arg_pair.value());
3336 if (!retAttrs.empty())
3337 mlir::function_interface_impl::setResultAttrs(func, 0, retAttrs);
3341 func.setCallingConv(callingConv);
3346 bool isIncompleteFunction,
3354 if (!isIncompleteFunction)
3356 getTypes().arrangeGlobalDeclaration(globalDecl),
3359 if (!isIncompleteFunction && func.isDeclaration())
3364 if (
const auto *errorAttr = funcDecl->getAttr<ErrorAttr>()) {
3365 if (errorAttr->isError())
3366 func->setAttr(cir::CIRDialect::getDontCallErrorAttrName(),
3368 errorAttr->getUserDiagnostic()));
3369 else if (errorAttr->isWarning())
3370 func->setAttr(cir::CIRDialect::getDontCallWarnAttrName(),
3372 errorAttr->getUserDiagnostic()));
3379 if (funcDecl->isInlineBuiltinDeclaration()) {
3381 bool hasBody = funcDecl->
hasBody(fdBody);
3383 assert(hasBody &&
"Inline builtin declarations should always have an "
3388 if (funcDecl->isReplaceableGlobalAllocationFunction()) {
3391 func->setAttr(cir::CIRDialect::getNoBuiltinAttrName(),
3399 if ((!
decl || !
decl->hasAttr<NoUwtableAttr>()) && codeGenOpts.UnwindTables)
3400 f.setUwtable(
static_cast<cir::UnwindTableKind
>(codeGenOpts.UnwindTables));
3405 f->setAttr(cir::CIRDialect::getNoThrowAttrName(),
3408 std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind();
3410 existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
3411 bool isAlwaysInline = existingInlineKind &&
3412 *existingInlineKind == cir::InlineKind::AlwaysInline;
3416 if (!isAlwaysInline &&
3421 f.setInlineKind(cir::InlineKind::NoInline);
3433 bool shouldAddOptNone =
3434 !codeGenOpts.DisableO0ImplyOptNone && codeGenOpts.OptimizationLevel == 0;
3436 shouldAddOptNone &= !
decl->hasAttr<MinSizeAttr>();
3437 shouldAddOptNone &= !
decl->hasAttr<AlwaysInlineAttr>();
3440 if ((shouldAddOptNone ||
decl->hasAttr<OptimizeNoneAttr>()) &&
3443 f->setAttr(cir::CIRDialect::getOptNoneAttrName(),
3447 f.setInlineKind(cir::InlineKind::NoInline);
3451 if (
decl->hasAttr<NakedAttr>())
3452 f->setAttr(cir::CIRDialect::getNakedAttrName(),
3456 f->removeAttr(cir::CIRDialect::getOptimizeForSizeAttrName());
3457 f->removeAttr(cir::CIRDialect::getMinSizeAttrName());
3458 }
else if (
decl->hasAttr<NakedAttr>()) {
3460 f->setAttr(cir::CIRDialect::getNakedAttrName(),
3462 f.setInlineKind(cir::InlineKind::NoInline);
3463 }
else if (
decl->hasAttr<NoDuplicateAttr>()) {
3464 f->setAttr(cir::CIRDialect::getNoDuplicatesAttrName(),
3466 }
else if (
decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) {
3468 f.setInlineKind(cir::InlineKind::NoInline);
3469 }
else if (
decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) {
3472 f.setInlineKind(cir::InlineKind::AlwaysInline);
3476 if (!isAlwaysInline)
3477 f.setInlineKind(cir::InlineKind::NoInline);
3482 if (
auto *fd = dyn_cast<FunctionDecl>(
decl)) {
3487 auto checkRedeclForInline = [](
const FunctionDecl *redecl) {
3488 return redecl->isInlineSpecified();
3490 if (any_of(
decl->redecls(), checkRedeclForInline))
3495 return any_of(pattern->
redecls(), checkRedeclForInline);
3497 if (checkForInline(fd)) {
3498 f.setInlineKind(cir::InlineKind::InlineHint);
3499 }
else if (codeGenOpts.getInlining() ==
3501 !fd->isInlined() && !isAlwaysInline) {
3502 f.setInlineKind(cir::InlineKind::NoInline);
3509 if (!
decl->hasAttr<OptimizeNoneAttr>()) {
3510 if (
decl->hasAttr<ColdAttr>()) {
3511 if (!shouldAddOptNone)
3512 f->setAttr(cir::CIRDialect::getOptimizeForSizeAttrName(),
3515 f->setAttr(cir::CIRDialect::getColdAttrName(),
3519 if (
decl->hasAttr<HotAttr>())
3520 f->setAttr(cir::CIRDialect::getHotAttrName(),
3523 if (
decl->hasAttr<MinSizeAttr>())
3524 f->setAttr(cir::CIRDialect::getMinSizeAttrName(),
3528 std::optional<uint64_t> explicitAlignment;
3529 if (
unsigned alignment =
3531 explicitAlignment = alignment;
3532 else if (langOpts.FunctionAlignment)
3533 explicitAlignment = 1ull << langOpts.FunctionAlignment;
3535 if (explicitAlignment) {
3536 f.setAlignment(*explicitAlignment);
3537 f.setPreferredAlignment(*explicitAlignment);
3538 }
else if (langOpts.PreferredFunctionAlignment) {
3539 f.setPreferredAlignment(langOpts.PreferredFunctionAlignment);
3561static cir::LangAddressSpace
3563 switch (addressSpace) {
3565 return cir::LangAddressSpace::OffloadGlobal;
3567 return cir::LangAddressSpace::OffloadConstant;
3569 return cir::LangAddressSpace::OffloadLocal;
3571 return cir::LangAddressSpace::OffloadGeneric;
3573 return cir::LangAddressSpace::OffloadGlobalDevice;
3575 return cir::LangAddressSpace::OffloadGlobalHost;
3579 return cir::LangAddressSpace::Default;
3585 assert(fd &&
"expected a kernel function declaration");
3598 argNames.push_back(builder.getStringAttr(param->getName()));
3601 std::string typeQuals;
3603 if (
type->isImageType() ||
type->isPipeType()) {
3605 "OpenCL kernel argument metadata for image and pipe types");
3609 accessQuals.push_back(builder.getStringAttr(
"none"));
3611 auto getTypeSpelling = [&](
QualType paramType) {
3612 std::string typeName = paramType.getUnqualifiedType().getAsString(policy);
3614 if (paramType.isCanonical()) {
3615 StringRef typeNameRef = typeName;
3616 if (typeNameRef.consume_front(
"unsigned "))
3617 return std::string(
"u") + typeNameRef.str();
3618 if (typeNameRef.consume_front(
"signed "))
3619 return typeNameRef.str();
3627 if (
type->isPointerType()) {
3629 addressQuals.push_back(cir::LangAddressSpaceAttr::get(
3633 argTypeNames.push_back(
3634 builder.getStringAttr(getTypeSpelling(
pointeeType) +
"*"));
3635 argBaseTypeNames.push_back(builder.getStringAttr(
3636 getTypeSpelling(
pointeeType.getCanonicalType()) +
"*"));
3638 if (
type.isRestrictQualified())
3639 typeQuals =
"restrict";
3642 typeQuals += typeQuals.empty() ?
"const" :
" const";
3644 typeQuals += typeQuals.empty() ?
"volatile" :
" volatile";
3646 addressQuals.push_back(cir::LangAddressSpaceAttr::get(
3649 argTypeNames.push_back(builder.getStringAttr(getTypeSpelling(
type)));
3650 argBaseTypeNames.push_back(
3651 builder.getStringAttr(getTypeSpelling(
type.getCanonicalType())));
3654 argTypeQuals.push_back(builder.getStringAttr(typeQuals));
3657 mlir::ArrayAttr names;
3659 names = builder.getArrayAttr(argNames);
3661 mlir::Attribute metadata = cir::OpenCLKernelArgMetadataAttr::get(
3662 func.getContext(), builder.getArrayAttr(addressQuals),
3663 builder.getArrayAttr(accessQuals), builder.getArrayAttr(argTypeNames),
3664 builder.getArrayAttr(argBaseTypeNames),
3665 builder.getArrayAttr(argTypeQuals), names);
3666 func->setAttr(cir::CIRDialect::getOpenCLKernelArgMetadataAttrName(),
3671 StringRef mangledName, mlir::Type funcType,
GlobalDecl gd,
bool forVTable,
3673 mlir::NamedAttrList extraAttrs) {
3676 if (
const auto *fd = cast_or_null<FunctionDecl>(d)) {
3678 if (
getLangOpts().OpenMPIsTargetDevice && openMPRuntime &&
3680 !dontDefer && !isForDefinition) {
3683 if (
const auto *cd = dyn_cast<CXXConstructorDecl>(fdDef))
3685 else if (
const auto *dd = dyn_cast<CXXDestructorDecl>(fdDef))
3695 if (fd->isMultiVersion())
3696 errorNYI(fd->getSourceRange(),
"getOrCreateCIRFunction: multi-version");
3702 assert(mlir::isa<cir::FuncOp>(entry));
3707 if (d && !d->
hasAttr<DLLImportAttr>() && !d->
hasAttr<DLLExportAttr>()) {
3715 if (isForDefinition && fn && !fn.isDeclaration()) {
3722 diagnosedConflictingDefinitions.insert(gd).second) {
3726 diag::note_previous_definition);
3730 if (fn && fn.getFunctionType() == funcType) {
3734 if (!isForDefinition) {
3742 auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.
getDecl());
3743 bool invalidLoc = !funcDecl ||
3744 funcDecl->getSourceRange().getBegin().isInvalid() ||
3745 funcDecl->getSourceRange().getEnd().isInvalid();
3747 invalidLoc ? theModule->getLoc() :
getLoc(funcDecl->getSourceRange()),
3748 mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
3750 if (funcDecl && funcDecl->hasAttr<AnnotateAttr>())
3751 deferredAnnotations[mangledName] = funcDecl;
3762 auto symbolOp = mlir::cast<mlir::SymbolOpInterface>(entry);
3770 if (symbolOp.getSymbolUses(symbolOp->getParentOp()))
3780 if (!extraAttrs.empty())
3781 for (mlir::NamedAttribute attr : extraAttrs)
3782 if (!funcOp->hasDiscardableAttr(
attr.getName()))
3783 funcOp->setDiscardableAttr(
attr.getName(),
attr.getValue());
3789 assert(funcOp.getFunctionType() == funcType);
3796 if (isa_and_nonnull<CXXDestructorDecl>(d) &&
3826 fd = fd->getPreviousDecl()) {
3828 if (fd->doesThisDeclarationHaveABody()) {
3841 cir::FuncType funcType,
3845 mlir::OpBuilder::InsertionGuard guard(builder);
3850 builder.setInsertionPointToEnd(
getModule().getBody());
3852 func = cir::FuncOp::create(builder, loc, name, funcType);
3859 func.setNoProto(
true);
3861 assert(func.isDeclaration() &&
"expected empty body");
3865 func.setLinkageAttr(cir::GlobalLinkageKindAttr::get(
3867 mlir::SymbolTable::setSymbolVisibility(
3868 func, mlir::SymbolTable::Visibility::Private);
3879 for (
const auto *
attr :
3893 fnOp.setBuiltin(
true);
3899 return cir::CtorKind::Default;
3901 return cir::CtorKind::Copy;
3903 return cir::CtorKind::Move;
3904 return cir::CtorKind::Custom;
3909 return cir::AssignKind::Copy;
3911 return cir::AssignKind::Move;
3912 llvm_unreachable(
"not a copy or move assignment operator");
3920 if (
const auto *dtor = dyn_cast<CXXDestructorDecl>(funcDecl)) {
3921 auto cxxDtor = cir::CXXDtorAttr::get(
3924 funcOp.setFuncInfoAttr(cxxDtor);
3928 if (
const auto *ctor = dyn_cast<CXXConstructorDecl>(funcDecl)) {
3930 auto cxxCtor = cir::CXXCtorAttr::get(
3932 kind, ctor->isTrivial());
3933 funcOp.setFuncInfoAttr(cxxCtor);
3937 const auto *method = dyn_cast<CXXMethodDecl>(funcDecl);
3938 if (method && (method->isCopyAssignmentOperator() ||
3939 method->isMoveAssignmentOperator())) {
3941 auto cxxAssign = cir::CXXAssignAttr::get(
3943 assignKind, method->isTrivial());
3944 funcOp.setFuncInfoAttr(cxxAssign);
3954 bool inStdNamespace = method ? method->getParent()->isInStdNamespace()
3956 if (!inStdNamespace)
3962 std::optional<cir::KnownFuncKind>
kind;
3964 kind = llvm::StringSwitch<std::optional<cir::KnownFuncKind>>(
3966 .Case(cir::StdFindOp::getFunctionName(),
3967 cir::StdFindOp::getFuncKind())
3968 .Default(std::nullopt);
3977 cir::FuncOp funcOp, StringRef name) {
3993 mlir::NamedAttrList extraAttrs,
3995 bool assumeConvergent) {
3996 if (assumeConvergent)
3997 errorNYI(
"createRuntimeFunction: assumeConvergent");
4007 entry.setDSOLocal(
true);
4013mlir::SymbolTable::Visibility
4017 if (op.isDeclaration())
4018 return mlir::SymbolTable::Visibility::Private;
4022mlir::SymbolTable::Visibility
4025 case cir::GlobalLinkageKind::InternalLinkage:
4026 case cir::GlobalLinkageKind::PrivateLinkage:
4027 return mlir::SymbolTable::Visibility::Private;
4028 case cir::GlobalLinkageKind::ExternalLinkage:
4029 case cir::GlobalLinkageKind::ExternalWeakLinkage:
4030 case cir::GlobalLinkageKind::LinkOnceODRLinkage:
4031 case cir::GlobalLinkageKind::AvailableExternallyLinkage:
4032 case cir::GlobalLinkageKind::CommonLinkage:
4033 case cir::GlobalLinkageKind::WeakAnyLinkage:
4034 case cir::GlobalLinkageKind::WeakODRLinkage:
4035 return mlir::SymbolTable::Visibility::Public;
4037 llvm::errs() <<
"visibility not implemented for '"
4038 << stringifyGlobalLinkageKind(glk) <<
"'\n";
4039 assert(0 &&
"not implemented");
4042 llvm_unreachable(
"linkage should be handled above!");
4045std::string CIRGenModule::getModuleInitializerName(
clang::Module *mod) {
4047 llvm::raw_string_ostream
out(name);
4049 .mangleModuleInitializer(mod,
out);
4056 applyReplacements();
4058 getModule()->setAttr(cir::CIRDialect::getModuleLevelAsmAttrName(),
4059 builder.getArrayAttr(globalScopeAsm));
4061 emitGlobalAnnotations();
4063 if (std::optional<cir::FramePointerKind>
kind =
4066 cir::CIRDialect::getModuleFramePointerAttrName(),
4069 if (!recordLayoutEntries.empty())
4071 cir::CIRDialect::getRecordLayoutsAttrName(),
4072 mlir::DictionaryAttr::get(&
getMLIRContext(), recordLayoutEntries));
4081 std::string cuidName =
4084 auto loc = builder.getUnknownLoc();
4085 mlir::ptr::MemorySpaceAttrInterface addrSpace =
4090 gv.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
4092 auto zeroAttr = cir::IntAttr::get(int8Ty, 0);
4093 gv.setInitialValueAttr(zeroAttr);
4095 mlir::SymbolTable::setSymbolVisibility(
4096 gv, mlir::SymbolTable::Visibility::Public);
4101 if (astContext.getLangOpts().CUDA && cudaRuntime)
4114 if (cxx20ModuleInits) {
4115 clang::Module *primary = astContext.getCurrentNamedModule();
4117 if (isInterfaceUnit)
4119 cir::CIRDialect::getCXXModuleInitFnNameAttrName(),
4120 builder.getStringAttr(getModuleInitializerName(primary)));
4126 primary, importedModules.getArrayRef())) {
4129 auto importLoc = moduleImportLocs.find(mod);
4130 mlir::Location loc =
4131 getLoc(importLoc != moduleImportLocs.end() ? importLoc->second
4133 importedInits.push_back(cir::CXXModuleInitAttr::get(
4135 builder.getStringAttr(getModuleInitializerName(mod)), loc));
4137 if (!importedInits.empty())
4138 getModule()->setAttr(cir::CIRDialect::getCXXModuleImportedInitsAttrName(),
4139 builder.getArrayAttr(importedInits));
4155 const AliasAttr *aa = d->
getAttr<AliasAttr>();
4156 assert(aa &&
"Not an alias?");
4160 if (aa->getAliasee() == mangledName) {
4161 diags.Report(aa->getLocation(), diag::err_cyclic_alias) << 0;
4169 auto entryGV = mlir::dyn_cast<cir::CIRGlobalValueInterface>(entry);
4170 if (entryGV && entryGV.isDefinition())
4183 cir::GlobalLinkageKind linkage;
4195 cir::CIRGlobalValueInterface alias =
4196 isFunction ? mlir::cast<cir::CIRGlobalValueInterface>(
4198 mlir::cast<cir::FuncType>(declTy),
4201 : mlir::cast<cir::CIRGlobalValueInterface>(
4212 entry, mlir::cast<cir::FuncOp>(alias.getOperation()));
4220 linkage = cir::GlobalLinkageKind::WeakAnyLinkage;
4224 mlir::SymbolTable::Visibility visibility =
4227 alias.setAliasee(aa->getAliasee());
4228 alias.setLinkage(linkage);
4229 mlir::SymbolTable::setSymbolVisibility(alias, visibility);
4237 cir::FuncOp aliasee,
4238 cir::GlobalLinkageKind linkage) {
4240 auto *aliasFD = dyn_cast<FunctionDecl>(aliasGD.
getDecl());
4241 assert(aliasFD &&
"expected FunctionDecl");
4252 mangledName, fnType, aliasFD);
4253 alias.setAliasee(aliasee.getName());
4254 alias.setLinkage(linkage);
4258 mlir::SymbolTable::setSymbolVisibility(
4259 alias, mlir::SymbolTable::Visibility::Private);
4271 "declaration exists with different type");
4283 return genTypes.convertType(
type);
4290 return mlir::verify(
getModule()).succeeded();
4299 return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
4302 langOpts.ObjCRuntime.isGNUFamily()) {
4303 errorNYI(loc,
"getAddrOfRTTIDescriptor: Objc PtrType & Objc RT GUN");
4313 llvm::iterator_range<CastExpr::path_const_iterator> path) {
4320 assert(!base->isVirtual() &&
"Should not see virtual bases here!");
4325 const auto *baseDecl = base->getType()->castAsCXXRecordDecl();
4337 llvm::StringRef feature) {
4338 unsigned diagID = diags.getCustomDiagID(
4340 return diags.Report(loc, diagID) << feature;
4344 llvm::StringRef feature) {
4356 "cannot compile this %0 yet");
4357 diags.Report(astContext.getFullLoc(s->
getBeginLoc()), diagId)
4364 "cannot compile this %0 yet");
4365 diags.Report(astContext.getFullLoc(d->
getLocation()), diagId) <<
type;
4373 "not a global temporary");
4385 materializedType = mte->
getType();
4394 llvm::raw_svector_ostream
out(name);
4398 auto insertResult = materializedGlobalTemporaryMap.insert({mte,
nullptr});
4399 if (!insertResult.second) {
4403 if (!insertResult.first->second) {
4406 insertResult.first->second =
4409 return insertResult.first->second;
4426 value = &evalResult.
Val;
4430 std::optional<ConstantEmitter> emitter;
4431 mlir::Attribute initialValue =
nullptr;
4432 bool isConstant =
false;
4436 emitter.emplace(*
this);
4437 initialValue = emitter->emitForInitializer(*value, materializedType);
4442 type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
4451 if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
4453 if (
varDecl->isStaticDataMember() &&
varDecl->getAnyInitializer(initVD) &&
4461 linkage = cir::GlobalLinkageKind::InternalLinkage;
4465 gv.setInitialValueAttr(initialValue);
4466 gv.setLinkage(linkage);
4470 emitter->finalize(gv);
4472 if (!gv.hasLocalLinkage()) {
4477 gv.setAlignment(align.getAsAlign().value());
4482 mlir::Operation *cv = gv;
4491 mlir::Operation *&entry = materializedGlobalTemporaryMap[mte];
4493 entry->replaceAllUsesWith(cv);
4508 return *globalOpEntry;
4515 "emitForInitializer should take gcd->getType().getAddressSpace()");
4517 auto typedInit = dyn_cast<mlir::TypedAttr>(init);
4521 "getAddrOfUnnamedGlobalConstantDecl: non-typed initializer");
4530 std::string name = numEntries == 0
4532 : (Twine(
".constant.") + Twine(numEntries)).str();
4534 typedInit.getType(),
true);
4535 globalOp.setLinkage(cir::GlobalLinkageKind::PrivateLinkage);
4538 globalOp.setAlignment(alignment.
getAsAlign().value());
4542 *globalOpEntry = globalOp;
4557 "emitForInitializer should take tpo->getType().getAddressSpace()");
4558 mlir::Attribute init =
4568 cir::GlobalLinkageKind linkage =
4570 ? cir::GlobalLinkageKind::LinkOnceODRLinkage
4571 : cir::GlobalLinkageKind::InternalLinkage;
4575 typedInit.getType(),
true);
4576 globalOp.setLinkage(linkage);
4577 globalOp.setAlignment(alignment.
getAsAlign().value());
4578 if (
supportsCOMDAT() && linkage == cir::GlobalLinkageKind::LinkOnceODRLinkage)
4579 globalOp.setSelfComdat();
4594CIRGenModule::getOrCreateAnnotationArgs(
const AnnotateAttr *
attr) {
4601 llvm::FoldingSetNodeID id;
4602 for (
Expr *e : exprs)
4605 mlir::ArrayAttr &lookup = annotationArgs[
id.computeHash()];
4610 args.reserve(exprs.size());
4611 for (
Expr *e : exprs) {
4612 if (
auto *strE = dyn_cast<clang::StringLiteral>(e->IgnoreParenCasts())) {
4613 args.push_back(builder.getStringAttr(strE->getString()));
4614 }
else if (
auto *intE =
4615 dyn_cast<clang::IntegerLiteral>(e->IgnoreParenCasts())) {
4616 auto intTy = builder.getIntegerType(intE->getValue().getBitWidth());
4617 args.push_back(builder.getIntegerAttr(intTy, intE->getValue()));
4619 errorNYI(e->getExprLoc(),
"annotation argument expression");
4623 return lookup = builder.getArrayAttr(args);
4626cir::AnnotationAttr CIRGenModule::emitAnnotateAttr(
const AnnotateAttr *aa) {
4627 mlir::StringAttr annoGV = builder.getStringAttr(aa->getAnnotation());
4628 mlir::ArrayAttr args = getOrCreateAnnotationArgs(aa);
4629 return cir::AnnotationAttr::get(&
getMLIRContext(), annoGV, args);
4633 mlir::Operation *gv) {
4634 assert(d->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
4636 "annotation only on globals");
4639 annotations.push_back(emitAnnotateAttr(i));
4640 if (
auto global = dyn_cast<cir::GlobalOp>(gv))
4641 global.setAnnotationsAttr(builder.getArrayAttr(annotations));
4642 else if (
auto func = dyn_cast<cir::FuncOp>(gv))
4643 func.setAnnotationsAttr(builder.getArrayAttr(annotations));
4646void CIRGenModule::emitGlobalAnnotations() {
4647 for (
const auto &[mangledName, vd] : deferredAnnotations) {
4652 deferredAnnotations.clear();
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 shouldSkipAliasEmission(const CIRGenModule &cgm, const ValueDecl *global)
static cir::LangAddressSpace getOpenCLKernelArgAddressSpace(LangAS addressSpace)
static mlir::Attribute getNewInitValue(CIRGenModule &cgm, cir::GlobalOp newGlob, mlir::Type oldTy, mlir::Attribute oldInit)
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 void setLinkageForFunction(CIRGenModule &cgm, cir::FuncOp &func, const NamedDecl *nd)
static cir::GlobalOp generateStringLiteral(mlir::Location loc, mlir::TypedAttr c, cir::GlobalLinkageKind lt, CIRGenModule &cgm, StringRef globalName, CharUnits alignment)
static std::vector< std::string > getFeatureDeltaFromDefault(const CIRGenModule &cgm, llvm::StringRef targetCPU, llvm::StringMap< bool > &featureMap)
Get the feature delta from the default feature map for the given target CPU.
static CIRGenCXXABI * createCXXABI(CIRGenModule &cgm)
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd)
static bool verifyPointerTypeArgs(cir::FuncOp oldF, cir::FuncOp newF, mlir::SymbolUserMap &userMap)
static mlir::Attribute createNewGlobalView(CIRGenModule &cgm, cir::GlobalOp newGlob, cir::GlobalViewAttr attr, mlir::Type oldTy)
static cir::CtorKind getCtorKindFromDecl(const CXXConstructorDecl *ctor)
static void emitUsed(CIRGenModule &cgm, StringRef name, std::vector< cir::CIRGlobalValueInterface > &list)
static cir::TLSModel getCIRTLSModel(StringRef S)
This file defines OpenACC nodes for declarative directives.
static constexpr bool needsDtor()
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
Defines the clang::Module class, which describes a module in the source code.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the SourceManager interface.
This file defines OpenMP AST classes for executable directives and clauses.
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)
cir::PointerType getVoidPtrTy(clang::LangAS langAS=clang::LangAS::Default)
mlir::ptr::MemorySpaceAttrInterface getDefaultGlobalsAddrSpace(mlir::MLIRContext *ctx) const
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 shouldExternalize(const Decl *D) const
Whether a C++ static variable or CUDA/HIP kernel should be externalized.
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
bool isSameEntity(const NamedDecl *X, const NamedDecl *Y) const
Determine whether the two declarations refer to the same entity.
const clang::PrintingPolicy & getPrintingPolicy() const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
DiagnosticsEngine & getDiagnostics() 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.
bool computeGlobalViewIndicesFromFlatOffset(int64_t offset, mlir::Type ty, const cir::CIRDataLayout &layout, llvm::SmallVectorImpl< int64_t > &indices)
mlir::Attribute getConstRecordOrZeroAttr(mlir::ArrayAttr arrayAttr, cir::RecordType recordTy)
uint64_t computeOffsetFromGlobalViewIndices(const cir::CIRDataLayout &layout, mlir::Type ty, llvm::ArrayRef< int64_t > indices)
cir::ConstArrayAttr getConstArray(mlir::Attribute attrs, cir::ArrayType arrayTy) const
virtual void handleGlobalReplace(cir::GlobalOp oldGV, cir::GlobalOp newGV)
virtual mlir::Operation * getKernelHandle(cir::FuncOp fn, GlobalDecl gd)=0
virtual void finalizeModule()
Perform module finalization: on device side, mark ODR-used device variables as compiler-used.
virtual void internalizeDeviceSideVar(const VarDecl *d, cir::GlobalLinkageKind &linkage)=0
Adjust linkage of shadow variables in host compilation.
virtual void handleVarRegistration(const VarDecl *vd, cir::GlobalOp var)=0
Check whether a variable is a device variable and register it if true.
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
cir::FuncOp generateCode(clang::GlobalDecl gd, cir::FuncOp fn, cir::FuncType funcType)
void emitVariablyModifiedType(QualType ty)
This class organizes the cross-function state that is used while generating CIR code.
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
void setGlobalVisibility(cir::CIRGlobalValueInterface gv, const NamedDecl *d) const
Set the visibility for the given global.
void addUsedOrCompilerUsedGlobal(cir::CIRGlobalValueInterface gv)
Add a global to a list to be added to the llvm.compiler.used metadata.
void setFuncInfoAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl)
Record the func_info tag for a function, either a C++ special member form (constructor,...
void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old, cir::FuncOp newFn)
This function is called when we implement a function with no prototype, e.g.
bool shouldEmitFunction(clang::GlobalDecl gd)
Check if fd ends up calling itself directly through asm label or builtin-pointer-to-self trickery (e....
llvm::StringRef getMangledName(clang::GlobalDecl gd)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
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.
cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd)
clang::ASTContext & getASTContext() const
void insertGlobalSymbol(mlir::Operation *op)
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
CIRGenCUDARuntime & getCUDARuntime()
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.
void addSYCLModuleIdAttr(cir::FuncOp fn)
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)
std::optional< llvm::SmallVector< int32_t > > buildMemberPath(const CXXRecordDecl *destClass, const ValueDecl *decl)
Build a GEP-style field-index path from destClass to decl.
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)
cir::TLSModel getDefaultCIRTLSModel() const
Get TLS mode from CodeGenOptions.
void setGlobalTlsReferences(const VarDecl &vd, cir::GlobalOp globalOp)
void emitOpenCLKernelArgMetadata(cir::FuncOp func, const clang::FunctionDecl *fd)
Generate OpenCL kernel argument metadata for a kernel function.
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.
cir::GlobalOp getAddrOfTemplateParamObject(const TemplateParamObjectDecl *tpo)
Get the GlobalOp of a template parameter object.
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.
llvm::DenseMap< const UnnamedGlobalConstantDecl *, cir::GlobalOp > unnamedGlobalConstantDeclMap
std::vector< cir::CIRGlobalValueInterface > llvmCompilerUsed
void emitOMPRequiresDecl(const OMPRequiresDecl *d)
void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
clang::DiagnosticsEngine & getDiags() const
cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd, GVALinkage linkage)
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty, bool forEH=false)
Get the address of the RTTI descriptor for the given type.
cir::GlobalOp createGlobalString(mlir::Location loc, llvm::StringRef str, llvm::StringRef name)
Create a private constant global holding the null-terminated string str, mirroring llvm::IRBuilder::C...
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)
const cir::CIRDataLayout & getDataLayout() const
void emitAliasDefinition(GlobalDecl gd)
Emit a definition for an __attribute__((alias)) declaration.
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)
static std::optional< cir::FramePointerKind > getFramePointerKind(CodeGenOptions::FramePointerKind kind)
Returns the frame pointer kind to record on functions and on the module, or std::nullopt when kind is...
cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name, mlir::NamedAttrList extraAttrs={}, bool isLocal=false, bool assumeConvergent=false)
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.
mlir::TypedAttr emitNullConstantAttr(QualType t)
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 setTLSMode(mlir::Operation *op, const VarDecl &d, bool isExtendingDecl=false)
Set TLS mode for the given operation based on the given variable declaration.
void emitExplicitCastExprType(const ExplicitCastExpr *e, CIRGenFunction *cgf=nullptr)
Emit type info if type of an expression is a variably modified type.
void eraseGlobalSymbol(mlir::Operation *op)
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.
llvm::StringMap< mlir::Operation * > symbolLookupCache
Cache for O(1) symbol lookups by name, replacing the O(N) linear scan in SymbolTable::lookupSymbolIn ...
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 printPostfixForExternalizedDecl(llvm::raw_ostream &os, const Decl *d)
Print the postfix for externalized static variable or kernels for single source offloading languages ...
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::GlobalOp createGlobalOp(mlir::Location loc, llvm::StringRef name, mlir::Type t, bool isConstant=false, mlir::ptr::MemorySpaceAttrInterface addrSpace={}, mlir::Operation *insertPoint=nullptr)
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.
mlir::Value castGlobalToDeclAddrSpace(mlir::Value addr, const VarDecl &vd)
Cast addr, the address of the global vd, to the address space of the declared type of vd if they diff...
void addDeferredDeclToEmit(clang::GlobalDecl GD)
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)
static cir::VisibilityKind getCIRVisibilityKind(Visibility v)
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
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 setCIRFunctionAttributesForDefinition(const clang::Decl *decl, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
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.
llvm::StringMap< unsigned > cgGlobalNames
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.
mlir::MLIRContext & getMLIRContext()
void emitSYCLKernelCaller(const clang::FunctionDecl *kernelEntryPointFn, clang::ASTContext &ctx)
Emit the SYCL kernel caller offload entry point function generated for a function declared with the s...
mlir::Operation * getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition=NotForDefinition)
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
bool isEmptyFieldForMemberPointer(const FieldDecl *field)
Returns true if field is a potentially-overlapping field with no CIR field index (e....
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.
bool lookupRepresentativeDecl(llvm::StringRef mangledName, clang::GlobalDecl &gd) const
void emitDeclContext(const DeclContext *dc)
mlir::ptr::MemorySpaceAttrInterface getGlobalCIRAddressSpace(LangAS as)
Return the CIR address space attribute for a global in as, honoring the target address space map wher...
clang::CharUnits getNaturalPointeeTypeAlignment(clang::QualType t, LValueBaseInfo *baseInfo=nullptr)
void emitGlobal(clang::GlobalDecl gd)
Emit code for a single global function or variable declaration.
bool mayBeEmittedEagerly(const clang::ValueDecl *d)
Determine whether the definition can be emitted eagerly, or should be delayed until the end of the tr...
void constructAttributeList(llvm::StringRef name, const CIRGenFunctionInfo &info, CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs, llvm::MutableArrayRef< mlir::NamedAttrList > argAttrs, mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv, bool attrOnCallSite, bool isThunk)
Get the CIR attributes and calling convention to use for a particular function type.
void addGlobalAnnotations(const clang::ValueDecl *d, mlir::Operation *gv)
Add global annotations for a global value (GlobalOp or FuncOp).
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)
CIRGenOpenMPRuntime & getOpenMPRuntime()
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.
void setCommonAttributes(GlobalDecl gd, mlir::Operation *op)
Set attributes which are common to any form of a global definition (alias, Objective-C method,...
void emitDeclareTargetFunction(const FunctionDecl *fd, cir::FuncOp funcOp)
If the function has an OMPDeclareTargetDeclAttr, set the corresponding omp.declare_target attribute o...
This class handles record and union layout info while lowering AST types to CIR types.
bool hasNonVirtualBaseCIRField(const CXXRecordDecl *rd) const
unsigned getCIRFieldNo(const clang::FieldDecl *fd) const
Return cir::RecordType element number that corresponds to the field FD.
bool hasCIRField(const clang::FieldDecl *fd) const
bool isZeroInitializable() const
Check whether this struct can be C++ zero-initialized with a zeroinitializer.
unsigned getNonVirtualBaseCIRFieldNo(const CXXRecordDecl *rd) const
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)
mlir::ptr::MemorySpaceAttrInterface getPointerAddressSpace(clang::QualType pointeeTy) const
Returns the CIR address space for a pointer/reference to pointeeTy, or a null attribute for the defau...
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
const CIRGenRecordLayout & getCIRGenRecordLayout(const clang::RecordDecl *rd)
Return record layout info for the given record decl.
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.
void finalize(cir::GlobalOp gv)
mlir::Attribute emitForInitializer(const APValue &value, QualType destType)
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 getGlobalCIRAddressSpace(clang::LangAS as) const
Get the CIR address space attribute for a global in AST address space as.
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.
CXXRecordDecl * getMostRecentDecl()
bool hasDefinition() const
This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits 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 isInStdNamespace() const
bool isWeakImported() const
Determine whether this is a weak-imported symbol.
bool isInExportDeclContext() const
Whether this declaration was exported in a lexical context.
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.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isPotentiallyOverlapping() const
Determine if this field is of potentially-overlapping class type, that is, subobject with the [[no_un...
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={})
ArrayRef< ParmVarDecl * > parameters() const
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.
FunctionDecl * getDefinition()
Get the definition for this declaration.
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.
CXXCtorType getCtorType() const
GlobalDecl getCanonicalDecl() const
KernelReferenceKind getKernelReferenceKind() const
GlobalDecl getWithDecl(const Decl *D)
unsigned getMultiVersionIndex() const
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...
std::string CUID
The user provided compilation unit ID, if non-empty.
Visibility getVisibility() const
void setLinkage(Linkage L)
Linkage getLinkage() const
bool isVisibilityExplicit() const
MangleContext - Context for tracking state which persists across multiple calls to the C++ name mangl...
bool isTriviallyRecursive(const FunctionDecl *FD)
Return true if FD's body contains a direct call back to the symbol it links as, through an asm label ...
bool shouldMangleDeclName(const NamedDecl *D)
void mangleName(GlobalDecl GD, raw_ostream &)
ManglerKind getKind() const
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.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
Describes a module or submodule.
SourceLocation DefinitionLoc
The location of the module definition.
llvm::iterator_range< submodule_iterator > submodules()
bool isModuleImplementation() const
Is this a module implementation.
bool isNamedModule() const
Does this Module is a named module of a standard named module?
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
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.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
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
Represents a struct/union/class.
RecordDecl * getMostRecentDecl()
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...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
uint32_t getCodeUnit(size_t I) const
Return the code unit at the given position.
StringRef getString() const
unsigned getCharByteWidth() const
Represents the declaration of a struct/union/class/enum.
static const auto & getSpelling(Kind ABIKind)
TargetOptions & getTargetOpts() const
Retrieve the target options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isReadOnlyFeature(StringRef Feature) const
Determine whether the given target feature is read only.
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const
Initialize the map with the default set of target features for the CPU this should include all legal ...
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings starting...
std::string TuneCPU
If given, the name of the target CPU to tune code for.
std::string CPU
If given, the name of the target CPU to generate code for.
A template parameter object.
const APValue & getValue() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
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
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
const APValue & getValue() 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.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
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_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.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
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.
mlir::ptr::MemorySpaceAttrInterface normalizeDefaultAddressSpace(mlir::ptr::MemorySpaceAttrInterface addrSpace)
Normalize LangAddressSpace::Default to null (empty attribute).
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)
std::unique_ptr< TargetCIRGenInfo > createCommonSPIRTargetCIRGenInfo(CIRGenTypes &cgt)
std::unique_ptr< TargetCIRGenInfo > createAArch64TargetCIRGenInfo(CIRGenTypes &cgt)
CIRGenCXXABI * CreateCIRGenMicrosoftCXXABI(CIRGenModule &cgm)
Creates Microsoft ABI.
CIRGenCUDARuntime * createNVCUDARuntime(CIRGenModule &cgm)
LangAS getGlobalConstantAddressSpace(const LangOptions &LangOpts, const TargetInfo &Target)
Determines whether the language options require us to model unwind exceptions.
bool isVarDeclStrongDefinition(const ASTContext &Ctx, const VarDecl *D, bool NoCommon)
Check whether D is a strong definition, and thus must not be given common linkage.
bool isEmptyFieldForLayout(const ASTContext &Ctx, const FieldDecl *FD)
Return true iff the field is "empty", that is, either a zero-width bit-field or an isEmptyRecordForLa...
llvm::SmallVector< Module *, 8 > importedModulesToInitialize(Module *Primary, llvm::ArrayRef< Module * > Imported)
The C++20 named modules whose Itanium initializer function the global init function of a translation ...
bool hasUnwindExceptions(const LangOptions &LangOpts)
bool shouldBeInCOMDAT(const ASTContext &Ctx, const Decl &D)
Check whether D should be emitted into a COMDAT group.
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Attr > attr
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
GVALinkage
A more specific kind of linkage than enum Linkage.
@ GVA_AvailableExternally
QualType pointeeType(QualType T)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ 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)
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t
static bool globalCtorLexOrder()
static bool opFuncArmNewAttr()
static bool getRuntimeFunctionDecl()
static bool weakRefReference()
static bool addressSpace()
static bool opGlobalUnnamedAddr()
static bool opGlobalThreadLocal()
static bool opFuncMultiVersioning()
static bool sourceLanguageCases()
static bool opFuncAstDeclAttr()
static bool stackProtector()
static bool moduleNameHash()
static bool opGlobalVisibility()
static bool setDLLStorageClass()
static bool opFuncParameterAttributes()
static bool targetCIRGenInfoArch()
static bool opFuncExtraAttrs()
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 opFuncExceptions()
static bool opFuncArmStreamingAttr()
static bool cudaSupport()
static bool opFuncMaybeHandleStaticInExternC()
static bool checkAliases()
static bool generateDebugInfo()
static bool emitModuleLinkOptions()
static bool targetCIRGenInfoOS()
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.
Describes how types, statements, expressions, and declarations should be printed.