aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-02 21:17:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-08 17:34:50 +0000
commit06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch)
tree62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
parentcf037972ea8863e2bab7461d77345367d2c1e054 (diff)
parent7fa27ce4a07f19b07799a767fc29416f3b625afb (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp538
1 files changed, 397 insertions, 141 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
index 12d602fed693..07a9dec12f6f 100644
--- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenModule.cpp
@@ -50,9 +50,9 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
+#include "llvm/IR/AttributeMask.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Intrinsics.h"
@@ -67,8 +67,9 @@
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TimeProfiler.h"
-#include "llvm/Support/X86TargetParser.h"
#include "llvm/Support/xxhash.h"
+#include "llvm/TargetParser/Triple.h"
+#include "llvm/TargetParser/X86TargetParser.h"
#include <optional>
using namespace clang;
@@ -100,6 +101,228 @@ static CGCXXABI *createCXXABI(CodeGenModule &CGM) {
llvm_unreachable("invalid C++ ABI kind");
}
+static std::unique_ptr<TargetCodeGenInfo>
+createTargetCodeGenInfo(CodeGenModule &CGM) {
+ const TargetInfo &Target = CGM.getTarget();
+ const llvm::Triple &Triple = Target.getTriple();
+ const CodeGenOptions &CodeGenOpts = CGM.getCodeGenOpts();
+
+ switch (Triple.getArch()) {
+ default:
+ return createDefaultTargetCodeGenInfo(CGM);
+
+ case llvm::Triple::le32:
+ return createPNaClTargetCodeGenInfo(CGM);
+ case llvm::Triple::m68k:
+ return createM68kTargetCodeGenInfo(CGM);
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ if (Triple.getOS() == llvm::Triple::NaCl)
+ return createPNaClTargetCodeGenInfo(CGM);
+ return createMIPSTargetCodeGenInfo(CGM, /*IsOS32=*/true);
+
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ return createMIPSTargetCodeGenInfo(CGM, /*IsOS32=*/false);
+
+ case llvm::Triple::avr: {
+ // For passing parameters, R8~R25 are used on avr, and R18~R25 are used
+ // on avrtiny. For passing return value, R18~R25 are used on avr, and
+ // R22~R25 are used on avrtiny.
+ unsigned NPR = Target.getABI() == "avrtiny" ? 6 : 18;
+ unsigned NRR = Target.getABI() == "avrtiny" ? 4 : 8;
+ return createAVRTargetCodeGenInfo(CGM, NPR, NRR);
+ }
+
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_32:
+ case llvm::Triple::aarch64_be: {
+ AArch64ABIKind Kind = AArch64ABIKind::AAPCS;
+ if (Target.getABI() == "darwinpcs")
+ Kind = AArch64ABIKind::DarwinPCS;
+ else if (Triple.isOSWindows())
+ return createWindowsAArch64TargetCodeGenInfo(CGM, AArch64ABIKind::Win64);
+
+ return createAArch64TargetCodeGenInfo(CGM, Kind);
+ }
+
+ case llvm::Triple::wasm32:
+ case llvm::Triple::wasm64: {
+ WebAssemblyABIKind Kind = WebAssemblyABIKind::MVP;
+ if (Target.getABI() == "experimental-mv")
+ Kind = WebAssemblyABIKind::ExperimentalMV;
+ return createWebAssemblyTargetCodeGenInfo(CGM, Kind);
+ }
+
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb: {
+ if (Triple.getOS() == llvm::Triple::Win32)
+ return createWindowsARMTargetCodeGenInfo(CGM, ARMABIKind::AAPCS_VFP);
+
+ ARMABIKind Kind = ARMABIKind::AAPCS;
+ StringRef ABIStr = Target.getABI();
+ if (ABIStr == "apcs-gnu")
+ Kind = ARMABIKind::APCS;
+ else if (ABIStr == "aapcs16")
+ Kind = ARMABIKind::AAPCS16_VFP;
+ else if (CodeGenOpts.FloatABI == "hard" ||
+ (CodeGenOpts.FloatABI != "soft" &&
+ (Triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
+ Triple.getEnvironment() == llvm::Triple::MuslEABIHF ||
+ Triple.getEnvironment() == llvm::Triple::EABIHF)))
+ Kind = ARMABIKind::AAPCS_VFP;
+
+ return createARMTargetCodeGenInfo(CGM, Kind);
+ }
+
+ case llvm::Triple::ppc: {
+ if (Triple.isOSAIX())
+ return createAIXTargetCodeGenInfo(CGM, /*Is64Bit=*/false);
+
+ bool IsSoftFloat =
+ CodeGenOpts.FloatABI == "soft" || Target.hasFeature("spe");
+ return createPPC32TargetCodeGenInfo(CGM, IsSoftFloat);
+ }
+ case llvm::Triple::ppcle: {
+ bool IsSoftFloat = CodeGenOpts.FloatABI == "soft";
+ return createPPC32TargetCodeGenInfo(CGM, IsSoftFloat);
+ }
+ case llvm::Triple::ppc64:
+ if (Triple.isOSAIX())
+ return createAIXTargetCodeGenInfo(CGM, /*Is64Bit=*/true);
+
+ if (Triple.isOSBinFormatELF()) {
+ PPC64_SVR4_ABIKind Kind = PPC64_SVR4_ABIKind::ELFv1;
+ if (Target.getABI() == "elfv2")
+ Kind = PPC64_SVR4_ABIKind::ELFv2;
+ bool IsSoftFloat = CodeGenOpts.FloatABI == "soft";
+
+ return createPPC64_SVR4_TargetCodeGenInfo(CGM, Kind, IsSoftFloat);
+ }
+ return createPPC64TargetCodeGenInfo(CGM);
+ case llvm::Triple::ppc64le: {
+ assert(Triple.isOSBinFormatELF() && "PPC64 LE non-ELF not supported!");
+ PPC64_SVR4_ABIKind Kind = PPC64_SVR4_ABIKind::ELFv2;
+ if (Target.getABI() == "elfv1")
+ Kind = PPC64_SVR4_ABIKind::ELFv1;
+ bool IsSoftFloat = CodeGenOpts.FloatABI == "soft";
+
+ return createPPC64_SVR4_TargetCodeGenInfo(CGM, Kind, IsSoftFloat);
+ }
+
+ case llvm::Triple::nvptx:
+ case llvm::Triple::nvptx64:
+ return createNVPTXTargetCodeGenInfo(CGM);
+
+ case llvm::Triple::msp430:
+ return createMSP430TargetCodeGenInfo(CGM);
+
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64: {
+ StringRef ABIStr = Target.getABI();
+ unsigned XLen = Target.getPointerWidth(LangAS::Default);
+ unsigned ABIFLen = 0;
+ if (ABIStr.endswith("f"))
+ ABIFLen = 32;
+ else if (ABIStr.endswith("d"))
+ ABIFLen = 64;
+ return createRISCVTargetCodeGenInfo(CGM, XLen, ABIFLen);
+ }
+
+ case llvm::Triple::systemz: {
+ bool SoftFloat = CodeGenOpts.FloatABI == "soft";
+ bool HasVector = !SoftFloat && Target.getABI() == "vector";
+ return createSystemZTargetCodeGenInfo(CGM, HasVector, SoftFloat);
+ }
+
+ case llvm::Triple::tce:
+ case llvm::Triple::tcele:
+ return createTCETargetCodeGenInfo(CGM);
+
+ case llvm::Triple::x86: {
+ bool IsDarwinVectorABI = Triple.isOSDarwin();
+ bool IsWin32FloatStructABI = Triple.isOSWindows() && !Triple.isOSCygMing();
+
+ if (Triple.getOS() == llvm::Triple::Win32) {
+ return createWinX86_32TargetCodeGenInfo(
+ CGM, IsDarwinVectorABI, IsWin32FloatStructABI,
+ CodeGenOpts.NumRegisterParameters);
+ }
+ return createX86_32TargetCodeGenInfo(
+ CGM, IsDarwinVectorABI, IsWin32FloatStructABI,
+ CodeGenOpts.NumRegisterParameters, CodeGenOpts.FloatABI == "soft");
+ }
+
+ case llvm::Triple::x86_64: {
+ StringRef ABI = Target.getABI();
+ X86AVXABILevel AVXLevel = (ABI == "avx512" ? X86AVXABILevel::AVX512
+ : ABI == "avx" ? X86AVXABILevel::AVX
+ : X86AVXABILevel::None);
+
+ switch (Triple.getOS()) {
+ case llvm::Triple::Win32:
+ return createWinX86_64TargetCodeGenInfo(CGM, AVXLevel);
+ default:
+ return createX86_64TargetCodeGenInfo(CGM, AVXLevel);
+ }
+ }
+ case llvm::Triple::hexagon:
+ return createHexagonTargetCodeGenInfo(CGM);
+ case llvm::Triple::lanai:
+ return createLanaiTargetCodeGenInfo(CGM);
+ case llvm::Triple::r600:
+ return createAMDGPUTargetCodeGenInfo(CGM);
+ case llvm::Triple::amdgcn:
+ return createAMDGPUTargetCodeGenInfo(CGM);
+ case llvm::Triple::sparc:
+ return createSparcV8TargetCodeGenInfo(CGM);
+ case llvm::Triple::sparcv9:
+ return createSparcV9TargetCodeGenInfo(CGM);
+ case llvm::Triple::xcore:
+ return createXCoreTargetCodeGenInfo(CGM);
+ case llvm::Triple::arc:
+ return createARCTargetCodeGenInfo(CGM);
+ case llvm::Triple::spir:
+ case llvm::Triple::spir64:
+ return createCommonSPIRTargetCodeGenInfo(CGM);
+ case llvm::Triple::spirv32:
+ case llvm::Triple::spirv64:
+ return createSPIRVTargetCodeGenInfo(CGM);
+ case llvm::Triple::ve:
+ return createVETargetCodeGenInfo(CGM);
+ case llvm::Triple::csky: {
+ bool IsSoftFloat = !Target.hasFeature("hard-float-abi");
+ bool hasFP64 =
+ Target.hasFeature("fpuv2_df") || Target.hasFeature("fpuv3_df");
+ return createCSKYTargetCodeGenInfo(CGM, IsSoftFloat ? 0
+ : hasFP64 ? 64
+ : 32);
+ }
+ case llvm::Triple::bpfeb:
+ case llvm::Triple::bpfel:
+ return createBPFTargetCodeGenInfo(CGM);
+ case llvm::Triple::loongarch32:
+ case llvm::Triple::loongarch64: {
+ StringRef ABIStr = Target.getABI();
+ unsigned ABIFRLen = 0;
+ if (ABIStr.endswith("f"))
+ ABIFRLen = 32;
+ else if (ABIStr.endswith("d"))
+ ABIFRLen = 64;
+ return createLoongArchTargetCodeGenInfo(
+ CGM, Target.getPointerWidth(LangAS::Default), ABIFRLen);
+ }
+ }
+}
+
+const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
+ if (!TheTargetCodeGenInfo)
+ TheTargetCodeGenInfo = createTargetCodeGenInfo(*this);
+ return *TheTargetCodeGenInfo;
+}
+
CodeGenModule::CodeGenModule(ASTContext &C,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
const HeaderSearchOptions &HSO,
@@ -107,11 +330,11 @@ CodeGenModule::CodeGenModule(ASTContext &C,
const CodeGenOptions &CGO, llvm::Module &M,
DiagnosticsEngine &diags,
CoverageSourceInfo *CoverageInfo)
- : Context(C), LangOpts(C.getLangOpts()), FS(std::move(FS)),
- HeaderSearchOpts(HSO), PreprocessorOpts(PPO), CodeGenOpts(CGO),
- TheModule(M), Diags(diags), Target(C.getTargetInfo()),
- ABI(createCXXABI(*this)), VMContext(M.getContext()), Types(*this),
- VTables(*this), SanitizerMD(new SanitizerMetadata(*this)) {
+ : Context(C), LangOpts(C.getLangOpts()), FS(FS), HeaderSearchOpts(HSO),
+ PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags),
+ Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
+ VMContext(M.getContext()), Types(*this), VTables(*this),
+ SanitizerMD(new SanitizerMetadata(*this)) {
// Initialize the type cache.
llvm::LLVMContext &LLVMContext = M.getContext();
@@ -174,8 +397,9 @@ CodeGenModule::CodeGenModule(ASTContext &C,
// If debug info or coverage generation is enabled, create the CGDebugInfo
// object.
- if (CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo ||
- CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)
+ if (CodeGenOpts.getDebugInfo() != llvm::codegenoptions::NoDebugInfo ||
+ CodeGenOpts.CoverageNotesFile.size() ||
+ CodeGenOpts.CoverageDataFile.size())
DebugInfo.reset(new CGDebugInfo(*this));
Block.GlobalUniqueCount = 0;
@@ -185,7 +409,8 @@ CodeGenModule::CodeGenModule(ASTContext &C,
if (CodeGenOpts.hasProfileClangUse()) {
auto ReaderOrErr = llvm::IndexedInstrProfReader::create(
- CodeGenOpts.ProfileInstrumentUsePath, CodeGenOpts.ProfileRemappingFile);
+ CodeGenOpts.ProfileInstrumentUsePath, *FS,
+ CodeGenOpts.ProfileRemappingFile);
// We're checking for profile read errors in CompilerInvocation, so if
// there was an error it should've already been caught. If it hasn't been
// somehow, trip an assertion.
@@ -245,7 +470,7 @@ void CodeGenModule::createOpenMPRuntime() {
case llvm::Triple::nvptx:
case llvm::Triple::nvptx64:
case llvm::Triple::amdgcn:
- assert(getLangOpts().OpenMPIsDevice &&
+ assert(getLangOpts().OpenMPIsTargetDevice &&
"OpenMP AMDGPU/NVPTX is only prepared to deal with device code.");
OpenMPRuntime.reset(new CGOpenMPRuntimeGPU(*this));
break;
@@ -272,7 +497,7 @@ void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) {
void CodeGenModule::applyReplacements() {
for (auto &I : Replacements) {
- StringRef MangledName = I.first();
+ StringRef MangledName = I.first;
llvm::Constant *Replacement = I.second;
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
if (!Entry)
@@ -337,10 +562,11 @@ static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) {
return FinalGV;
}
-static bool checkAliasedGlobal(DiagnosticsEngine &Diags,
- SourceLocation Location, bool IsIFunc,
- const llvm::GlobalValue *Alias,
- const llvm::GlobalValue *&GV) {
+static bool checkAliasedGlobal(
+ DiagnosticsEngine &Diags, SourceLocation Location, bool IsIFunc,
+ const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV,
+ const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames,
+ SourceRange AliasRange) {
GV = getAliasedGlobal(Alias);
if (!GV) {
Diags.Report(Location, diag::err_cyclic_alias) << IsIFunc;
@@ -349,6 +575,22 @@ static bool checkAliasedGlobal(DiagnosticsEngine &Diags,
if (GV->isDeclaration()) {
Diags.Report(Location, diag::err_alias_to_undefined) << IsIFunc << IsIFunc;
+ Diags.Report(Location, diag::note_alias_requires_mangled_name)
+ << IsIFunc << IsIFunc;
+ // Provide a note if the given function is not found and exists as a
+ // mangled name.
+ for (const auto &[Decl, Name] : MangledDeclNames) {
+ if (const auto *ND = dyn_cast<NamedDecl>(Decl.getDecl())) {
+ if (ND->getName() == GV->getName()) {
+ Diags.Report(Location, diag::note_alias_mangled_name_alternative)
+ << Name
+ << FixItHint::CreateReplacement(
+ AliasRange,
+ (Twine(IsIFunc ? "ifunc" : "alias") + "(\"" + Name + "\")")
+ .str());
+ }
+ }
+ }
return false;
}
@@ -380,16 +622,19 @@ void CodeGenModule::checkAliases() {
for (const GlobalDecl &GD : Aliases) {
const auto *D = cast<ValueDecl>(GD.getDecl());
SourceLocation Location;
+ SourceRange Range;
bool IsIFunc = D->hasAttr<IFuncAttr>();
- if (const Attr *A = D->getDefiningAttr())
+ if (const Attr *A = D->getDefiningAttr()) {
Location = A->getLocation();
- else
+ Range = A->getRange();
+ } else
llvm_unreachable("Not an alias or ifunc?");
StringRef MangledName = getMangledName(GD);
llvm::GlobalValue *Alias = GetGlobalValue(MangledName);
const llvm::GlobalValue *GV = nullptr;
- if (!checkAliasedGlobal(Diags, Location, IsIFunc, Alias, GV)) {
+ if (!checkAliasedGlobal(Diags, Location, IsIFunc, Alias, GV,
+ MangledDeclNames, Range)) {
Error = true;
continue;
}
@@ -508,7 +753,7 @@ static void setVisibilityFromDLLStorageClass(const clang::LangOptions &LO,
}
void CodeGenModule::Release() {
- Module *Primary = getContext().getModuleForCodeGen();
+ Module *Primary = getContext().getCurrentNamedModule();
if (CXX20ModuleInits && Primary && !Primary->isHeaderLikeModule())
EmitModuleInitializers(Primary);
EmitDeferred();
@@ -527,6 +772,8 @@ void CodeGenModule::Release() {
GlobalTopLevelStmtBlockInFlight = {nullptr, nullptr};
}
+ // Module implementations are initialized the same way as a regular TU that
+ // imports one or more modules.
if (CXX20ModuleInits && Primary && Primary->isInterfaceOrPartition())
EmitCXXModuleInitFunc(Primary);
else
@@ -579,20 +826,6 @@ void CodeGenModule::Release() {
EmitMainVoidAlias();
if (getTriple().isAMDGPU()) {
- // Emit reference of __amdgpu_device_library_preserve_asan_functions to
- // preserve ASAN functions in bitcode libraries.
- if (LangOpts.Sanitize.has(SanitizerKind::Address)) {
- auto *FT = llvm::FunctionType::get(VoidTy, {});
- auto *F = llvm::Function::Create(
- FT, llvm::GlobalValue::ExternalLinkage,
- "__amdgpu_device_library_preserve_asan_functions", &getModule());
- auto *Var = new llvm::GlobalVariable(
- getModule(), FT->getPointerTo(),
- /*isConstant=*/true, llvm::GlobalValue::WeakAnyLinkage, F,
- "__amdgpu_device_library_preserve_asan_functions_ptr", nullptr,
- llvm::GlobalVariable::NotThreadLocal);
- addCompilerUsedGlobal(Var);
- }
// Emit amdgpu_code_object_version module flag, which is code object version
// times 100.
if (getTarget().getTargetOpts().CodeObjectVersion !=
@@ -601,6 +834,17 @@ void CodeGenModule::Release() {
"amdgpu_code_object_version",
getTarget().getTargetOpts().CodeObjectVersion);
}
+
+ // Currently, "-mprintf-kind" option is only supported for HIP
+ if (LangOpts.HIP) {
+ auto *MDStr = llvm::MDString::get(
+ getLLVMContext(), (getTarget().getTargetOpts().AMDGPUPrintfKindVal ==
+ TargetOptions::AMDGPUPrintfKind::Hostcall)
+ ? "hostcall"
+ : "buffered");
+ getModule().addModuleFlag(llvm::Module::Error, "amdgpu_printf_kind",
+ MDStr);
+ }
}
// Emit a global array containing all external kernels or device variables
@@ -845,7 +1089,7 @@ void CodeGenModule::Release() {
// Indicate whether this Module was compiled with -fopenmp
if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd)
getModule().addModuleFlag(llvm::Module::Max, "openmp", LangOpts.OpenMP);
- if (getLangOpts().OpenMPIsDevice)
+ if (getLangOpts().OpenMPIsTargetDevice)
getModule().addModuleFlag(llvm::Module::Max, "openmp-device",
LangOpts.OpenMP);
@@ -898,6 +1142,12 @@ void CodeGenModule::Release() {
if (CodeGenOpts.NoPLT)
getModule().setRtLibUseGOT();
+ if (getTriple().isOSBinFormatELF() &&
+ CodeGenOpts.DirectAccessExternalData !=
+ getModule().getDirectAccessExternalData()) {
+ getModule().setDirectAccessExternalData(
+ CodeGenOpts.DirectAccessExternalData);
+ }
if (CodeGenOpts.UnwindTables)
getModule().setUwtable(llvm::UWTableKind(CodeGenOpts.UnwindTables));
@@ -918,7 +1168,8 @@ void CodeGenModule::Release() {
if (getCodeGenOpts().EmitDeclMetadata)
EmitDeclMetadata();
- if (getCodeGenOpts().EmitGcovArcs || getCodeGenOpts().EmitGcovNotes)
+ if (getCodeGenOpts().CoverageNotesFile.size() ||
+ getCodeGenOpts().CoverageDataFile.size())
EmitCoverageFile();
if (CGDebugInfo *DI = getModuleDebugInfo())
@@ -946,6 +1197,10 @@ void CodeGenModule::Release() {
if (getCodeGenOpts().SkipRaxSetup)
getModule().addModuleFlag(llvm::Module::Override, "SkipRaxSetup", 1);
+ if (getContext().getTargetInfo().getMaxTLSAlign())
+ getModule().addModuleFlag(llvm::Module::Error, "MaxTLSAlign",
+ getContext().getTargetInfo().getMaxTLSAlign());
+
getTargetCodeGenInfo().emitTargetMetadata(*this, MangledDeclNames);
EmitBackendOptionsMetadata(getCodeGenOpts());
@@ -977,9 +1232,9 @@ void CodeGenModule::EmitOpenCLMetadata() {
}
void CodeGenModule::EmitBackendOptionsMetadata(
- const CodeGenOptions CodeGenOpts) {
+ const CodeGenOptions &CodeGenOpts) {
if (getTriple().isRISCV()) {
- getModule().addModuleFlag(llvm::Module::Error, "SmallDataLimit",
+ getModule().addModuleFlag(llvm::Module::Min, "SmallDataLimit",
CodeGenOpts.SmallDataLimit);
}
}
@@ -1347,8 +1602,13 @@ static void AppendTargetVersionMangling(const CodeGenModule &CGM,
if (Attr->isDefaultVersion())
return;
Out << "._";
+ const TargetInfo &TI = CGM.getTarget();
llvm::SmallVector<StringRef, 8> Feats;
Attr->getFeatures(Feats);
+ llvm::stable_sort(Feats, [&TI](const StringRef FeatL, const StringRef FeatR) {
+ return TI.multiVersionSortPriority(FeatL) <
+ TI.multiVersionSortPriority(FeatR);
+ });
for (const auto &Feat : Feats) {
Out << 'M';
Out << Feat;
@@ -1400,13 +1660,19 @@ static void AppendTargetClonesMangling(const CodeGenModule &CGM,
const TargetClonesAttr *Attr,
unsigned VersionIndex,
raw_ostream &Out) {
- if (CGM.getTarget().getTriple().isAArch64()) {
+ const TargetInfo &TI = CGM.getTarget();
+ if (TI.getTriple().isAArch64()) {
StringRef FeatureStr = Attr->getFeatureStr(VersionIndex);
if (FeatureStr == "default")
return;
Out << "._";
SmallVector<StringRef, 8> Features;
FeatureStr.split(Features, "+");
+ llvm::stable_sort(Features,
+ [&TI](const StringRef FeatL, const StringRef FeatR) {
+ return TI.multiVersionSortPriority(FeatL) <
+ TI.multiVersionSortPriority(FeatR);
+ });
for (auto &Feat : Features) {
Out << 'M';
Out << Feat;
@@ -1726,7 +1992,11 @@ llvm::ConstantInt *CodeGenModule::CreateKCFITypeId(QualType T) {
std::string OutName;
llvm::raw_string_ostream Out(OutName);
- getCXXABI().getMangleContext().mangleTypeName(T, Out);
+ getCXXABI().getMangleContext().mangleTypeName(
+ T, Out, getCodeGenOpts().SanitizeCfiICallNormalizeIntegers);
+
+ if (getCodeGenOpts().SanitizeCfiICallNormalizeIntegers)
+ Out << ".normalized";
return llvm::ConstantInt::get(Int32Ty,
static_cast<uint32_t>(llvm::xxHash64(OutName)));
@@ -1981,22 +2251,6 @@ CodeGenModule::getMostBaseClasses(const CXXRecordDecl *RD) {
return MostBases.takeVector();
}
-llvm::GlobalVariable *
-CodeGenModule::GetOrCreateRTTIProxyGlobalVariable(llvm::Constant *Addr) {
- auto It = RTTIProxyMap.find(Addr);
- if (It != RTTIProxyMap.end())
- return It->second;
-
- auto *FTRTTIProxy = new llvm::GlobalVariable(
- TheModule, Addr->getType(),
- /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage, Addr,
- "__llvm_rtti_proxy");
- FTRTTIProxy->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-
- RTTIProxyMap[Addr] = FTRTTIProxy;
- return FTRTTIProxy;
-}
-
void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
llvm::Function *F) {
llvm::AttrBuilder B(F->getContext());
@@ -2132,8 +2386,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
// functions. If the current target's C++ ABI requires this and this is a
// member function, set its alignment accordingly.
if (getTarget().getCXXABI().areMemberFunctionsAligned()) {
- if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D))
- F->setAlignment(llvm::Align(2));
+ if (F->getPointerAlignment(getDataLayout()) < 2 && isa<CXXMethodDecl>(D))
+ F->setAlignment(std::max(llvm::Align(2), F->getAlign().valueOrOne()));
}
// In the cross-dso CFI mode with canonical jump tables, we want !type
@@ -2162,15 +2416,6 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
}
}
-void CodeGenModule::setLLVMFunctionFEnvAttributes(const FunctionDecl *D,
- llvm::Function *F) {
- if (D->hasAttr<StrictFPAttr>()) {
- llvm::AttrBuilder FuncAttrs(F->getContext());
- FuncAttrs.addAttribute("strictfp");
- F->addFnAttrs(FuncAttrs);
- }
-}
-
void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) {
const Decl *D = GD.getDecl();
if (isa_and_nonnull<NamedDecl>(D))
@@ -2181,16 +2426,19 @@ void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) {
if (D && D->hasAttr<UsedAttr>())
addUsedOrCompilerUsedGlobal(GV);
- if (CodeGenOpts.KeepStaticConsts && D && isa<VarDecl>(D)) {
- const auto *VD = cast<VarDecl>(D);
- if (VD->getType().isConstQualified() &&
- VD->getStorageDuration() == SD_Static)
- addUsedOrCompilerUsedGlobal(GV);
- }
+ if (const auto *VD = dyn_cast_if_present<VarDecl>(D);
+ VD &&
+ ((CodeGenOpts.KeepPersistentStorageVariables &&
+ (VD->getStorageDuration() == SD_Static ||
+ VD->getStorageDuration() == SD_Thread)) ||
+ (CodeGenOpts.KeepStaticConsts && VD->getStorageDuration() == SD_Static &&
+ VD->getType().isConstQualified())))
+ addUsedOrCompilerUsedGlobal(GV);
}
bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
- llvm::AttrBuilder &Attrs) {
+ llvm::AttrBuilder &Attrs,
+ bool SetTargetFeatures) {
// Add target-cpu and target-features attributes to functions. If
// we have a decl for the function and it has a target attribute then
// parse that and add it to the feature set.
@@ -2233,8 +2481,7 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
if (SD) {
// Apply the given CPU name as the 'tune-cpu' so that the optimizer can
// favor this processor.
- TuneCPU = getTarget().getCPUSpecificTuneName(
- SD->getCPUName(GD.getMultiVersionIndex())->getName());
+ TuneCPU = SD->getCPUName(GD.getMultiVersionIndex())->getName();
}
} else {
// Otherwise just add the existing target cpu and target features to the
@@ -2250,7 +2497,10 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD,
Attrs.addAttribute("tune-cpu", TuneCPU);
AddedAttr = true;
}
- if (!Features.empty()) {
+ if (!Features.empty() && SetTargetFeatures) {
+ llvm::erase_if(Features, [&](const std::string& F) {
+ return getTarget().isReadOnlyFeature(F.substr(1));
+ });
llvm::sort(Features);
Attrs.addAttribute("target-features", llvm::join(Features, ","));
AddedAttr = true;
@@ -2353,9 +2603,6 @@ void CodeGenModule::CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
}
void CodeGenModule::setKCFIType(const FunctionDecl *FD, llvm::Function *F) {
- if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())
- return;
-
llvm::LLVMContext &Ctx = F->getContext();
llvm::MDBuilder MDB(Ctx);
F->setMetadata(llvm::LLVMContext::MD_kcfi_type,
@@ -3067,12 +3314,14 @@ bool CodeGenModule::MustBeEmitted(const ValueDecl *Global) {
if (LangOpts.EmitAllDecls)
return true;
- if (CodeGenOpts.KeepStaticConsts) {
- const auto *VD = dyn_cast<VarDecl>(Global);
- if (VD && VD->getType().isConstQualified() &&
- VD->getStorageDuration() == SD_Static)
- return true;
- }
+ const auto *VD = dyn_cast<VarDecl>(Global);
+ if (VD &&
+ ((CodeGenOpts.KeepPersistentStorageVariables &&
+ (VD->getStorageDuration() == SD_Static ||
+ VD->getStorageDuration() == SD_Thread)) ||
+ (CodeGenOpts.KeepStaticConsts && VD->getStorageDuration() == SD_Static &&
+ VD->getType().isConstQualified())))
+ return true;
return getContext().DeclMustBeEmitted(Global);
}
@@ -3115,7 +3364,7 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) {
// codegen for global variables, because they may be marked as threadprivate.
if (LangOpts.OpenMP && LangOpts.OpenMPUseTLS &&
getContext().getTargetInfo().isTLSSupported() && isa<VarDecl>(Global) &&
- !isTypeConstant(Global->getType(), false) &&
+ !isTypeConstant(Global->getType(), false, false) &&
!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(Global))
return false;
@@ -3223,9 +3472,13 @@ ConstantAddress CodeGenModule::GetAddrOfTemplateParamObject(
return ConstantAddress::invalid();
}
- auto *GV = new llvm::GlobalVariable(
- getModule(), Init->getType(),
- /*isConstant=*/true, llvm::GlobalValue::LinkOnceODRLinkage, Init, Name);
+ llvm::GlobalValue::LinkageTypes Linkage =
+ isExternallyVisible(TPO->getLinkageAndVisibility().getLinkage())
+ ? llvm::GlobalValue::LinkOnceODRLinkage
+ : llvm::GlobalValue::InternalLinkage;
+ auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(),
+ /*isConstant=*/true, Linkage, Init, Name);
+ setGVProperties(GV, TPO);
if (supportsCOMDAT())
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
Emitter.finalize(GV);
@@ -3318,7 +3571,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
if (MustBeEmitted(Global))
EmitOMPDeclareReduction(DRD);
return;
- } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Global)) {
+ }
+ if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Global)) {
if (MustBeEmitted(Global))
EmitOMPDeclareMapper(DMD);
return;
@@ -4007,7 +4261,7 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
// the iFunc instead. Name Mangling will handle the rest of the changes.
if (const FunctionDecl *FD = cast_or_null<FunctionDecl>(D)) {
// For the device mark the function as one that should be emitted.
- if (getLangOpts().OpenMPIsDevice && OpenMPRuntime &&
+ if (getLangOpts().OpenMPIsTargetDevice && OpenMPRuntime &&
!OpenMPRuntime->markAsGlobalTarget(GD) && FD->isDefined() &&
!DontDefer && !IsForDefinition) {
if (const FunctionDecl *FDDef = FD->getDefinition()) {
@@ -4184,13 +4438,10 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
/// GetAddrOfFunction - Return the address of the given function. If Ty is
/// non-null, then this function will use the specified type if it has to
/// create it (this occurs when we see a definition of the function).
-llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD,
- llvm::Type *Ty,
- bool ForVTable,
- bool DontDefer,
- ForDefinition_t IsForDefinition) {
- assert(!cast<FunctionDecl>(GD.getDecl())->isConsteval() &&
- "consteval function should never be emitted");
+llvm::Constant *
+CodeGenModule::GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty, bool ForVTable,
+ bool DontDefer,
+ ForDefinition_t IsForDefinition) {
// If there was no specific requested type, just convert it now.
if (!Ty) {
const auto *FD = cast<FunctionDecl>(GD.getDecl());
@@ -4315,8 +4566,9 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name,
///
/// If ExcludeCtor is true, the duration when the object's constructor runs
/// will not be considered. The caller will need to verify that the object is
-/// not written to during its construction.
-bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
+/// not written to during its construction. ExcludeDtor works similarly.
+bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor,
+ bool ExcludeDtor) {
if (!Ty.isConstant(Context) && !Ty->isReferenceType())
return false;
@@ -4324,7 +4576,7 @@ bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
if (const CXXRecordDecl *Record
= Context.getBaseElementType(Ty)->getAsCXXRecordDecl())
return ExcludeCtor && !Record->hasMutableFields() &&
- Record->hasTrivialDestructor();
+ (Record->hasTrivialDestructor() || ExcludeDtor);
}
return true;
@@ -4437,7 +4689,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty,
// FIXME: This code is overly simple and should be merged with other global
// handling.
- GV->setConstant(isTypeConstant(D->getType(), false));
+ GV->setConstant(isTypeConstant(D->getType(), false, false));
GV->setAlignment(getContext().getDeclAlign(D).getAsAlign());
@@ -4514,7 +4766,8 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty,
}
}
- if (GV->isDeclaration()) {
+ if (D &&
+ D->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly) {
getTargetCodeGenInfo().setTargetAttributes(D, GV, *this);
// External HIP managed variables needed to be recorded for transformation
// in both device and host compilations.
@@ -4687,16 +4940,17 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
return LangAS::sycl_global;
if (LangOpts.CUDA && LangOpts.CUDAIsDevice) {
- if (D && D->hasAttr<CUDAConstantAttr>())
- return LangAS::cuda_constant;
- else if (D && D->hasAttr<CUDASharedAttr>())
- return LangAS::cuda_shared;
- else if (D && D->hasAttr<CUDADeviceAttr>())
- return LangAS::cuda_device;
- else if (D && D->getType().isConstQualified())
- return LangAS::cuda_constant;
- else
- return LangAS::cuda_device;
+ if (D) {
+ if (D->hasAttr<CUDAConstantAttr>())
+ return LangAS::cuda_constant;
+ if (D->hasAttr<CUDASharedAttr>())
+ return LangAS::cuda_shared;
+ if (D->hasAttr<CUDADeviceAttr>())
+ return LangAS::cuda_device;
+ if (D->getType().isConstQualified())
+ return LangAS::cuda_constant;
+ }
+ return LangAS::cuda_device;
}
if (LangOpts.OpenMP) {
@@ -4807,6 +5061,10 @@ static bool shouldBeInCOMDAT(CodeGenModule &CGM, const Decl &D) {
llvm_unreachable("No such linkage");
}
+bool CodeGenModule::supportsCOMDAT() const {
+ return getTriple().supportsCOMDAT();
+}
+
void CodeGenModule::maybeSetTrivialComdat(const Decl &D,
llvm::GlobalObject &GO) {
if (!shouldBeInCOMDAT(*this, D))
@@ -4825,7 +5083,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
// If this is OpenMP device, check if it is legal to emit this global
// normally.
- if (LangOpts.OpenMPIsDevice && OpenMPRuntime &&
+ if (LangOpts.OpenMPIsTargetDevice && OpenMPRuntime &&
OpenMPRuntime->emitTargetGlobalVariable(D))
return;
@@ -4973,7 +5231,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
// Is accessible from all the threads within the grid and from the host
// through the runtime library (cudaGetSymbolAddress() / cudaGetSymbolSize()
// / cudaMemcpyToSymbol() / cudaMemcpyFromSymbol())."
- if (GV && LangOpts.CUDA) {
+ if (LangOpts.CUDA) {
if (LangOpts.CUDAIsDevice) {
if (Linkage != llvm::GlobalValue::InternalLinkage &&
(D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>() ||
@@ -4992,7 +5250,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
// If it is safe to mark the global 'constant', do so now.
GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor &&
- isTypeConstant(D->getType(), true));
+ isTypeConstant(D->getType(), true, true));
// If it is in a read-only section, mark it 'constant'.
if (const SectionAttr *SA = D->getAttr<SectionAttr>()) {
@@ -5396,9 +5654,6 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
maybeSetTrivialComdat(*D, *Fn);
- // Set CodeGen attributes that represent floating point environment.
- setLLVMFunctionFEnvAttributes(D, Fn);
-
CodeGenFunction(*this).GenerateCode(GD, Fn, FI);
setNonAliasAttributes(GD, Fn);
@@ -5845,6 +6100,7 @@ CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) {
// Resize the string to the right size, which is indicated by its type.
const ConstantArrayType *CAT = Context.getAsConstantArrayType(E->getType());
+ assert(CAT && "String literal not of constant array type!");
Str.resize(CAT->getSize().getZExtValue());
return llvm::ConstantDataArray::getString(VMContext, Str, false);
}
@@ -6066,7 +6322,8 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
emitter.emplace(*this);
InitialValue = emitter->emitForInitializer(*Value, AddrSpace,
MaterializedType);
- Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/Value);
+ Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/ Value,
+ /*ExcludeDtor*/ false);
Type = InitialValue->getType();
} else {
// No initializer, the initialization will be provided when we
@@ -6228,6 +6485,10 @@ void CodeGenModule::EmitLinkageSpec(const LinkageSpecDecl *LSD) {
}
void CodeGenModule::EmitTopLevelStmt(const TopLevelStmtDecl *D) {
+ // Device code should not be at top level.
+ if (LangOpts.CUDA && LangOpts.CUDAIsDevice)
+ return;
+
std::unique_ptr<CodeGenFunction> &CurCGF =
GlobalTopLevelStmtBlockInFlight.first;
@@ -6283,9 +6544,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
return;
// Consteval function shouldn't be emitted.
- if (auto *FD = dyn_cast<FunctionDecl>(D))
- if (FD->isConsteval())
- return;
+ if (auto *FD = dyn_cast<FunctionDecl>(D); FD && FD->isImmediateFunction())
+ return;
switch (D->getKind()) {
case Decl::CXXConversion:
@@ -6459,7 +6719,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
if (LangOpts.CUDA && LangOpts.CUDAIsDevice)
break;
// File-scope asm is ignored during device-side OpenMP compilation.
- if (LangOpts.OpenMPIsDevice)
+ if (LangOpts.OpenMPIsTargetDevice)
break;
// File-scope asm is ignored during device-side SYCL compilation.
if (LangOpts.SYCLIsDevice)
@@ -6511,16 +6771,14 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
EmitTopLevelDecl(D);
// Visit the submodules of this module.
- for (clang::Module::submodule_iterator Sub = Mod->submodule_begin(),
- SubEnd = Mod->submodule_end();
- Sub != SubEnd; ++Sub) {
+ for (auto *Submodule : Mod->submodules()) {
// Skip explicit children; they need to be explicitly imported to emit
// the initializers.
- if ((*Sub)->IsExplicit)
+ if (Submodule->IsExplicit)
continue;
- if (Visited.insert(*Sub).second)
- Stack.push_back(*Sub);
+ if (Visited.insert(Submodule).second)
+ Stack.push_back(Submodule);
}
}
break;
@@ -6869,10 +7127,6 @@ void CodeGenModule::EmitCommandLineMetadata() {
}
void CodeGenModule::EmitCoverageFile() {
- if (getCodeGenOpts().CoverageDataFile.empty() &&
- getCodeGenOpts().CoverageNotesFile.empty())
- return;
-
llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu");
if (!CUNode)
return;
@@ -6895,10 +7149,8 @@ llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
// Return a bogus pointer if RTTI is disabled, unless it's for EH.
// FIXME: should we even be calling this method if RTTI is disabled
// and it's not for EH?
- if ((!ForEH && !getLangOpts().RTTI) || getLangOpts().CUDAIsDevice ||
- (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
- getTriple().isNVPTX()))
- return llvm::Constant::getNullValue(Int8PtrTy);
+ if (!shouldEmitRTTI(ForEH))
+ return llvm::Constant::getNullValue(GlobalsInt8PtrTy);
if (ForEH && Ty->isObjCObjectPointerType() &&
LangOpts.ObjCRuntime.isGNUFamily())
@@ -6942,7 +7194,12 @@ CodeGenModule::CreateMetadataIdentifierImpl(QualType T, MetadataTypeMap &Map,
if (isExternallyVisible(T->getLinkage())) {
std::string OutName;
llvm::raw_string_ostream Out(OutName);
- getCXXABI().getMangleContext().mangleTypeName(T, Out);
+ getCXXABI().getMangleContext().mangleTypeName(
+ T, Out, getCodeGenOpts().SanitizeCfiICallNormalizeIntegers);
+
+ if (getCodeGenOpts().SanitizeCfiICallNormalizeIntegers)
+ Out << ".normalized";
+
Out << Suffix;
InternalId = llvm::MDString::get(getLLVMContext(), Out.str());
@@ -7202,7 +7459,6 @@ void CodeGenModule::moveLazyEmissionStates(CodeGenModule *NewBuilder) {
"Newly created module should not have manglings");
NewBuilder->Manglings = std::move(Manglings);
- assert(WeakRefReferences.empty() && "Not all WeakRefRefs have been applied");
NewBuilder->WeakRefReferences = std::move(WeakRefReferences);
NewBuilder->TBAA = std::move(TBAA);