diff options
author | dim <dim@FreeBSD.org> | 2017-04-02 17:24:58 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2017-04-02 17:24:58 +0000 |
commit | 60b571e49a90d38697b3aca23020d9da42fc7d7f (patch) | |
tree | 99351324c24d6cb146b6285b6caffa4d26fce188 /contrib/llvm/tools/clang/lib/Basic | |
parent | bea1b22c7a9bce1dfdd73e6e5b65bc4752215180 (diff) | |
download | FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.zip FreeBSD-src-60b571e49a90d38697b3aca23020d9da42fc7d7f.tar.gz |
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release:
MFC r309142 (by emaste):
Add WITH_LLD_AS_LD build knob
If set it installs LLD as /usr/bin/ld. LLD (as of version 3.9) is not
capable of linking the world and kernel, but can self-host and link many
substantial applications. GNU ld continues to be used for the world and
kernel build, regardless of how this knob is set.
It is on by default for arm64, and off for all other CPU architectures.
Sponsored by: The FreeBSD Foundation
MFC r310840:
Reapply 310775, now it also builds correctly if lldb is disabled:
Move llvm-objdump from CLANG_EXTRAS to installed by default
We currently install three tools from binutils 2.17.50: as, ld, and
objdump. Work is underway to migrate to a permissively-licensed
tool-chain, with one goal being the retirement of binutils 2.17.50.
LLVM's llvm-objdump is intended to be compatible with GNU objdump
although it is currently missing some options and may have formatting
differences. Enable it by default for testing and further investigation.
It may later be changed to install as /usr/bin/objdump, it becomes a
fully viable replacement.
Reviewed by: emaste
Differential Revision: https://reviews.freebsd.org/D8879
MFC r312855 (by emaste):
Rename LLD_AS_LD to LLD_IS_LD, for consistency with CLANG_IS_CC
Reported by: Dan McGregor <dan.mcgregor usask.ca>
MFC r313559 | glebius | 2017-02-10 18:34:48 +0100 (Fri, 10 Feb 2017) | 5 lines
Don't check struct rtentry on FreeBSD, it is an internal kernel structure.
On other systems it may be API structure for SIOCADDRT/SIOCDELRT.
Reviewed by: emaste, dim
MFC r314152 (by jkim):
Remove an assembler flag, which is redundant since r309124. The upstream
took care of it by introducing a macro NO_EXEC_STACK_DIRECTIVE.
http://llvm.org/viewvc/llvm-project?rev=273500&view=rev
Reviewed by: dim
MFC r314564:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
4.0.0 (branches/release_40 296509). The release will follow soon.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Also note that as of 4.0.0, lld should be able to link the base system
on amd64 and aarch64. See the WITH_LLD_IS_LLD setting in src.conf(5).
Though please be aware that this is work in progress.
Release notes for llvm, clang and lld will be available here:
<http://releases.llvm.org/4.0.0/docs/ReleaseNotes.html>
<http://releases.llvm.org/4.0.0/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/4.0.0/tools/lld/docs/ReleaseNotes.html>
Thanks to Ed Maste, Jan Beich, Antoine Brodin and Eric Fiselier for
their help.
Relnotes: yes
Exp-run: antoine
PR: 215969, 216008
MFC r314708:
For now, revert r287232 from upstream llvm trunk (by Daniil Fukalov):
[SCEV] limit recursion depth of CompareSCEVComplexity
Summary:
CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled
loop) and runs almost infinite time.
Added cache of "equal" SCEV pairs to earlier cutoff of further
estimation. Recursion depth limit was also introduced as a parameter.
Reviewers: sanjoy
Subscribers: mzolotukhin, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D26389
This commit is the cause of excessive compile times on skein_block.c
(and possibly other files) during kernel builds on amd64.
We never saw the problematic behavior described in this upstream commit,
so for now it is better to revert it. An upstream bug has been filed
here: https://bugs.llvm.org/show_bug.cgi?id=32142
Reported by: mjg
MFC r314795:
Reapply r287232 from upstream llvm trunk (by Daniil Fukalov):
[SCEV] limit recursion depth of CompareSCEVComplexity
Summary:
CompareSCEVComplexity goes too deep (50+ on a quite a big unrolled
loop) and runs almost infinite time.
Added cache of "equal" SCEV pairs to earlier cutoff of further
estimation. Recursion depth limit was also introduced as a parameter.
Reviewers: sanjoy
Subscribers: mzolotukhin, tstellarAMD, llvm-commits
Differential Revision: https://reviews.llvm.org/D26389
Pull in r296992 from upstream llvm trunk (by Sanjoy Das):
[SCEV] Decrease the recursion threshold for CompareValueComplexity
Fixes PR32142.
r287232 accidentally increased the recursion threshold for
CompareValueComplexity from 2 to 32. This change reverses that
change by introducing a separate flag for CompareValueComplexity's
threshold.
The latter revision fixes the excessive compile times for skein_block.c.
MFC r314907 | mmel | 2017-03-08 12:40:27 +0100 (Wed, 08 Mar 2017) | 7 lines
Unbreak ARMv6 world.
The new compiler_rt library imported with clang 4.0.0 have several fatal
issues (non-functional __udivsi3 for example) with ARM specific instrict
functions. As temporary workaround, until upstream solve these problems,
disable all thumb[1][2] related feature.
MFC r315016:
Update clang, llvm, lld, lldb, compiler-rt and libc++ to 4.0.0 release.
We were already very close to the last release candidate, so this is a
pretty minor update.
Relnotes: yes
MFC r316005:
Revert r314907, and pull in r298713 from upstream compiler-rt trunk (by
Weiming Zhao):
builtins: Select correct code fragments when compiling for Thumb1/Thum2/ARM ISA.
Summary:
Value of __ARM_ARCH_ISA_THUMB isn't based on the actual compilation
mode (-mthumb, -marm), it reflect's capability of given CPU.
Due to this:
- use __tbumb__ and __thumb2__ insteand of __ARM_ARCH_ISA_THUMB
- use '.thumb' directive consistently in all affected files
- decorate all thumb functions using
DEFINE_COMPILERRT_THUMB_FUNCTION()
---------
Note: This patch doesn't fix broken Thumb1 variant of __udivsi3 !
Reviewers: weimingz, rengolin, compnerd
Subscribers: aemerson, dim
Differential Revision: https://reviews.llvm.org/D30938
Discussed with: mmel
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp | 21 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/FileManager.cpp | 24 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp | 6 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp | 18 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp | 7 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Module.cpp | 11 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp | 174 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp | 1 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp | 40 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp | 48 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Targets.cpp | 811 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Version.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp | 134 |
14 files changed, 993 insertions, 306 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp index f10d156..7529c47 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp @@ -55,10 +55,12 @@ static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT, Output.append(Str.begin(), Str.end()); } -DiagnosticsEngine::DiagnosticsEngine( - const IntrusiveRefCntPtr<DiagnosticIDs> &diags, DiagnosticOptions *DiagOpts, - DiagnosticConsumer *client, bool ShouldOwnClient) - : Diags(diags), DiagOpts(DiagOpts), Client(nullptr), SourceMgr(nullptr) { +DiagnosticsEngine::DiagnosticsEngine(IntrusiveRefCntPtr<DiagnosticIDs> diags, + DiagnosticOptions *DiagOpts, + DiagnosticConsumer *client, + bool ShouldOwnClient) + : Diags(std::move(diags)), DiagOpts(DiagOpts), Client(nullptr), + SourceMgr(nullptr) { setClient(client, ShouldOwnClient); ArgToStringFn = DummyArgToStringFn; ArgToStringCookie = nullptr; @@ -740,7 +742,10 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, // "%diff{compare $ to $|other text}1,2" // treat it as: // "compare %1 to %2" - const char *Pipe = ScanFormat(Argument, Argument + ArgumentLen, '|'); + const char *ArgumentEnd = Argument + ArgumentLen; + const char *Pipe = ScanFormat(Argument, ArgumentEnd, '|'); + assert(ScanFormat(Pipe + 1, ArgumentEnd, '|') == ArgumentEnd && + "Found too many '|'s in a %diff modifier!"); const char *FirstDollar = ScanFormat(Argument, Pipe, '$'); const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$'); const char ArgStr1[] = { '%', static_cast<char>('0' + ArgNo) }; @@ -1008,7 +1013,7 @@ PartialDiagnostic::StorageAllocator::StorageAllocator() { PartialDiagnostic::StorageAllocator::~StorageAllocator() { // Don't assert if we are in a CrashRecovery context, as this invariant may // be invalidated during a crash. - assert((NumFreeListEntries == NumCached || - llvm::CrashRecoveryContext::isRecoveringFromCrash()) && - "A partial is on the lamb"); + assert((NumFreeListEntries == NumCached || + llvm::CrashRecoveryContext::isRecoveringFromCrash()) && + "A partial is on the lam"); } diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp index f54a0ef..93c2196 100644 --- a/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticOptions.cpp @@ -16,7 +16,7 @@ namespace clang { -raw_ostream& operator<<(raw_ostream& Out, DiagnosticLevelMask M) { +raw_ostream &operator<<(raw_ostream &Out, DiagnosticLevelMask M) { using UT = std::underlying_type<DiagnosticLevelMask>::type; return Out << static_cast<UT>(M); } diff --git a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp index ce9b7e1..50050d0 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp @@ -26,10 +26,13 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" -#include <map> -#include <set> +#include <algorithm> +#include <cassert> +#include <climits> +#include <cstdint> +#include <cstdlib> #include <string> -#include <system_error> +#include <utility> using namespace clang; @@ -137,7 +140,7 @@ void FileManager::addAncestorsAsVirtualDirs(StringRef Path) { // Add the virtual directory to the cache. auto UDE = llvm::make_unique<DirectoryEntry>(); - UDE->Name = NamedDirEnt.first().data(); + UDE->Name = NamedDirEnt.first(); NamedDirEnt.second = UDE.get(); VirtualDirectoryEntries.push_back(std::move(UDE)); @@ -182,7 +185,7 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName, // Get the null-terminated directory name as stored as the key of the // SeenDirEntries map. - const char *InterndDirName = NamedDirEnt.first().data(); + StringRef InterndDirName = NamedDirEnt.first(); // Check to see if the directory exists. FileData Data; @@ -200,7 +203,7 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName, DirectoryEntry &UDE = UniqueRealDirs[Data.UniqueID]; NamedDirEnt.second = &UDE; - if (!UDE.getName()) { + if (UDE.getName().empty()) { // We don't have this directory yet, add it. We use the string // key from the SeenDirEntries map as the string. UDE.Name = InterndDirName; @@ -229,7 +232,7 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, // Get the null-terminated file name as stored as the key of the // SeenFileEntries map. - const char *InterndFileName = NamedFileEnt.first().data(); + StringRef InterndFileName = NamedFileEnt.first(); // Look up the directory for the file. When looking up something like // sys/foo.h we'll discover all of the search directories that have a 'sys' @@ -420,7 +423,7 @@ FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, if (isVolatile) FileSize = -1; - const char *Filename = Entry->getName(); + StringRef Filename = Entry->getName(); // If the file is already open, use the open file descriptor. if (Entry->File) { auto Result = @@ -460,7 +463,7 @@ FileManager::getBufferForFile(StringRef Filename) { /// if the path points to a virtual file or does not exist, or returns /// false if it's an existent real file. If FileDescriptor is NULL, /// do directory look-up instead of file look-up. -bool FileManager::getStatValue(const char *Path, FileData &Data, bool isFile, +bool FileManager::getStatValue(StringRef Path, FileData &Data, bool isFile, std::unique_ptr<vfs::File> *F) { // FIXME: FileSystemOpts shouldn't be passed in here, all paths should be // absolute! @@ -497,7 +500,6 @@ void FileManager::invalidateCache(const FileEntry *Entry) { UniqueRealFiles.erase(Entry->getUniqueID()); } - void FileManager::GetUniqueIDMapping( SmallVectorImpl<const FileEntry *> &UIDToFiles) const { UIDToFiles.clear(); @@ -533,7 +535,7 @@ StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { #ifdef LLVM_ON_UNIX char CanonicalNameBuf[PATH_MAX]; - if (realpath(Dir->getName(), CanonicalNameBuf)) + if (realpath(Dir->getName().str().c_str(), CanonicalNameBuf)) CanonicalName = StringRef(CanonicalNameBuf).copy(CanonicalNameStorage); #else SmallString<256> CanonicalNameBuf(CanonicalName); diff --git a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp index 187ea37..799df1d 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp @@ -23,7 +23,7 @@ static void copyStatusToFileData(const vfs::Status &Status, FileData &Data) { Data.Name = Status.getName(); Data.Size = Status.getSize(); - Data.ModTime = Status.getLastModificationTime().toEpochTime(); + Data.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); Data.UniqueID = Status.getUniqueID(); Data.IsDirectory = Status.isDirectory(); Data.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; @@ -40,7 +40,7 @@ static void copyStatusToFileData(const vfs::Status &Status, /// success for directories (not files). On a successful file lookup, the /// implementation can optionally fill in FileDescriptor with a valid /// descriptor and the client guarantees that it will close it. -bool FileSystemStatCache::get(const char *Path, FileData &Data, bool isFile, +bool FileSystemStatCache::get(StringRef Path, FileData &Data, bool isFile, std::unique_ptr<vfs::File> *F, FileSystemStatCache *Cache, vfs::FileSystem &FS) { LookupResult R; @@ -107,7 +107,7 @@ bool FileSystemStatCache::get(const char *Path, FileData &Data, bool isFile, } MemorizeStatCalls::LookupResult -MemorizeStatCalls::getStat(const char *Path, FileData &Data, bool isFile, +MemorizeStatCalls::getStat(StringRef Path, FileData &Data, bool isFile, std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) { LookupResult Result = statChained(Path, Data, isFile, F, FS); diff --git a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp index d6ad0f5..af424cd 100644 --- a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp @@ -113,7 +113,8 @@ namespace { KEYOBJC2 = 0x20000, KEYZVECTOR = 0x40000, KEYCOROUTINES = 0x80000, - KEYALL = (0xfffff & ~KEYNOMS18 & + KEYMODULES = 0x100000, + KEYALL = (0x1fffff & ~KEYNOMS18 & ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude. }; @@ -147,9 +148,10 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts, // We treat bridge casts as objective-C keywords so we can warn on them // in non-arc mode. if (LangOpts.ObjC2 && (Flags & KEYARC)) return KS_Enabled; - if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS)) return KS_Enabled; if (LangOpts.ObjC2 && (Flags & KEYOBJC2)) return KS_Enabled; - if (LangOpts.Coroutines && (Flags & KEYCOROUTINES)) return KS_Enabled; + if (LangOpts.ConceptsTS && (Flags & KEYCONCEPTS)) return KS_Enabled; + if (LangOpts.CoroutinesTS && (Flags & KEYCOROUTINES)) return KS_Enabled; + if (LangOpts.ModulesTS && (Flags & KEYMODULES)) return KS_Enabled; if (LangOpts.CPlusPlus && (Flags & KEYCXX11)) return KS_Future; return KS_Disabled; } @@ -441,9 +443,11 @@ std::string Selector::getAsString() const { if (getIdentifierInfoFlag() < MultiArg) { IdentifierInfo *II = getAsIdentifierInfo(); - // If the number of arguments is 0 then II is guaranteed to not be null. - if (getNumArgs() == 0) + if (getNumArgs() == 0) { + assert(II && "If the number of arguments is 0 then II is guaranteed to " + "not be null."); return II->getName(); + } if (!II) return ":"; @@ -619,8 +623,8 @@ Selector SelectorTable::getSelector(unsigned nKeys, IdentifierInfo **IIV) { // variable size array (for parameter types) at the end of them. unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *); MultiKeywordSelector *SI = - (MultiKeywordSelector*)SelTabImpl.Allocator.Allocate(Size, - llvm::alignOf<MultiKeywordSelector>()); + (MultiKeywordSelector *)SelTabImpl.Allocator.Allocate( + Size, alignof(MultiKeywordSelector)); new (SI) MultiKeywordSelector(nKeys, IIV); SelTabImpl.Table.InsertNode(SI, InsertPos); return Selector(SI); diff --git a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp index 8c0ecd4..ff10a77 100644 --- a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp @@ -15,7 +15,8 @@ using namespace clang; -LangOptions::LangOptions() { +LangOptions::LangOptions() + : IsHeaderFile(false) { #define LANGOPT(Name, Bits, Default, Description) Name = Default; #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default); #include "clang/Basic/LangOptions.def" @@ -34,10 +35,10 @@ void LangOptions::resetNonModularOptions() { SanitizerBlacklistFiles.clear(); CurrentModule.clear(); + IsHeaderFile = false; } -bool LangOptions::isNoBuiltinFunc(const char *Name) const { - StringRef FuncName(Name); +bool LangOptions::isNoBuiltinFunc(StringRef FuncName) const { for (unsigned i = 0, e = NoBuiltinFuncs.size(); i != e; ++i) if (FuncName.equals(NoBuiltinFuncs[i])) return true; diff --git a/contrib/llvm/tools/clang/lib/Basic/Module.cpp b/contrib/llvm/tools/clang/lib/Basic/Module.cpp index 3d1a40d..80bbc24 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Module.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Module.cpp @@ -33,7 +33,7 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), InferExportWildcard(false), ConfigMacrosExhaustive(false), - NameVisibility(Hidden) { + NoUndeclaredIncludes(false), NameVisibility(Hidden) { if (Parent) { if (!Parent->isAvailable()) IsAvailable = false; @@ -41,6 +41,8 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, IsSystem = true; if (Parent->IsExternC) IsExternC = true; + if (Parent->NoUndeclaredIncludes) + NoUndeclaredIncludes = true; IsMissingRequirement = Parent->IsMissingRequirement; Parent->SubModuleIndex[Name] = Parent->SubModules.size(); @@ -64,6 +66,8 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, .Case("blocks", LangOpts.Blocks) .Case("cplusplus", LangOpts.CPlusPlus) .Case("cplusplus11", LangOpts.CPlusPlus11) + .Case("freestanding", LangOpts.Freestanding) + .Case("gnuinlineasm", LangOpts.GNUAsm) .Case("objc", LangOpts.ObjC1) .Case("objc_arc", LangOpts.ObjCAutoRefCount) .Case("opencl", LangOpts.OpenCL) @@ -179,6 +183,11 @@ bool Module::directlyUses(const Module *Requested) const { for (auto *Use : Top->DirectUses) if (Requested->isSubModuleOf(Use)) return true; + + // Anyone is allowed to use our builtin stddef.h and its accompanying module. + if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") + return true; + return false; } diff --git a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp index d1e4779..905c369 100644 --- a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp @@ -610,6 +610,106 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_target_simd: + switch (CKind) { +#define OPENMP_TARGET_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_teams_distribute: + switch (CKind) { +#define OPENMP_TEAMS_DISTRIBUTE_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_teams_distribute_simd: + switch (CKind) { +#define OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_teams_distribute_parallel_for_simd: + switch (CKind) { +#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_teams_distribute_parallel_for: + switch (CKind) { +#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_teams: + switch (CKind) { +#define OPENMP_TARGET_TEAMS_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_teams_distribute: + switch (CKind) { +#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_teams_distribute_parallel_for: + switch (CKind) { +#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_teams_distribute_parallel_for_simd: + switch (CKind) { +#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_teams_distribute_simd: + switch (CKind) { +#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; case OMPD_declare_target: case OMPD_end_declare_target: case OMPD_unknown: @@ -635,8 +735,15 @@ bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_distribute_parallel_for || DKind == OMPD_distribute_parallel_for_simd || DKind == OMPD_distribute_simd || - DKind == OMPD_target_parallel_for_simd; - // TODO add next directives. + DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd || + DKind == OMPD_teams_distribute || + DKind == OMPD_teams_distribute_simd || + DKind == OMPD_teams_distribute_parallel_for_simd || + DKind == OMPD_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute || + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_simd; } bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { @@ -647,8 +754,11 @@ bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_target_parallel_for || DKind == OMPD_distribute_parallel_for || DKind == OMPD_distribute_parallel_for_simd || - DKind == OMPD_target_parallel_for_simd; - // TODO add next directives. + DKind == OMPD_target_parallel_for_simd || + DKind == OMPD_teams_distribute_parallel_for_simd || + DKind == OMPD_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd; } bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) { @@ -661,15 +771,21 @@ bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_target_parallel || DKind == OMPD_target_parallel_for || DKind == OMPD_distribute_parallel_for || DKind == OMPD_distribute_parallel_for_simd || - DKind == OMPD_target_parallel_for_simd; - // TODO add next directives. + DKind == OMPD_target_parallel_for_simd || + DKind == OMPD_teams_distribute_parallel_for || + DKind == OMPD_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd; } bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) { - // TODO add next directives. return DKind == OMPD_target || DKind == OMPD_target_parallel || DKind == OMPD_target_parallel_for || - DKind == OMPD_target_parallel_for_simd; + DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd || + DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute || + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_simd; } bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) { @@ -677,25 +793,50 @@ bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) { DKind == OMPD_target_exit_data || DKind == OMPD_target_update; } +bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) { + return DKind == OMPD_teams || DKind == OMPD_teams_distribute || + DKind == OMPD_teams_distribute_simd || + DKind == OMPD_teams_distribute_parallel_for_simd || + DKind == OMPD_teams_distribute_parallel_for; +} + bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) { - return DKind == OMPD_teams; // TODO add next directives. + return isOpenMPNestingTeamsDirective(DKind) || + DKind == OMPD_target_teams || DKind == OMPD_target_teams_distribute || + DKind == OMPD_target_teams_distribute_parallel_for || + DKind == OMPD_target_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_simd; } bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_simd || DKind == OMPD_for_simd || DKind == OMPD_parallel_for_simd || DKind == OMPD_taskloop_simd || DKind == OMPD_distribute_parallel_for_simd || - DKind == OMPD_distribute_simd; - // TODO add next directives. + DKind == OMPD_distribute_simd || DKind == OMPD_target_simd || + DKind == OMPD_teams_distribute_simd || + DKind == OMPD_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_parallel_for_simd || + DKind == OMPD_target_teams_distribute_simd; } -bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) { +bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) { return Kind == OMPD_distribute || Kind == OMPD_distribute_parallel_for || Kind == OMPD_distribute_parallel_for_simd || Kind == OMPD_distribute_simd; // TODO add next directives. } +bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) { + return isOpenMPNestingDistributeDirective(Kind) || + Kind == OMPD_teams_distribute || Kind == OMPD_teams_distribute_simd || + Kind == OMPD_teams_distribute_parallel_for_simd || + Kind == OMPD_teams_distribute_parallel_for || + Kind == OMPD_target_teams_distribute || + Kind == OMPD_target_teams_distribute_parallel_for || + Kind == OMPD_target_teams_distribute_parallel_for_simd || + Kind == OMPD_target_teams_distribute_simd; +} + bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) { return Kind == OMPC_private || Kind == OMPC_firstprivate || Kind == OMPC_lastprivate || Kind == OMPC_linear || @@ -713,5 +854,12 @@ bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) { bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) { return Kind == OMPD_distribute_parallel_for || Kind == OMPD_distribute_parallel_for_simd || - Kind == OMPD_distribute_simd; + Kind == OMPD_distribute_simd || Kind == OMPD_teams_distribute || + Kind == OMPD_teams_distribute_simd || + Kind == OMPD_teams_distribute_parallel_for_simd || + Kind == OMPD_teams_distribute_parallel_for || + Kind == OMPD_target_teams_distribute || + Kind == OMPD_target_teams_distribute_parallel_for || + Kind == OMPD_target_teams_distribute_parallel_for_simd || + Kind == OMPD_target_teams_distribute_simd; } diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp index d254e86..a58d046 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp @@ -14,7 +14,6 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/SourceManager.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" #include <cstdio> using namespace clang; diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp index 1e83b63..380ca37 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp @@ -25,7 +25,6 @@ #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cstring> -#include <string> using namespace clang; using namespace SrcMgr; @@ -387,8 +386,6 @@ SourceManager::~SourceManager() { ContentCacheAlloc.Deallocate(I->second); } } - - llvm::DeleteContainerSeconds(MacroArgsCacheMap); } void SourceManager::clearIDTables() { @@ -1438,8 +1435,8 @@ SourceManager::getFileCharacteristic(SourceLocation Loc) const { /// Return the filename or buffer identifier of the buffer the location is in. /// Note that this name does not respect \#line directives. Use getPresumedLoc /// for normal clients. -const char *SourceManager::getBufferName(SourceLocation Loc, - bool *Invalid) const { +StringRef SourceManager::getBufferName(SourceLocation Loc, + bool *Invalid) const { if (isInvalid(Loc, Invalid)) return "<invalid loc>"; return getBuffer(getFileID(Loc), Invalid)->getBufferIdentifier(); @@ -1471,7 +1468,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, // To get the source name, first consult the FileEntry (if one exists) // before the MemBuffer as this will avoid unnecessarily paging in the // MemBuffer. - const char *Filename; + StringRef Filename; if (C->OrigEntry) Filename = C->OrigEntry->getName(); else @@ -1514,7 +1511,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, } } - return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc); + return PresumedLoc(Filename.data(), LineNo, ColNo, IncludeLoc); } /// \brief Returns whether the PresumedLoc for a given SourceLocation is @@ -1785,13 +1782,10 @@ SourceLocation SourceManager::translateLineCol(FileID FID, /// 0 -> SourceLocation() /// 100 -> Expanded macro arg location /// 110 -> SourceLocation() -void SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr, +void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache, FileID FID) const { assert(FID.isValid()); - assert(!CachePtr); - CachePtr = new MacroArgsMap(); - MacroArgsMap &MacroArgsCache = *CachePtr; // Initially no macro argument chunk is present. MacroArgsCache.insert(std::make_pair(0, SourceLocation())); @@ -1941,9 +1935,11 @@ SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const { if (FID.isInvalid()) return Loc; - MacroArgsMap *&MacroArgsCache = MacroArgsCacheMap[FID]; - if (!MacroArgsCache) - computeMacroArgsCache(MacroArgsCache, FID); + std::unique_ptr<MacroArgsMap> &MacroArgsCache = MacroArgsCacheMap[FID]; + if (!MacroArgsCache) { + MacroArgsCache = llvm::make_unique<MacroArgsMap>(); + computeMacroArgsCache(*MacroArgsCache, FID); + } assert(!MacroArgsCache->empty()); MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset); @@ -2096,10 +2092,10 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, // Clear the lookup cache, it depends on a common location. IsBeforeInTUCache.clear(); - const char *LB = getBuffer(LOffs.first)->getBufferIdentifier(); - const char *RB = getBuffer(ROffs.first)->getBufferIdentifier(); - bool LIsBuiltins = strcmp("<built-in>", LB) == 0; - bool RIsBuiltins = strcmp("<built-in>", RB) == 0; + StringRef LB = getBuffer(LOffs.first)->getBufferIdentifier(); + StringRef RB = getBuffer(ROffs.first)->getBufferIdentifier(); + bool LIsBuiltins = LB == "<built-in>"; + bool RIsBuiltins = RB == "<built-in>"; // Sort built-in before non-built-in. if (LIsBuiltins || RIsBuiltins) { if (LIsBuiltins != RIsBuiltins) @@ -2108,8 +2104,8 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, // lower IDs come first. return LOffs.first < ROffs.first; } - bool LIsAsm = strcmp("<inline asm>", LB) == 0; - bool RIsAsm = strcmp("<inline asm>", RB) == 0; + bool LIsAsm = LB == "<inline asm>"; + bool RIsAsm = RB == "<inline asm>"; // Sort assembler after built-ins, but before the rest. if (LIsAsm || RIsAsm) { if (LIsAsm != RIsAsm) @@ -2117,8 +2113,8 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, assert(LOffs.first == ROffs.first); return false; } - bool LIsScratch = strcmp("<scratch space>", LB) == 0; - bool RIsScratch = strcmp("<scratch space>", RB) == 0; + bool LIsScratch = LB == "<scratch space>"; + bool RIsScratch = RB == "<scratch space>"; // Sort scratch after inline asm, but before the rest. if (LIsScratch || RIsScratch) { if (LIsScratch != RIsScratch) diff --git a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp index 92f658a..b1b01e5 100644 --- a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp @@ -27,7 +27,7 @@ static const LangAS::Map DefaultAddrSpaceMap = { 0 }; TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { // Set defaults. Defaults are set for a 32-bit RISC platform, like PPC or // SPARC. These should be overridden by concrete targets as needed. - BigEndian = true; + BigEndian = !T.isLittleEndian(); TLSSupported = true; NoAsmVariants = false; HasFloat128 = false; @@ -39,6 +39,13 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { SuitableAlign = 64; DefaultAlignForAttributeAligned = 128; MinGlobalAlign = 0; + // 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 + if (T.isGNUEnvironment()) + NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0; + else + NewAlign = 0; // Infer from basic type alignment. HalfWidth = 16; HalfAlign = 16; FloatWidth = 32; @@ -70,16 +77,17 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { UseZeroLengthBitfieldAlignment = false; UseExplicitBitFieldAlignment = true; ZeroLengthBitfieldBoundary = 0; - HalfFormat = &llvm::APFloat::IEEEhalf; - FloatFormat = &llvm::APFloat::IEEEsingle; - DoubleFormat = &llvm::APFloat::IEEEdouble; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; - Float128Format = &llvm::APFloat::IEEEquad; + HalfFormat = &llvm::APFloat::IEEEhalf(); + FloatFormat = &llvm::APFloat::IEEEsingle(); + DoubleFormat = &llvm::APFloat::IEEEdouble(); + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); + Float128Format = &llvm::APFloat::IEEEquad(); MCountName = "mcount"; RegParmMax = 0; SSERegParmMax = 0; HasAlignMac68kSupport = false; HasBuiltinMSVaList = false; + IsRenderScriptTarget = false; // Default to no types using fpret. RealTypeUsesObjCFPRet = 0; @@ -219,12 +227,12 @@ TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const { switch (BitWidth) { case 96: - if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended) + if (&getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended()) return LongDouble; break; case 128: - if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble || - &getLongDoubleFormat() == &llvm::APFloat::IEEEquad) + if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble() || + &getLongDoubleFormat() == &llvm::APFloat::IEEEquad()) return LongDouble; if (hasFloat128Type()) return Float128; @@ -301,12 +309,13 @@ void TargetInfo::adjust(const LangOptions &Opts) { // to generating illegal code that uses 64bit doubles. if (DoubleWidth != FloatWidth) { DoubleWidth = DoubleAlign = 64; - DoubleFormat = &llvm::APFloat::IEEEdouble; + DoubleFormat = &llvm::APFloat::IEEEdouble(); } LongDoubleWidth = LongDoubleAlign = 128; - assert(PointerWidth == 32 || PointerWidth == 64); - bool Is32BitArch = PointerWidth == 32; + unsigned MaxPointerWidth = getMaxPointerWidth(); + assert(MaxPointerWidth == 32 || MaxPointerWidth == 64); + bool Is32BitArch = MaxPointerWidth == 32; SizeType = Is32BitArch ? UnsignedInt : UnsignedLong; PtrDiffType = Is32BitArch ? SignedInt : SignedLong; IntPtrType = Is32BitArch ? SignedInt : SignedLong; @@ -314,10 +323,13 @@ void TargetInfo::adjust(const LangOptions &Opts) { IntMaxType = SignedLongLong; Int64Type = SignedLong; - HalfFormat = &llvm::APFloat::IEEEhalf; - FloatFormat = &llvm::APFloat::IEEEsingle; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + HalfFormat = &llvm::APFloat::IEEEhalf(); + FloatFormat = &llvm::APFloat::IEEEsingle(); + LongDoubleFormat = &llvm::APFloat::IEEEquad(); } + + if (Opts.NewAlignOverride) + NewAlign = Opts.NewAlignOverride * getCharWidth(); } bool TargetInfo::initFeatureMap( @@ -398,8 +410,8 @@ bool TargetInfo::isValidGCCRegisterName(StringRef Name) const { return false; } -StringRef -TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const { +StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name, + bool ReturnCanonical) const { assert(isValidGCCRegisterName(Name) && "Invalid register passed in"); // Get rid of any register prefix. @@ -424,7 +436,7 @@ TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const { // Make sure the register that the additional name is for is within // the bounds of the register names from above. if (AN == Name && ARN.RegNum < Names.size()) - return Name; + return ReturnCanonical ? Names[ARN.RegNum] : Name; } // Now check aliases. diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index be5d4ad..1a95ff2 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -21,6 +21,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Basic/Version.h" +#include "clang/Frontend/CodeGenOptions.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" @@ -464,6 +465,8 @@ protected: Triple.getEnvironmentVersion(Maj, Min, Rev); this->PlatformName = "android"; this->PlatformMinVersion = VersionTuple(Maj, Min, Rev); + if (Maj) + Builder.defineMacro("__ANDROID_API__", Twine(Maj)); } if (Opts.POSIXThreads) Builder.defineMacro("_REENTRANT"); @@ -509,7 +512,7 @@ protected: Builder.defineMacro("__unix__"); Builder.defineMacro("__ELF__"); if (Opts.POSIXThreads) - Builder.defineMacro("_POSIX_THREADS"); + Builder.defineMacro("_REENTRANT"); switch (Triple.getArch()) { default: @@ -805,8 +808,8 @@ public: this->SizeType = TargetInfo::UnsignedInt; this->PtrDiffType = TargetInfo::SignedInt; this->IntPtrType = TargetInfo::SignedInt; - // RegParmMax is inherited from the underlying architecture - this->LongDoubleFormat = &llvm::APFloat::IEEEdouble; + // RegParmMax is inherited from the underlying architecture. + this->LongDoubleFormat = &llvm::APFloat::IEEEdouble(); if (Triple.getArch() == llvm::Triple::arm) { // Handled in ARM's setABI(). } else if (Triple.getArch() == llvm::Triple::x86) { @@ -822,6 +825,28 @@ public: } }; +// Fuchsia Target +template<typename Target> +class FuchsiaTargetInfo : public OSTargetInfo<Target> { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + Builder.defineMacro("__Fuchsia__"); + Builder.defineMacro("__ELF__"); + if (Opts.POSIXThreads) + Builder.defineMacro("_REENTRANT"); + // Required by the libc++ locale support. + if (Opts.CPlusPlus) + Builder.defineMacro("_GNU_SOURCE"); + } +public: + FuchsiaTargetInfo(const llvm::Triple &Triple, + const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { + this->MCountName = "__mcount"; + } +}; + // WebAssembly target template <typename Target> class WebAssemblyOSTargetInfo : public OSTargetInfo<Target> { @@ -869,6 +894,7 @@ class PPCTargetInfo : public TargetInfo { bool HasHTM; bool HasBPERMD; bool HasExtDiv; + bool HasP9Vector; protected: std::string ABI; @@ -877,11 +903,10 @@ public: PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple), HasVSX(false), HasP8Vector(false), HasP8Crypto(false), HasDirectMove(false), HasQPX(false), HasHTM(false), - HasBPERMD(false), HasExtDiv(false) { - BigEndian = (Triple.getArch() != llvm::Triple::ppc64le); + HasBPERMD(false), HasExtDiv(false), HasP9Vector(false) { SimdDefaultAlign = 128; LongDoubleWidth = LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; + LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble(); } /// \brief Flags for architecture specific defines. @@ -1121,7 +1146,7 @@ public: bool useFloat128ManglingForLongDouble() const override { return LongDoubleWidth == 128 && - LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble && + LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble() && getTriple().isOSBinFormatELF(); } }; @@ -1157,6 +1182,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasHTM = true; } else if (Feature == "+float128") { HasFloat128 = true; + } else if (Feature == "+power9-vector") { + HasP9Vector = true; } // TODO: Finish this list and add an assert that we've handled them // all. @@ -1326,6 +1353,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__HTM__"); if (HasFloat128) Builder.defineMacro("__FLOAT128__"); + if (HasP9Vector) + Builder.defineMacro("__POWER9_VECTOR__"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); @@ -1355,8 +1384,12 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, } // Handle explicit options being passed to the compiler here: if we've -// explicitly turned off vsx and turned on power8-vector or direct-move then -// go ahead and error since the customer has expressed a somewhat incompatible +// explicitly turned off vsx and turned on any of: +// - power8-vector +// - direct-move +// - float128 +// - power9-vector +// then go ahead and error since the customer has expressed an incompatible // set of options. static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, const std::vector<std::string> &FeaturesVec) { @@ -1383,6 +1416,13 @@ static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, << "-mno-vsx"; return false; } + + if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+power9-vector") != + FeaturesVec.end()) { + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mpower9-vector" + << "-mno-vsx"; + return false; + } } return true; @@ -1407,6 +1447,7 @@ bool PPCTargetInfo::initFeatureMap( .Default(false); Features["qpx"] = (CPU == "a2q"); + Features["power9-vector"] = (CPU == "pwr9"); Features["crypto"] = llvm::StringSwitch<bool>(CPU) .Case("ppc64le", true) .Case("pwr9", true) @@ -1459,6 +1500,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const { .Case("bpermd", HasBPERMD) .Case("extdiv", HasExtDiv) .Case("float128", HasFloat128) + .Case("power9-vector", HasP9Vector) .Default(false); } @@ -1468,19 +1510,21 @@ void PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, // as well. Do the inverse if we're disabling vsx. We'll diagnose any user // incompatible options. if (Enabled) { - if (Name == "direct-move") { - Features[Name] = Features["vsx"] = true; - } else if (Name == "power8-vector") { - Features[Name] = Features["vsx"] = true; - } else if (Name == "float128") { + if (Name == "direct-move" || + Name == "power8-vector" || + Name == "float128" || + Name == "power9-vector") { + // power9-vector is really a superset of power8-vector so encode that. Features[Name] = Features["vsx"] = true; + if (Name == "power9-vector") + Features["power8-vector"] = true; } else { Features[Name] = true; } } else { if (Name == "vsx") { Features[Name] = Features["direct-move"] = Features["power8-vector"] = - Features["float128"] = false; + Features["float128"] = Features["power9-vector"] = false; } else { Features[Name] = false; } @@ -1606,7 +1650,7 @@ public: if (getTriple().getOS() == llvm::Triple::FreeBSD) { LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } // PPC32 supports atomics up to 4 bytes. @@ -1640,7 +1684,7 @@ public: switch (getTriple().getOS()) { case llvm::Triple::FreeBSD: LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); break; case llvm::Triple::NetBSD: IntMaxType = SignedLongLong; @@ -1707,31 +1751,57 @@ class NVPTXTargetInfo : public TargetInfo { static const char *const GCCRegNames[]; static const Builtin::Info BuiltinInfo[]; CudaArch GPU; + std::unique_ptr<TargetInfo> HostTarget; public: - NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts, + unsigned TargetPointerWidth) : TargetInfo(Triple) { - BigEndian = false; + assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) && + "NVPTX only supports 32- and 64-bit modes."); + TLSSupported = false; - LongWidth = LongAlign = 64; AddrSpaceMap = &NVPTXAddrSpaceMap; UseAddrSpaceMapMangling = true; + // Define available target features // These must be defined in sorted order! NoAsmVariants = true; GPU = CudaArch::SM_20; + if (TargetPointerWidth == 32) + resetDataLayout("e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"); + else + resetDataLayout("e-i64:64-v16:16-v32:32-n16:32:64"); + // If possible, get a TargetInfo for our host triple, so we can match its // types. llvm::Triple HostTriple(Opts.HostTriple); - if (HostTriple.isNVPTX()) - return; - std::unique_ptr<TargetInfo> HostTarget( - AllocateTarget(llvm::Triple(Opts.HostTriple), Opts)); + if (!HostTriple.isNVPTX()) + HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts)); + + // If no host target, make some guesses about the data layout and return. if (!HostTarget) { + LongWidth = LongAlign = TargetPointerWidth; + PointerWidth = PointerAlign = TargetPointerWidth; + switch (TargetPointerWidth) { + case 32: + SizeType = TargetInfo::UnsignedInt; + PtrDiffType = TargetInfo::SignedInt; + IntPtrType = TargetInfo::SignedInt; + break; + case 64: + SizeType = TargetInfo::UnsignedLong; + PtrDiffType = TargetInfo::SignedLong; + IntPtrType = TargetInfo::SignedLong; + break; + default: + llvm_unreachable("TargetPointerWidth must be 32 or 64"); + } return; } + // Copy properties from host target. PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0); PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0); BoolWidth = HostTarget->getBoolWidth(); @@ -1749,6 +1819,7 @@ public: LongLongWidth = HostTarget->getLongLongWidth(); LongLongAlign = HostTarget->getLongLongAlign(); MinGlobalAlign = HostTarget->getMinGlobalAlign(); + NewAlign = HostTarget->getNewAlign(); DefaultAlignForAttributeAligned = HostTarget->getDefaultAlignForAttributeAligned(); SizeType = HostTarget->getSizeType(); @@ -1769,6 +1840,12 @@ public: UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment(); ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary(); + // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and + // we need those macros to be identical on host and device, because (among + // other things) they affect which standard library classes are defined, and + // we need all classes to be defined on both the host and device. + MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth(); + // Properties intentionally not copied from host: // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the // host/device boundary. @@ -1825,8 +1902,19 @@ public: return llvm::makeArrayRef(BuiltinInfo, clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin); } + bool + initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, + StringRef CPU, + const std::vector<std::string> &FeaturesVec) const override { + Features["satom"] = GPU >= CudaArch::SM_60; + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); + } + bool hasFeature(StringRef Feature) const override { - return Feature == "ptx" || Feature == "nvptx"; + return llvm::StringSwitch<bool>(Feature) + .Cases("ptx", "nvptx", true) + .Case("satom", GPU >= CudaArch::SM_60) // Atomics w/ scope. + .Default(false); } ArrayRef<const char *> getGCCRegNames() const override; @@ -1863,16 +1951,26 @@ public: } void setSupportedOpenCLOpts() override { auto &Opts = getSupportedOpenCLOpts(); - Opts.cl_clang_storage_class_specifiers = 1; - Opts.cl_khr_gl_sharing = 1; - Opts.cl_khr_icd = 1; + Opts.support("cl_clang_storage_class_specifiers"); + Opts.support("cl_khr_gl_sharing"); + Opts.support("cl_khr_icd"); + + Opts.support("cl_khr_fp64"); + Opts.support("cl_khr_byte_addressable_store"); + Opts.support("cl_khr_global_int32_base_atomics"); + Opts.support("cl_khr_global_int32_extended_atomics"); + Opts.support("cl_khr_local_int32_base_atomics"); + Opts.support("cl_khr_local_int32_extended_atomics"); + } - Opts.cl_khr_fp64 = 1; - Opts.cl_khr_byte_addressable_store = 1; - Opts.cl_khr_global_int32_base_atomics = 1; - Opts.cl_khr_global_int32_extended_atomics = 1; - Opts.cl_khr_local_int32_base_atomics = 1; - Opts.cl_khr_local_int32_extended_atomics = 1; + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + // CUDA compilations support all of the host's calling conventions. + // + // TODO: We should warn if you apply a non-default CC to anything other than + // a host function. + if (HostTarget) + return HostTarget->checkCallingConvention(CC); + return CCCR_Warning; } }; @@ -1881,6 +1979,8 @@ const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = { { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, #include "clang/Basic/BuiltinsNVPTX.def" }; @@ -1890,31 +1990,6 @@ ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const { return llvm::makeArrayRef(GCCRegNames); } -class NVPTX32TargetInfo : public NVPTXTargetInfo { -public: - NVPTX32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : NVPTXTargetInfo(Triple, Opts) { - LongWidth = LongAlign = 32; - PointerWidth = PointerAlign = 32; - SizeType = TargetInfo::UnsignedInt; - PtrDiffType = TargetInfo::SignedInt; - IntPtrType = TargetInfo::SignedInt; - resetDataLayout("e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"); - } -}; - -class NVPTX64TargetInfo : public NVPTXTargetInfo { -public: - NVPTX64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : NVPTXTargetInfo(Triple, Opts) { - PointerWidth = PointerAlign = 64; - SizeType = TargetInfo::UnsignedLong; - PtrDiffType = TargetInfo::SignedLong; - IntPtrType = TargetInfo::SignedLong; - resetDataLayout("e-i64:64-v16:16-v32:32-n16:32:64"); - } -}; - static const unsigned AMDGPUAddrSpaceMap[] = { 1, // opencl_global 3, // opencl_local @@ -1952,26 +2027,28 @@ class AMDGPUTargetInfo final : public TargetInfo { GK_EVERGREEN_DOUBLE_OPS, GK_NORTHERN_ISLANDS, GK_CAYMAN, - GK_SOUTHERN_ISLANDS, - GK_SEA_ISLANDS, - GK_VOLCANIC_ISLANDS + GK_GFX6, + GK_GFX7, + GK_GFX8 } GPU; bool hasFP64:1; bool hasFMAF:1; bool hasLDEXPF:1; + bool hasFullSpeedFP32Denorms:1; static bool isAMDGCN(const llvm::Triple &TT) { return TT.getArch() == llvm::Triple::amdgcn; } public: - AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple) , - GPU(isAMDGCN(Triple) ? GK_SOUTHERN_ISLANDS : GK_R600), + GPU(isAMDGCN(Triple) ? GK_GFX6 : GK_R600), hasFP64(false), hasFMAF(false), - hasLDEXPF(false) { + hasLDEXPF(false), + hasFullSpeedFP32Denorms(false){ if (getTriple().getArch() == llvm::Triple::amdgcn) { hasFP64 = true; hasFMAF = true; @@ -1999,6 +2076,10 @@ public: } } + uint64_t getMaxPointerWidth() const override { + return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32; + } + const char * getClobbers() const override { return ""; } @@ -2025,6 +2106,24 @@ public: DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeatureVec) const override; + void adjustTargetOptions(const CodeGenOptions &CGOpts, + TargetOptions &TargetOpts) const override { + bool hasFP32Denormals = false; + bool hasFP64Denormals = false; + for (auto &I : TargetOpts.FeaturesAsWritten) { + if (I == "+fp32-denormals" || I == "-fp32-denormals") + hasFP32Denormals = true; + if (I == "+fp64-denormals" || I == "-fp64-denormals") + hasFP64Denormals = true; + } + if (!hasFP32Denormals) + TargetOpts.Features.push_back((Twine(hasFullSpeedFP32Denorms && + !CGOpts.FlushDenorm ? '+' : '-') + Twine("fp32-denormals")).str()); + // Always do not flush fp64 denorms. + if (!hasFP64Denormals && hasFP64) + TargetOpts.Features.push_back("+fp64-denormals"); + } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { return llvm::makeArrayRef(BuiltinInfo, clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin); @@ -2081,23 +2180,32 @@ public: static GPUKind parseAMDGCNName(StringRef Name) { return llvm::StringSwitch<GPUKind>(Name) - .Case("tahiti", GK_SOUTHERN_ISLANDS) - .Case("pitcairn", GK_SOUTHERN_ISLANDS) - .Case("verde", GK_SOUTHERN_ISLANDS) - .Case("oland", GK_SOUTHERN_ISLANDS) - .Case("hainan", GK_SOUTHERN_ISLANDS) - .Case("bonaire", GK_SEA_ISLANDS) - .Case("kabini", GK_SEA_ISLANDS) - .Case("kaveri", GK_SEA_ISLANDS) - .Case("hawaii", GK_SEA_ISLANDS) - .Case("mullins", GK_SEA_ISLANDS) - .Case("tonga", GK_VOLCANIC_ISLANDS) - .Case("iceland", GK_VOLCANIC_ISLANDS) - .Case("carrizo", GK_VOLCANIC_ISLANDS) - .Case("fiji", GK_VOLCANIC_ISLANDS) - .Case("stoney", GK_VOLCANIC_ISLANDS) - .Case("polaris10", GK_VOLCANIC_ISLANDS) - .Case("polaris11", GK_VOLCANIC_ISLANDS) + .Case("tahiti", GK_GFX6) + .Case("pitcairn", GK_GFX6) + .Case("verde", GK_GFX6) + .Case("oland", GK_GFX6) + .Case("hainan", GK_GFX6) + .Case("bonaire", GK_GFX7) + .Case("kabini", GK_GFX7) + .Case("kaveri", GK_GFX7) + .Case("hawaii", GK_GFX7) + .Case("mullins", GK_GFX7) + .Case("gfx700", GK_GFX7) + .Case("gfx701", GK_GFX7) + .Case("gfx702", GK_GFX7) + .Case("tonga", GK_GFX8) + .Case("iceland", GK_GFX8) + .Case("carrizo", GK_GFX8) + .Case("fiji", GK_GFX8) + .Case("stoney", GK_GFX8) + .Case("polaris10", GK_GFX8) + .Case("polaris11", GK_GFX8) + .Case("gfx800", GK_GFX8) + .Case("gfx801", GK_GFX8) + .Case("gfx802", GK_GFX8) + .Case("gfx803", GK_GFX8) + .Case("gfx804", GK_GFX8) + .Case("gfx810", GK_GFX8) .Default(GK_NONE); } @@ -2112,26 +2220,34 @@ public: void setSupportedOpenCLOpts() override { auto &Opts = getSupportedOpenCLOpts(); - Opts.cl_clang_storage_class_specifiers = 1; - Opts.cl_khr_icd = 1; + Opts.support("cl_clang_storage_class_specifiers"); + Opts.support("cl_khr_icd"); if (hasFP64) - Opts.cl_khr_fp64 = 1; + Opts.support("cl_khr_fp64"); if (GPU >= GK_EVERGREEN) { - Opts.cl_khr_byte_addressable_store = 1; - Opts.cl_khr_global_int32_base_atomics = 1; - Opts.cl_khr_global_int32_extended_atomics = 1; - Opts.cl_khr_local_int32_base_atomics = 1; - Opts.cl_khr_local_int32_extended_atomics = 1; + Opts.support("cl_khr_byte_addressable_store"); + Opts.support("cl_khr_global_int32_base_atomics"); + Opts.support("cl_khr_global_int32_extended_atomics"); + Opts.support("cl_khr_local_int32_base_atomics"); + Opts.support("cl_khr_local_int32_extended_atomics"); } - if (GPU >= GK_SOUTHERN_ISLANDS) { - Opts.cl_khr_fp16 = 1; - Opts.cl_khr_int64_base_atomics = 1; - Opts.cl_khr_int64_extended_atomics = 1; - Opts.cl_khr_3d_image_writes = 1; + if (GPU >= GK_GFX6) { + Opts.support("cl_khr_fp16"); + Opts.support("cl_khr_int64_base_atomics"); + Opts.support("cl_khr_int64_extended_atomics"); + Opts.support("cl_khr_mipmap_image"); + Opts.support("cl_khr_subgroups"); + Opts.support("cl_khr_3d_image_writes"); + Opts.support("cl_amd_media_ops"); + Opts.support("cl_amd_media_ops2"); } } + LangAS::ID getOpenCLImageAddrSpace() const override { + return LangAS::opencl_constant; + } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { switch (CC) { default: @@ -2141,6 +2257,13 @@ public: return CCCR_OK; } } + + // In amdgcn target the null pointer in global, constant, and generic + // address space has value 0 but in private and local address space has + // value ~0. + uint64_t getNullPointerValue(unsigned AS) const override { + return AS != LangAS::opencl_local && AS != 0 ? 0 : ~0; + } }; const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = { @@ -2218,11 +2341,11 @@ bool AMDGPUTargetInfo::initFeatureMap( CPU = "tahiti"; switch (parseAMDGCNName(CPU)) { - case GK_SOUTHERN_ISLANDS: - case GK_SEA_ISLANDS: + case GK_GFX6: + case GK_GFX7: break; - case GK_VOLCANIC_ISLANDS: + case GK_GFX8: Features["s-memrealtime"] = true; Features["16-bit-insts"] = true; break; @@ -2258,17 +2381,25 @@ bool AMDGPUTargetInfo::initFeatureMap( return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); } -// Namespace for x86 abstract base class -const Builtin::Info BuiltinInfo[] = { +const Builtin::Info BuiltinInfoX86[] = { #define BUILTIN(ID, TYPE, ATTRS) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, -#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ - { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, #include "clang/Basic/BuiltinsX86.def" + +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr }, +#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ + { #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, +#include "clang/Basic/BuiltinsX86_64.def" }; + static const char* const GCCRegNames[] = { "ax", "dx", "cx", "bx", "si", "di", "bp", "sp", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", @@ -2287,6 +2418,7 @@ static const char* const GCCRegNames[] = { "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", "zmm16", "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm24", "zmm25", "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31", + "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7", }; const TargetInfo::AddlRegName AddlRegNames[] = { @@ -2531,6 +2663,12 @@ class X86TargetInfo : public TargetInfo { CK_BDVER4, //@} + /// \name zen + /// Zen architecture processors. + //@{ + CK_ZNVER1, + //@} + /// This specification is deprecated and will be removed in the future. /// Users should prefer \see CK_K8. // FIXME: Warn on this when the CPU is set to it. @@ -2612,6 +2750,7 @@ class X86TargetInfo : public TargetInfo { .Case("bdver2", CK_BDVER2) .Case("bdver3", CK_BDVER3) .Case("bdver4", CK_BDVER4) + .Case("znver1", CK_ZNVER1) .Case("x86-64", CK_x86_64) .Case("geode", CK_Geode) .Default(CK_Generic); @@ -2626,17 +2765,12 @@ class X86TargetInfo : public TargetInfo { public: X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - BigEndian = false; - LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; + LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); } unsigned getFloatEvalMethod() const override { // X87 evaluates with 80 bits "long double" precision. return SSELevel == NoSSE ? 2 : 0; } - ArrayRef<Builtin::Info> getTargetBuiltins() const override { - return llvm::makeArrayRef(BuiltinInfo, - clang::X86::LastTSBuiltin-Builtin::FirstTSBuiltin); - } ArrayRef<const char *> getGCCRegNames() const override { return llvm::makeArrayRef(GCCRegNames); } @@ -2674,6 +2808,40 @@ public: const char *getClobbers() const override { return "~{dirflag},~{fpsr},~{flags}"; } + + StringRef getConstraintRegister(const StringRef &Constraint, + const StringRef &Expression) const override { + StringRef::iterator I, E; + for (I = Constraint.begin(), E = Constraint.end(); I != E; ++I) { + if (isalpha(*I)) + break; + } + if (I == E) + return ""; + switch (*I) { + // For the register constraints, return the matching register name + case 'a': + return "ax"; + case 'b': + return "bx"; + case 'c': + return "cx"; + case 'd': + return "dx"; + case 'S': + return "si"; + case 'D': + return "di"; + // In case the constraint is 'r' we need to return Expression + case 'r': + return Expression; + default: + // Default value if there is no constraint for the register + return ""; + } + return ""; + } + void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; static void setSSELevel(llvm::StringMap<bool> &Features, X86SSEEnum Level, @@ -2782,6 +2950,7 @@ public: case CK_BDVER2: case CK_BDVER3: case CK_BDVER4: + case CK_ZNVER1: case CK_x86_64: return true; } @@ -2797,6 +2966,7 @@ public: case CC_X86FastCall: case CC_X86StdCall: case CC_X86VectorCall: + case CC_X86RegCall: case CC_C: case CC_Swift: case CC_X86Pascal: @@ -2816,7 +2986,7 @@ public: } void setSupportedOpenCLOpts() override { - getSupportedOpenCLOpts().setAll(); + getSupportedOpenCLOpts().supportAll(); } }; @@ -3028,6 +3198,33 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "cx16", true); setFeatureEnabledImpl(Features, "fxsr", true); break; + case CK_ZNVER1: + setFeatureEnabledImpl(Features, "adx", true); + setFeatureEnabledImpl(Features, "aes", true); + setFeatureEnabledImpl(Features, "avx2", true); + setFeatureEnabledImpl(Features, "bmi", true); + setFeatureEnabledImpl(Features, "bmi2", true); + setFeatureEnabledImpl(Features, "clflushopt", true); + setFeatureEnabledImpl(Features, "cx16", true); + setFeatureEnabledImpl(Features, "f16c", true); + setFeatureEnabledImpl(Features, "fma", true); + setFeatureEnabledImpl(Features, "fsgsbase", true); + setFeatureEnabledImpl(Features, "fxsr", true); + setFeatureEnabledImpl(Features, "lzcnt", true); + setFeatureEnabledImpl(Features, "mwaitx", true); + setFeatureEnabledImpl(Features, "movbe", true); + setFeatureEnabledImpl(Features, "pclmul", true); + setFeatureEnabledImpl(Features, "popcnt", true); + setFeatureEnabledImpl(Features, "prfchw", true); + setFeatureEnabledImpl(Features, "rdrnd", true); + setFeatureEnabledImpl(Features, "rdseed", true); + setFeatureEnabledImpl(Features, "sha", true); + setFeatureEnabledImpl(Features, "sse4a", true); + setFeatureEnabledImpl(Features, "xsave", true); + setFeatureEnabledImpl(Features, "xsavec", true); + setFeatureEnabledImpl(Features, "xsaveopt", true); + setFeatureEnabledImpl(Features, "xsaves", true); + break; case CK_BDVER4: setFeatureEnabledImpl(Features, "avx2", true); setFeatureEnabledImpl(Features, "bmi2", true); @@ -3244,6 +3441,12 @@ void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, Name == "avx512vbmi" || Name == "avx512ifma") { if (Enabled) setSSELevel(Features, AVX512F, Enabled); + // Enable BWI instruction if VBMI is being enabled. + if (Name == "avx512vbmi" && Enabled) + Features["avx512bw"] = true; + // Also disable VBMI if BWI is being disabled. + if (Name == "avx512bw" && !Enabled) + Features["avx512vbmi"] = false; } else if (Name == "fma") { if (Enabled) setSSELevel(Features, AVX, Enabled); @@ -3573,6 +3776,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_BDVER4: defineCPUMacros(Builder, "bdver4"); break; + case CK_ZNVER1: + defineCPUMacros(Builder, "znver1"); + break; case CK_Geode: defineCPUMacros(Builder, "geode"); break; @@ -3891,6 +4097,7 @@ X86TargetInfo::validateAsmConstraint(const char *&Name, case 't': // Any SSE register, when SSE2 is enabled. case 'i': // Any SSE register, when SSE2 and inter-unit moves enabled. case 'm': // Any MMX register, when inter-unit moves enabled. + case 'k': // AVX512 arch mask registers: k1-k7. Info.setAllowsRegister(); return true; } @@ -3911,7 +4118,10 @@ X86TargetInfo::validateAsmConstraint(const char *&Name, case 'u': // Second from top of floating point stack. case 'q': // Any register accessible as [r]l: a, b, c, and d. case 'y': // Any MMX register. + case 'v': // Any {X,Y,Z}MM register (Arch & context dependent) case 'x': // Any SSE register. + case 'k': // Any AVX512 mask register (same as Yk, additionaly allows k0 + // for intermideate k reg operations). case 'Q': // Any register accessible as [r]h: a, b, c, and d. case 'R': // "Legacy" registers: ax, bx, cx, dx, di, si, sp, bp. case 'l': // "Index" registers: any general register that can be used as an @@ -3945,12 +4155,15 @@ bool X86TargetInfo::validateOperandSize(StringRef Constraint, unsigned Size) const { switch (Constraint[0]) { default: break; + case 'k': + // Registers k0-k7 (AVX512) size limit is 64 bit. case 'y': return Size <= 64; case 'f': case 't': case 'u': return Size <= 128; + case 'v': case 'x': if (SSELevel >= AVX512F) // 512-bit zmm registers can be used if target supports AVX512F. @@ -3965,6 +4178,7 @@ bool X86TargetInfo::validateOperandSize(StringRef Constraint, default: break; case 'm': // 'Ym' is synonymous with 'y'. + case 'k': return Size <= 64; case 'i': case 't': @@ -3996,6 +4210,20 @@ X86TargetInfo::convertConstraint(const char *&Constraint) const { return std::string("{st}"); case 'u': // second from top of floating point stack. return std::string("{st(1)}"); // second from top of floating point stack. + case 'Y': + switch (Constraint[1]) { + default: + // Break from inner switch and fall through (copy single char), + // continue parsing after copying the current constraint into + // the return string. + break; + case 'k': + // "^" hints llvm that this is a 2 letter constraint. + // "Constraint++" is used to promote the string iterator + // to the next constraint. + return std::string("^") + std::string(Constraint++, 2); + } + LLVM_FALLTHROUGH; default: return std::string(1, *Constraint); } @@ -4055,6 +4283,10 @@ public: return X86TargetInfo::validateOperandSize(Constraint, Size); } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return llvm::makeArrayRef(BuiltinInfoX86, clang::X86::LastX86CommonBuiltin - + Builtin::FirstTSBuiltin + 1); + } }; class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> { @@ -4149,7 +4381,7 @@ public: const TargetOptions &Opts) : WindowsX86_32TargetInfo(Triple, Opts) { LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -4248,7 +4480,7 @@ public: MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : X86_32TargetInfo(Triple, Opts) { LongDoubleWidth = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); resetDataLayout("e-m:e-p:32:32-i64:32-f64:32-f128:32-n8:16:32-a:0:32-S32"); WIntType = UnsignedInt; } @@ -4380,6 +4612,7 @@ public: case CC_X86_64Win64: case CC_PreserveMost: case CC_PreserveAll: + case CC_X86RegCall: return CCCR_OK; default: return CCCR_Warning; @@ -4410,6 +4643,10 @@ public: return X86TargetInfo::validateGlobalRegisterVariable(RegName, RegSize, HasSizeMismatch); } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return llvm::makeArrayRef(BuiltinInfoX86, + X86::LastTSBuiltin - Builtin::FirstTSBuiltin); + } }; // x86-64 Windows target @@ -4447,6 +4684,8 @@ public: case CC_X86VectorCall: case CC_IntelOclBicc: case CC_X86_64SysV: + case CC_Swift: + case CC_X86RegCall: return CCCR_OK; default: return CCCR_Warning; @@ -4461,7 +4700,7 @@ public: const TargetOptions &Opts) : WindowsX86_64TargetInfo(Triple, Opts) { LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -4480,7 +4719,7 @@ public: // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks // with x86 FP ops. Weird. LongDoubleWidth = LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; + LongDoubleFormat = &llvm::APFloat::x87DoubleExtended(); } void getTargetDefines(const LangOptions &Opts, @@ -4641,8 +4880,10 @@ class ARMTargetInfo : public TargetInfo { DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; const llvm::Triple &T = getTriple(); - // size_t is unsigned long on MachO-derived environments, NetBSD and Bitrig. + // size_t is unsigned long on MachO-derived environments, NetBSD, + // OpenBSD and Bitrig. if (T.isOSBinFormatMachO() || T.getOS() == llvm::Triple::NetBSD || + T.getOS() == llvm::Triple::OpenBSD || T.getOS() == llvm::Triple::Bitrig) SizeType = UnsignedLong; else @@ -4650,6 +4891,7 @@ class ARMTargetInfo : public TargetInfo { switch (T.getOS()) { case llvm::Triple::NetBSD: + case llvm::Triple::OpenBSD: WCharType = SignedInt; break; case llvm::Triple::Win32: @@ -4824,6 +5066,8 @@ class ARMTargetInfo : public TargetInfo { return "8M_BASE"; case llvm::ARM::AK_ARMV8MMainline: return "8M_MAIN"; + case llvm::ARM::AK_ARMV8R: + return "8R"; } } @@ -4841,14 +5085,13 @@ class ARMTargetInfo : public TargetInfo { } public: - ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts, - bool IsBigEndian) + ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0), HW_FP(0) { - BigEndian = IsBigEndian; switch (getTriple().getOS()) { case llvm::Triple::NetBSD: + case llvm::Triple::OpenBSD: PtrDiffType = SignedLong; break; default: @@ -4871,7 +5114,7 @@ public: // the frontend matches that. if (Triple.getEnvironment() == llvm::Triple::EABI || Triple.getOS() == llvm::Triple::UnknownOS || - StringRef(CPU).startswith("cortex-m")) { + ArchProfile == llvm::ARM::PK_M) { setABI("aapcs"); } else if (Triple.isWatchABI()) { setABI("aapcs16"); @@ -4951,7 +5194,7 @@ public: StringRef CPU, const std::vector<std::string> &FeaturesVec) const override { - std::vector<const char*> TargetFeatures; + std::vector<StringRef> TargetFeatures; unsigned Arch = llvm::ARM::parseArch(getTriple().getArchName()); // get default FPU features @@ -4962,9 +5205,9 @@ public: unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch); llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures); - for (const char *Feature : TargetFeatures) + for (auto Feature : TargetFeatures) if (Feature[0] == '+') - Features[Feature+1] = true; + Features[Feature.drop_front(1)] = true; return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } @@ -5200,7 +5443,7 @@ public: if (SoftFloat) Builder.defineMacro("__SOFTFP__"); - if (CPU == "xscale") + if (ArchKind == llvm::ARM::AK_XSCALE) Builder.defineMacro("__XSCALE__"); if (isThumb()) { @@ -5232,6 +5475,8 @@ public: Builder.defineMacro("__ARM_VFPV3__"); if (FPU & VFP4FPU) Builder.defineMacro("__ARM_VFPV4__"); + if (FPU & FPARMV8) + Builder.defineMacro("__ARM_FPV5__"); } // This only gets set when Neon instructions are actually available, unlike @@ -5479,13 +5724,15 @@ const Builtin::Info ARMTargetInfo::BuiltinInfo[] = { { #ID, TYPE, ATTRS, nullptr, LANG, nullptr }, #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ { #ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr }, +#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ + { #ID, TYPE, ATTRS, HEADER, LANGS, FEATURE }, #include "clang/Basic/BuiltinsARM.def" }; class ARMleTargetInfo : public ARMTargetInfo { public: ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : ARMTargetInfo(Triple, Opts, /*BigEndian=*/false) {} + : ARMTargetInfo(Triple, Opts) {} void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { Builder.defineMacro("__ARMEL__"); @@ -5496,7 +5743,7 @@ public: class ARMbeTargetInfo : public ARMTargetInfo { public: ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : ARMTargetInfo(Triple, Opts, /*BigEndian=*/true) {} + : ARMTargetInfo(Triple, Opts) {} void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { Builder.defineMacro("__ARMEB__"); @@ -5697,7 +5944,7 @@ public: MaxAtomicPromoteWidth = 128; LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); // {} in inline assembly are neon specifiers, not assembly variant // specifiers. @@ -5728,16 +5975,9 @@ public: } bool setCPU(const std::string &Name) override { - bool CPUKnown = llvm::StringSwitch<bool>(Name) - .Case("generic", true) - .Cases("cortex-a53", "cortex-a57", "cortex-a72", - "cortex-a35", "exynos-m1", true) - .Case("cortex-a73", true) - .Case("cyclone", true) - .Case("kryo", true) - .Case("vulcan", true) - .Default(false); - return CPUKnown; + return Name == "generic" || + llvm::AArch64::parseCPUArch(Name) != + static_cast<unsigned>(llvm::AArch64::ArchKind::AK_INVALID); } void getTargetDefines(const LangOptions &Opts, @@ -6014,7 +6254,6 @@ class AArch64leTargetInfo : public AArch64TargetInfo { public: AArch64leTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : AArch64TargetInfo(Triple, Opts) { - BigEndian = false; } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -6064,7 +6303,7 @@ public: UseSignedCharForObjCBool = false; LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); TheCXXABI.set(TargetCXXABI::iOS64); } @@ -6081,11 +6320,11 @@ class HexagonTargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; std::string CPU; bool HasHVX, HasHVXDouble; + bool UseLongCalls; public: HexagonTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - BigEndian = false; // Specify the vector alignment explicitly. For v512x1, the calculated // alignment would be 512*alignment(i1), which is 512 bytes, instead of // the required minimum of 64 bytes. @@ -6105,6 +6344,7 @@ public: UseBitFieldTypeAlignment = true; ZeroLengthBitfieldBoundary = 32; HasHVX = HasHVXDouble = false; + UseLongCalls = false; } ArrayRef<Builtin::Info> getTargetBuiltins() const override { @@ -6139,6 +6379,7 @@ public: .Case("hexagon", true) .Case("hvx", HasHVX) .Case("hvx-double", HasHVXDouble) + .Case("long-calls", UseLongCalls) .Default(false); } @@ -6149,6 +6390,9 @@ public: bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override; + void setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, + bool Enabled) const override; + BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } @@ -6217,6 +6461,17 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, } } +bool HexagonTargetInfo::initFeatureMap(llvm::StringMap<bool> &Features, + DiagnosticsEngine &Diags, StringRef CPU, + const std::vector<std::string> &FeaturesVec) const { + // Default for v60: -hvx, -hvx-double. + Features["hvx"] = false; + Features["hvx-double"] = false; + Features["long-calls"] = false; + + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); +} + bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) { for (auto &F : Features) { @@ -6228,21 +6483,27 @@ bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasHVX = HasHVXDouble = true; else if (F == "-hvx-double") HasHVXDouble = false; + + if (F == "+long-calls") + UseLongCalls = true; + else if (F == "-long-calls") + UseLongCalls = false; } return true; } -bool HexagonTargetInfo::initFeatureMap(llvm::StringMap<bool> &Features, - DiagnosticsEngine &Diags, StringRef CPU, - const std::vector<std::string> &FeaturesVec) const { - // Default for v60: -hvx, -hvx-double. - Features["hvx"] = false; - Features["hvx-double"] = false; - - return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); +void HexagonTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, bool Enabled) const { + if (Enabled) { + if (Name == "hvx-double") + Features["hvx"] = true; + } else { + if (Name == "hvx") + Features["hvx-double"] = false; + } + Features[Name] = Enabled; } - const char *const HexagonTargetInfo::GCCRegNames[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -6472,8 +6733,9 @@ public: CK_NIAGARA2, CK_NIAGARA3, CK_NIAGARA4, - CK_MYRIAD2_1, - CK_MYRIAD2_2, + CK_MYRIAD2100, + CK_MYRIAD2150, + CK_MYRIAD2450, CK_LEON2, CK_LEON2_AT697E, CK_LEON2_AT697F, @@ -6500,8 +6762,9 @@ public: case CK_SPARCLITE86X: case CK_SPARCLET: case CK_TSC701: - case CK_MYRIAD2_1: - case CK_MYRIAD2_2: + case CK_MYRIAD2100: + case CK_MYRIAD2150: + case CK_MYRIAD2450: case CK_LEON2: case CK_LEON2_AT697E: case CK_LEON2_AT697F: @@ -6540,9 +6803,14 @@ public: .Case("niagara2", CK_NIAGARA2) .Case("niagara3", CK_NIAGARA3) .Case("niagara4", CK_NIAGARA4) - .Case("myriad2", CK_MYRIAD2_1) - .Case("myriad2.1", CK_MYRIAD2_1) - .Case("myriad2.2", CK_MYRIAD2_2) + .Case("ma2100", CK_MYRIAD2100) + .Case("ma2150", CK_MYRIAD2150) + .Case("ma2450", CK_MYRIAD2450) + // FIXME: the myriad2[.n] spellings are obsolete, + // but a grace period is needed to allow updating dependent builds. + .Case("myriad2", CK_MYRIAD2100) + .Case("myriad2.1", CK_MYRIAD2100) + .Case("myriad2.2", CK_MYRIAD2150) .Case("leon2", CK_LEON2) .Case("at697e", CK_LEON2_AT697E) .Case("at697f", CK_LEON2_AT697F) @@ -6630,7 +6898,10 @@ public: PtrDiffType = SignedLong; break; } - MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + // Up to 32 bits are lock-free atomic, but we're willing to do atomic ops + // on up to 64 bits. + MaxAtomicPromoteWidth = 64; + MaxAtomicInlineWidth = 32; } void getTargetDefines(const LangOptions &Opts, @@ -6651,18 +6922,27 @@ public: break; } if (getTriple().getVendor() == llvm::Triple::Myriad) { + std::string MyriadArchValue, Myriad2Value; + Builder.defineMacro("__sparc_v8__"); + Builder.defineMacro("__leon__"); switch (CPU) { - case CK_MYRIAD2_1: - Builder.defineMacro("__myriad2", "1"); - Builder.defineMacro("__myriad2__", "1"); + case CK_MYRIAD2150: + MyriadArchValue = "__ma2150"; + Myriad2Value = "2"; break; - case CK_MYRIAD2_2: - Builder.defineMacro("__myriad2", "2"); - Builder.defineMacro("__myriad2__", "2"); + case CK_MYRIAD2450: + MyriadArchValue = "__ma2450"; + Myriad2Value = "2"; break; default: + MyriadArchValue = "__ma2100"; + Myriad2Value = "1"; break; } + Builder.defineMacro(MyriadArchValue, "1"); + Builder.defineMacro(MyriadArchValue+"__", "1"); + Builder.defineMacro("__myriad2__", Myriad2Value); + Builder.defineMacro("__myriad2", Myriad2Value); } } @@ -6677,7 +6957,6 @@ class SparcV8elTargetInfo : public SparcV8TargetInfo { SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : SparcV8TargetInfo(Triple, Opts) { resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64"); - BigEndian = false; } }; @@ -6702,7 +6981,7 @@ public: // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned. LongDoubleWidth = 128; LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } @@ -6745,7 +7024,7 @@ public: PointerWidth = PointerAlign = 64; LongDoubleWidth = 128; LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); DefaultAlignForAttributeAligned = 64; MinGlobalAlign = 16; resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); @@ -6791,9 +7070,13 @@ public: CPU = Name; bool CPUKnown = llvm::StringSwitch<bool>(Name) .Case("z10", true) + .Case("arch8", true) .Case("z196", true) + .Case("arch9", true) .Case("zEC12", true) + .Case("arch10", true) .Case("z13", true) + .Case("arch11", true) .Default(false); return CPUKnown; @@ -6802,9 +7085,9 @@ public: initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const override { - if (CPU == "zEC12") + if (CPU == "zEC12" || CPU == "arch10") Features["transactional-execution"] = true; - if (CPU == "z13") { + if (CPU == "z13" || CPU == "arch11") { Features["transactional-execution"] = true; Features["vector"] = true; } @@ -6912,7 +7195,6 @@ class MSP430TargetInfo : public TargetInfo { public: MSP430TargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - BigEndian = false; TLSSupported = false; IntWidth = 16; IntAlign = 16; @@ -7018,11 +7300,14 @@ public: DoubleAlign = 32; LongDoubleWidth = 32; LongDoubleAlign = 32; - FloatFormat = &llvm::APFloat::IEEEsingle; - DoubleFormat = &llvm::APFloat::IEEEsingle; - LongDoubleFormat = &llvm::APFloat::IEEEsingle; - resetDataLayout("E-p:32:32-i8:8:32-i16:16:32-i64:32" - "-f64:32-v64:32-v128:32-a:0:32-n32"); + FloatFormat = &llvm::APFloat::IEEEsingle(); + DoubleFormat = &llvm::APFloat::IEEEsingle(); + LongDoubleFormat = &llvm::APFloat::IEEEsingle(); + resetDataLayout("E-p:32:32:32-i1:8:8-i8:8:32-" + "i16:16:32-i32:32:32-i64:32:32-" + "f32:32:32-f64:32:32-v64:32:32-" + "v128:32:32-v256:32:32-v512:32:32-" + "v1024:32:32-a0:0:32-n32"); AddrSpaceMap = &TCEOpenCLAddrSpaceMap; UseAddrSpaceMapMangling = true; } @@ -7050,6 +7335,31 @@ public: } }; +class TCELETargetInfo : public TCETargetInfo { +public: + TCELETargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : TCETargetInfo(Triple, Opts) { + BigEndian = false; + + resetDataLayout("e-p:32:32:32-i1:8:8-i8:8:32-" + "i16:16:32-i32:32:32-i64:32:32-" + "f32:32:32-f64:32:32-v64:32:32-" + "v128:32:32-v256:32:32-v512:32:32-" + "v1024:32:32-a0:0:32-n32"); + + } + + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "tcele", Opts); + Builder.defineMacro("__TCE__"); + Builder.defineMacro("__TCE_V1__"); + Builder.defineMacro("__TCELE__"); + Builder.defineMacro("__TCELE_V1__"); + } + +}; + class BPFTargetInfo : public TargetInfo { public: BPFTargetInfo(const llvm::Triple &Triple, const TargetOptions &) @@ -7062,10 +7372,8 @@ public: Int64Type = SignedLong; RegParmMax = 5; if (Triple.getArch() == llvm::Triple::bpfeb) { - BigEndian = true; resetDataLayout("E-m:e-p:64:64-i64:64-n32:64-S128"); } else { - BigEndian = false; resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128"); } MaxAtomicPromoteWidth = 64; @@ -7144,8 +7452,6 @@ public: IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat), DspRev(NoDSP), HasMSA(false), HasFP64(false) { TheCXXABI.set(TargetCXXABI::GenericMIPS); - BigEndian = getTriple().getArch() == llvm::Triple::mips || - getTriple().getArch() == llvm::Triple::mips64; setABI((getTriple().getArch() == llvm::Triple::mips || getTriple().getArch() == llvm::Triple::mipsel) @@ -7206,7 +7512,7 @@ public: void setO32ABITypes() { Int64Type = SignedLongLong; IntMaxType = Int64Type; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); LongDoubleWidth = LongDoubleAlign = 64; LongWidth = LongAlign = 32; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; @@ -7218,10 +7524,10 @@ public: void setN32N64ABITypes() { LongDoubleWidth = LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); if (getTriple().getOS() == llvm::Triple::FreeBSD) { LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; SuitableAlign = 128; @@ -7648,7 +7954,6 @@ class PNaClTargetInfo : public TargetInfo { public: PNaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple) { - BigEndian = false; this->LongAlign = 32; this->LongWidth = 32; this->PointerAlign = 32; @@ -7716,7 +8021,6 @@ class Le64TargetInfo : public TargetInfo { public: Le64TargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - BigEndian = false; NoAsmVariants = true; LongWidth = LongAlign = PointerWidth = PointerAlign = 64; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; @@ -7762,7 +8066,6 @@ class WebAssemblyTargetInfo : public TargetInfo { public: explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &) : TargetInfo(T), SIMDLevel(NoSIMD) { - BigEndian = false; NoAsmVariants = true; SuitableAlign = 128; LargeArrayMinWidth = 128; @@ -7770,7 +8073,10 @@ public: SimdDefaultAlign = 128; SigAtomicType = SignedLong; LongDoubleWidth = LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + IntPtrType = SignedInt; } protected: @@ -7889,6 +8195,9 @@ public: LongAlign = LongWidth = 64; PointerAlign = PointerWidth = 64; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + SizeType = UnsignedLong; + PtrDiffType = SignedLong; + IntPtrType = SignedLong; resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128"); } @@ -7923,7 +8232,6 @@ public: "SPIR target must use unknown OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && "SPIR target must use unknown environment type"); - BigEndian = false; TLSSupported = false; LongWidth = LongAlign = 64; AddrSpaceMap = &SPIRAddrSpaceMap; @@ -7966,7 +8274,7 @@ public: void setSupportedOpenCLOpts() override { // Assume all OpenCL extensions and optional core features are supported // for SPIR since it is a generic target. - getSupportedOpenCLOpts().setAll(); + getSupportedOpenCLOpts().supportAll(); } }; @@ -8007,7 +8315,6 @@ class XCoreTargetInfo : public TargetInfo { public: XCoreTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { - BigEndian = false; NoAsmVariants = true; LongLongAlign = 32; SuitableAlign = 32; @@ -8073,7 +8380,7 @@ public: : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) { SuitableAlign = 32; LongDoubleWidth = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } }; @@ -8082,7 +8389,7 @@ class AndroidX86_64TargetInfo : public LinuxTargetInfo<X86_64TargetInfo> { public: AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) { - LongDoubleFormat = &llvm::APFloat::IEEEquad; + LongDoubleFormat = &llvm::APFloat::IEEEquad(); } bool useFloat128ManglingForLongDouble() const override { @@ -8099,6 +8406,7 @@ public: Triple.getOSName(), Triple.getEnvironmentName()), Opts) { + IsRenderScriptTarget = true; LongWidth = LongAlign = 64; } void getTargetDefines(const LangOptions &Opts, @@ -8116,7 +8424,9 @@ public: : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(), Triple.getOSName(), Triple.getEnvironmentName()), - Opts) {} + Opts) { + IsRenderScriptTarget = true; + } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -8125,6 +8435,107 @@ public: } }; + +// AVR Target +class AVRTargetInfo : public TargetInfo { +public: + AVRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { + TLSSupported = false; + PointerWidth = 16; + PointerAlign = 8; + IntWidth = 16; + IntAlign = 8; + LongWidth = 32; + LongAlign = 8; + LongLongWidth = 64; + LongLongAlign = 8; + SuitableAlign = 8; + DefaultAlignForAttributeAligned = 8; + HalfWidth = 16; + HalfAlign = 8; + FloatWidth = 32; + FloatAlign = 8; + DoubleWidth = 32; + DoubleAlign = 8; + DoubleFormat = &llvm::APFloat::IEEEsingle(); + LongDoubleWidth = 32; + LongDoubleAlign = 8; + LongDoubleFormat = &llvm::APFloat::IEEEsingle(); + SizeType = UnsignedInt; + PtrDiffType = SignedInt; + IntPtrType = SignedInt; + Char16Type = UnsignedInt; + WCharType = SignedInt; + WIntType = SignedInt; + Char32Type = UnsignedLong; + SigAtomicType = SignedChar; + resetDataLayout("e-p:16:16:16-i8:8:8-i16:16:16-i32:32:32-i64:64:64" + "-f32:32:32-f64:64:64-n8"); + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override { + Builder.defineMacro("__AVR__"); + } + + ArrayRef<Builtin::Info> getTargetBuiltins() const override { + return None; + } + + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } + + const char *getClobbers() const override { + return ""; + } + + ArrayRef<const char *> getGCCRegNames() const override { + static const char * const GCCRegNames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "X", "Y", "Z", "SP" + }; + return llvm::makeArrayRef(GCCRegNames); + } + + ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { + return None; + } + + ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override { + static const TargetInfo::AddlRegName AddlRegNames[] = { + { { "r26", "r27"}, 26 }, + { { "r28", "r29"}, 27 }, + { { "r30", "r31"}, 28 }, + { { "SPL", "SPH"}, 29 }, + }; + return llvm::makeArrayRef(AddlRegNames); + } + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const override { + return false; + } + + IntType getIntTypeByWidth(unsigned BitWidth, + bool IsSigned) const final { + // AVR prefers int for 16-bit integers. + return BitWidth == 16 ? (IsSigned ? SignedInt : UnsignedInt) + : TargetInfo::getIntTypeByWidth(BitWidth, IsSigned); + } + + IntType getLeastIntTypeByWidth(unsigned BitWidth, + bool IsSigned) const final { + // AVR uses int for int_least16_t and int_fast16_t. + return BitWidth == 16 + ? (IsSigned ? SignedInt : UnsignedInt) + : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); + } +}; + } // end anonymous namespace //===----------------------------------------------------------------------===// @@ -8157,6 +8568,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new CloudABITargetInfo<AArch64leTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<AArch64leTargetInfo>(Triple, Opts); case llvm::Triple::Linux: return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: @@ -8169,6 +8582,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, switch (os) { case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<AArch64beTargetInfo>(Triple, Opts); case llvm::Triple::Linux: return new LinuxTargetInfo<AArch64beTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: @@ -8189,6 +8604,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: return new NetBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: @@ -8225,6 +8642,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new LinuxTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: @@ -8239,6 +8658,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new ARMbeTargetInfo(Triple, Opts); } + case llvm::Triple::avr: + return new AVRTargetInfo(Triple, Opts); case llvm::Triple::bpfeb: case llvm::Triple::bpfel: return new BPFTargetInfo(Triple, Opts); @@ -8364,9 +8785,9 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, } case llvm::Triple::nvptx: - return new NVPTX32TargetInfo(Triple, Opts); + return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/32); case llvm::Triple::nvptx64: - return new NVPTX64TargetInfo(Triple, Opts); + return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/64); case llvm::Triple::amdgcn: case llvm::Triple::r600: @@ -8430,6 +8851,9 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::tce: return new TCETargetInfo(Triple, Opts); + case llvm::Triple::tcele: + return new TCELETargetInfo(Triple, Opts); + case llvm::Triple::x86: if (Triple.isOSDarwin()) return new DarwinI386TargetInfo(Triple, Opts); @@ -8455,6 +8879,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new BitrigI386TargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::KFreeBSD: return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::Minix: @@ -8510,6 +8936,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple, return new BitrigX86_64TargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); + case llvm::Triple::Fuchsia: + return new FuchsiaTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::KFreeBSD: return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::Solaris: @@ -8612,6 +9040,7 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, return nullptr; Target->setSupportedOpenCLOpts(); + Target->setOpenCLExtensionOpts(); if (!Target->validateTarget(Diags)) return nullptr; diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp index 4fa52b4..97e75a9 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Version.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Version.cpp @@ -36,7 +36,7 @@ std::string getClangRepositoryPath() { // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. - StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_391/final/lib/Basic/Version.cpp $"); + StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_400/final/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); diff --git a/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp b/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp index 8ace2b3..50fcb22 100644 --- a/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp @@ -47,7 +47,7 @@ Status::Status(const file_status &Status) User(Status.getUser()), Group(Status.getGroup()), Size(Status.getSize()), Type(Status.type()), Perms(Status.permissions()), IsVFSMapped(false) {} -Status::Status(StringRef Name, UniqueID UID, sys::TimeValue MTime, +Status::Status(StringRef Name, UniqueID UID, sys::TimePoint<> MTime, uint32_t User, uint32_t Group, uint64_t Size, file_type Type, perms Perms) : Name(Name), UID(UID), MTime(MTime), User(User), Group(Group), Size(Size), @@ -494,8 +494,8 @@ public: InMemoryFileSystem::InMemoryFileSystem(bool UseNormalizedPaths) : Root(new detail::InMemoryDirectory( - Status("", getNextVirtualUniqueID(), llvm::sys::TimeValue::MinTime(), - 0, 0, 0, llvm::sys::fs::file_type::directory_file, + Status("", getNextVirtualUniqueID(), llvm::sys::TimePoint<>(), 0, 0, + 0, llvm::sys::fs::file_type::directory_file, llvm::sys::fs::perms::all_all))), UseNormalizedPaths(UseNormalizedPaths) {} @@ -532,7 +532,7 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, // End of the path, create a new file. // FIXME: expose the status details in the interface. Status Stat(P.str(), getNextVirtualUniqueID(), - llvm::sys::TimeValue(ModificationTime, 0), 0, 0, + llvm::sys::toTimePoint(ModificationTime), 0, 0, Buffer->getBufferSize(), llvm::sys::fs::file_type::regular_file, llvm::sys::fs::all_all); @@ -545,9 +545,9 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, // FIXME: expose the status details in the interface. Status Stat( StringRef(Path.str().begin(), Name.end() - Path.str().begin()), - getNextVirtualUniqueID(), llvm::sys::TimeValue(ModificationTime, 0), - 0, 0, Buffer->getBufferSize(), - llvm::sys::fs::file_type::directory_file, llvm::sys::fs::all_all); + getNextVirtualUniqueID(), llvm::sys::toTimePoint(ModificationTime), 0, + 0, Buffer->getBufferSize(), llvm::sys::fs::file_type::directory_file, + llvm::sys::fs::all_all); Dir = cast<detail::InMemoryDirectory>(Dir->addChild( Name, llvm::make_unique<detail::InMemoryDirectory>(std::move(Stat)))); continue; @@ -801,6 +801,7 @@ public: /// 'case-sensitive': <boolean, default=true> /// 'use-external-names': <boolean, default=true> /// 'overlay-relative': <boolean, default=false> +/// 'ignore-non-existent-contents': <boolean, default=true> /// /// Virtual directories are represented as /// \verbatim @@ -860,6 +861,14 @@ class RedirectingFileSystem : public vfs::FileSystem { /// \brief Whether to use to use the value of 'external-contents' for the /// names of files. This global value is overridable on a per-file basis. bool UseExternalNames = true; + + /// \brief Whether an invalid path obtained via 'external-contents' should + /// cause iteration on the VFS to stop. If 'true', the VFS should ignore + /// the entry and continue with the next. Allows YAML files to be shared + /// across multiple compiler invocations regardless of prior existent + /// paths in 'external-contents'. This global value is overridable on a + /// per-file basis. + bool IgnoreNonExistentContents = true; /// @} /// Virtual file paths and external files could be canonicalized without "..", @@ -878,9 +887,6 @@ private: RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS) : ExternalFS(std::move(ExternalFS)) {} - /// \brief Looks up \p Path in \c Roots. - ErrorOr<Entry *> lookupPath(const Twine &Path); - /// \brief Looks up the path <tt>[Start, End)</tt> in \p From, possibly /// recursing into the contents of \p From if it is a directory. ErrorOr<Entry *> lookupPath(sys::path::const_iterator Start, @@ -890,6 +896,9 @@ private: ErrorOr<Status> status(const Twine &Path, Entry *E); public: + /// \brief Looks up \p Path in \c Roots. + ErrorOr<Entry *> lookupPath(const Twine &Path); + /// \brief Parses \p Buffer, which is expected to be in YAML format and /// returns a virtual file system representing its contents. static RedirectingFileSystem * @@ -937,6 +946,10 @@ public: return ExternalContentsPrefixDir; } + bool ignoreNonExistentContents() const { + return IgnoreNonExistentContents; + } + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void dump() const { for (const std::unique_ptr<Entry> &Root : Roots) @@ -1060,8 +1073,9 @@ class RedirectingFileSystemParser { // ... or create a new one std::unique_ptr<Entry> E = llvm::make_unique<RedirectingDirectoryEntry>( - Name, Status("", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0, - 0, file_type::directory_file, sys::fs::all_all)); + Name, + Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), + 0, 0, 0, file_type::directory_file, sys::fs::all_all)); if (!ParentEntry) { // Add a new root to the overlay FS->Roots.push_back(std::move(E)); @@ -1262,8 +1276,8 @@ class RedirectingFileSystemParser { case EK_Directory: Result = llvm::make_unique<RedirectingDirectoryEntry>( LastComponent, std::move(EntryArrayContents), - Status("", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0, 0, - file_type::directory_file, sys::fs::all_all)); + Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), + 0, 0, 0, file_type::directory_file, sys::fs::all_all)); break; } @@ -1279,8 +1293,8 @@ class RedirectingFileSystemParser { Entries.push_back(std::move(Result)); Result = llvm::make_unique<RedirectingDirectoryEntry>( *I, std::move(Entries), - Status("", getNextVirtualUniqueID(), sys::TimeValue::now(), 0, 0, 0, - file_type::directory_file, sys::fs::all_all)); + Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), + 0, 0, 0, file_type::directory_file, sys::fs::all_all)); } return Result; } @@ -1301,6 +1315,7 @@ public: KeyStatusPair("case-sensitive", false), KeyStatusPair("use-external-names", false), KeyStatusPair("overlay-relative", false), + KeyStatusPair("ignore-non-existent-contents", false), KeyStatusPair("roots", true), }; @@ -1359,6 +1374,9 @@ public: } else if (Key == "use-external-names") { if (!parseScalarBool(I->getValue(), FS->UseExternalNames)) return false; + } else if (Key == "ignore-non-existent-contents") { + if (!parseScalarBool(I->getValue(), FS->IgnoreNonExistentContents)) + return false; } else { llvm_unreachable("key missing from Keys"); } @@ -1588,6 +1606,47 @@ vfs::getVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer, std::move(ExternalFS)); } +static void getVFSEntries(Entry *SrcE, SmallVectorImpl<StringRef> &Path, + SmallVectorImpl<YAMLVFSEntry> &Entries) { + auto Kind = SrcE->getKind(); + if (Kind == EK_Directory) { + auto *DE = dyn_cast<RedirectingDirectoryEntry>(SrcE); + assert(DE && "Must be a directory"); + for (std::unique_ptr<Entry> &SubEntry : + llvm::make_range(DE->contents_begin(), DE->contents_end())) { + Path.push_back(SubEntry->getName()); + getVFSEntries(SubEntry.get(), Path, Entries); + Path.pop_back(); + } + return; + } + + assert(Kind == EK_File && "Must be a EK_File"); + auto *FE = dyn_cast<RedirectingFileEntry>(SrcE); + assert(FE && "Must be a file"); + SmallString<128> VPath; + for (auto &Comp : Path) + llvm::sys::path::append(VPath, Comp); + Entries.push_back(YAMLVFSEntry(VPath.c_str(), FE->getExternalContentsPath())); +} + +void vfs::collectVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer, + SourceMgr::DiagHandlerTy DiagHandler, + StringRef YAMLFilePath, + SmallVectorImpl<YAMLVFSEntry> &CollectedEntries, + void *DiagContext, + IntrusiveRefCntPtr<FileSystem> ExternalFS) { + RedirectingFileSystem *VFS = RedirectingFileSystem::create( + std::move(Buffer), DiagHandler, YAMLFilePath, DiagContext, + std::move(ExternalFS)); + ErrorOr<Entry *> RootE = VFS->lookupPath("/"); + if (!RootE) + return; + SmallVector<StringRef, 8> Components; + Components.push_back("/"); + getVFSEntries(*RootE, Components, CollectedEntries); +} + UniqueID vfs::getNextVirtualUniqueID() { static std::atomic<unsigned> UID; unsigned ID = ++UID; @@ -1619,7 +1678,7 @@ public: JSONWriter(llvm::raw_ostream &OS) : OS(OS) {} void write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> UseExternalNames, Optional<bool> IsCaseSensitive, Optional<bool> IsOverlayRelative, - StringRef OverlayDir); + Optional<bool> IgnoreNonExistentContents, StringRef OverlayDir); }; } @@ -1675,6 +1734,7 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> UseExternalNames, Optional<bool> IsCaseSensitive, Optional<bool> IsOverlayRelative, + Optional<bool> IgnoreNonExistentContents, StringRef OverlayDir) { using namespace llvm::sys; @@ -1692,6 +1752,9 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, OS << " 'overlay-relative': '" << (UseOverlayRelative ? "true" : "false") << "',\n"; } + if (IgnoreNonExistentContents.hasValue()) + OS << " 'ignore-non-existent-contents': '" + << (IgnoreNonExistentContents.getValue() ? "true" : "false") << "',\n"; OS << " 'roots': [\n"; if (!Entries.empty()) { @@ -1748,7 +1811,8 @@ void YAMLVFSWriter::write(llvm::raw_ostream &OS) { }); JSONWriter(OS).write(Mappings, UseExternalNames, IsCaseSensitive, - IsOverlayRelative, OverlayDir); + IsOverlayRelative, IgnoreNonExistentContents, + OverlayDir); } VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl( @@ -1756,29 +1820,47 @@ VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl( RedirectingDirectoryEntry::iterator Begin, RedirectingDirectoryEntry::iterator End, std::error_code &EC) : Dir(_Path.str()), FS(FS), Current(Begin), End(End) { - if (Current != End) { + while (Current != End) { SmallString<128> PathStr(Dir); llvm::sys::path::append(PathStr, (*Current)->getName()); llvm::ErrorOr<vfs::Status> S = FS.status(PathStr); - if (S) + if (S) { CurrentEntry = *S; - else + return; + } + // Skip entries which do not map to a reliable external content. + if (FS.ignoreNonExistentContents() && + S.getError() == llvm::errc::no_such_file_or_directory) { + ++Current; + continue; + } else { EC = S.getError(); + break; + } } } std::error_code VFSFromYamlDirIterImpl::increment() { assert(Current != End && "cannot iterate past end"); - if (++Current != End) { + while (++Current != End) { SmallString<128> PathStr(Dir); llvm::sys::path::append(PathStr, (*Current)->getName()); llvm::ErrorOr<vfs::Status> S = FS.status(PathStr); - if (!S) - return S.getError(); + if (!S) { + // Skip entries which do not map to a reliable external content. + if (FS.ignoreNonExistentContents() && + S.getError() == llvm::errc::no_such_file_or_directory) { + continue; + } else { + return S.getError(); + } + } CurrentEntry = *S; - } else { - CurrentEntry = Status(); + break; } + + if (Current == End) + CurrentEntry = Status(); return std::error_code(); } |