clang 24.0.0git
CIRGenModule.h
Go to the documentation of this file.
1//===--- CIRGenModule.h - Per-Module state for CIR gen ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This is the internal per-translation-unit state used for CIR translation.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
14#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
15
16#include "CIRGenBuilder.h"
17#include "CIRGenCUDARuntime.h"
18#include "CIRGenCall.h"
19#include "CIRGenOpenMPRuntime.h"
20#include "CIRGenTypeCache.h"
21#include "CIRGenTypes.h"
22#include "CIRGenVTables.h"
23#include "CIRGenValue.h"
24
25#include "clang/AST/CharUnits.h"
28
29#include "TargetInfo.h"
30#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
31#include "mlir/IR/Builders.h"
32#include "mlir/IR/BuiltinOps.h"
33#include "mlir/IR/MLIRContext.h"
34#include "clang/AST/Decl.h"
39#include "llvm/ADT/SetVector.h"
40#include "llvm/ADT/SmallPtrSet.h"
41#include "llvm/ADT/StringMap.h"
42#include "llvm/ADT/StringRef.h"
43#include "llvm/TargetParser/Triple.h"
44
45namespace clang {
46class ASTContext;
47class CodeGenOptions;
48class Decl;
49class GlobalDecl;
50class LangOptions;
54class TargetInfo;
55class VarDecl;
56
57namespace CIRGen {
58
59class CIRGenFunction;
60class CIRGenCXXABI;
61
62enum ForDefinition_t : bool { NotForDefinition = false, ForDefinition = true };
63
64/// This class organizes the cross-function state that is used while generating
65/// CIR code.
66class CIRGenModule : public CIRGenTypeCache {
67 CIRGenModule(CIRGenModule &) = delete;
68 CIRGenModule &operator=(CIRGenModule &) = delete;
69
70public:
71 CIRGenModule(mlir::MLIRContext &mlirContext, clang::ASTContext &astContext,
72 const clang::CodeGenOptions &cgo,
74
76
77private:
78 mutable std::unique_ptr<TargetCIRGenInfo> theTargetCIRGenInfo;
79
80 CIRGenBuilderTy builder;
81
82 /// Hold Clang AST information.
83 clang::ASTContext &astContext;
84
85 const clang::LangOptions &langOpts;
86
87 /// Seeded from langOpts and then pushed and popped by clang::atomic.
88 clang::AtomicOptions atomicOpts;
89
90 const clang::CodeGenOptions &codeGenOpts;
91
92 /// A "module" matches a c/cpp source file: containing a list of functions.
93 mlir::OwningOpRef<mlir::ModuleOp> theModule;
94
95 /// Cached data layout for the module. Built lazily: the layout spec is
96 /// attached after construction, in CIRGenerator::Initialize.
97 mutable std::optional<cir::CIRDataLayout> dataLayout;
98
100
101 const clang::TargetInfo &target;
102
103 std::unique_ptr<CIRGenCXXABI> abi;
104
105 CIRGenTypes genTypes;
106
107 /// Holds information about C++ vtables.
108 CIRGenVTables vtables;
109
110 /// Holds the CUDA runtime
111 std::unique_ptr<CIRGenCUDARuntime> cudaRuntime;
112
113 /// Holds the OpenMP runtime
114 std::unique_ptr<CIRGenOpenMPRuntime> openMPRuntime;
115
116 /// Per-function codegen information. Updated everytime emitCIR is called
117 /// for FunctionDecls's.
118 CIRGenFunction *curCGF = nullptr;
119
121
122 /// Accumulated record layout entries, materialized in release().
123 llvm::SmallVector<mlir::NamedAttribute> recordLayoutEntries;
124
125 /// Whether C++20 named modules get their own module initializer function,
126 /// which requires the Itanium mangling of the initializer name.
127 bool cxx20ModuleInits = false;
128
129 /// The complete set of modules that have been imported.
130 llvm::SetVector<clang::Module *> importedModules;
131
132 /// The location of the first import declaration of each imported module.
133 llvm::DenseMap<clang::Module *, clang::SourceLocation> moduleImportLocs;
134
135 /// The set of modules for which the module initializers have been emitted.
136 llvm::SmallPtrSet<clang::Module *, 16> emittedModuleInitializers;
137
138 /// The Itanium-mangled name of the initializer function of a C++20 named
139 /// module.
140 std::string getModuleInitializerName(clang::Module *mod);
141
142 llvm::DenseSet<clang::GlobalDecl> diagnosedConflictingDefinitions;
143
144 /// Symbols created as the target of a weakref. They are extern_weak until
145 /// something names them in a way that is not itself weak, such as an
146 /// ordinary declaration or definition of the target.
148
149 /// -------
150 /// Annotations
151 /// -------
152
153 /// We store each annotation as an attribute of GlobalOp and FuncOp rather
154 /// than collecting them into a single module-level list. The deferred map
155 /// lets us attach annotations at the end of codegen so the most up-to-date
156 /// ValueDecl (which carries all inherited annotations) is used.
157
158 /// Used for uniquing of annotation arguments.
159 llvm::DenseMap<unsigned, mlir::ArrayAttr> annotationArgs;
160
161 /// Store deferred function annotations so they can be emitted at the end
162 /// with the most up to date ValueDecl that will have all the inherited
163 /// annotations.
164 llvm::DenseMap<llvm::StringRef, const clang::ValueDecl *> deferredAnnotations;
165
166 /// A queue of (optional) vtables to consider emitting.
167 std::vector<const CXXRecordDecl *> deferredVTables;
168
169 /// A queue of (optional) vtables that may be emitted opportunistically.
170 std::vector<const CXXRecordDecl *> opportunisticVTables;
171
172 void createCUDARuntime();
173 void createOpenMPRuntime();
174 void setOpenCLVersionAttr(llvm::StringRef attrName, unsigned version);
175
176 /// A helper for constructAttributeList that handles return attributes.
177 void constructFunctionReturnAttributes(const CIRGenFunctionInfo &info,
178 const Decl *targetDecl, bool isThunk,
179 mlir::NamedAttrList &retAttrs);
180 /// A helper for constructAttributeList that handles argument attributes.
181 void constructFunctionArgumentAttributes(
182 const CIRGenFunctionInfo &info, clang::GlobalDecl calleeDecl,
183 bool isThunk, bool attrOnCallSite,
185 /// A helper function for constructAttributeList that determines whether a
186 /// return value might have been discarded.
187 bool mayDropFunctionReturn(const ASTContext &context, QualType retTy);
188 /// A helper function for constructAttributeList that determines whether
189 /// `noundef` on a return is possible.
190 bool hasStrictReturn(QualType retTy, const Decl *targetDecl);
191
192 llvm::DenseMap<const Expr *, mlir::Operation *>
193 materializedGlobalTemporaryMap;
194
195public:
196 mlir::ModuleOp getModule() const { return *theModule; }
197 CIRGenBuilderTy &getBuilder() { return builder; }
198
199 /// Queue a record layout entry for materialization in release().
200 void addRecordLayout(mlir::StringAttr name, cir::RecordLayoutAttr attr) {
201 recordLayoutEntries.push_back(mlir::NamedAttribute(name, attr));
202 }
203 clang::ASTContext &getASTContext() const { return astContext; }
204 const clang::TargetInfo &getTarget() const { return target; }
205 const clang::CodeGenOptions &getCodeGenOpts() const { return codeGenOpts; }
206 clang::DiagnosticsEngine &getDiags() const { return diags; }
207 CIRGenTypes &getTypes() { return genTypes; }
208 const clang::LangOptions &getLangOpts() const { return langOpts; }
209
210 /// The atomic options in effect at the point currently being emitted.
211 /// clang::atomic adjusts these for the extent of the statement it is attached
212 /// to, so they are module state rather than a fixed language option.
213 clang::AtomicOptions getAtomicOpts() const { return atomicOpts; }
214 void setAtomicOpts(clang::AtomicOptions opts) { atomicOpts = opts; }
215
216 CIRGenCXXABI &getCXXABI() const { return *abi; }
217 mlir::MLIRContext &getMLIRContext() { return *builder.getContext(); }
218
220 if (!dataLayout)
221 dataLayout.emplace(getModule());
222 return *dataLayout;
223 }
224
225 /// -------
226 /// Handling globals
227 /// -------
228
229 mlir::Operation *lastGlobalOp = nullptr;
230
231 /// Keep a map between lambda fields and names, this needs to be per module
232 /// since lambdas might get generated later as part of defered work, and since
233 /// the pointers are supposed to be uniqued, should be fine. Revisit this if
234 /// it ends up taking too much memory.
235 llvm::DenseMap<const clang::FieldDecl *, llvm::StringRef> lambdaFieldToName;
236
237 /// Add a global value to the llvmUsed list.
238 void addUsedGlobal(cir::CIRGlobalValueInterface gv);
239
240 /// Add a global value to the llvmCompilerUsed list.
241 void addCompilerUsedGlobal(cir::CIRGlobalValueInterface gv);
242
243 /// Add a global to a list to be added to the llvm.compiler.used metadata.
244 void addUsedOrCompilerUsedGlobal(cir::CIRGlobalValueInterface gv);
245
246 /// Emit llvm.used and llvm.compiler.used globals.
247 void emitLLVMUsed();
248
249 /// Tell the consumer that this variable has been instantiated.
251
252 llvm::DenseMap<const Decl *, cir::GlobalOp> staticLocalDeclMap;
253 llvm::DenseMap<const VarDecl *, cir::GlobalOp> initializerConstants;
254
255 /// Cache for O(1) symbol lookups by name, replacing the O(N) linear scan
256 /// in SymbolTable::lookupSymbolIn that getGlobalValue used previously.
257 llvm::StringMap<mlir::Operation *> symbolLookupCache;
258
259 mlir::Operation *getGlobalValue(llvm::StringRef ref);
260
261 /// O(1) lookup of a FuncOp by name in the symbol cache.
262 /// Returns nullptr if the name is not found or is not a FuncOp.
263 cir::FuncOp lookupFuncOp(llvm::StringRef name) {
264 auto *op = getGlobalValue(name);
265 return op ? mlir::dyn_cast<cir::FuncOp>(op) : cir::FuncOp{};
266 }
267
268 void insertGlobalSymbol(mlir::Operation *op) {
269 if (auto sym = mlir::dyn_cast<mlir::SymbolOpInterface>(op))
270 symbolLookupCache[sym.getName()] = op;
271 }
272 void eraseGlobalSymbol(mlir::Operation *op) {
273 if (auto sym = mlir::dyn_cast<mlir::SymbolOpInterface>(op)) {
274 auto it = symbolLookupCache.find(sym.getName());
275 if (it != symbolLookupCache.end() && it->second == op)
276 symbolLookupCache.erase(it);
277 }
278 }
279
280 cir::GlobalOp getStaticLocalDeclAddress(const VarDecl *d) {
281 return staticLocalDeclMap[d];
282 }
283
284 void setStaticLocalDeclAddress(const VarDecl *d, cir::GlobalOp c) {
285 staticLocalDeclMap[d] = c;
286 }
287
288 cir::GlobalOp getOrCreateStaticVarDecl(const VarDecl &d,
289 cir::GlobalLinkageKind linkage);
290
291 Address createUnnamedGlobalFrom(const VarDecl &d, mlir::Attribute constAttr,
292 CharUnits align);
293
294 /// If the specified mangled name is not in the module, create and return an
295 /// mlir::GlobalOp value
296 cir::GlobalOp getOrCreateCIRGlobal(llvm::StringRef mangledName, mlir::Type ty,
297 LangAS langAS, mlir::Location loc,
298 const VarDecl *d,
299 ForDefinition_t isForDefinition);
300
301 cir::GlobalOp getOrCreateCIRGlobal(const VarDecl *d, mlir::Type ty,
302 ForDefinition_t isForDefinition);
303
304 /// Return the symbol that a weakref declaration refers to: the cir.func or
305 /// cir.global named by its alias target, declared extern_weak if it did not
306 /// already exist.
307 mlir::Operation *getWeakRefReference(const clang::ValueDecl *vd);
308
309 cir::GlobalOp
310 createGlobalOp(mlir::Location loc, llvm::StringRef name, mlir::Type t,
311 bool isConstant = false,
312 mlir::ptr::MemorySpaceAttrInterface addrSpace = {},
313 mlir::Operation *insertPoint = nullptr);
314
315 /// Add a global constructor or destructor to the module.
316 /// The priority is optional, if not specified, the default priority is used.
317 void addGlobalCtor(cir::FuncOp ctor,
318 std::optional<int> priority = std::nullopt);
319 void addGlobalDtor(cir::FuncOp dtor,
320 std::optional<int> priority = std::nullopt);
321
323 // In C23 (N3096) $6.7.10:
324 // """
325 // If any object is initialized with an empty initializer, then it is
326 // subject to default initialization:
327 // - if it is an aggregate, every member is initialized (recursively)
328 // according to these rules, and any padding is initialized to zero bits;
329 // - if it is a union, the first named member is initialized (recursively)
330 // according to these rules, and any padding is initialized to zero bits.
331 //
332 // If the aggregate or union contains elements or members that are
333 // aggregates or unions, these rules apply recursively to the subaggregates
334 // or contained unions.
335 //
336 // If there are fewer initializers in a brace-enclosed list than there are
337 // elements or members of an aggregate, or fewer characters in a string
338 // literal used to initialize an array of known size than there are elements
339 // in the array, the remainder of the aggregate is subject to default
340 // initialization.
341 // """
342 //
343 // The standard seems ambiguous in the following two areas:
344 // 1. For a union type with empty initializer, if the first named member is
345 // not the largest member, then the bytes comes after the first named member
346 // but before padding are left unspecified. An example is:
347 // union U { int a; long long b;};
348 // union U u = {}; // The first 4 bytes are 0, but 4-8 bytes are left
349 // unspecified.
350 //
351 // 2. It only mentions padding for empty initializer, but doesn't mention
352 // padding for a non empty initialization list. And if the aggregation or
353 // union contains elements or members that are aggregates or unions, and
354 // some are non empty initializers, while others are empty initializers,
355 // the padding initialization is unclear. An example is:
356 // struct S1 { int a; long long b; };
357 // struct S2 { char c; struct S1 s1; };
358 // // The values for paddings between s2.c and s2.s1.a, between s2.s1.a
359 // and s2.s1.b are unclear.
360 // struct S2 s2 = { 'c' };
361 //
362 // Here we choose to zero initiailize left bytes of a union type because
363 // projects like the Linux kernel are relying on this behavior. If we don't
364 // explicitly zero initialize them, the undef values can be optimized to
365 // return garbage data. We also choose to zero initialize paddings for
366 // aggregates and unions, no matter they are initialized by empty
367 // initializers or non empty initializers. This can provide a consistent
368 // behavior. So projects like the Linux kernel can rely on it.
369 return !getLangOpts().CPlusPlus;
370 }
371
372 llvm::StringMap<unsigned> cgGlobalNames;
373 std::string getUniqueGlobalName(const std::string &baseName);
374
375 /// Return the mlir::Value for the address of the given global variable.
376 /// If Ty is non-null and if the global doesn't exist, then it will be created
377 /// with the specified type instead of whatever the normal requested type
378 /// would be. If IsForDefinition is true, it is guaranteed that an actual
379 /// global with type Ty will be returned, not conversion of a variable with
380 /// the same mangled name but some other type.
381 mlir::Value
382 getAddrOfGlobalVar(const VarDecl *d, mlir::Type ty = {},
383 ForDefinition_t isForDefinition = NotForDefinition);
384
385 /// Cast \p addr, the address of the global \p vd, to the address space of
386 /// the declared type of \p vd if they differ.
387 mlir::Value castGlobalToDeclAddrSpace(mlir::Value addr, const VarDecl &vd);
388
389 /// Get or create a thunk function with the given name and type.
390 cir::FuncOp getAddrOfThunk(StringRef name, mlir::Type fnTy, GlobalDecl gd);
391
392 /// Return the mlir::GlobalViewAttr for the address of the given global.
393 cir::GlobalViewAttr getAddrOfGlobalVarAttr(const VarDecl *d);
394
395 /// Get the GlobalOp of a template parameter object.
396 cir::GlobalOp
398 // Get the GlobalOp of a source_location object.
399 cir::GlobalOp
401
403 const CXXRecordDecl *derivedClass,
404 llvm::iterator_range<CastExpr::path_const_iterator> path);
405
406 /// Get the CIR attributes and calling convention to use for a particular
407 /// function type.
408 ///
409 /// \param name - The function name.
410 /// \param info - The function type information.
411 /// \param calleeInfo - The callee information these attributes are being
412 /// constructed for. If valid, the attributes applied to this decl may
413 /// contribute to the function attributes and calling convention.
414 /// \param attrs [out] - On return, the attribute list to use.
415 /// \param callingConv [out] - On return, the calling convention to use.
416 /// \param attrOnCallSite - Whether or not the attributes are on a call site.
417 /// \param isThunk - Whether the function is a thunk.
419 llvm::StringRef name, const CIRGenFunctionInfo &info,
420 CIRGenCalleeInfo calleeInfo, mlir::NamedAttrList &attrs,
422 mlir::NamedAttrList &retAttrs, cir::CallingConv &callingConv,
423 bool attrOnCallSite, bool isThunk);
424 /// Helper function for constructAttributeList/others. Builds a set of
425 /// function attributes to add to a function based on language opts, codegen
426 /// opts, and some small properties.
427 void addDefaultFunctionAttributes(StringRef name, bool hasOptNoneAttr,
428 bool attrOnCallSite,
429 mlir::NamedAttrList &attrs);
430
431 /// Returns the frame pointer kind to record on functions and on the module,
432 /// or std::nullopt when \p kind is CodeGenOptions::FramePointerKind::None,
433 /// the default, which is left implicit.
434 static std::optional<cir::FramePointerKind>
436
437 /// Will return a global variable of the given type. If a variable with a
438 /// different type already exists then a new variable with the right type
439 /// will be created and all uses of the old variable will be replaced with a
440 /// bitcast to the new variable.
442 mlir::Location loc, llvm::StringRef name, mlir::Type ty,
443 cir::GlobalLinkageKind linkage, clang::CharUnits alignment);
444
445 void emitVTable(const CXXRecordDecl *rd);
446
447 /// Return the appropriate linkage for the vtable, VTT, and type information
448 /// of the given class.
449 cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *rd);
450
451 /// Get the address of the RTTI descriptor for the given type.
452 mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty,
453 bool forEH = false);
454
455 static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v) {
456 switch (v) {
458 return mlir::SymbolTable::Visibility::Public;
459 case HiddenVisibility:
460 return mlir::SymbolTable::Visibility::Private;
462 // The distinction between ProtectedVisibility and DefaultVisibility is
463 // that symbols with ProtectedVisibility, while visible to the dynamic
464 // linker like DefaultVisibility, are guaranteed to always dynamically
465 // resolve to a symbol in the current shared object. There is currently no
466 // equivalent MLIR visibility, so we fall back on the fact that the symbol
467 // is visible.
468 return mlir::SymbolTable::Visibility::Public;
469 }
470 llvm_unreachable("unknown visibility!");
471 }
472
473 static cir::VisibilityKind getCIRVisibilityKind(Visibility v) {
474 switch (v) {
476 return cir::VisibilityKind::Default;
477 case HiddenVisibility:
478 return cir::VisibilityKind::Hidden;
480 return cir::VisibilityKind::Protected;
481 }
482
483 llvm_unreachable("unknown visibility!");
484 }
485
486 llvm::DenseMap<mlir::Attribute, cir::GlobalOp> constantStringMap;
487 llvm::DenseMap<const UnnamedGlobalConstantDecl *, cir::GlobalOp>
489 llvm::DenseMap<const CompoundLiteralExpr *, cir::GlobalOp>
491
492 cir::GlobalOp
497 cir::GlobalOp gv) {
498 [[maybe_unused]] bool ok = emittedCompoundLiterals.insert({e, gv}).second;
499 assert(ok && "compound literal global already emitted");
500 }
501
502 /// Return a constant array for the given string.
503 mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e);
504
505 /// Return a global symbol reference to a constant array for the given string
506 /// literal.
507 cir::GlobalOp getGlobalForStringLiteral(const StringLiteral *s,
508 llvm::StringRef name = ".str");
509
510 /// Return a global symbol reference to a constant array for the given string
511 /// literal.
512 cir::GlobalViewAttr
514 llvm::StringRef name = ".str");
515
516 /// Create a private constant global holding the null-terminated string
517 /// \p str, mirroring llvm::IRBuilder::CreateGlobalString.
518 cir::GlobalOp createGlobalString(mlir::Location loc, llvm::StringRef str,
519 llvm::StringRef name);
520
521 /// Returns the address space for temporary allocations in the language. This
522 /// ensures that the allocated variable's address space matches the
523 /// expectations of the AST, rather than using the target's allocation address
524 /// space, which may lead to type mismatches in other parts of the IR.
526
527 /// Return the CIR address space attribute for a global in \p as, honoring
528 /// the target address space map where the LangAS fold would lose it.
529 mlir::ptr::MemorySpaceAttrInterface getGlobalCIRAddressSpace(LangAS as);
530
531 /// Set attributes which are common to any form of a global definition (alias,
532 /// Objective-C method, function, global variable).
533 ///
534 /// NOTE: This should only be called for definitions.
535 void setCommonAttributes(GlobalDecl gd, mlir::Operation *op);
536
538
539 /// Helpers to convert the presumed location of Clang's SourceLocation to an
540 /// MLIR Location.
541 mlir::Location getLoc(clang::SourceLocation cLoc);
542 mlir::Location getLoc(clang::SourceRange cRange);
543
544 /// Return the best known alignment for an unknown pointer to a
545 /// particular class.
547
548 /// FIXME: this could likely be a common helper and not necessarily related
549 /// with codegen.
551 LValueBaseInfo *baseInfo = nullptr,
552 bool forPointeeType = false);
555 LValueBaseInfo *baseInfo = nullptr);
556
557 /// Returns the minimum object size for an object of the given class type
558 /// (or a class derived from it).
560
561 /// Returns the minimum object size for an object of the given type.
567
568 /// TODO: Add TBAAAccessInfo
570 const CXXRecordDecl *baseDecl,
571 CharUnits expectedTargetAlign);
572
573 /// Returns the assumed alignment of a virtual base of a class.
575 const CXXRecordDecl *derived,
576 const CXXRecordDecl *vbase);
577
578 cir::FuncOp
580 const CIRGenFunctionInfo *fnInfo = nullptr,
581 cir::FuncType fnType = nullptr, bool dontDefer = false,
582 ForDefinition_t isForDefinition = NotForDefinition) {
583 return getAddrAndTypeOfCXXStructor(gd, fnInfo, fnType, dontDefer,
584 isForDefinition)
585 .second;
586 }
587
588 std::pair<cir::FuncType, cir::FuncOp> getAddrAndTypeOfCXXStructor(
589 clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo = nullptr,
590 cir::FuncType fnType = nullptr, bool dontDefer = false,
591 ForDefinition_t isForDefinition = NotForDefinition);
592
593 /// List of global values which are required to be present in the object file;
594 /// This is used for forcing visibility of symbols which may otherwise be
595 /// optimized out.
596 std::vector<cir::CIRGlobalValueInterface> llvmUsed;
597 std::vector<cir::CIRGlobalValueInterface> llvmCompilerUsed;
598
599 mlir::Type getVTableComponentType();
600 CIRGenVTables &getVTables() { return vtables; }
601
603 return vtables.getItaniumVTableContext();
604 }
606 return vtables.getItaniumVTableContext();
607 }
608
609 /// This contains all the decls which have definitions but which are deferred
610 /// for emission and therefore should only be output if they are actually
611 /// used. If a decl is in this, then it is known to have not been referenced
612 /// yet.
613 std::map<llvm::StringRef, clang::GlobalDecl> deferredDecls;
614
615 // This is a list of deferred decls which we have seen that *are* actually
616 // referenced. These get code generated when the module is done.
617 std::vector<clang::GlobalDecl> deferredDeclsToEmit;
619 deferredDeclsToEmit.emplace_back(GD);
620 }
621
623
624 /// Determine whether the definition must be emitted; if this returns \c
625 /// false, the definition can be emitted lazily if it's used.
626 bool mustBeEmitted(const clang::ValueDecl *d);
627
628 /// Check if `fd` ends up calling itself directly through asm label or
629 /// builtin-pointer-to-self trickery (e.g., glibc's `extern inline` libc
630 /// wrappers that call `__builtin_strrchr`, which the codegen lowers to a
631 /// call on the same asm-named symbol). Emitting an
632 /// `available_externally` body for such a function feeds the LLVM
633 /// Decide whether to emit the body of `gd` to CIR. Returns false for
634 /// available_externally functions that are trivially recursive (PR9614).
635 /// Mirrors classic CodeGen's `CodeGenModule::shouldEmitFunction`.
637
638 /// Determine whether the definition can be emitted eagerly, or should be
639 /// delayed until the end of the translation unit. This is relevant for
640 /// definitions whose linkage can change, e.g. implicit function
641 /// instantiations which may later be explicitly instantiated.
643
644 bool verifyModule() const;
645
646 /// Return the address of the given function. If funcType is non-null, then
647 /// this function will use the specified type if it has to create it.
648 // TODO: this is a bit weird as `GetAddr` given we give back a FuncOp?
649 cir::FuncOp
650 getAddrOfFunction(clang::GlobalDecl gd, mlir::Type funcType = nullptr,
651 bool forVTable = false, bool dontDefer = false,
652 ForDefinition_t isForDefinition = NotForDefinition);
653
654 mlir::Operation *
656 ForDefinition_t isForDefinition = NotForDefinition);
657
658 /// Return a function pointer for a reference to the given function.
659 /// This correctly handles weak references, but does not apply a
660 /// pointer signature.
661 cir::FuncOp getRawFunctionPointer(GlobalDecl GD);
662
663 /// Return the ABI-correct function pointer value for a reference
664 /// to the given function. This will apply a pointer signature if
665 /// necessary, caching the result for the given function.
666 cir::FuncOp getFunctionPointer(GlobalDecl GD);
667
668 // Return whether RTTI information should be emitted for this target.
669 bool shouldEmitRTTI(bool forEH = false) {
670 return (forEH || getLangOpts().RTTI) && !getLangOpts().CUDAIsDevice &&
671 !(getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice &&
672 getTriple().isNVPTX());
673 }
674
675 /// Emit type info if type of an expression is a variably modified
676 /// type. Also emit proper debug info for cast types.
678 CIRGenFunction *cgf = nullptr);
679
681 deferredVTables.push_back(rd);
682 }
683
684 /// Emit code for a single global function or variable declaration. Forward
685 /// declarations are emitted lazily.
687
688 void emitAliasForGlobal(llvm::StringRef mangledName, mlir::Operation *op,
689 GlobalDecl aliasGD, cir::FuncOp aliasee,
690 cir::GlobalLinkageKind linkage);
691
692 /// Emit a definition for an `__attribute__((alias))` declaration.
694
695 mlir::Type convertType(clang::QualType type);
696
697 /// Set the visibility for the given global.
698 void setGlobalVisibility(cir::CIRGlobalValueInterface gv,
699 const NamedDecl *d) const;
700 void setDSOLocal(mlir::Operation *op) const;
701 void setDSOLocal(cir::CIRGlobalValueInterface gv) const;
702
703 /// Set visibility, dllimport/dllexport and dso_local.
704 /// This must be called after dllimport/dllexport is set.
705 void setGVProperties(mlir::Operation *op, const NamedDecl *d) const;
706 void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const;
707
708 /// Set TLS mode for the given operation based on the given variable
709 /// declaration. If `isExtendingDecl` is true, then the operation is a
710 /// temporary whose lifetime is extended by the variable declared by `d`.
711 void setTLSMode(mlir::Operation *op, const VarDecl &d,
712 bool isExtendingDecl = false);
713
714 /// Get TLS mode from CodeGenOptions.
715 cir::TLSModel getDefaultCIRTLSModel() const;
716
717 /// Set function attributes for a function declaration.
718 void setFunctionAttributes(GlobalDecl gd, cir::FuncOp f,
719 bool isIncompleteFunction, bool isThunk);
720
721 /// Set the CIR function attributes (Sext, zext, etc).
723 cir::FuncOp func, bool isThunk);
724
725 /// Set extra attributes (inline, etc.) for a function.
727 cir::FuncOp f);
728
729 /// Generate OpenCL kernel argument metadata for a kernel function.
730 void emitOpenCLKernelArgMetadata(cir::FuncOp func,
731 const clang::FunctionDecl *fd);
732
734 mlir::Operation *op = nullptr);
735 void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op);
736
737 /// Emit the SYCL kernel caller offload entry point function generated for a
738 /// function declared with the sycl_kernel_entry_point attribute.
739 void emitSYCLKernelCaller(const clang::FunctionDecl *kernelEntryPointFn,
740 clang::ASTContext &ctx);
741
742 void addSYCLModuleIdAttr(cir::FuncOp fn);
744 bool isTentative = false);
745
746 /// Helper function for the below two that will create the
747 /// constructor/destructor in specified regions, rather than in the GlobalOp.
748 void emitCXXSpecialVarDeclInit(const VarDecl *varDecl, cir::GlobalOp addr,
749 bool performInit, mlir::Region &ctorRegion,
750 mlir::Region &dtorRegion);
751 /// Emit the function that initializes the specified static-local variable.
752 void emitCXXStaticLocalVarDeclInit(const VarDecl *varDecl, cir::GlobalOp addr,
753 bool performInit);
754 /// Emit the function that initializes the specified global
755 void emitCXXGlobalVarDeclInit(const VarDecl *varDecl, cir::GlobalOp addr,
756 bool performInit);
757
758 void setGlobalTlsReferences(const VarDecl &vd, cir::GlobalOp globalOp);
759 void emitCXXGlobalVarDeclInitFunc(const VarDecl *vd, cir::GlobalOp addr,
760 bool performInit);
761
765 template <typename BeforeOpTy, typename DataClauseTy>
766 void emitGlobalOpenACCDeclareDataOperands(const Expr *varOperand,
767 DataClauseTy dataClause,
768 OpenACCModifierKind modifiers,
769 bool structured, bool implicit,
770 bool requiresDtor);
771 // Each of the acc.routine operations must have a unique name, so we just use
772 // an integer counter. This is how Flang does it, so it seems reasonable.
773 unsigned routineCounter = 0;
774 void emitOpenACCRoutineDecl(const clang::FunctionDecl *funcDecl,
775 cir::FuncOp func, SourceLocation pragmaLoc,
777
785
786 // C++ related functions.
787 void emitDeclContext(const DeclContext *dc);
788
789 /// Return the result of value-initializing the given type, i.e. a null
790 /// expression of the given type.
791 mlir::Value emitNullConstant(QualType t, mlir::Location loc);
792
793 mlir::TypedAttr emitNullConstantAttr(QualType t);
794
795 /// Get target specific null pointer.
796 mlir::Value getNullPointer(cir::PointerType ptrTy, QualType qt,
797 mlir::Location loc);
798
799 /// Return a null constant appropriate for zero-initializing a base class with
800 /// the given type. This is usually, but not always, an LLVM null constant.
801 mlir::TypedAttr emitNullConstantForBase(const CXXRecordDecl *record);
802
803 mlir::Value emitMemberPointerConstant(const UnaryOperator *e);
804 /// Returns a null attribute to represent either a null method or null data
805 /// member, depending on the type of mpt.
806 mlir::TypedAttr emitNullMemberAttr(QualType t, const MemberPointerType *mpt);
807
808 /// Build a GEP-style field-index path from \p destClass to \p decl.
809 /// \p decl may be a FieldDecl, or an IndirectFieldDecl(in the case of an
810 /// anonymous struct/union).
811 /// Returns std::nullopt and emits errorNYI for virtual-base paths.
812 std::optional<llvm::SmallVector<int32_t>>
813 buildMemberPath(const CXXRecordDecl *destClass, const ValueDecl *decl);
814
815 /// Returns true if \p field is a potentially-overlapping field with no CIR
816 /// field index (e.g. a [[no_unique_address]] member that is empty for both
817 /// layout and the ABI). Such fields have no entry in the CIR record, so a
818 /// pointer-to-data-member to them is represented by an explicit byte offset
819 /// (#cir.data_member_offset) rather than a field-index path.
820 bool isEmptyFieldForMemberPointer(const FieldDecl *field);
821
822 llvm::StringRef getMangledName(clang::GlobalDecl gd);
823 // This function is to support the OpenACC 'bind' clause, which names an
824 // alternate name for the function to be called by. This function mangles
825 // `attachedFunction` as-if its name was actually `bindName` (that is, with
826 // the same signature). It has some additional complications, as the 'bind'
827 // target is always going to be a global function, so member functions need an
828 // explicit instead of implicit 'this' parameter, and thus gets mangled
829 // differently.
830 std::string getOpenACCBindMangledName(const IdentifierInfo *bindName,
831 const FunctionDecl *attachedFunction);
832
833 void emitTentativeDefinition(const VarDecl *d);
834
835 // Make sure that this type is translated.
836 void updateCompletedType(const clang::TagDecl *td);
837
838 // Produce code for this constructor/destructor. This method doesn't try to
839 // apply any ABI rules about which other constructors/destructors are needed
840 // or if they are alias to each other.
842
843 bool lookupRepresentativeDecl(llvm::StringRef mangledName,
844 clang::GlobalDecl &gd) const;
845
846 bool supportsCOMDAT() const;
847 void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op);
848
849 static void setInitializer(cir::GlobalOp &op, mlir::Attribute value);
850
851 /// Print the postfix for externalized static variable or kernels for single
852 /// source offloading languages CUDA and HIP. The unique postfix is created
853 /// using either the CUID argument, or the file's UniqueID and active macros.
854 /// The fallback method without a CUID requires that the offloading toolchain
855 /// does not define separate macros via the -cc1 options.
856 void printPostfixForExternalizedDecl(llvm::raw_ostream &os, const Decl *d);
857
858 /// Replace all uses of the old global with the new global, updating types
859 /// and references as needed. Erases the old global when done.
860 void replaceGlobal(cir::GlobalOp oldGV, cir::GlobalOp newGV);
861
862 void replaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *old,
863 cir::FuncOp newFn);
864
865 cir::FuncOp
866 getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType,
867 clang::GlobalDecl gd, bool forVTable,
868 bool dontDefer = false, bool isThunk = false,
869 ForDefinition_t isForDefinition = NotForDefinition,
870 mlir::NamedAttrList extraAttrs = {});
871
872 cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName,
873 mlir::Type funcType, clang::GlobalDecl gd,
874 bool forVTable,
875 mlir::NamedAttrList extraAttrs) {
876 return getOrCreateCIRFunction(mangledName, funcType, gd, forVTable,
877 /*dontDefer=*/false, /*isThunk=*/false,
878 NotForDefinition, extraAttrs);
879 }
880
881 cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name,
882 cir::FuncType funcType,
883 const clang::FunctionDecl *funcDecl);
884
885 /// Create a CIR function with builtin attribute set.
886 cir::FuncOp createCIRBuiltinFunction(mlir::Location loc, llvm::StringRef name,
887 cir::FuncType ty,
888 const clang::FunctionDecl *fd);
889
890 /// Record the func_info tag for a function, either a C++ special member
891 /// form (constructor, destructor, assignment) or a known standard library
892 /// entity that passes can recognize without the AST.
893 void setFuncInfoAttr(cir::FuncOp funcOp, const clang::FunctionDecl *funcDecl);
894
895 cir::FuncOp createRuntimeFunction(cir::FuncType ty, llvm::StringRef name,
896 mlir::NamedAttrList extraAttrs = {},
897 bool isLocal = false,
898 bool assumeConvergent = false);
899
900 /// Given a builtin id for a function like "__builtin_fabsf", return a
901 /// Function* for "fabsf".
902 cir::FuncOp getBuiltinLibFunction(const FunctionDecl *fd, unsigned builtinID);
903
905 assert(cudaRuntime != nullptr);
906 return *cudaRuntime;
907 }
908
910 assert(openMPRuntime != nullptr);
911 return *openMPRuntime;
912 }
913
916
917 mlir::IntegerAttr getSize(CharUnits size) {
918 return builder.getSizeFromCharUnits(size);
919 }
920
921 /// Emit any needed decls for which code generation was deferred.
922 void emitDeferred();
923
925 /// Emit any vtables which we deferred and still have a use for.
926 void emitDeferredVTables();
927
928 /// Try to emit external vtables as available_externally if they have emitted
929 /// all inlined virtual functions. It runs after EmitDeferred() and therefore
930 /// is not allowed to create new references to things that need to be emitted
931 /// lazily.
933
934 /// Helper for `emitDeferred` to apply actual codegen.
935 void emitGlobalDecl(const clang::GlobalDecl &d);
936
937 const llvm::Triple &getTriple() const { return target.getTriple(); }
938
939 // Finalize CIR code generation.
940 void release();
941
942 /// Returns a pointer to a global variable representing a temporary with
943 /// static or thread storage duration.
944 mlir::Operation *getAddrOfGlobalTemporary(const MaterializeTemporaryExpr *mte,
945 const Expr *init);
946
947 /// -------
948 /// Visibility and Linkage
949 /// -------
950
951 static mlir::SymbolTable::Visibility
952 getMLIRVisibilityFromCIRLinkage(cir::GlobalLinkageKind GLK);
953 cir::GlobalLinkageKind getFunctionLinkage(GlobalDecl gd);
954 static mlir::SymbolTable::Visibility getMLIRVisibility(cir::GlobalOp op);
955 cir::GlobalLinkageKind getCIRLinkageForDeclarator(const DeclaratorDecl *dd,
956 GVALinkage linkage);
957 void setFunctionLinkage(GlobalDecl gd, cir::FuncOp f) {
958 cir::GlobalLinkageKind l = getFunctionLinkage(gd);
959 f.setLinkageAttr(cir::GlobalLinkageKindAttr::get(&getMLIRContext(), l));
960 mlir::SymbolTable::setSymbolVisibility(f,
962 }
963
964 cir::GlobalLinkageKind getCIRLinkageVarDefinition(const VarDecl *vd);
965
966 void addReplacement(llvm::StringRef name, mlir::Operation *op);
967
968 /// Helpers to emit "not yet implemented" error diagnostics
969 DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef);
970
971 template <typename T>
972 DiagnosticBuilder errorNYI(SourceLocation loc, llvm::StringRef feature,
973 const T &name) {
974 unsigned diagID =
975 diags.getCustomDiagID(DiagnosticsEngine::Error,
976 "ClangIR code gen Not Yet Implemented: %0: %1");
977 return diags.Report(loc, diagID) << feature << name;
978 }
979
980 DiagnosticBuilder errorNYI(mlir::Location loc, llvm::StringRef feature) {
981 // TODO: Convert the location to a SourceLocation
982 unsigned diagID = diags.getCustomDiagID(
983 DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0");
984 return diags.Report(diagID) << feature;
985 }
986
987 DiagnosticBuilder errorNYI(llvm::StringRef feature) const {
988 // TODO: Make a default location? currSrcLoc?
989 unsigned diagID = diags.getCustomDiagID(
990 DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0");
991 return diags.Report(diagID) << feature;
992 }
993
994 DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef);
995
996 template <typename T>
997 DiagnosticBuilder errorNYI(SourceRange loc, llvm::StringRef feature,
998 const T &name) {
999 return errorNYI(loc.getBegin(), feature, name) << loc;
1000 }
1001
1002 /// Emit a general error that something can't be done.
1003 void error(SourceLocation loc, llvm::StringRef error);
1004
1005 /// Print out an error that codegen doesn't support the specified stmt yet.
1006 void errorUnsupported(const Stmt *s, llvm::StringRef type);
1007
1008 /// Print out an error that codegen doesn't support the specified decl yet.
1009 void errorUnsupported(const Decl *d, llvm::StringRef type);
1010
1011 /// Emits AMDGPU specific Metadata.
1012 void emitAMDGPUMetadata();
1013
1014 /// Add global annotations for a global value (GlobalOp or FuncOp).
1015 void addGlobalAnnotations(const clang::ValueDecl *d, mlir::Operation *gv);
1016
1017private:
1018 /// Search \p currentClass and its non-virtual base subobjects for \p field,
1019 /// appending CIR field indices along the path from \p currentClass.
1020 bool findFieldMemberPath(const CXXRecordDecl *currentClass,
1021 const FieldDecl *field,
1023
1024 // An ordered map of canonical GlobalDecls to their mangled names.
1025 llvm::MapVector<clang::GlobalDecl, llvm::StringRef> mangledDeclNames;
1026 llvm::StringMap<clang::GlobalDecl, llvm::BumpPtrAllocator> manglings;
1027
1028 // FIXME: should we use llvm::TrackingVH<mlir::Operation> here?
1029 llvm::MapVector<StringRef, mlir::Operation *> replacements;
1030 /// Call replaceAllUsesWith on all pairs in replacements.
1031 void applyReplacements();
1032
1033 bool getCPUAndFeaturesAttributes(GlobalDecl gd,
1034 llvm::StringMap<std::string> &attrs,
1035 bool setTargetFeatures = true);
1036 void setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op);
1037
1038 /// Map source language used to a CIR attribute.
1039 std::optional<cir::SourceLanguage> getCIRSourceLanguage() const;
1040
1041 /// Emit all the global annotations.
1042 void emitGlobalAnnotations();
1043
1044 /// Build (or fetch from the dedup cache) the args ArrayAttr for an
1045 /// annotation. Returns the empty ArrayAttr when the annotation has none.
1046 mlir::ArrayAttr getOrCreateAnnotationArgs(const clang::AnnotateAttr *attr);
1047
1048 /// Create cir::AnnotationAttr for a single AnnotateAttr on a global.
1049 cir::AnnotationAttr emitAnnotateAttr(const clang::AnnotateAttr *aa);
1050
1051 /// Return the AST address space of the underlying global variable for D, as
1052 /// determined by its declaration. Normally this is the same as the address
1053 /// space of D's type, but in CUDA, address spaces are associated with
1054 /// declarations, not types. If D is nullptr, return the default address
1055 /// space for global variable.
1056 ///
1057 /// For languages without explicit address spaces, if D has default address
1058 /// space, target-specific global or constant address space may be returned.
1059 LangAS getGlobalVarAddressSpace(const VarDecl *decl);
1060};
1061} // namespace CIRGen
1062
1063} // namespace clang
1064
1065#endif // LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H
Defines some OpenACC-specific enums and functions.
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the SourceManager interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:245
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
Implements C++ ABI-specific code generation functions.
Abstract information about a function or function prototype.
Definition CIRGenCall.h:27
cir::GlobalOp getAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *gcd)
mlir::Value getNullPointer(cir::PointerType ptrTy, QualType qt, mlir::Location loc)
Get target specific null pointer.
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 emitCXXGlobalVarDeclInit(const VarDecl *varDecl, cir::GlobalOp addr, bool performInit)
Emit the function that initializes the specified global.
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)
cir::GlobalOp getOrCreateStaticVarDecl(const VarDecl &d, cir::GlobalLinkageKind linkage)
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
mlir::Operation * getWeakRefReference(const clang::ValueDecl *vd)
Return the symbol that a weakref declaration refers to: the cir.func or cir.global named by its alias...
bool isPaddedAtomicType(QualType type)
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)
CharUnits getDynamicOffsetAlignment(CharUnits actualBaseAlign, const CXXRecordDecl *baseDecl, CharUnits expectedTargetAlign)
TODO: Add TBAAAccessInfo.
void emitGlobalOpenACCDeclareDataOperands(const Expr *varOperand, DataClauseTy dataClause, OpenACCModifierKind modifiers, bool structured, bool implicit, bool requiresDtor)
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)
clang::AtomicOptions getAtomicOpts() const
The atomic options in effect at the point currently being emitted.
llvm::DenseMap< const VarDecl *, cir::GlobalOp > initializerConstants
llvm::DenseMap< const CompoundLiteralExpr *, cir::GlobalOp > emittedCompoundLiterals
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 addDefaultFunctionAttributes(StringRef name, bool hasOptNoneAttr, bool attrOnCallSite, mlir::NamedAttrList &attrs)
Helper function for constructAttributeList/others.
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.
DiagnosticBuilder errorNYI(SourceRange loc, llvm::StringRef feature, const T &name)
CIRGenBuilderTy & getBuilder()
void setDSOLocal(mlir::Operation *op) const
void emitCXXStaticLocalVarDeclInit(const VarDecl *varDecl, cir::GlobalOp addr, bool performInit)
Emit the function that initializes the specified static-local variable.
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)
ItaniumVTableContext & getItaniumVTableContext()
void setGVProperties(mlir::Operation *op, const NamedDecl *d) const
Set visibility, dllimport/dllexport and dso_local.
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.
llvm::DenseMap< const Decl *, cir::GlobalOp > staticLocalDeclMap
cir::FuncOp lookupFuncOp(llvm::StringRef name)
O(1) lookup of a FuncOp by name in the symbol cache.
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
cir::FuncOp getRawFunctionPointer(GlobalDecl GD)
Return a function pointer for a reference to the given function.
CharUnits getMinimumClassObjectSize(const CXXRecordDecl *cd)
Returns the minimum object size for an object of the given class type (or a class derived from it).
void emitOMPRequiresDecl(const OMPRequiresDecl *d)
void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op=nullptr)
clang::DiagnosticsEngine & getDiags() const
CharUnits getVBaseAlignment(CharUnits derivedAlign, const CXXRecordDecl *derived, const CXXRecordDecl *vbase)
Returns the assumed alignment of a virtual base of a class.
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 ItaniumVTableContext & getItaniumVTableContext() const
const clang::TargetInfo & getTarget() const
mlir::TypedAttr emitNullConstantForBase(const CXXRecordDecl *record)
Return a null constant appropriate for zero-initializing a base class with the given type.
void setCIRFunctionAttributes(GlobalDecl gd, const CIRGenFunctionInfo &info, cir::FuncOp func, bool isThunk)
Set the CIR function attributes (Sext, zext, etc).
cir::FuncOp getBuiltinLibFunction(const FunctionDecl *fd, unsigned builtinID)
Given a builtin id for a function like "__builtin_fabsf", return a Function* for "fabsf".
const llvm::Triple & getTriple() const
static mlir::SymbolTable::Visibility getMLIRVisibility(Visibility v)
void emitTentativeDefinition(const VarDecl *d)
const cir::CIRDataLayout & getDataLayout() const
CharUnits getMinimumObjectSize(QualType ty)
Returns the minimum object size for an object of the given type.
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 getAddrOfThunk(StringRef name, mlir::Type fnTy, GlobalDecl gd)
Get or create a thunk function with the given name and type.
DiagnosticBuilder errorNYI(mlir::Location loc, llvm::StringRef feature)
void addRecordLayout(mlir::StringAttr name, cir::RecordLayoutAttr attr)
Queue a record layout entry for materialization in release().
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)
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)
void setAtomicOpts(clang::AtomicOptions opts)
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 addDeferredVTable(const CXXRecordDecl *rd)
void setStaticLocalDeclAddress(const VarDecl *d, cir::GlobalOp c)
void setGVPropertiesAux(mlir::Operation *op, const NamedDecl *d) const
LangAS getLangTempAllocaAddressSpace() const
Returns the address space for temporary allocations in the language.
cir::FuncOp codegenCXXStructor(clang::GlobalDecl gd)
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
cir::FuncOp getFunctionPointer(GlobalDecl GD)
Return the ABI-correct function pointer value for a reference to the given function.
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)
cir::GlobalOp getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *e)
mlir::Value emitNullConstant(QualType t, mlir::Location loc)
Return the result of value-initializing the given type, i.e.
void emitOMPDeclareReduction(const OMPDeclareReductionDecl *d)
mlir::ModuleOp getModule() 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)
DiagnosticBuilder errorNYI(llvm::StringRef feature) const
void maybeSetTrivialComdat(const clang::Decl &d, mlir::Operation *op)
cir::GlobalOp getStaticLocalDeclAddress(const VarDecl *d)
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.
void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *e, cir::GlobalOp gv)
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...
cir::FuncOp getOrCreateCIRFunction(llvm::StringRef mangledName, mlir::Type funcType, clang::GlobalDecl gd, bool forVTable, mlir::NamedAttrList extraAttrs)
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...
llvm::DenseMap< const clang::FieldDecl *, llvm::StringRef > lambdaFieldToName
Keep a map between lambda fields and names, this needs to be per module since lambdas might get gener...
DiagnosticBuilder errorNYI(SourceLocation loc, llvm::StringRef feature, const T &name)
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)
cir::GlobalOp getOrCreateCIRGlobal(llvm::StringRef mangledName, mlir::Type ty, LangAS langAS, mlir::Location loc, const VarDecl *d, ForDefinition_t isForDefinition)
If the specified mangled name is not in the module, create and return an mlir::GlobalOp value.
std::vector< clang::GlobalDecl > deferredDeclsToEmit
void emitVTable(const CXXRecordDecl *rd)
This is a callback from Sema to tell us that a particular vtable is required to be emitted in this tr...
void emitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *d)
CIRGenOpenMPRuntime & getOpenMPRuntime()
void emitAMDGPUMetadata()
Emits AMDGPU specific Metadata.
void emitOMPGroupPrivateDecl(const OMPGroupPrivateDecl *d)
cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *rd)
Return the appropriate linkage for the vtable, VTT, and type information of the given class.
Address createUnnamedGlobalFrom(const VarDecl &d, mlir::Attribute constAttr, CharUnits align)
void emitCXXSpecialVarDeclInit(const VarDecl *varDecl, cir::GlobalOp addr, bool performInit, mlir::Region &ctorRegion, mlir::Region &dtorRegion)
Helper function for the below two that will create the constructor/destructor in specified regions,...
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,...
This class organizes the cross-module state that is used while lowering AST types to CIR types.
Definition CIRGenTypes.h:51
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3674
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1467
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:782
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:241
ExplicitCastExpr - An explicit cast written in the source code.
Definition Expr.h:3997
This represents one expression.
Definition Expr.h:114
Represents a member of a struct/union/class.
Definition Decl.h:3311
Represents a function declaration or definition.
Definition Decl.h:2071
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:60
One of these records is kept for each identifier that is lexed.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4974
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3751
Describes a module or submodule.
Definition Module.h:340
This represents a decl that may have a name.
Definition Decl.h:276
This represents 'pragma omp allocate ...' directive.
Definition DeclOpenMP.h:536
Pseudo declaration for capturing expressions.
Definition DeclOpenMP.h:445
This represents 'pragma omp declare mapper ...' directive.
Definition DeclOpenMP.h:349
This represents 'pragma omp declare reduction ...' directive.
Definition DeclOpenMP.h:239
This represents 'pragma omp groupprivate ...' directive.
Definition DeclOpenMP.h:173
This represents 'pragma omp requires...' directive.
Definition DeclOpenMP.h:479
This represents 'pragma omp threadprivate ...' directive.
Definition DeclOpenMP.h:110
A (possibly-)qualified type.
Definition TypeBase.h:938
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Stmt - This represents one statement.
Definition Stmt.h:85
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1844
Represents the declaration of a struct/union/class/enum.
Definition Decl.h:3868
Exposes information about the current target.
Definition TargetInfo.h:228
A template parameter object.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2313
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
Definition DeclCXX.h:4508
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:714
Represents a variable declaration or definition.
Definition Decl.h:934
Defines the clang::TargetInfo interface.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicDynCastAllOfMatcher< Decl, VarDecl > varDecl
Matches variable declarations.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
Top level wrappers for InstallAPI frontend operations.
GVALinkage
A more specific kind of linkage than enum Linkage.
Definition Linkage.h:72
OpenACCModifierKind
const FunctionProtoType * T
LangAS
Defines the address space values used by the address space qualifier of QualType.
Visibility
Describes the different kinds of visibility that a declaration may have.
Definition Visibility.h:34
@ HiddenVisibility
Objects with "hidden" visibility are not seen by the dynamic linker.
Definition Visibility.h:37
@ ProtectedVisibility
Objects with "protected" visibility are seen by the dynamic linker but always dynamically resolve to ...
Definition Visibility.h:42
@ DefaultVisibility
Objects with "default" visibility are seen by the dynamic linker and act like normal objects.
Definition Visibility.h:46