diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h | 317 |
1 files changed, 236 insertions, 81 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h index 1fcd5d4d808a..d9ece4d98eec 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.h @@ -26,16 +26,19 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/NoSanitizeList.h" +#include "clang/Basic/ProfileList.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/XRayLists.h" #include "clang/Lex/PreprocessorOptions.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/Module.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Transforms/Utils/SanitizerStats.h" +#include <optional> namespace llvm { class Module; @@ -47,6 +50,10 @@ class DataLayout; class FunctionType; class LLVMContext; class IndexedInstrProfReader; + +namespace vfs { +class FileSystem; +} } namespace clang { @@ -85,6 +92,7 @@ class CGObjCRuntime; class CGOpenCLRuntime; class CGOpenMPRuntime; class CGCUDARuntime; +class CGHLSLRuntime; class CoverageMappingModuleGen; class TargetCodeGenInfo; @@ -207,16 +215,14 @@ struct ObjCEntrypoints { /// This class records statistics on instrumentation based profiling. class InstrProfStats { - uint32_t VisitedInMainFile; - uint32_t MissingInMainFile; - uint32_t Visited; - uint32_t Missing; - uint32_t Mismatched; + uint32_t VisitedInMainFile = 0; + uint32_t MissingInMainFile = 0; + uint32_t Visited = 0; + uint32_t Missing = 0; + uint32_t Mismatched = 0; public: - InstrProfStats() - : VisitedInMainFile(0), MissingInMainFile(0), Visited(0), Missing(0), - Mismatched(0) {} + InstrProfStats() = default; /// Record that we've visited a function and whether or not that function was /// in the main source file. void addVisited(bool MainFile) { @@ -277,12 +283,15 @@ class CodeGenModule : public CodeGenTypeCache { public: struct Structor { - Structor() : Priority(0), Initializer(nullptr), AssociatedData(nullptr) {} - Structor(int Priority, llvm::Constant *Initializer, + Structor() + : Priority(0), LexOrder(~0u), Initializer(nullptr), + AssociatedData(nullptr) {} + Structor(int Priority, unsigned LexOrder, llvm::Constant *Initializer, llvm::Constant *AssociatedData) - : Priority(Priority), Initializer(Initializer), + : Priority(Priority), LexOrder(LexOrder), Initializer(Initializer), AssociatedData(AssociatedData) {} int Priority; + unsigned LexOrder; llvm::Constant *Initializer; llvm::Constant *AssociatedData; }; @@ -292,6 +301,7 @@ public: private: ASTContext &Context; const LangOptions &LangOpts; + IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; // Only used for debug info. const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info. const PreprocessorOptions &PreprocessorOpts; // Only used for debug info. const CodeGenOptions &CodeGenOpts; @@ -302,7 +312,7 @@ private: std::unique_ptr<CGCXXABI> ABI; llvm::LLVMContext &VMContext; std::string ModuleNameHash; - + bool CXX20ModuleInits = false; std::unique_ptr<CodeGenTBAA> TBAA; mutable std::unique_ptr<TargetCodeGenInfo> TheTargetCodeGenInfo; @@ -319,6 +329,7 @@ private: std::unique_ptr<CGOpenCLRuntime> OpenCLRuntime; std::unique_ptr<CGOpenMPRuntime> OpenMPRuntime; std::unique_ptr<CGCUDARuntime> CUDARuntime; + std::unique_ptr<CGHLSLRuntime> HLSLRuntime; std::unique_ptr<CGDebugInfo> DebugInfo; std::unique_ptr<ObjCEntrypoints> ObjCData; llvm::MDNode *NoObjCARCExceptionsMetadata = nullptr; @@ -342,18 +353,41 @@ private: std::vector<GlobalDecl> DeferredDeclsToEmit; void addDeferredDeclToEmit(GlobalDecl GD) { DeferredDeclsToEmit.emplace_back(GD); + addEmittedDeferredDecl(GD); + } + + /// Decls that were DeferredDecls and have now been emitted. + llvm::DenseMap<llvm::StringRef, GlobalDecl> EmittedDeferredDecls; + + void addEmittedDeferredDecl(GlobalDecl GD) { + // Reemission is only needed in incremental mode. + if (!Context.getLangOpts().IncrementalExtensions) + return; + + // Assume a linkage by default that does not need reemission. + auto L = llvm::GlobalValue::ExternalLinkage; + if (llvm::isa<FunctionDecl>(GD.getDecl())) + L = getFunctionLinkage(GD); + else if (auto *VD = llvm::dyn_cast<VarDecl>(GD.getDecl())) + L = getLLVMLinkageVarDefinition(VD); + + if (llvm::GlobalValue::isInternalLinkage(L) || + llvm::GlobalValue::isLinkOnceLinkage(L) || + llvm::GlobalValue::isWeakLinkage(L)) { + EmittedDeferredDecls[getMangledName(GD)] = GD; + } } /// List of alias we have emitted. Used to make sure that what they point to /// is defined once we get to the end of the of the translation unit. std::vector<GlobalDecl> Aliases; - /// List of multiversion functions that have to be emitted. Used to make sure - /// we properly emit the iFunc. + /// List of multiversion functions to be emitted. This list is processed in + /// conjunction with other deferred symbols and is used to ensure that + /// multiversion function resolvers and ifuncs are defined and emitted. std::vector<GlobalDecl> MultiVersionFuncs; - typedef llvm::StringMap<llvm::TrackingVH<llvm::Constant> > ReplacementsTy; - ReplacementsTy Replacements; + llvm::MapVector<StringRef, llvm::TrackingVH<llvm::Constant>> Replacements; /// List of global values to be replaced with something else. Used when we /// want to replace a GlobalValue but can't identify it by its mangled name @@ -397,6 +431,10 @@ private: /// Global annotations. std::vector<llvm::Constant*> Annotations; + // Store deferred function annotations so they can be emitted at the end with + // most up to date ValueDecl that will have all the inherited annotations. + llvm::DenseMap<StringRef, const ValueDecl *> DeferredAnnotations; + /// Map used to get unique annotation strings. llvm::StringMap<llvm::Constant*> AnnotationStrings; @@ -406,6 +444,8 @@ private: llvm::StringMap<llvm::GlobalVariable *> CFConstantStringMap; llvm::DenseMap<llvm::Constant *, llvm::GlobalVariable *> ConstantStringMap; + llvm::DenseMap<const UnnamedGlobalConstantDecl *, llvm::GlobalVariable *> + UnnamedGlobalConstantDeclMap; llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap; llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap; llvm::DenseMap<const Expr*, llvm::Constant *> MaterializedGlobalTemporaryMap; @@ -509,6 +549,7 @@ private: void createOpenCLRuntime(); void createOpenMPRuntime(); void createCUDARuntime(); + void createHLSLRuntime(); bool isTriviallyRecursive(const FunctionDecl *F); bool shouldEmitFunction(GlobalDecl GD); @@ -561,8 +602,14 @@ private: MetadataTypeMap VirtualMetadataIdMap; MetadataTypeMap GeneralizedMetadataIdMap; + // Helps squashing blocks of TopLevelStmtDecl into a single llvm::Function + // when used with -fincremental-extensions. + std::pair<std::unique_ptr<CodeGenFunction>, const TopLevelStmtDecl *> + GlobalTopLevelStmtBlockInFlight; + public: - CodeGenModule(ASTContext &C, const HeaderSearchOptions &headersearchopts, + CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, + const HeaderSearchOptions &headersearchopts, const PreprocessorOptions &ppopts, const CodeGenOptions &CodeGenOpts, llvm::Module &M, DiagnosticsEngine &Diags, @@ -607,6 +654,12 @@ public: return *CUDARuntime; } + /// Return a reference to the configured HLSL runtime. + CGHLSLRuntime &getHLSLRuntime() { + assert(HLSLRuntime != nullptr); + return *HLSLRuntime; + } + ObjCEntrypoints &getObjCEntrypoints() const { assert(ObjCData != nullptr); return *ObjCData; @@ -678,12 +731,16 @@ public: llvm::MDNode *getNoObjCARCExceptionsMetadata() { if (!NoObjCARCExceptionsMetadata) - NoObjCARCExceptionsMetadata = llvm::MDNode::get(getLLVMContext(), None); + NoObjCARCExceptionsMetadata = + llvm::MDNode::get(getLLVMContext(), std::nullopt); return NoObjCARCExceptionsMetadata; } ASTContext &getContext() const { return Context; } const LangOptions &getLangOpts() const { return LangOpts; } + const IntrusiveRefCntPtr<llvm::vfs::FileSystem> &getFileSystem() const { + return FS; + } const HeaderSearchOptions &getHeaderSearchOpts() const { return HeaderSearchOpts; } const PreprocessorOptions &getPreprocessorOpts() @@ -714,6 +771,10 @@ public: return VTables.getItaniumVTableContext(); } + const ItaniumVTableContext &getItaniumVTableContext() const { + return VTables.getItaniumVTableContext(); + } + MicrosoftVTableContext &getMicrosoftVTableContext() { return VTables.getMicrosoftVTableContext(); } @@ -765,8 +826,6 @@ public: return getTBAAAccessInfo(AccessType); } - bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor); - bool isPaddedAtomicType(QualType type); bool isPaddedAtomicType(const AtomicType *type); @@ -786,6 +845,14 @@ public: void setDSOLocal(llvm::GlobalValue *GV) const; + bool shouldMapVisibilityToDLLExport(const NamedDecl *D) const { + return getLangOpts().hasDefaultVisibilityExportMapping() && D && + (D->getLinkageAndVisibility().getVisibility() == + DefaultVisibility) && + (getLangOpts().isAllDefaultVisibilityExportMapping() || + (getLangOpts().isExplicitDefaultVisibilityExportMapping() && + D->getLinkageAndVisibility().isVisibilityExplicit())); + } void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const; void setDLLImportDLLExport(llvm::GlobalValue *GV, const NamedDecl *D) const; /// Set visibility, dllimport/dllexport and dso_local. @@ -822,11 +889,13 @@ public: llvm::GlobalVariable * CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, llvm::GlobalValue::LinkageTypes Linkage, - unsigned Alignment); + llvm::Align Alignment); llvm::Function *CreateGlobalInitOrCleanUpFunction( llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, - SourceLocation Loc = SourceLocation(), bool TLS = false); + SourceLocation Loc = SourceLocation(), bool TLS = false, + llvm::GlobalVariable::LinkageTypes Linkage = + llvm::GlobalVariable::InternalLinkage); /// Return the AST address space of the underlying global variable for D, as /// determined by its declaration. Normally this is the same as the address @@ -867,12 +936,23 @@ public: // Return the function body address of the given function. llvm::Constant *GetFunctionStart(const ValueDecl *Decl); + // Return whether RTTI information should be emitted for this target. + bool shouldEmitRTTI(bool ForEH = false) { + return (ForEH || getLangOpts().RTTI) && !getLangOpts().CUDAIsDevice && + !(getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice && + getTriple().isNVPTX()); + } + /// Get the address of the RTTI descriptor for the given type. llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false); /// Get the address of a GUID. ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD); + /// Get the address of a UnnamedGlobalConstant + ConstantAddress + GetAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *GCD); + /// Get the address of a template parameter object. ConstantAddress GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO); @@ -949,11 +1029,6 @@ public: /// Return a pointer to a constant CFString object for the given string. ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal); - /// Return a pointer to a constant NSString object for the given string. Or a - /// user defined String object as defined via - /// -fconstant-string-class=class_name option. - ConstantAddress GetAddrOfConstantString(const StringLiteral *Literal); - /// Return a constant array for the given string. llvm::Constant *GetConstantArrayFromStringLiteral(const StringLiteral *E); @@ -1025,7 +1100,8 @@ public: llvm::Constant *getBuiltinLibFunction(const FunctionDecl *FD, unsigned BuiltinID); - llvm::Function *getIntrinsic(unsigned IID, ArrayRef<llvm::Type*> Tys = None); + llvm::Function *getIntrinsic(unsigned IID, + ArrayRef<llvm::Type *> Tys = std::nullopt); /// Emit code for a single top level declaration. void EmitTopLevelDecl(Decl *D); @@ -1163,6 +1239,9 @@ public: /// Return true iff the given type uses 'sret' when used as a return type. bool ReturnTypeUsesSRet(const CGFunctionInfo &FI); + /// Return true iff the given type has `inreg` set. + bool ReturnTypeHasInReg(const CGFunctionInfo &FI); + /// Return true iff the given type uses an argument slot when 'sret' is used /// as a return type. bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI); @@ -1188,24 +1267,11 @@ public: llvm::AttributeList &Attrs, unsigned &CallingConv, bool AttrOnCallSite, bool IsThunk); - /// Adds attributes to F according to our CodeGenOptions and LangOptions, as - /// though we had emitted it ourselves. We remove any attributes on F that - /// conflict with the attributes we add here. - /// - /// This is useful for adding attrs to bitcode modules that you want to link - /// with but don't control, such as CUDA's libdevice. When linking with such - /// a bitcode library, you might want to set e.g. its functions' - /// "unsafe-fp-math" attribute to match the attr of the functions you're - /// codegen'ing. Otherwise, LLVM will interpret the bitcode module's lack of - /// unsafe-fp-math attrs as tantamount to unsafe-fp-math=false, and then LLVM - /// will propagate unsafe-fp-math=false up to every transitive caller of a - /// function in the bitcode library! - /// - /// With the exception of fast-math attrs, this will only make the attributes - /// on the function more conservative. But it's unsafe to call this on a - /// function which relies on particular fast-math attributes for correctness. - /// It's up to you to ensure that this is safe. - void addDefaultFunctionDefinitionAttributes(llvm::Function &F); + /// Adjust Memory attribute to ensure that the BE gets the right attribute + // in order to generate the library call or the intrinsic for the function + // name 'Name'. + void AdjustMemoryAttribute(StringRef Name, CGCalleeInfo CalleeInfo, + llvm::AttributeList &Attrs); /// Like the overload taking a `Function &`, but intended specifically /// for frontends that want to build on Clang's target-configuration logic. @@ -1213,6 +1279,7 @@ public: StringRef getMangledName(GlobalDecl GD); StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD); + const GlobalDecl getMangledNameDecl(StringRef); void EmitTentativeDefinition(const VarDecl *D); @@ -1247,12 +1314,11 @@ public: /// Returns LLVM linkage for a declarator. llvm::GlobalValue::LinkageTypes - getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage, - bool IsConstantVariable); + getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage); /// Returns LLVM linkage for a declarator. llvm::GlobalValue::LinkageTypes - getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant); + getLLVMLinkageVarDefinition(const VarDecl *VD); /// Emit all the global annotations. void EmitGlobalAnnotations(); @@ -1287,8 +1353,9 @@ public: bool isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn, SourceLocation Loc) const; - bool isInNoSanitizeList(llvm::GlobalVariable *GV, SourceLocation Loc, - QualType Ty, StringRef Category = StringRef()) const; + bool isInNoSanitizeList(SanitizerMask Kind, llvm::GlobalVariable *GV, + SourceLocation Loc, QualType Ty, + StringRef Category = StringRef()) const; /// Imbue XRay attributes to a function, applying the always/never attribute /// lists in the process. Returns true if we did imbue attributes this way, @@ -1296,9 +1363,16 @@ public: bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, StringRef Category = StringRef()) const; - /// Returns true if function at the given location should be excluded from - /// profile instrumentation. - bool isProfileInstrExcluded(llvm::Function *Fn, SourceLocation Loc) const; + /// \returns true if \p Fn at \p Loc should be excluded from profile + /// instrumentation by the SCL passed by \p -fprofile-list. + ProfileList::ExclusionType + isFunctionBlockedByProfileList(llvm::Function *Fn, SourceLocation Loc) const; + + /// \returns true if \p Fn at \p Loc should be excluded from profile + /// instrumentation. + ProfileList::ExclusionType + isFunctionBlockedFromProfileInstr(llvm::Function *Fn, + SourceLocation Loc) const; SanitizerMetadata *getSanitizerMetadata() { return SanitizerMD.get(); @@ -1346,15 +1420,18 @@ public: /// \param D The allocate declaration void EmitOMPAllocateDecl(const OMPAllocateDecl *D); + /// Return the alignment specified in an allocate directive, if present. + std::optional<CharUnits> getOMPAllocateAlignment(const VarDecl *VD); + /// Returns whether the given record has hidden LTO visibility and therefore /// may participate in (single-module) CFI and whole-program vtable /// optimization. bool HasHiddenLTOVisibility(const CXXRecordDecl *RD); - /// Returns whether the given record has public std LTO visibility - /// and therefore may not participate in (single-module) CFI and whole-program - /// vtable optimization. - bool HasLTOVisibilityPublicStd(const CXXRecordDecl *RD); + /// Returns whether the given record has public LTO visibility (regardless of + /// -lto-whole-program-visibility) and therefore may not participate in + /// (single-module) CFI and whole-program vtable optimization. + bool AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD); /// Returns the vcall visibility of the given type. This is the scope in which /// a virtual function call could be made which ends up being dispatched to a @@ -1371,9 +1448,14 @@ public: llvm::GlobalVariable *VTable, const VTableLayout &VTLayout); + llvm::Type *getVTableComponentType() const; + /// Generate a cross-DSO type identifier for MD. llvm::ConstantInt *CreateCrossDsoCfiTypeId(llvm::Metadata *MD); + /// Generate a KCFI type identifier for T. + llvm::ConstantInt *CreateKCFITypeId(QualType T); + /// Create a metadata identifier for the given type. This may either be an /// MDString (for external identifiers) or a distinct unnamed MDNode (for /// internal identifiers). @@ -1392,9 +1474,16 @@ public: void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD, llvm::Function *F); + /// Set type metadata to the given function. + void setKCFIType(const FunctionDecl *FD, llvm::Function *F); + + /// Emit KCFI type identifier constants and remove unused identifiers. + void finalizeKCFITypes(); + /// Whether this function's return type has no side effects, and thus may /// be trivially discarded if it is unused. - bool MayDropFunctionReturn(const ASTContext &Context, QualType ReturnType); + bool MayDropFunctionReturn(const ASTContext &Context, + QualType ReturnType) const; /// Returns whether this module needs the "all-vtables" type identifier. bool NeedAllVtablesTypeId() const; @@ -1408,7 +1497,7 @@ public: /// /// A most-base class of a class C is defined as a recursive base class of C, /// including C itself, that does not have any bases. - std::vector<const CXXRecordDecl *> + SmallVector<const CXXRecordDecl *, 0> getMostBaseClasses(const CXXRecordDecl *RD); /// Get the declaration of std::terminate for the platform. @@ -1429,7 +1518,7 @@ public: /// \param FN is a pointer to IR function being generated. /// \param FD is a pointer to function declaration if any. /// \param CGF is a pointer to CodeGenFunction that generates this function. - void GenOpenCLArgMetadata(llvm::Function *FN, + void GenKernelArgMetadata(llvm::Function *FN, const FunctionDecl *FD = nullptr, CodeGenFunction *CGF = nullptr); @@ -1447,9 +1536,53 @@ public: TBAAAccessInfo *TBAAInfo = nullptr); bool stopAutoInit(); - /// Print the postfix for externalized static variable for single source - /// offloading languages CUDA and HIP. - void printPostfixForExternalizedStaticVar(llvm::raw_ostream &OS) const; + /// Print the postfix for externalized static variable or kernels for single + /// source offloading languages CUDA and HIP. The unique postfix is created + /// using either the CUID argument, or the file's UniqueID and active macros. + /// The fallback method without a CUID requires that the offloading toolchain + /// does not define separate macros via the -cc1 options. + void printPostfixForExternalizedDecl(llvm::raw_ostream &OS, + const Decl *D) const; + + /// Move some lazily-emitted states to the NewBuilder. This is especially + /// essential for the incremental parsing environment like Clang Interpreter, + /// because we'll lose all important information after each repl. + void moveLazyEmissionStates(CodeGenModule *NewBuilder); + + /// Emit the IR encoding to attach the CUDA launch bounds attribute to \p F. + /// If \p MaxThreadsVal is not nullptr, the max threads value is stored in it, + /// if a valid one was found. + void handleCUDALaunchBoundsAttr(llvm::Function *F, + const CUDALaunchBoundsAttr *A, + int32_t *MaxThreadsVal = nullptr, + int32_t *MinBlocksVal = nullptr, + int32_t *MaxClusterRankVal = nullptr); + + /// Emit the IR encoding to attach the AMD GPU flat-work-group-size attribute + /// to \p F. Alternatively, the work group size can be taken from a \p + /// ReqdWGS. If \p MinThreadsVal is not nullptr, the min threads value is + /// stored in it, if a valid one was found. If \p MaxThreadsVal is not + /// nullptr, the max threads value is stored in it, if a valid one was found. + void handleAMDGPUFlatWorkGroupSizeAttr( + llvm::Function *F, const AMDGPUFlatWorkGroupSizeAttr *A, + const ReqdWorkGroupSizeAttr *ReqdWGS = nullptr, + int32_t *MinThreadsVal = nullptr, int32_t *MaxThreadsVal = nullptr); + + /// Emit the IR encoding to attach the AMD GPU waves-per-eu attribute to \p F. + void handleAMDGPUWavesPerEUAttr(llvm::Function *F, + const AMDGPUWavesPerEUAttr *A); + + llvm::Constant * + GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, LangAS AddrSpace, + const VarDecl *D, + ForDefinition_t IsForDefinition = NotForDefinition); + + // FIXME: Hardcoding priority here is gross. + void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535, + unsigned LexOrder = ~0U, + llvm::Constant *AssociatedData = nullptr); + void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535, + bool IsDtorAttrFunc = false); private: llvm::Constant *GetOrCreateLLVMFunction( @@ -1458,19 +1591,24 @@ private: llvm::AttributeList ExtraAttrs = llvm::AttributeList(), ForDefinition_t IsForDefinition = NotForDefinition); - llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD, - llvm::Type *DeclTy, - const FunctionDecl *FD); + // References to multiversion functions are resolved through an implicitly + // defined resolver function. This function is responsible for creating + // the resolver symbol for the provided declaration. The value returned + // will be for an ifunc (llvm::GlobalIFunc) if the current target supports + // that feature and for a regular function (llvm::GlobalValue) otherwise. + llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD); + + // In scenarios where a function is not known to be a multiversion function + // until a later declaration, it is sometimes necessary to change the + // previously created mangled name to align with requirements of whatever + // multiversion function kind the function is now known to be. This function + // is responsible for performing such mangled name updates. void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD, StringRef &CurName); - llvm::Constant * - GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, LangAS AddrSpace, - const VarDecl *D, - ForDefinition_t IsForDefinition = NotForDefinition); - bool GetCPUAndFeaturesAttributes(GlobalDecl GD, - llvm::AttrBuilder &AttrBuilder); + llvm::AttrBuilder &AttrBuilder, + bool SetTargetFeatures = true); void setNonAliasAttributes(GlobalDecl GD, llvm::GlobalObject *GO); /// Set function attributes for a function declaration. @@ -1487,7 +1625,6 @@ private: void EmitAliasDefinition(GlobalDecl GD); void emitIFuncDefinition(GlobalDecl GD); void emitCPUDispatchDefinition(GlobalDecl GD); - void EmitTargetClonesResolver(GlobalDecl GD); void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); void EmitObjCIvarInitializations(ObjCImplementationDecl *D); @@ -1495,10 +1632,14 @@ private: void EmitDeclContext(const DeclContext *DC); void EmitLinkageSpec(const LinkageSpecDecl *D); + void EmitTopLevelStmt(const TopLevelStmtDecl *D); /// Emit the function that initializes C++ thread_local variables. void EmitCXXThreadLocalInitFunc(); + /// Emit the function that initializes global variables for a C++ Module. + void EmitCXXModuleInitFunc(clang::Module *Primary); + /// Emit the function that initializes C++ globals. void EmitCXXGlobalInitFunc(); @@ -1514,12 +1655,6 @@ private: void EmitPointerToInitFunc(const VarDecl *VD, llvm::GlobalVariable *Addr, llvm::Function *InitFunc, InitSegAttr *ISA); - // FIXME: Hardcoding priority here is gross. - void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535, - llvm::Constant *AssociatedData = nullptr); - void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535, - bool IsDtorAttrFunc = false); - /// EmitCtorList - Generates a global array of functions and priorities using /// the given list and name. This array will have appending linkage and is /// suitable for use as a LLVM constructor or destructor array. Clears Fns. @@ -1553,6 +1688,7 @@ private: // registered by the atexit subroutine using unatexit. void unregisterGlobalDtorsWithUnAtExit(); + /// Emit deferred multiversion function resolvers and associated variants. void emitMultiVersionFunctions(); /// Emit any vtables which we deferred and still have a use for. @@ -1565,9 +1701,22 @@ private: /// Emit the llvm.used and llvm.compiler.used metadata. void emitLLVMUsed(); + /// For C++20 Itanium ABI, emit the initializers for the module. + void EmitModuleInitializers(clang::Module *Primary); + /// Emit the link options introduced by imported modules. void EmitModuleLinkOptions(); + /// Helper function for EmitStaticExternCAliases() to redirect ifuncs that + /// have a resolver name that matches 'Elem' to instead resolve to the name of + /// 'CppFunc'. This redirection is necessary in cases where 'Elem' has a name + /// that will be emitted as an alias of the name bound to 'CppFunc'; ifuncs + /// may not reference aliases. Redirection is only performed if 'Elem' is only + /// used by ifuncs in which case, 'Elem' is destroyed. 'true' is returned if + /// redirection is successful, and 'false' is returned otherwise. + bool CheckAndReplaceExternCIFuncs(llvm::GlobalValue *Elem, + llvm::GlobalValue *CppFunc); + /// Emit aliases for internal-linkage declarations inside "C" language /// linkage specifications, giving them the "expected" name where possible. void EmitStaticExternCAliases(); @@ -1582,7 +1731,7 @@ private: /// Emit the module flag metadata used to pass options controlling the /// the backend to LLVM. - void EmitBackendOptionsMetadata(const CodeGenOptions CodeGenOpts); + void EmitBackendOptionsMetadata(const CodeGenOptions &CodeGenOpts); /// Emits OpenCL specific Metadata e.g. OpenCL version. void EmitOpenCLMetadata(); @@ -1605,6 +1754,12 @@ private: /// function. void SimplifyPersonality(); + /// Helper function for getDefaultFunctionAttributes. Builds a set of function + /// attributes which can be simply added to a function. + void getTrivialDefaultFunctionAttributes(StringRef Name, bool HasOptnone, + bool AttrOnCallSite, + llvm::AttrBuilder &FuncAttrs); + /// Helper function for ConstructAttributeList and /// addDefaultFunctionDefinitionAttributes. Builds a set of function /// attributes to add to a function with the given properties. |