Merge llvm-project release/14.x llvmorg-14.0.4-0-g29f1039a7285

This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and
openmp to llvmorg-14.0.4-0-g29f1039a7285, aka 14.0.4 release.

PR:		261742
MFC after:	3 days
This commit is contained in:
Dimitry Andric 2022-06-04 14:30:46 +02:00
commit 2a66634d1b
39 changed files with 1529 additions and 216 deletions

View File

@ -3279,10 +3279,10 @@ OPT_LIST(V)
/// Return a new OMPTraitInfo object owned by this context.
OMPTraitInfo &getNewOMPTraitInfo();
/// Whether a C++ static variable may be externalized.
/// Whether a C++ static variable or CUDA/HIP kernel may be externalized.
bool mayExternalizeStaticVar(const Decl *D) const;
/// Whether a C++ static variable should be externalized.
/// Whether a C++ static variable or CUDA/HIP kernel should be externalized.
bool shouldExternalizeStaticVar(const Decl *D) const;
StringRef getCUIDHash() const;

View File

@ -8551,12 +8551,11 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
RecordDecl *VaListTagDecl = Context->buildImplicitRecord("__va_list");
if (Context->getLangOpts().CPlusPlus) {
// namespace std { struct __va_list {
NamespaceDecl *NS;
NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context),
Context->getTranslationUnitDecl(),
/*Inline*/ false, SourceLocation(),
SourceLocation(), &Context->Idents.get("std"),
/*PrevDecl*/ nullptr);
auto *NS = NamespaceDecl::Create(
const_cast<ASTContext &>(*Context), Context->getTranslationUnitDecl(),
/*Inline*/ false, SourceLocation(), SourceLocation(),
&Context->Idents.get("std"),
/*PrevDecl*/ nullptr);
NS->setImplicit();
VaListTagDecl->setDeclContext(NS);
}
@ -12264,14 +12263,18 @@ bool ASTContext::mayExternalizeStaticVar(const Decl *D) const {
(D->hasAttr<CUDAConstantAttr>() &&
!D->getAttr<CUDAConstantAttr>()->isImplicit());
// CUDA/HIP: static managed variables need to be externalized since it is
// a declaration in IR, therefore cannot have internal linkage.
return IsStaticVar &&
(D->hasAttr<HIPManagedAttr>() || IsExplicitDeviceVar);
// a declaration in IR, therefore cannot have internal linkage. Kernels in
// anonymous name space needs to be externalized to avoid duplicate symbols.
return (IsStaticVar &&
(D->hasAttr<HIPManagedAttr>() || IsExplicitDeviceVar)) ||
(D->hasAttr<CUDAGlobalAttr>() &&
basicGVALinkageForFunction(*this, cast<FunctionDecl>(D)) ==
GVA_Internal);
}
bool ASTContext::shouldExternalizeStaticVar(const Decl *D) const {
return mayExternalizeStaticVar(D) &&
(D->hasAttr<HIPManagedAttr>() ||
(D->hasAttr<HIPManagedAttr>() || D->hasAttr<CUDAGlobalAttr>() ||
CUDADeviceVarODRUsedByHost.count(cast<VarDecl>(D)));
}

View File

@ -40,65 +40,10 @@ using namespace clang;
namespace {
/// Retrieve the declaration context that should be used when mangling the given
/// declaration.
static const DeclContext *getEffectiveDeclContext(const Decl *D) {
// The ABI assumes that lambda closure types that occur within
// default arguments live in the context of the function. However, due to
// the way in which Clang parses and creates function declarations, this is
// not the case: the lambda closure type ends up living in the context
// where the function itself resides, because the function declaration itself
// had not yet been created. Fix the context here.
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
if (RD->isLambda())
if (ParmVarDecl *ContextParam
= dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
return ContextParam->getDeclContext();
}
// Perform the same check for block literals.
if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
if (ParmVarDecl *ContextParam
= dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
return ContextParam->getDeclContext();
}
const DeclContext *DC = D->getDeclContext();
if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
isa<OMPDeclareMapperDecl>(DC)) {
return getEffectiveDeclContext(cast<Decl>(DC));
}
if (const auto *VD = dyn_cast<VarDecl>(D))
if (VD->isExternC())
return VD->getASTContext().getTranslationUnitDecl();
if (const auto *FD = dyn_cast<FunctionDecl>(D))
if (FD->isExternC())
return FD->getASTContext().getTranslationUnitDecl();
return DC->getRedeclContext();
}
static const DeclContext *getEffectiveParentContext(const DeclContext *DC) {
return getEffectiveDeclContext(cast<Decl>(DC));
}
static bool isLocalContainerContext(const DeclContext *DC) {
return isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC) || isa<BlockDecl>(DC);
}
static const RecordDecl *GetLocalClassDecl(const Decl *D) {
const DeclContext *DC = getEffectiveDeclContext(D);
while (!DC->isNamespace() && !DC->isTranslationUnit()) {
if (isLocalContainerContext(DC))
return dyn_cast<RecordDecl>(D);
D = cast<Decl>(DC);
DC = getEffectiveDeclContext(D);
}
return nullptr;
}
static const FunctionDecl *getStructor(const FunctionDecl *fn) {
if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate())
return ftd->getTemplatedDecl();
@ -126,6 +71,7 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
const DiscriminatorOverrideTy DiscriminatorOverride = nullptr;
NamespaceDecl *StdNamespace = nullptr;
bool NeedsUniqueInternalLinkageNames = false;
@ -249,6 +195,16 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
return DiscriminatorOverride;
}
NamespaceDecl *getStdNamespace();
const DeclContext *getEffectiveDeclContext(const Decl *D);
const DeclContext *getEffectiveParentContext(const DeclContext *DC) {
return getEffectiveDeclContext(cast<Decl>(DC));
}
bool isInternalLinkageDecl(const NamedDecl *ND);
const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC);
/// @}
};
@ -427,6 +383,15 @@ class CXXNameMangler {
ASTContext &getASTContext() const { return Context.getASTContext(); }
bool isStd(const NamespaceDecl *NS);
bool isStdNamespace(const DeclContext *DC);
const RecordDecl *GetLocalClassDecl(const Decl *D);
const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC);
bool isSpecializedAs(QualType S, llvm::StringRef Name, QualType A);
bool isStdCharSpecialization(const ClassTemplateSpecializationDecl *SD,
llvm::StringRef Name, bool HasAllocator);
public:
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
const NamedDecl *D = nullptr, bool NullOut_ = false)
@ -628,7 +593,71 @@ class CXXNameMangler {
}
static bool isInternalLinkageDecl(const NamedDecl *ND) {
NamespaceDecl *ItaniumMangleContextImpl::getStdNamespace() {
if (!StdNamespace) {
StdNamespace = NamespaceDecl::Create(
getASTContext(), getASTContext().getTranslationUnitDecl(),
/*Inline*/ false, SourceLocation(), SourceLocation(),
&getASTContext().Idents.get("std"),
/*PrevDecl*/ nullptr);
StdNamespace->setImplicit();
}
return StdNamespace;
}
/// Retrieve the declaration context that should be used when mangling the given
/// declaration.
const DeclContext *
ItaniumMangleContextImpl::getEffectiveDeclContext(const Decl *D) {
// The ABI assumes that lambda closure types that occur within
// default arguments live in the context of the function. However, due to
// the way in which Clang parses and creates function declarations, this is
// not the case: the lambda closure type ends up living in the context
// where the function itself resides, because the function declaration itself
// had not yet been created. Fix the context here.
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
if (RD->isLambda())
if (ParmVarDecl *ContextParam =
dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
return ContextParam->getDeclContext();
}
// Perform the same check for block literals.
if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
if (ParmVarDecl *ContextParam =
dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
return ContextParam->getDeclContext();
}
// On ARM and AArch64, the va_list tag is always mangled as if in the std
// namespace. We do not represent va_list as actually being in the std
// namespace in C because this would result in incorrect debug info in C,
// among other things. It is important for both languages to have the same
// mangling in order for -fsanitize=cfi-icall to work.
if (D == getASTContext().getVaListTagDecl()) {
const llvm::Triple &T = getASTContext().getTargetInfo().getTriple();
if (T.isARM() || T.isThumb() || T.isAArch64())
return getStdNamespace();
}
const DeclContext *DC = D->getDeclContext();
if (isa<CapturedDecl>(DC) || isa<OMPDeclareReductionDecl>(DC) ||
isa<OMPDeclareMapperDecl>(DC)) {
return getEffectiveDeclContext(cast<Decl>(DC));
}
if (const auto *VD = dyn_cast<VarDecl>(D))
if (VD->isExternC())
return getASTContext().getTranslationUnitDecl();
if (const auto *FD = dyn_cast<FunctionDecl>(D))
if (FD->isExternC())
return getASTContext().getTranslationUnitDecl();
return DC->getRedeclContext();
}
bool ItaniumMangleContextImpl::isInternalLinkageDecl(const NamedDecl *ND) {
if (ND && ND->getFormalLinkage() == InternalLinkage &&
!ND->isExternallyVisible() &&
getEffectiveDeclContext(ND)->isFileContext() &&
@ -862,18 +891,9 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) {
MangleReturnType, FD);
}
static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) {
while (isa<LinkageSpecDecl>(DC)) {
DC = getEffectiveParentContext(DC);
}
return DC;
}
/// Return whether a given namespace is the 'std' namespace.
static bool isStd(const NamespaceDecl *NS) {
if (!IgnoreLinkageSpecDecls(getEffectiveParentContext(NS))
->isTranslationUnit())
bool CXXNameMangler::isStd(const NamespaceDecl *NS) {
if (!Context.getEffectiveParentContext(NS)->isTranslationUnit())
return false;
const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier();
@ -882,7 +902,7 @@ static bool isStd(const NamespaceDecl *NS) {
// isStdNamespace - Return whether a given decl context is a toplevel 'std'
// namespace.
static bool isStdNamespace(const DeclContext *DC) {
bool CXXNameMangler::isStdNamespace(const DeclContext *DC) {
if (!DC->isNamespace())
return false;
@ -956,6 +976,17 @@ void CXXNameMangler::mangleName(GlobalDecl GD) {
}
}
const RecordDecl *CXXNameMangler::GetLocalClassDecl(const Decl *D) {
const DeclContext *DC = Context.getEffectiveDeclContext(D);
while (!DC->isNamespace() && !DC->isTranslationUnit()) {
if (isLocalContainerContext(DC))
return dyn_cast<RecordDecl>(D);
D = cast<Decl>(DC);
DC = Context.getEffectiveDeclContext(D);
}
return nullptr;
}
void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
const AbiTagList *AdditionalAbiTags) {
const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
@ -964,7 +995,7 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
// ::= [<module-name>] <unscoped-template-name> <template-args>
// ::= <local-name>
//
const DeclContext *DC = getEffectiveDeclContext(ND);
const DeclContext *DC = Context.getEffectiveDeclContext(ND);
// If this is an extern variable declared locally, the relevant DeclContext
// is that of the containing namespace, or the translation unit.
@ -972,13 +1003,13 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD,
// a proper semantic declaration context!
if (isLocalContainerContext(DC) && ND->hasLinkage() && !isLambda(ND))
while (!DC->isNamespace() && !DC->isTranslationUnit())
DC = getEffectiveParentContext(DC);
DC = Context.getEffectiveParentContext(DC);
else if (GetLocalClassDecl(ND)) {
mangleLocalName(GD, AdditionalAbiTags);
return;
}
DC = IgnoreLinkageSpecDecls(DC);
assert(!isa<LinkageSpecDecl>(DC) && "context cannot be LinkageSpecDecl");
if (isLocalContainerContext(DC)) {
mangleLocalName(GD, AdditionalAbiTags);
@ -1054,7 +1085,7 @@ void CXXNameMangler::mangleModuleNamePrefix(StringRef Name) {
void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs) {
const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD));
const DeclContext *DC = Context.getEffectiveDeclContext(TD);
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
mangleUnscopedTemplateName(TD, nullptr);
@ -1070,7 +1101,7 @@ void CXXNameMangler::mangleUnscopedName(GlobalDecl GD,
// <unscoped-name> ::= <unqualified-name>
// ::= St <unqualified-name> # ::std::
if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND))))
if (isStdNamespace(Context.getEffectiveDeclContext(ND)))
Out << "St";
mangleUnqualifiedName(GD, AdditionalAbiTags);
@ -1430,7 +1461,7 @@ void CXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
// 12_GLOBAL__N_1 mangling is quite sufficient there, and this better
// matches GCC anyway, because GCC does not treat anonymous namespaces as
// implying internal linkage.
if (isInternalLinkageDecl(ND))
if (Context.isInternalLinkageDecl(ND))
Out << 'L';
auto *FD = dyn_cast<FunctionDecl>(ND);
@ -1745,7 +1776,7 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD,
// <discriminator> := _ <non-negative number>
assert(isa<NamedDecl>(D) || isa<BlockDecl>(D));
const RecordDecl *RD = GetLocalClassDecl(D);
const DeclContext *DC = getEffectiveDeclContext(RD ? RD : D);
const DeclContext *DC = Context.getEffectiveDeclContext(RD ? RD : D);
Out << 'Z';
@ -1798,13 +1829,13 @@ void CXXNameMangler::mangleLocalName(GlobalDecl GD,
if (const NamedDecl *PrefixND = getClosurePrefix(BD))
mangleClosurePrefix(PrefixND, true /*NoFunction*/);
else
manglePrefix(getEffectiveDeclContext(BD), true /*NoFunction*/);
manglePrefix(Context.getEffectiveDeclContext(BD), true /*NoFunction*/);
assert(!AdditionalAbiTags && "Block cannot have additional abi tags");
mangleUnqualifiedBlock(BD);
} else {
const NamedDecl *ND = cast<NamedDecl>(D);
mangleNestedName(GD, getEffectiveDeclContext(ND), AdditionalAbiTags,
true /*NoFunction*/);
mangleNestedName(GD, Context.getEffectiveDeclContext(ND),
AdditionalAbiTags, true /*NoFunction*/);
}
} else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
// Mangle a block in a default parameter; see above explanation for
@ -1843,7 +1874,7 @@ void CXXNameMangler::mangleBlockForPrefix(const BlockDecl *Block) {
mangleLocalName(Block, /* AdditionalAbiTags */ nullptr);
return;
}
const DeclContext *DC = getEffectiveDeclContext(Block);
const DeclContext *DC = Context.getEffectiveDeclContext(Block);
if (isLocalContainerContext(DC)) {
mangleLocalName(Block, /* AdditionalAbiTags */ nullptr);
return;
@ -2030,7 +2061,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
// ::= # empty
// ::= <substitution>
DC = IgnoreLinkageSpecDecls(DC);
assert(!isa<LinkageSpecDecl>(DC) && "prefix cannot be LinkageSpecDecl");
if (DC->isTranslationUnit())
return;
@ -2053,7 +2084,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
mangleClosurePrefix(PrefixND, NoFunction);
mangleUnqualifiedName(ND, nullptr);
} else {
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
manglePrefix(Context.getEffectiveDeclContext(ND), NoFunction);
mangleUnqualifiedName(ND, nullptr);
}
@ -2107,7 +2138,7 @@ void CXXNameMangler::mangleTemplatePrefix(GlobalDecl GD,
if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) {
mangleTemplateParameter(TTP->getDepth(), TTP->getIndex());
} else {
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
manglePrefix(Context.getEffectiveDeclContext(ND), NoFunction);
if (isa<BuiltinTemplateDecl>(ND) || isa<ConceptDecl>(ND))
mangleUnqualifiedName(GD, nullptr);
else
@ -2152,7 +2183,7 @@ void CXXNameMangler::mangleClosurePrefix(const NamedDecl *ND, bool NoFunction) {
mangleTemplatePrefix(TD, NoFunction);
mangleTemplateArgs(asTemplateName(TD), *TemplateArgs);
} else {
manglePrefix(getEffectiveDeclContext(ND), NoFunction);
manglePrefix(Context.getEffectiveDeclContext(ND), NoFunction);
mangleUnqualifiedName(ND, nullptr);
}
@ -5969,56 +6000,61 @@ bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) {
return true;
}
static bool isCharType(QualType T) {
if (T.isNull())
/// Returns whether S is a template specialization of std::Name with a single
/// argument of type A.
bool CXXNameMangler::isSpecializedAs(QualType S, llvm::StringRef Name,
QualType A) {
if (S.isNull())
return false;
return T->isSpecificBuiltinType(BuiltinType::Char_S) ||
T->isSpecificBuiltinType(BuiltinType::Char_U);
}
/// Returns whether a given type is a template specialization of a given name
/// with a single argument of type char.
static bool isCharSpecialization(QualType T, const char *Name) {
if (T.isNull())
return false;
const RecordType *RT = T->getAs<RecordType>();
const RecordType *RT = S->getAs<RecordType>();
if (!RT)
return false;
const ClassTemplateSpecializationDecl *SD =
dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
if (!SD)
if (!SD || !SD->getIdentifier()->isStr(Name))
return false;
if (!isStdNamespace(getEffectiveDeclContext(SD)))
if (!isStdNamespace(Context.getEffectiveDeclContext(SD)))
return false;
const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
if (TemplateArgs.size() != 1)
return false;
if (!isCharType(TemplateArgs[0].getAsType()))
if (TemplateArgs[0].getAsType() != A)
return false;
return SD->getIdentifier()->getName() == Name;
return true;
}
template <std::size_t StrLen>
static bool isStreamCharSpecialization(const ClassTemplateSpecializationDecl*SD,
const char (&Str)[StrLen]) {
if (!SD->getIdentifier()->isStr(Str))
/// Returns whether SD is a template specialization std::Name<char,
/// std::char_traits<char> [, std::allocator<char>]>
/// HasAllocator controls whether the 3rd template argument is needed.
bool CXXNameMangler::isStdCharSpecialization(
const ClassTemplateSpecializationDecl *SD, llvm::StringRef Name,
bool HasAllocator) {
if (!SD->getIdentifier()->isStr(Name))
return false;
const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
if (TemplateArgs.size() != 2)
if (TemplateArgs.size() != (HasAllocator ? 3 : 2))
return false;
if (!isCharType(TemplateArgs[0].getAsType()))
QualType A = TemplateArgs[0].getAsType();
if (A.isNull())
return false;
// Plain 'char' is named Char_S or Char_U depending on the target ABI.
if (!A->isSpecificBuiltinType(BuiltinType::Char_S) &&
!A->isSpecificBuiltinType(BuiltinType::Char_U))
return false;
if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits"))
if (!isSpecializedAs(TemplateArgs[1].getAsType(), "char_traits", A))
return false;
if (HasAllocator &&
!isSpecializedAs(TemplateArgs[2].getAsType(), "allocator", A))
return false;
return true;
@ -6031,10 +6067,11 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
Out << "St";
return true;
}
return false;
}
if (const ClassTemplateDecl *TD = dyn_cast<ClassTemplateDecl>(ND)) {
if (!isStdNamespace(getEffectiveDeclContext(TD)))
if (!isStdNamespace(Context.getEffectiveDeclContext(TD)))
return false;
// <substitution> ::= Sa # ::std::allocator
@ -6048,56 +6085,45 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
Out << "Sb";
return true;
}
return false;
}
if (const ClassTemplateSpecializationDecl *SD =
dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
if (!isStdNamespace(getEffectiveDeclContext(SD)))
if (!isStdNamespace(Context.getEffectiveDeclContext(SD)))
return false;
// <substitution> ::= Ss # ::std::basic_string<char,
// ::std::char_traits<char>,
// ::std::allocator<char> >
if (SD->getIdentifier()->isStr("basic_string")) {
const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs();
if (TemplateArgs.size() != 3)
return false;
if (!isCharType(TemplateArgs[0].getAsType()))
return false;
if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits"))
return false;
if (!isCharSpecialization(TemplateArgs[2].getAsType(), "allocator"))
return false;
if (isStdCharSpecialization(SD, "basic_string", /*HasAllocator=*/true)) {
Out << "Ss";
return true;
}
// <substitution> ::= Si # ::std::basic_istream<char,
// ::std::char_traits<char> >
if (isStreamCharSpecialization(SD, "basic_istream")) {
if (isStdCharSpecialization(SD, "basic_istream", /*HasAllocator=*/false)) {
Out << "Si";
return true;
}
// <substitution> ::= So # ::std::basic_ostream<char,
// ::std::char_traits<char> >
if (isStreamCharSpecialization(SD, "basic_ostream")) {
if (isStdCharSpecialization(SD, "basic_ostream", /*HasAllocator=*/false)) {
Out << "So";
return true;
}
// <substitution> ::= Sd # ::std::basic_iostream<char,
// ::std::char_traits<char> >
if (isStreamCharSpecialization(SD, "basic_iostream")) {
if (isStdCharSpecialization(SD, "basic_iostream", /*HasAllocator=*/false)) {
Out << "Sd";
return true;
}
return false;
}
return false;
}

View File

@ -1466,8 +1466,7 @@ void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
if (!Policy.SuppressScope)
AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
IdentifierInfo *II = TD->getIdentifier();
OS << II->getName();
OS << TD->getName();
} else {
T->getTemplateName().print(OS, Policy);
}

View File

@ -69,11 +69,11 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
// From the glibc documentation, on GNU systems, malloc guarantees 16-byte
// alignment on 64-bit systems and 8-byte alignment on 32-bit systems. See
// https://www.gnu.org/software/libc/manual/html_node/Malloc-Examples.html.
// This alignment guarantee also applies to Windows and Android. On Darwin,
// the alignment is 16 bytes on both 64-bit and 32-bit systems.
// This alignment guarantee also applies to Windows and Android. On Darwin
// and OpenBSD, the alignment is 16 bytes on both 64-bit and 32-bit systems.
if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid())
NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;
else if (T.isOSDarwin())
else if (T.isOSDarwin() || T.isOSOpenBSD())
NewAlign = 128;
else
NewAlign = 0; // Infer from basic type alignment.

View File

@ -287,7 +287,7 @@ std::string CGNVCUDARuntime::getDeviceSideName(const NamedDecl *ND) {
SmallString<256> Buffer;
llvm::raw_svector_ostream Out(Buffer);
Out << DeviceSideName;
CGM.printPostfixForExternalizedStaticVar(Out);
CGM.printPostfixForExternalizedDecl(Out, ND);
DeviceSideName = std::string(Out.str());
}
return DeviceSideName;

View File

@ -1572,7 +1572,7 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
llvm::Value *allocSize =
EmitCXXNewAllocSize(*this, E, minElements, numElements,
allocSizeWithoutCookie);
CharUnits allocAlign = getContext().getPreferredTypeAlignInChars(allocType);
CharUnits allocAlign = getContext().getTypeAlignInChars(allocType);
// Emit the allocation call. If the allocator is a global placement
// operator, just "inline" it directly.

View File

@ -1367,7 +1367,7 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD,
if (CGM.getContext().shouldExternalizeStaticVar(ND) &&
CGM.getLangOpts().GPURelocatableDeviceCode &&
CGM.getLangOpts().CUDAIsDevice && !CGM.getLangOpts().CUID.empty())
CGM.printPostfixForExternalizedStaticVar(Out);
CGM.printPostfixForExternalizedDecl(Out, ND);
return std::string(Out.str());
}
@ -1455,7 +1455,7 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
// directly between host- and device-compilations, the host- and
// device-mangling in host compilation could help catching certain ones.
assert(!isa<FunctionDecl>(ND) || !ND->hasAttr<CUDAGlobalAttr>() ||
getLangOpts().CUDAIsDevice ||
getContext().shouldExternalizeStaticVar(ND) || getLangOpts().CUDAIsDevice ||
(getContext().getAuxTargetInfo() &&
(getContext().getAuxTargetInfo()->getCXXABI() !=
getContext().getTargetInfo().getCXXABI())) ||
@ -6645,7 +6645,14 @@ bool CodeGenModule::stopAutoInit() {
return false;
}
void CodeGenModule::printPostfixForExternalizedStaticVar(
llvm::raw_ostream &OS) const {
OS << "__static__" << getContext().getCUIDHash();
void CodeGenModule::printPostfixForExternalizedDecl(llvm::raw_ostream &OS,
const Decl *D) const {
StringRef Tag;
// ptxas does not allow '.' in symbol names. On the other hand, HIP prefers
// postfix beginning with '.' since the symbol name can be demangled.
if (LangOpts.HIP)
Tag = (isa<VarDecl>(D) ? ".static." : ".intern.");
else
Tag = (isa<VarDecl>(D) ? "__static__" : "__intern__");
OS << Tag << getContext().getCUIDHash();
}

View File

@ -1447,9 +1447,10 @@ class CodeGenModule : public CodeGenTypeCache {
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.
void printPostfixForExternalizedDecl(llvm::raw_ostream &OS,
const Decl *D) const;
private:
llvm::Constant *GetOrCreateLLVMFunction(

View File

@ -510,7 +510,7 @@ void RocmInstallationDetector::AddHIPIncludeArgs(const ArgList &DriverArgs,
return;
}
CC1Args.push_back("-internal-isystem");
CC1Args.push_back("-idirafter");
CC1Args.push_back(DriverArgs.MakeArgString(getIncludePath()));
if (UsesRuntimeWrapper)
CC1Args.append({"-include", "__clang_hip_runtime_wrapper.h"});

View File

@ -85,7 +85,8 @@ void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA,
assert(Output.isNothing() && "Invalid output.");
}
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
options::OPT_r)) {
if (!Args.hasArg(options::OPT_shared)) {
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o")));
}
@ -111,12 +112,15 @@ void ananas::Linker::ConstructJob(Compilation &C, const JobAction &JA,
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
if (ToolChain.ShouldLinkCXXStdlib(Args))
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
options::OPT_r)) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
CmdArgs.push_back("-lc");
}
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
options::OPT_r)) {
if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie))
CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
else

View File

@ -661,6 +661,17 @@ void tools::addOpenMPRuntimeSpecificRPath(const ToolChain &TC,
}
}
void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC,
const ArgList &Args,
ArgStringList &CmdArgs) {
// Default to clang lib / lib64 folder, i.e. the same location as device
// runtime.
SmallString<256> DefaultLibPath =
llvm::sys::path::parent_path(TC.getDriver().Dir);
llvm::sys::path::append(DefaultLibPath, Twine("lib") + CLANG_LIBDIR_SUFFIX);
CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
}
void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
// Enable -frtlib-add-rpath by default for the case of VE.
@ -720,6 +731,7 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
if (RTKind == Driver::OMPRT_OMP)
addOpenMPRuntimeSpecificRPath(TC, Args, CmdArgs);
addOpenMPRuntimeLibraryPath(TC, Args, CmdArgs);
return true;
}

View File

@ -111,6 +111,9 @@ void addOpenMPRuntimeSpecificRPath(const ToolChain &TC,
llvm::opt::ArgStringList &CmdArgs);
void addArchSpecificRPath(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
void addOpenMPRuntimeLibraryPath(const ToolChain &TC,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
/// Returns true, if an OpenMP runtime has been added.
bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC,
const llvm::opt::ArgList &Args,

View File

@ -301,18 +301,12 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths);
// Similar to the logic for GCC above, if we are currently running Clang
// inside of the requested system root, add its parent library path to those
// searched.
// FIXME: It's not clear whether we should use the driver's installed
// directory ('Dir' below) or the ResourceDir.
if (StringRef(D.Dir).startswith(SysRoot)) {
// Even if OSLibDir != "lib", this is needed for Clang in the build
// directory (not installed) to find libc++.
// The deprecated -DLLVM_ENABLE_PROJECTS=libcxx configuration installs
// libc++.so in D.Dir+"/../lib/". Detect this path.
// TODO Remove once LLVM_ENABLE_PROJECTS=libcxx is unsupported.
if (StringRef(D.Dir).startswith(SysRoot) &&
D.getVFS().exists(D.Dir + "/../lib/libc++.so"))
addPathIfExists(D, D.Dir + "/../lib", Paths);
if (OSLibDir != "lib")
addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
}
addPathIfExists(D, SysRoot + "/lib", Paths);
addPathIfExists(D, SysRoot + "/usr/lib", Paths);

View File

@ -82,7 +82,8 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
assert(Output.isNothing() && "Invalid output.");
}
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
options::OPT_r)) {
if (!Args.hasArg(options::OPT_shared))
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
@ -122,7 +123,8 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
options::OPT_r)) {
if (getToolChain().ShouldLinkCXXStdlib(Args))
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
if (Args.hasArg(options::OPT_fstack_protector) ||
@ -149,11 +151,13 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
linkSanitizerRuntimeDeps(getToolChain(), CmdArgs);
}
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
options::OPT_r)) {
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
CmdArgs.push_back(
Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
}
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
getToolChain().addProfileRTLibs(Args, CmdArgs);

View File

@ -45,3 +45,5 @@ intercept setjmp, _ZN14__interception11real_setjmpE
intercept _setjmp, _ZN14__interception12real__setjmpE
intercept sigsetjmp, _ZN14__interception14real_sigsetjmpE
intercept __sigsetjmp, _ZN14__interception16real___sigsetjmpE
NO_EXEC_STACK_DIRECTIVE

View File

@ -68,8 +68,6 @@ namespace ranges {
template <range _Rp>
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>;
#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
// [range.sized]
template <class _Tp>
concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
@ -135,8 +133,6 @@ namespace ranges {
(is_lvalue_reference_v<_Tp> ||
(movable<remove_reference_t<_Tp>> && !__is_std_initializer_list<remove_cvref_t<_Tp>>))));
#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
} // namespace ranges
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)

View File

@ -24,7 +24,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
// [range.prim.data]
@ -99,7 +99,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
_LIBCPP_END_NAMESPACE_STD

View File

@ -24,7 +24,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD
#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
namespace ranges {
template<class>
@ -128,7 +128,7 @@ inline namespace __cpo {
} // namespace __cpo
} // namespace ranges
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
_LIBCPP_END_NAMESPACE_STD

View File

@ -256,9 +256,11 @@ void AArch64::writePlt(uint8_t *buf, const Symbol &sym,
bool AArch64::needsThunk(RelExpr expr, RelType type, const InputFile *file,
uint64_t branchAddr, const Symbol &s,
int64_t a) const {
// If s is an undefined weak symbol and does not have a PLT entry then it
// will be resolved as a branch to the next instruction.
if (s.isUndefWeak() && !s.isInPlt())
// If s is an undefined weak symbol and does not have a PLT entry then it will
// be resolved as a branch to the next instruction. If it is hidden, its
// binding has been converted to local, so we just check isUndefined() here. A
// undefined non-weak symbol will have been errored.
if (s.isUndefined() && !s.isInPlt())
return false;
// ELF for the ARM 64-bit architecture, section Call and Jump relocations
// only permits range extension thunks for R_AARCH64_CALL26 and

View File

@ -296,9 +296,11 @@ void ARM::addPltSymbols(InputSection &isec, uint64_t off) const {
bool ARM::needsThunk(RelExpr expr, RelType type, const InputFile *file,
uint64_t branchAddr, const Symbol &s,
int64_t a) const {
// If S is an undefined weak symbol and does not have a PLT entry then it
// will be resolved as a branch to the next instruction.
if (s.isUndefWeak() && !s.isInPlt())
// If s is an undefined weak symbol and does not have a PLT entry then it will
// be resolved as a branch to the next instruction. If it is hidden, its
// binding has been converted to local, so we just check isUndefined() here. A
// undefined non-weak symbol will have been errored.
if (s.isUndefined() && !s.isInPlt())
return false;
// A state change from ARM to Thumb and vice versa must go through an
// interworking thunk if the relocation type is not R_ARM_CALL or

View File

@ -733,11 +733,13 @@ uint64_t InputSectionBase::getRelocTargetVA(const InputFile *file, RelType type,
if (expr == R_ARM_PCA)
// Some PC relative ARM (Thumb) relocations align down the place.
p = p & 0xfffffffc;
if (sym.isUndefWeak()) {
if (sym.isUndefined()) {
// On ARM and AArch64 a branch to an undefined weak resolves to the next
// instruction, otherwise the place. On RISCV, resolve an undefined weak
// to the same instruction to cause an infinite loop (making the user
// aware of the issue) while ensuring no overflow.
// Note: if the symbol is hidden, its binding has been converted to local,
// so we just check isUndefined() here.
if (config->emachine == EM_ARM)
dest = getARMUndefinedRelativeWeakVA(type, a, p);
else if (config->emachine == EM_AARCH64)

View File

@ -695,6 +695,7 @@ def plugin_opt_eq : J<"plugin-opt=">;
def: F<"detect-odr-violations">;
def: Flag<["-"], "g">;
def: F<"long-plt">;
def: FF<"no-add-needed">;
def: F<"no-copy-dt-needed-entries">;
def: F<"no-ctors-in-init-array">;
def: F<"no-keep-memory">;

View File

@ -290,6 +290,8 @@ AARCH64_CPU_NAME("a64fx", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_FP16 | AArch64::AEK_SVE))
AARCH64_CPU_NAME("carmel", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
AArch64::AEK_FP16)
AARCH64_CPU_NAME("ampere1", ARMV8_6A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_FP16 | AArch64::AEK_SB | AArch64::AEK_SSBS))
// Invalid CPU
AARCH64_CPU_NAME("invalid", INVALID, FK_INVALID, true, AArch64::AEK_INVALID)
#undef AARCH64_CPU_NAME

View File

@ -3469,8 +3469,13 @@ bool IRTranslator::runOnMachineFunction(MachineFunction &CurMF) {
return false;
}
if (!finalizeBasicBlock(*BB, MBB))
if (!finalizeBasicBlock(*BB, MBB)) {
OptimizationRemarkMissed R("gisel-irtranslator", "GISelFailure",
BB->getTerminator()->getDebugLoc(), BB);
R << "unable to translate basic block";
reportTranslationError(*MF, *TPC, *ORE, R);
return false;
}
}
#ifndef NDEBUG
WrapperObserver.removeObserver(&Verifier);

View File

@ -549,9 +549,27 @@ void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
uint64_t Size = 0;
const MCExpr *ESize = MSD.Symbol->getSize();
if (!ESize && Base)
if (!ESize && Base) {
// For expressions like .set y, x+1, if y's size is unset, inherit from x.
ESize = Base->getSize();
// For `.size x, 2; y = x; .size y, 1; z = y; z1 = z; .symver y, y@v1`, z,
// z1, and y@v1's st_size equals y's. However, `Base` is `x` which will give
// us 2. Follow the MCSymbolRefExpr assignment chain, which covers most
// needs. MCBinaryExpr is not handled.
const MCSymbolELF *Sym = &Symbol;
while (Sym->isVariable()) {
if (auto *Expr =
dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) {
Sym = cast<MCSymbolELF>(&Expr->getSymbol());
if (!Sym->getSize())
continue;
ESize = Sym->getSize();
}
break;
}
}
if (ESize) {
int64_t Res;
if (!ESize->evaluateKnownAbsolute(Res, Layout))

View File

@ -296,6 +296,12 @@ StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) {
}
}
if (Implementer == "0xc0") { // Ampere Computing
return StringSwitch<const char *>(Part)
.Case("0xac3", "ampere1")
.Default("generic");
}
return "generic";
}

View File

@ -557,6 +557,7 @@ include "AArch64Schedule.td"
include "AArch64InstrInfo.td"
include "AArch64SchedPredicates.td"
include "AArch64SchedPredExynos.td"
include "AArch64SchedPredAmpere.td"
include "AArch64Combine.td"
def AArch64InstrInfo : InstrInfo;
@ -626,6 +627,7 @@ include "AArch64SchedThunderX2T99.td"
include "AArch64SchedA64FX.td"
include "AArch64SchedThunderX3T110.td"
include "AArch64SchedTSV110.td"
include "AArch64SchedAmpere1.td"
def TuneA35 : SubtargetFeature<"a35", "ARMProcFamily", "CortexA35",
"Cortex-A35 ARM processors">;
@ -939,6 +941,16 @@ def TuneTSV110 : SubtargetFeature<"tsv110", "ARMProcFamily", "TSV110",
FeatureFuseAES,
FeaturePostRAScheduler]>;
def TuneAmpere1 : SubtargetFeature<"ampere1", "ARMProcFamily", "Ampere1",
"Ampere Computing Ampere-1 processors", [
FeaturePostRAScheduler,
FeatureFuseAES,
FeatureLSLFast,
FeatureAggressiveFMA,
FeatureArithmeticBccFusion,
FeatureCmpBccFusion,
FeatureFuseAddress,
FeatureFuseLiterals]>;
def ProcessorFeatures {
list<SubtargetFeature> A53 = [HasV8_0aOps, FeatureCRC, FeatureCrypto,
@ -1047,6 +1059,8 @@ def ProcessorFeatures {
list<SubtargetFeature> TSV110 = [HasV8_2aOps, FeatureCrypto, FeatureFPARMv8,
FeatureNEON, FeaturePerfMon, FeatureSPE,
FeatureFullFP16, FeatureFP16FML, FeatureDotProd];
list<SubtargetFeature> Ampere1 = [HasV8_6aOps, FeatureNEON, FeaturePerfMon,
FeatureMTE, FeatureSSBS];
// ETE and TRBE are future architecture extensions. We temporarily enable them
// by default for users targeting generic AArch64. The extensions do not
@ -1184,6 +1198,10 @@ def : ProcessorModel<"a64fx", A64FXModel, ProcessorFeatures.A64FX,
def : ProcessorModel<"carmel", NoSchedModel, ProcessorFeatures.Carmel,
[TuneCarmel]>;
// Ampere Computing
def : ProcessorModel<"ampere1", Ampere1Model, ProcessorFeatures.Ampere1,
[TuneAmpere1]>;
//===----------------------------------------------------------------------===//
// Assembly parser
//===----------------------------------------------------------------------===//

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
//===- AArch64SchedPredAmpere.td - AArch64 Sched Preds -----*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines scheduling predicate definitions that are used by the
// AArch64 Ampere Computing processors.
//
//===----------------------------------------------------------------------===//
// Auxiliary predicates.
// Check for a LSL shift <= 4
def AmpereCheapLSL : MCSchedPredicate<
CheckAny<[CheckShiftBy0,
CheckAll<
[CheckShiftLSL,
CheckAny<
[CheckShiftBy1,
CheckShiftBy2,
CheckShiftBy3,
CheckShiftBy4]>]>]>>;

View File

@ -53,7 +53,7 @@ let FunctionMapper = "AArch64_AM::getShiftType" in {
}
// Check for shifting in arithmetic and logic instructions.
foreach I = {0-3, 8} in {
foreach I = {0-4, 8} in {
let FunctionMapper = "AArch64_AM::getShiftValue" in
def CheckShiftBy#I : CheckImmOperand<3, I>;
}

View File

@ -221,6 +221,12 @@ void AArch64Subtarget::initializeProperties() {
// FIXME: remove this to enable 64-bit SLP if performance looks good.
MinVectorRegisterBitWidth = 128;
break;
case Ampere1:
CacheLineSize = 64;
PrefFunctionLogAlignment = 6;
PrefLoopLogAlignment = 6;
MaxInterleaveFactor = 4;
break;
}
}

View File

@ -40,6 +40,7 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
enum ARMProcFamilyEnum : uint8_t {
Others,
A64FX,
Ampere1,
AppleA7,
AppleA10,
AppleA11,

View File

@ -27,6 +27,8 @@ def RetCC_AVR_BUILTIN : CallingConv<[
// Calling convention for variadic functions.
def ArgCC_AVR_Vararg : CallingConv<[
// i8 are always passed through the stack with a byte slot and byte alignment.
CCIfType<[i8], CCAssignToStack<1, 1>>,
// i16 are always passed through the stack with an alignment of 1.
CCAssignToStack<2, 1>
]>;

View File

@ -194,6 +194,11 @@ def brtarget_13 : Operand<OtherVT> {
let EncoderMethod = "encodeRelCondBrTarget<AVR::fixup_13_pcrel>";
}
def rcalltarget_13 : Operand<i16> {
let PrintMethod = "printPCRelImm";
let EncoderMethod = "encodeRelCondBrTarget<AVR::fixup_13_pcrel>";
}
// The target of a 22 or 16-bit call/jmp instruction.
def call_target : Operand<iPTR> {
let EncoderMethod = "encodeCallTarget";
@ -965,10 +970,8 @@ let isBarrier = 1, isBranch = 1, isTerminator = 1 in {
let isCall = 1 in {
// SP is marked as a use to prevent stack-pointer assignments that appear
// immediately before calls from potentially appearing dead.
let Uses = [SP] in def RCALLk : FBRk<1, (outs),
(ins brtarget_13
: $target),
"rcall\t$target", []>;
let Uses = [SP] in def RCALLk : FBRk<1, (outs), (ins rcalltarget_13:$k),
"rcall\t$k", [(AVRcall imm:$k)]>;
// SP is marked as a use to prevent stack-pointer assignments that appear
// immediately before calls from potentially appearing dead.
@ -985,13 +988,10 @@ let isCall = 1 in {
// SP is marked as a use to prevent stack-pointer assignments that appear
// immediately before calls from potentially appearing dead.
//
//: TODO: the imm field can be either 16 or 22 bits in devices with more
// TODO: the imm field can be either 16 or 22 bits in devices with more
// than 64k of ROM, fix it once we support the largest devices.
let Uses = [SP] in def CALLk : F32BRk<0b111, (outs),
(ins call_target
: $k),
"call\t$k", [(AVRcall imm
: $k)]>,
let Uses = [SP] in def CALLk : F32BRk<0b111, (outs), (ins call_target:$k),
"call\t$k", [(AVRcall imm:$k)]>,
Requires<[HasJMPCALL]>;
}
@ -2457,8 +2457,12 @@ def : Pat<(adde i8
: $src2))>;
// Calls.
def : Pat<(AVRcall(i16 tglobaladdr : $dst)), (CALLk tglobaladdr : $dst)>;
def : Pat<(AVRcall(i16 texternalsym : $dst)), (CALLk texternalsym : $dst)>;
let Predicates = [HasJMPCALL] in {
def : Pat<(AVRcall(i16 tglobaladdr:$dst)), (CALLk tglobaladdr:$dst)>;
def : Pat<(AVRcall(i16 texternalsym:$dst)), (CALLk texternalsym:$dst)>;
}
def : Pat<(AVRcall(i16 tglobaladdr:$dst)), (RCALLk tglobaladdr:$dst)>;
def : Pat<(AVRcall(i16 texternalsym:$dst)), (RCALLk texternalsym:$dst)>;
// `anyext`
def : Pat<(i16(anyext i8

View File

@ -37,6 +37,8 @@ class SystemZMCCodeEmitter : public MCCodeEmitter {
const MCInstrInfo &MCII;
MCContext &Ctx;
mutable unsigned MemOpsEmitted;
public:
SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
: MCII(mcii), Ctx(ctx) {
@ -165,6 +167,7 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
MemOpsEmitted = 0;
uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
unsigned Size = MCII.get(MI.getOpcode()).getSize();
// Big-endian insertion of Size bytes.
@ -191,12 +194,14 @@ getDispOpValue(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups,
SystemZ::FixupKind Kind) const {
const MCOperand &MO = MI.getOperand(OpNum);
if (MO.isImm())
if (MO.isImm()) {
++MemOpsEmitted;
return static_cast<uint64_t>(MO.getImm());
}
if (MO.isExpr()) {
// All instructions follow the pattern where the first displacement has a
// 2 bytes offset, and the second one 4 bytes.
unsigned ByteOffs = Fixups.size() == 0 ? 2 : 4;
unsigned ByteOffs = MemOpsEmitted++ == 0 ? 2 : 4;
Fixups.push_back(MCFixup::create(ByteOffs, MO.getExpr(), (MCFixupKind)Kind,
MI.getLoc()));
assert(Fixups.size() <= 2 && "More than two memory operands in MI?");

View File

@ -6442,22 +6442,26 @@ SDValue SystemZTargetLowering::combineINT_TO_FP(
SDNode *N, DAGCombinerInfo &DCI) const {
if (DCI.Level != BeforeLegalizeTypes)
return SDValue();
SelectionDAG &DAG = DCI.DAG;
LLVMContext &Ctx = *DAG.getContext();
unsigned Opcode = N->getOpcode();
EVT OutVT = N->getValueType(0);
SelectionDAG &DAG = DCI.DAG;
Type *OutLLVMTy = OutVT.getTypeForEVT(Ctx);
SDValue Op = N->getOperand(0);
unsigned OutScalarBits = OutVT.getScalarSizeInBits();
unsigned OutScalarBits = OutLLVMTy->getScalarSizeInBits();
unsigned InScalarBits = Op->getValueType(0).getScalarSizeInBits();
// Insert an extension before type-legalization to avoid scalarization, e.g.:
// v2f64 = uint_to_fp v2i16
// =>
// v2f64 = uint_to_fp (v2i64 zero_extend v2i16)
if (OutVT.isVector() && OutScalarBits > InScalarBits) {
MVT ExtVT = MVT::getVectorVT(MVT::getIntegerVT(OutVT.getScalarSizeInBits()),
OutVT.getVectorNumElements());
if (OutLLVMTy->isVectorTy() && OutScalarBits > InScalarBits &&
OutScalarBits <= 64) {
unsigned NumElts = cast<FixedVectorType>(OutLLVMTy)->getNumElements();
EVT ExtVT = EVT::getVectorVT(
Ctx, EVT::getIntegerVT(Ctx, OutLLVMTy->getScalarSizeInBits()), NumElts);
unsigned ExtOpcode =
(Opcode == ISD::UINT_TO_FP ? ISD::ZERO_EXTEND : ISD::SIGN_EXTEND);
(Opcode == ISD::UINT_TO_FP ? ISD::ZERO_EXTEND : ISD::SIGN_EXTEND);
SDValue ExtOp = DAG.getNode(ExtOpcode, SDLoc(N), ExtVT, Op);
return DAG.getNode(Opcode, SDLoc(N), OutVT, ExtOp);
}

View File

@ -2488,8 +2488,12 @@ Value *InstCombinerImpl::matchSelectFromAndOr(Value *A, Value *C, Value *B,
// not create unnecessary casts if the types already match.
Type *SelTy = A->getType();
if (auto *VecTy = dyn_cast<VectorType>(Cond->getType())) {
// For a fixed or scalable vector get N from <{vscale x} N x iM>
unsigned Elts = VecTy->getElementCount().getKnownMinValue();
Type *EltTy = Builder.getIntNTy(SelTy->getPrimitiveSizeInBits() / Elts);
// For a fixed or scalable vector, get the size in bits of N x iM; for a
// scalar this is just M.
unsigned SelEltSize = SelTy->getPrimitiveSizeInBits().getKnownMinSize();
Type *EltTy = Builder.getIntNTy(SelEltSize / Elts);
SelTy = VectorType::get(EltTy, VecTy->getElementCount());
}
Value *BitcastC = Builder.CreateBitCast(C, SelTy);

View File

@ -342,7 +342,8 @@ static void findReturnsToZap(Function &F,
}
static bool removeNonFeasibleEdges(const SCCPSolver &Solver, BasicBlock *BB,
DomTreeUpdater &DTU) {
DomTreeUpdater &DTU,
BasicBlock *&NewUnreachableBB) {
SmallPtrSet<BasicBlock *, 8> FeasibleSuccessors;
bool HasNonFeasibleEdges = false;
for (BasicBlock *Succ : successors(BB)) {
@ -385,6 +386,23 @@ static bool removeNonFeasibleEdges(const SCCPSolver &Solver, BasicBlock *BB,
} else if (FeasibleSuccessors.size() > 1) {
SwitchInstProfUpdateWrapper SI(*cast<SwitchInst>(TI));
SmallVector<DominatorTree::UpdateType, 8> Updates;
// If the default destination is unfeasible it will never be taken. Replace
// it with a new block with a single Unreachable instruction.
BasicBlock *DefaultDest = SI->getDefaultDest();
if (!FeasibleSuccessors.contains(DefaultDest)) {
if (!NewUnreachableBB) {
NewUnreachableBB =
BasicBlock::Create(DefaultDest->getContext(), "default.unreachable",
DefaultDest->getParent(), DefaultDest);
new UnreachableInst(DefaultDest->getContext(), NewUnreachableBB);
}
SI->setDefaultDest(NewUnreachableBB);
Updates.push_back({DominatorTree::Delete, BB, DefaultDest});
Updates.push_back({DominatorTree::Insert, BB, NewUnreachableBB});
}
for (auto CI = SI->case_begin(); CI != SI->case_end();) {
if (FeasibleSuccessors.contains(CI->getCaseSuccessor())) {
++CI;
@ -532,8 +550,9 @@ bool llvm::runIPSCCP(
NumInstRemoved += changeToUnreachable(F.front().getFirstNonPHI(),
/*PreserveLCSSA=*/false, &DTU);
BasicBlock *NewUnreachableBB = nullptr;
for (BasicBlock &BB : F)
MadeChanges |= removeNonFeasibleEdges(Solver, &BB, DTU);
MadeChanges |= removeNonFeasibleEdges(Solver, &BB, DTU, NewUnreachableBB);
for (BasicBlock *DeadBB : BlocksToErase)
DTU.deleteBB(DeadBB);