diff options
author | dim <dim@FreeBSD.org> | 2016-12-26 20:36:37 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2016-12-26 20:36:37 +0000 |
commit | 06210ae42d418d50d8d9365d5c9419308ae9e7ee (patch) | |
tree | ab60b4cdd6e430dda1f292a46a77ddb744723f31 /contrib/llvm/tools/clang/lib/Basic | |
parent | 2dd166267f53df1c3748b4325d294b9b839de74b (diff) | |
download | FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.zip FreeBSD-src-06210ae42d418d50d8d9365d5c9419308ae9e7ee.tar.gz |
MFC r309124:
Upgrade our copies of clang, llvm, lldb, compiler-rt and libc++ to 3.9.0
release, and add lld 3.9.0. Also completely revamp the build system for
clang, llvm, lldb and their related tools.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Release notes for llvm, clang and lld are available here:
<http://llvm.org/releases/3.9.0/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.9.0/tools/clang/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.9.0/tools/lld/docs/ReleaseNotes.html>
Thanks to Ed Maste, Bryan Drewery, Andrew Turner, Antoine Brodin and Jan
Beich for their help.
Relnotes: yes
MFC r309147:
Pull in r282174 from upstream llvm trunk (by Krzysztof Parzyszek):
[PPC] Set SP after loading data from stack frame, if no red zone is
present
Follow-up to r280705: Make sure that the SP is only restored after
all data is loaded from the stack frame, if there is no red zone.
This completes the fix for
https://llvm.org/bugs/show_bug.cgi?id=26519.
Differential Revision: https://reviews.llvm.org/D24466
Reported by: Mark Millard
PR: 214433
MFC r309149:
Pull in r283060 from upstream llvm trunk (by Hal Finkel):
[PowerPC] Refactor soft-float support, and enable PPC64 soft float
This change enables soft-float for PowerPC64, and also makes
soft-float disable all vector instruction sets for both 32-bit and
64-bit modes. This latter part is necessary because the PPC backend
canonicalizes many Altivec vector types to floating-point types, and
so soft-float breaks scalarization support for many operations. Both
for embedded targets and for operating-system kernels desiring
soft-float support, it seems reasonable that disabling hardware
floating-point also disables vector instructions (embedded targets
without hardware floating point support are unlikely to have Altivec,
etc. and operating system kernels desiring not to use floating-point
registers to lower syscall cost are unlikely to want to use vector
registers either). If someone needs this to work, we'll need to
change the fact that we promote many Altivec operations to act on
v4f32. To make it possible to disable Altivec when soft-float is
enabled, hardware floating-point support needs to be expressed as a
positive feature, like the others, and not a negative feature,
because target features cannot have dependencies on the disabling of
some other feature. So +soft-float has now become -hard-float.
Fixes PR26970.
Pull in r283061 from upstream clang trunk (by Hal Finkel):
[PowerPC] Enable soft-float for PPC64, and +soft-float -> -hard-float
Enable soft-float support on PPC64, as the backend now supports it.
Also, the backend now uses -hard-float instead of +soft-float, so set
the target features accordingly.
Fixes PR26970.
Reported by: Mark Millard
PR: 214433
MFC r309212:
Add a few missed clang 3.9.0 files to OptionalObsoleteFiles.
MFC r309262:
Fix packaging for clang, lldb and lld 3.9.0
During the upgrade of clang/llvm etc to 3.9.0 in r309124, the PACKAGE
directive in the usr.bin/clang/*.mk files got dropped accidentally.
Restore it, with a few minor changes and additions:
* Correct license in clang.ucl to NCSA
* Add PACKAGE=clang for clang and most of the "ll" tools
* Put lldb in its own package
* Put lld in its own package
Reviewed by: gjb, jmallett
Differential Revision: https://reviews.freebsd.org/D8666
MFC r309656:
During the bootstrap phase, when building the minimal llvm library on
PowerPC, add lib/Support/Atomic.cpp. This is needed because upstream
llvm revision r271821 disabled the use of std::call_once, which causes
some fallback functions from Atomic.cpp to be used instead.
Reported by: Mark Millard
PR: 214902
MFC r309835:
Tentatively apply https://reviews.llvm.org/D18730 to work around gcc PR
70528 (bogus error: constructor required before non-static data member).
This should fix buildworld with the external gcc package.
Reported by: https://jenkins.freebsd.org/job/FreeBSD_HEAD_amd64_gcc/
MFC r310194:
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
3.9.1 release.
Please note that from 3.5.0 onwards, clang, llvm and lldb require C++11
support to build; see UPDATING for more information.
Release notes for llvm, clang and lld will be available here:
<http://releases.llvm.org/3.9.1/docs/ReleaseNotes.html>
<http://releases.llvm.org/3.9.1/tools/clang/docs/ReleaseNotes.html>
<http://releases.llvm.org/3.9.1/tools/lld/docs/ReleaseNotes.html>
Relnotes: yes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Builtins.cpp | 4 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Cuda.cpp | 171 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp | 1 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp | 8 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/FileManager.cpp | 10 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp | 1 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp | 1 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Module.cpp | 11 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp | 203 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp | 1 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp | 45 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp | 12 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Targets.cpp | 2394 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/Version.cpp | 2 | ||||
-rw-r--r-- | contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp | 363 |
15 files changed, 2237 insertions, 990 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp index fb6a645..28695d6 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp @@ -69,7 +69,9 @@ bool Builtin::Context::builtinIsSupported(const Builtin::Info &BuiltinInfo, bool MSModeUnsupported = !LangOpts.MicrosoftExt && (BuiltinInfo.Langs & MS_LANG); bool ObjCUnsupported = !LangOpts.ObjC1 && BuiltinInfo.Langs == OBJC_LANG; - return !BuiltinsUnsupported && !MathBuiltinsUnsupported && + bool OclCUnsupported = LangOpts.OpenCLVersion != 200 && + BuiltinInfo.Langs == OCLC20_LANG; + return !BuiltinsUnsupported && !MathBuiltinsUnsupported && !OclCUnsupported && !GnuModeUnsupported && !MSModeUnsupported && !ObjCUnsupported; } diff --git a/contrib/llvm/tools/clang/lib/Basic/Cuda.cpp b/contrib/llvm/tools/clang/lib/Basic/Cuda.cpp new file mode 100644 index 0000000..3264078 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Basic/Cuda.cpp @@ -0,0 +1,171 @@ +#include "clang/Basic/Cuda.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" + +namespace clang { + +const char *CudaVersionToString(CudaVersion V) { + switch (V) { + case CudaVersion::UNKNOWN: + return "unknown"; + case CudaVersion::CUDA_70: + return "7.0"; + case CudaVersion::CUDA_75: + return "7.5"; + case CudaVersion::CUDA_80: + return "8.0"; + } + llvm_unreachable("invalid enum"); +} + +const char *CudaArchToString(CudaArch A) { + switch (A) { + case CudaArch::UNKNOWN: + return "unknown"; + case CudaArch::SM_20: + return "sm_20"; + case CudaArch::SM_21: + return "sm_21"; + case CudaArch::SM_30: + return "sm_30"; + case CudaArch::SM_32: + return "sm_32"; + case CudaArch::SM_35: + return "sm_35"; + case CudaArch::SM_37: + return "sm_37"; + case CudaArch::SM_50: + return "sm_50"; + case CudaArch::SM_52: + return "sm_52"; + case CudaArch::SM_53: + return "sm_53"; + case CudaArch::SM_60: + return "sm_60"; + case CudaArch::SM_61: + return "sm_61"; + case CudaArch::SM_62: + return "sm_62"; + } + llvm_unreachable("invalid enum"); +} + +CudaArch StringToCudaArch(llvm::StringRef S) { + return llvm::StringSwitch<CudaArch>(S) + .Case("sm_20", CudaArch::SM_20) + .Case("sm_21", CudaArch::SM_21) + .Case("sm_30", CudaArch::SM_30) + .Case("sm_32", CudaArch::SM_32) + .Case("sm_35", CudaArch::SM_35) + .Case("sm_37", CudaArch::SM_37) + .Case("sm_50", CudaArch::SM_50) + .Case("sm_52", CudaArch::SM_52) + .Case("sm_53", CudaArch::SM_53) + .Case("sm_60", CudaArch::SM_60) + .Case("sm_61", CudaArch::SM_61) + .Case("sm_62", CudaArch::SM_62) + .Default(CudaArch::UNKNOWN); +} + +const char *CudaVirtualArchToString(CudaVirtualArch A) { + switch (A) { + case CudaVirtualArch::UNKNOWN: + return "unknown"; + case CudaVirtualArch::COMPUTE_20: + return "compute_20"; + case CudaVirtualArch::COMPUTE_30: + return "compute_30"; + case CudaVirtualArch::COMPUTE_32: + return "compute_32"; + case CudaVirtualArch::COMPUTE_35: + return "compute_35"; + case CudaVirtualArch::COMPUTE_37: + return "compute_37"; + case CudaVirtualArch::COMPUTE_50: + return "compute_50"; + case CudaVirtualArch::COMPUTE_52: + return "compute_52"; + case CudaVirtualArch::COMPUTE_53: + return "compute_53"; + case CudaVirtualArch::COMPUTE_60: + return "compute_60"; + case CudaVirtualArch::COMPUTE_61: + return "compute_61"; + case CudaVirtualArch::COMPUTE_62: + return "compute_62"; + } + llvm_unreachable("invalid enum"); +} + +CudaVirtualArch StringToCudaVirtualArch(llvm::StringRef S) { + return llvm::StringSwitch<CudaVirtualArch>(S) + .Case("compute_20", CudaVirtualArch::COMPUTE_20) + .Case("compute_30", CudaVirtualArch::COMPUTE_30) + .Case("compute_32", CudaVirtualArch::COMPUTE_32) + .Case("compute_35", CudaVirtualArch::COMPUTE_35) + .Case("compute_37", CudaVirtualArch::COMPUTE_37) + .Case("compute_50", CudaVirtualArch::COMPUTE_50) + .Case("compute_52", CudaVirtualArch::COMPUTE_52) + .Case("compute_53", CudaVirtualArch::COMPUTE_53) + .Case("compute_60", CudaVirtualArch::COMPUTE_60) + .Case("compute_61", CudaVirtualArch::COMPUTE_61) + .Case("compute_62", CudaVirtualArch::COMPUTE_62) + .Default(CudaVirtualArch::UNKNOWN); +} + +CudaVirtualArch VirtualArchForCudaArch(CudaArch A) { + switch (A) { + case CudaArch::UNKNOWN: + return CudaVirtualArch::UNKNOWN; + case CudaArch::SM_20: + case CudaArch::SM_21: + return CudaVirtualArch::COMPUTE_20; + case CudaArch::SM_30: + return CudaVirtualArch::COMPUTE_30; + case CudaArch::SM_32: + return CudaVirtualArch::COMPUTE_32; + case CudaArch::SM_35: + return CudaVirtualArch::COMPUTE_35; + case CudaArch::SM_37: + return CudaVirtualArch::COMPUTE_37; + case CudaArch::SM_50: + return CudaVirtualArch::COMPUTE_50; + case CudaArch::SM_52: + return CudaVirtualArch::COMPUTE_52; + case CudaArch::SM_53: + return CudaVirtualArch::COMPUTE_53; + case CudaArch::SM_60: + return CudaVirtualArch::COMPUTE_60; + case CudaArch::SM_61: + return CudaVirtualArch::COMPUTE_61; + case CudaArch::SM_62: + return CudaVirtualArch::COMPUTE_62; + } + llvm_unreachable("invalid enum"); +} + +CudaVersion MinVersionForCudaArch(CudaArch A) { + switch (A) { + case CudaArch::UNKNOWN: + return CudaVersion::UNKNOWN; + case CudaArch::SM_20: + case CudaArch::SM_21: + case CudaArch::SM_30: + case CudaArch::SM_32: + case CudaArch::SM_35: + case CudaArch::SM_37: + case CudaArch::SM_50: + case CudaArch::SM_52: + case CudaArch::SM_53: + return CudaVersion::CUDA_70; + case CudaArch::SM_60: + case CudaArch::SM_61: + case CudaArch::SM_62: + return CudaVersion::CUDA_80; + } + llvm_unreachable("invalid enum"); +} + +} // namespace clang diff --git a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp index 7cf7305..f10d156 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp @@ -68,6 +68,7 @@ DiagnosticsEngine::DiagnosticsEngine( WarningsAsErrors = false; EnableAllWarnings = false; ErrorsAsFatal = false; + FatalsAsError = false; SuppressSystemWarnings = false; SuppressAllDiagnostics = false; ElideType = true; diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp index a34c7fec..3c370f6 100644 --- a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp @@ -351,7 +351,7 @@ bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) { if (DiagID >= diag::DIAG_UPPER_LIMIT) return false; - return GetDefaultDiagMapping(DiagID).getSeverity() == diag::Severity::Error; + return GetDefaultDiagMapping(DiagID).getSeverity() >= diag::Severity::Error; } /// getDescription - Given a diagnostic ID, return a description of the @@ -462,6 +462,12 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, Result = diag::Severity::Fatal; } + // If explicitly requested, map fatal errors to errors. + if (Result == diag::Severity::Fatal) { + if (Diag.FatalsAsError) + Result = diag::Severity::Error; + } + // Custom diagnostics always are emitted in system headers. bool ShowInSystemHeader = !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader; diff --git a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp index cb3f75c..ce9b7e1 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp @@ -19,7 +19,6 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemStatCache.h" -#include "clang/Frontend/PCHContainerOperations.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/llvm-config.h" #include "llvm/ADT/STLExtras.h" @@ -124,7 +123,7 @@ static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr, void FileManager::addAncestorsAsVirtualDirs(StringRef Path) { StringRef DirName = llvm::sys::path::parent_path(Path); if (DirName.empty()) - return; + DirName = "."; auto &NamedDirEnt = *SeenDirEntries.insert(std::make_pair(DirName, nullptr)).first; @@ -313,6 +312,9 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, UFE.InPCH = Data.InPCH; UFE.File = std::move(F); UFE.IsValid = true; + if (UFE.File) + if (auto RealPathName = UFE.File->getName()) + UFE.RealPathName = *RealPathName; return &UFE; } @@ -564,7 +566,3 @@ void FileManager::PrintStats() const { //llvm::errs() << PagesMapped << BytesOfPagesMapped << FSLookups; } - -// Virtual destructors for abstract base classes that need live in Basic. -PCHContainerWriter::~PCHContainerWriter() {} -PCHContainerReader::~PCHContainerReader() {} diff --git a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp index 67de1cb..d6ad0f5 100644 --- a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp @@ -42,6 +42,7 @@ IdentifierInfo::IdentifierInfo() { NeedsHandleIdentifier = false; IsFromAST = false; ChangedAfterLoad = false; + FEChangedAfterLoad = false; RevertedTokenID = false; OutOfDate = false; IsModulesImport = false; diff --git a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp index 1b08b06..8c0ecd4 100644 --- a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp @@ -34,7 +34,6 @@ void LangOptions::resetNonModularOptions() { SanitizerBlacklistFiles.clear(); CurrentModule.clear(); - ImplementationOfModule.clear(); } bool LangOptions::isNoBuiltinFunc(const char *Name) const { diff --git a/contrib/llvm/tools/clang/lib/Basic/Module.cpp b/contrib/llvm/tools/clang/lib/Basic/Module.cpp index 0b78326..3d1a40d 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Module.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Module.cpp @@ -418,12 +418,8 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { OS.indent(Indent + 2); OS << "export "; printModuleId(OS, UnresolvedExports[I].Id); - if (UnresolvedExports[I].Wildcard) { - if (UnresolvedExports[I].Id.empty()) - OS << "*"; - else - OS << ".*"; - } + if (UnresolvedExports[I].Wildcard) + OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"); OS << "\n"; } @@ -486,12 +482,13 @@ void Module::print(raw_ostream &OS, unsigned Indent) const { OS << "}\n"; } -void Module::dump() const { +LLVM_DUMP_METHOD void Module::dump() const { print(llvm::errs()); } void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, VisibleCallback Vis, ConflictCallback Cb) { + assert(Loc.isValid() && "setVisible expects a valid import location"); if (isVisible(M)) return; diff --git a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp index 577132d..d1e4779 100644 --- a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp @@ -55,6 +55,7 @@ OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) { return llvm::StringSwitch<OpenMPClauseKind>(Str) #define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name) #include "clang/Basic/OpenMPKinds.def" + .Case("uniform", OMPC_uniform) .Default(OMPC_unknown); } @@ -67,6 +68,8 @@ const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) { case OMPC_##Name: \ return #Name; #include "clang/Basic/OpenMPKinds.def" + case OMPC_uniform: + return "uniform"; case OMPC_threadprivate: return "threadprivate or thread local"; } @@ -109,6 +112,19 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, #define OPENMP_MAP_KIND(Name) .Case(#Name, OMPC_MAP_##Name) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_MAP_unknown); + case OMPC_dist_schedule: + return llvm::StringSwitch<OpenMPDistScheduleClauseKind>(Str) +#define OPENMP_DIST_SCHEDULE_KIND(Name) .Case(#Name, OMPC_DIST_SCHEDULE_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_DIST_SCHEDULE_unknown); + case OMPC_defaultmap: + return llvm::StringSwitch<unsigned>(Str) +#define OPENMP_DEFAULTMAP_KIND(Name) \ + .Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_##Name)) +#define OPENMP_DEFAULTMAP_MODIFIER(Name) \ + .Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_MODIFIER_##Name)) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_DEFAULTMAP_unknown); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -145,6 +161,11 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_nogroup: case OMPC_num_tasks: case OMPC_hint: + case OMPC_uniform: + case OMPC_to: + case OMPC_from: + case OMPC_use_device_ptr: + case OMPC_is_device_ptr: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); @@ -219,6 +240,30 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, break; } llvm_unreachable("Invalid OpenMP 'map' clause type"); + case OMPC_dist_schedule: + switch (Type) { + case OMPC_DIST_SCHEDULE_unknown: + return "unknown"; +#define OPENMP_DIST_SCHEDULE_KIND(Name) \ + case OMPC_DIST_SCHEDULE_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'dist_schedule' clause type"); + case OMPC_defaultmap: + switch (Type) { + case OMPC_DEFAULTMAP_unknown: + case OMPC_DEFAULTMAP_MODIFIER_last: + return "unknown"; +#define OPENMP_DEFAULTMAP_KIND(Name) \ + case OMPC_DEFAULTMAP_##Name: \ + return #Name; +#define OPENMP_DEFAULTMAP_MODIFIER(Name) \ + case OMPC_DEFAULTMAP_MODIFIER_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'schedule' clause type"); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -255,6 +300,11 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_nogroup: case OMPC_num_tasks: case OMPC_hint: + case OMPC_uniform: + case OMPC_to: + case OMPC_from: + case OMPC_use_device_ptr: + case OMPC_is_device_ptr: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); @@ -398,6 +448,56 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_target_enter_data: + switch (CKind) { +#define OPENMP_TARGET_ENTER_DATA_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_exit_data: + switch (CKind) { +#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_parallel: + switch (CKind) { +#define OPENMP_TARGET_PARALLEL_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_parallel_for: + switch (CKind) { +#define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_update: + switch (CKind) { +#define OPENMP_TARGET_UPDATE_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; case OMPD_teams: switch (CKind) { #define OPENMP_TEAMS_CLAUSE(Name) \ @@ -408,6 +508,8 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_declare_simd: + break; case OMPD_cancel: switch (CKind) { #define OPENMP_CANCEL_CLAUSE(Name) \ @@ -468,6 +570,48 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_distribute_parallel_for: + switch (CKind) { +#define OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_distribute_parallel_for_simd: + switch (CKind) { +#define OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_distribute_simd: + switch (CKind) { +#define OPENMP_DISTRIBUTE_SIMD_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; + case OMPD_target_parallel_for_simd: + switch (CKind) { +#define OPENMP_TARGET_PARALLEL_FOR_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: case OMPD_threadprivate: case OMPD_section: @@ -477,6 +621,7 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, case OMPD_taskwait: case OMPD_taskgroup: case OMPD_cancellation_point: + case OMPD_declare_reduction: break; } return false; @@ -485,17 +630,25 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_simd || DKind == OMPD_for || DKind == OMPD_for_simd || DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd || - DKind == OMPD_taskloop || - DKind == OMPD_taskloop_simd || - DKind == OMPD_distribute; // TODO add next directives. + DKind == OMPD_taskloop || DKind == OMPD_taskloop_simd || + DKind == OMPD_distribute || DKind == OMPD_target_parallel_for || + 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. } bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_for || DKind == OMPD_for_simd || DKind == OMPD_sections || DKind == OMPD_section || DKind == OMPD_single || DKind == OMPD_parallel_for || - DKind == OMPD_parallel_for_simd || - DKind == OMPD_parallel_sections; // TODO add next directives. + DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections || + 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. } bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) { @@ -504,12 +657,24 @@ bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) { bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_parallel || DKind == OMPD_parallel_for || - DKind == OMPD_parallel_for_simd || - DKind == OMPD_parallel_sections; // TODO add next directives. + DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections || + 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. } -bool clang::isOpenMPTargetDirective(OpenMPDirectiveKind DKind) { - return DKind == OMPD_target; // TODO add next directives. +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; +} + +bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) { + return DKind == OMPD_target_data || DKind == OMPD_target_enter_data || + DKind == OMPD_target_exit_data || DKind == OMPD_target_update; } bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) { @@ -518,12 +683,17 @@ bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) { bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) { return DKind == OMPD_simd || DKind == OMPD_for_simd || - DKind == OMPD_parallel_for_simd || - DKind == OMPD_taskloop_simd; // TODO add next directives. + DKind == OMPD_parallel_for_simd || DKind == OMPD_taskloop_simd || + DKind == OMPD_distribute_parallel_for_simd || + DKind == OMPD_distribute_simd; + // TODO add next directives. } bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) { - return Kind == OMPD_distribute; // TODO add next directives. + 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::isOpenMPPrivate(OpenMPClauseKind Kind) { @@ -536,3 +706,12 @@ bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) { return Kind == OMPC_threadprivate || Kind == OMPC_copyin; } +bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) { + return Kind == OMPD_task || isOpenMPTaskLoopDirective(Kind); +} + +bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) { + return Kind == OMPD_distribute_parallel_for || + Kind == OMPD_distribute_parallel_for_simd || + Kind == OMPD_distribute_simd; +} diff --git a/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp b/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp index ade8d6d..384d23c 100644 --- a/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp @@ -53,6 +53,7 @@ prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, case tok::pipeequal: return prec::Assignment; case tok::question: return prec::Conditional; case tok::pipepipe: return prec::LogicalOr; + case tok::caretcaret: case tok::ampamp: return prec::LogicalAnd; case tok::pipe: return prec::InclusiveOr; case tok::caret: return prec::ExclusiveOr; diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp index 4c50161..1e83b63 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp @@ -1160,7 +1160,8 @@ unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos, // isInvalid - Return the result of calling loc.isInvalid(), and // if Invalid is not null, set its value to same. -static bool isInvalid(SourceLocation Loc, bool *Invalid) { +template<typename LocType> +static bool isInvalid(LocType Loc, bool *Invalid) { bool MyInvalid = Loc.isInvalid(); if (Invalid) *Invalid = MyInvalid; @@ -1183,8 +1184,9 @@ unsigned SourceManager::getExpansionColumnNumber(SourceLocation Loc, unsigned SourceManager::getPresumedColumnNumber(SourceLocation Loc, bool *Invalid) const { - if (isInvalid(Loc, Invalid)) return 0; - return getPresumedLoc(Loc).getColumn(); + PresumedLoc PLoc = getPresumedLoc(Loc); + if (isInvalid(PLoc, Invalid)) return 0; + return PLoc.getColumn(); } #ifdef __SSE2__ @@ -1258,15 +1260,19 @@ FoundSpecialChar: if (Buf[0] == '\n' || Buf[0] == '\r') { // If this is \n\r or \r\n, skip both characters. - if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1]) - ++Offs, ++Buf; - ++Offs, ++Buf; + if ((Buf[1] == '\n' || Buf[1] == '\r') && Buf[0] != Buf[1]) { + ++Offs; + ++Buf; + } + ++Offs; + ++Buf; LineOffsets.push_back(Offs); } else { // Otherwise, this is a null. If end of file, exit. if (Buf == End) break; // Otherwise, skip the null. - ++Offs, ++Buf; + ++Offs; + ++Buf; } } @@ -1388,8 +1394,9 @@ unsigned SourceManager::getExpansionLineNumber(SourceLocation Loc, } unsigned SourceManager::getPresumedLineNumber(SourceLocation Loc, bool *Invalid) const { - if (isInvalid(Loc, Invalid)) return 0; - return getPresumedLoc(Loc).getLine(); + PresumedLoc PLoc = getPresumedLoc(Loc); + if (isInvalid(PLoc, Invalid)) return 0; + return PLoc.getLine(); } /// getFileCharacteristic - return the file characteristic of the specified @@ -2089,10 +2096,10 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, // Clear the lookup cache, it depends on a common location. IsBeforeInTUCache.clear(); - llvm::MemoryBuffer *LBuf = getBuffer(LOffs.first); - llvm::MemoryBuffer *RBuf = getBuffer(ROffs.first); - bool LIsBuiltins = strcmp("<built-in>", LBuf->getBufferIdentifier()) == 0; - bool RIsBuiltins = strcmp("<built-in>", RBuf->getBufferIdentifier()) == 0; + 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; // Sort built-in before non-built-in. if (LIsBuiltins || RIsBuiltins) { if (LIsBuiltins != RIsBuiltins) @@ -2101,8 +2108,8 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, // lower IDs come first. return LOffs.first < ROffs.first; } - bool LIsAsm = strcmp("<inline asm>", LBuf->getBufferIdentifier()) == 0; - bool RIsAsm = strcmp("<inline asm>", RBuf->getBufferIdentifier()) == 0; + bool LIsAsm = strcmp("<inline asm>", LB) == 0; + bool RIsAsm = strcmp("<inline asm>", RB) == 0; // Sort assembler after built-ins, but before the rest. if (LIsAsm || RIsAsm) { if (LIsAsm != RIsAsm) @@ -2110,6 +2117,14 @@ 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; + // Sort scratch after inline asm, but before the rest. + if (LIsScratch || RIsScratch) { + if (LIsScratch != RIsScratch) + return LIsScratch; + return LOffs.second < ROffs.second; + } llvm_unreachable("Unsortable locations found"); } diff --git a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp index 1648a27..92f658a 100644 --- a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp @@ -30,6 +30,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { BigEndian = true; TLSSupported = true; NoAsmVariants = false; + HasFloat128 = false; PointerWidth = PointerAlign = 32; BoolWidth = BoolAlign = 8; IntWidth = IntAlign = 32; @@ -46,6 +47,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { DoubleAlign = 64; LongDoubleWidth = 64; LongDoubleAlign = 64; + Float128Align = 128; LargeArrayMinWidth = 0; LargeArrayAlign = 0; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0; @@ -66,13 +68,13 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { UseSignedCharForObjCBool = true; UseBitFieldTypeAlignment = true; UseZeroLengthBitfieldAlignment = false; + UseExplicitBitFieldAlignment = true; ZeroLengthBitfieldBoundary = 0; HalfFormat = &llvm::APFloat::IEEEhalf; FloatFormat = &llvm::APFloat::IEEEsingle; DoubleFormat = &llvm::APFloat::IEEEdouble; LongDoubleFormat = &llvm::APFloat::IEEEdouble; - DataLayoutString = nullptr; - UserLabelPrefix = "_"; + Float128Format = &llvm::APFloat::IEEEquad; MCountName = "mcount"; RegParmMax = 0; SSERegParmMax = 0; @@ -224,6 +226,8 @@ TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const { if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble || &getLongDoubleFormat() == &llvm::APFloat::IEEEquad) return LongDouble; + if (hasFloat128Type()) + return Float128; break; } @@ -276,6 +280,10 @@ void TargetInfo::adjust(const LangOptions &Opts) { UseBitFieldTypeAlignment = false; if (Opts.ShortWChar) WCharType = UnsignedShort; + if (Opts.AlignDouble) { + DoubleAlign = LongLongAlign = 64; + LongDoubleAlign = 64; + } if (Opts.OpenCL) { // OpenCL C requires specific widths for types, irrespective of diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index 7fce33a..be5d4ad 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -12,12 +12,13 @@ // //===----------------------------------------------------------------------===// -#include "clang/Basic/TargetInfo.h" #include "clang/Basic/Builtins.h" +#include "clang/Basic/Cuda.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/MacroBuilder.h" #include "clang/Basic/TargetBuiltins.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Basic/Version.h" #include "llvm/ADT/APFloat.h" @@ -65,6 +66,9 @@ static void defineCPUMacros(MacroBuilder &Builder, StringRef CPUName, Builder.defineMacro("__tune_" + CPUName + "__"); } +static TargetInfo *AllocateTarget(const llvm::Triple &Triple, + const TargetOptions &Opts); + //===----------------------------------------------------------------------===// // Defines specific to certain operating systems. //===----------------------------------------------------------------------===// @@ -76,7 +80,8 @@ protected: virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const=0; public: - OSTargetInfo(const llvm::Triple &Triple) : TgtInfo(Triple) {} + OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : TgtInfo(Triple, Opts) {} void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { TgtInfo::getTargetDefines(Opts, Builder); @@ -101,10 +106,8 @@ protected: } public: - CloudABITargetInfo(const llvm::Triple &Triple) - : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; - } + CloudABITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) {} }; static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, @@ -139,7 +142,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, unsigned Maj, Min, Rev; if (Triple.isMacOSX()) { Triple.getMacOSXVersion(Maj, Min, Rev); - PlatformName = "macosx"; + PlatformName = "macos"; } else { Triple.getOSVersion(Maj, Min, Rev); PlatformName = llvm::Triple::getOSTypeName(Triple.getOS()); @@ -155,14 +158,25 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, // Set the appropriate OS version define. if (Triple.isiOS()) { - assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!"); - char Str[6]; - Str[0] = '0' + Maj; - Str[1] = '0' + (Min / 10); - Str[2] = '0' + (Min % 10); - Str[3] = '0' + (Rev / 10); - Str[4] = '0' + (Rev % 10); - Str[5] = '\0'; + assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!"); + char Str[7]; + if (Maj < 10) { + Str[0] = '0' + Maj; + Str[1] = '0' + (Min / 10); + Str[2] = '0' + (Min % 10); + Str[3] = '0' + (Rev / 10); + Str[4] = '0' + (Rev % 10); + Str[5] = '\0'; + } else { + // Handle versions >= 10. + Str[0] = '0' + (Maj / 10); + Str[1] = '0' + (Maj % 10); + Str[2] = '0' + (Min / 10); + Str[3] = '0' + (Min % 10); + Str[4] = '0' + (Rev / 10); + Str[5] = '0' + (Rev % 10); + Str[6] = '\0'; + } if (Triple.isTvOS()) Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str); else @@ -209,6 +223,10 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, if (Triple.isOSDarwin()) Builder.defineMacro("__MACH__"); + // The Watch ABI uses Dwarf EH. + if(Triple.isWatchABI()) + Builder.defineMacro("__ARM_DWARF_EH__"); + PlatformMinVersion = VersionTuple(Maj, Min, Rev); } @@ -222,7 +240,8 @@ protected: } public: - DarwinTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + DarwinTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { // By default, no TLS, and we whitelist permitted architecture/OS // combinations. this->TLSSupported = false; @@ -264,6 +283,13 @@ public: bool hasProtectedVisibility() const override { return false; } + + unsigned getExnObjectAlignment() const override { + // The alignment of an exception object is 8-bytes for darwin since + // libc++abi doesn't declare _Unwind_Exception with __attribute__((aligned)) + // and therefore doesn't guarantee 16-byte alignment. + return 64; + } }; @@ -282,10 +308,8 @@ protected: DefineStd(Builder, "unix", Opts); } public: - DragonFlyBSDTargetInfo(const llvm::Triple &Triple) - : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; - + DragonFlyBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { switch (Triple.getArch()) { default: case llvm::Triple::x86: @@ -333,9 +357,8 @@ protected: Builder.defineMacro("__STDC_MB_MIGHT_NEQ_WC__", "1"); } public: - FreeBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; - + FreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { switch (Triple.getArch()) { default: case llvm::Triple::x86: @@ -374,9 +397,30 @@ protected: Builder.defineMacro("_GNU_SOURCE"); } public: - KFreeBSDTargetInfo(const llvm::Triple &Triple) - : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; + KFreeBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) {} +}; + +// Haiku Target +template<typename Target> +class HaikuTargetInfo : public OSTargetInfo<Target> { +protected: + void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, + MacroBuilder &Builder) const override { + // Haiku defines; list based off of gcc output + Builder.defineMacro("__HAIKU__"); + Builder.defineMacro("__ELF__"); + DefineStd(Builder, "unix", Opts); + } +public: + HaikuTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { + this->SizeType = TargetInfo::UnsignedLong; + this->IntPtrType = TargetInfo::SignedLong; + this->PtrDiffType = TargetInfo::SignedLong; + this->ProcessIDType = TargetInfo::SignedLong; + this->TLSSupported = false; + } }; @@ -399,9 +443,8 @@ protected: DefineStd(Builder, "unix", Opts); } public: - MinixTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; - } + MinixTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) {} }; // Linux target @@ -426,10 +469,12 @@ protected: Builder.defineMacro("_REENTRANT"); if (Opts.CPlusPlus) Builder.defineMacro("_GNU_SOURCE"); + if (this->HasFloat128) + Builder.defineMacro("__FLOAT128__"); } public: - LinuxTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; + LinuxTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { this->WIntType = TargetInfo::UnsignedInt; switch (Triple.getArch()) { @@ -440,6 +485,11 @@ public: case llvm::Triple::ppc64le: this->MCountName = "_mcount"; break; + case llvm::Triple::x86: + case llvm::Triple::x86_64: + case llvm::Triple::systemz: + this->HasFloat128 = true; + break; } } @@ -473,8 +523,8 @@ protected: } } public: - NetBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; + NetBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { this->MCountName = "_mcount"; } }; @@ -494,8 +544,8 @@ protected: Builder.defineMacro("_REENTRANT"); } public: - OpenBSDTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; + OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { this->TLSSupported = false; switch (Triple.getArch()) { @@ -542,8 +592,8 @@ protected: } } public: - BitrigTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; + BitrigTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { this->MCountName = "__mcount"; } }; @@ -561,9 +611,7 @@ protected: Builder.defineMacro("__ELF__"); } public: - PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; - } + PSPTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) {} }; // PS3 PPU Target @@ -582,14 +630,14 @@ protected: Builder.defineMacro("__powerpc64__"); } public: - PS3PPUTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; + PS3PPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { this->LongWidth = this->LongAlign = 32; this->PointerWidth = this->PointerAlign = 32; this->IntMaxType = TargetInfo::SignedLongLong; this->Int64Type = TargetInfo::SignedLongLong; this->SizeType = TargetInfo::UnsignedInt; - this->DataLayoutString = "E-m:e-p:32:32-i64:64-n32:64"; + this->resetDataLayout("E-m:e-p:32:32-i64:64-n32:64"); } }; @@ -603,15 +651,19 @@ protected: Builder.defineMacro("__KPRINTF_ATTRIBUTE__"); DefineStd(Builder, "unix", Opts); Builder.defineMacro("__ELF__"); - Builder.defineMacro("__PS4__"); + Builder.defineMacro("__ORBIS__"); } public: - PS4OSTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { + PS4OSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { this->WCharType = this->UnsignedShort; // On PS4, TLS variable cannot be aligned to more than 32 bytes (256 bits). this->MaxTLSAlign = 256; - this->UserLabelPrefix = ""; + + // On PS4, do not honor explicit bit field alignment, + // as in "__attribute__((aligned(2))) int b : 1;". + this->UseExplicitBitFieldAlignment = false; switch (Triple.getArch()) { default: @@ -649,8 +701,8 @@ protected: Builder.defineMacro("_REENTRANT"); } public: - SolarisTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; + SolarisTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { this->WCharType = this->SignedInt; // FIXME: WIntType should be SignedLong } @@ -694,6 +746,13 @@ protected: if (Opts.CPlusPlus11 && Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1)); + + if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) { + if (Opts.CPlusPlus1z) + Builder.defineMacro("_MSVC_LANG", "201403L"); + else if (Opts.CPlusPlus14) + Builder.defineMacro("_MSVC_LANG", "201402L"); + } } if (Opts.MicrosoftExt) { @@ -710,8 +769,8 @@ protected: } public: - WindowsTargetInfo(const llvm::Triple &Triple) - : OSTargetInfo<Target>(Triple) {} + WindowsTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) {} }; template <typename Target> @@ -730,8 +789,8 @@ protected: } public: - NaClTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; + NaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { this->LongAlign = 32; this->LongWidth = 32; this->PointerAlign = 32; @@ -751,14 +810,14 @@ public: if (Triple.getArch() == llvm::Triple::arm) { // Handled in ARM's setABI(). } else if (Triple.getArch() == llvm::Triple::x86) { - this->DataLayoutString = "e-m:e-p:32:32-i64:64-n8:16:32-S128"; + this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32-S128"); } else if (Triple.getArch() == llvm::Triple::x86_64) { - this->DataLayoutString = "e-m:e-p:32:32-i64:64-n8:16:32:64-S128"; + this->resetDataLayout("e-m:e-p:32:32-i64:64-n8:16:32:64-S128"); } else if (Triple.getArch() == llvm::Triple::mipsel) { - // Handled on mips' setDataLayoutString. + // Handled on mips' setDataLayout. } else { assert(Triple.getArch() == llvm::Triple::le32); - this->DataLayoutString = "e-p:32:32-i64:64"; + this->resetDataLayout("e-p:32:32-i64:64"); } } }; @@ -782,10 +841,10 @@ class WebAssemblyOSTargetInfo : public OSTargetInfo<Target> { } public: - explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple) - : OSTargetInfo<Target>(Triple) { + explicit WebAssemblyOSTargetInfo(const llvm::Triple &Triple, + const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { this->MCountName = "__mcount"; - this->UserLabelPrefix = ""; this->TheCXXABI.set(TargetCXXABI::WebAssembly); } }; @@ -815,7 +874,7 @@ protected: std::string ABI; public: - PPCTargetInfo(const llvm::Triple &Triple) + 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) { @@ -841,8 +900,9 @@ public: ArchDefinePwr6x = 1 << 10, ArchDefinePwr7 = 1 << 11, ArchDefinePwr8 = 1 << 12, - ArchDefineA2 = 1 << 13, - ArchDefineA2q = 1 << 14 + ArchDefinePwr9 = 1 << 13, + ArchDefineA2 = 1 << 14, + ArchDefineA2q = 1 << 15 } ArchDefineTypes; // Note: GCC recognizes the following additional cpus: @@ -891,6 +951,8 @@ public: .Case("pwr7", true) .Case("power8", true) .Case("pwr8", true) + .Case("power9", true) + .Case("pwr9", true) .Case("powerpc", true) .Case("ppc", true) .Case("powerpc64", true) @@ -1093,6 +1155,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasQPX = true; } else if (Feature == "+htm") { HasHTM = true; + } else if (Feature == "+float128") { + HasFloat128 = true; } // TODO: Finish this list and add an assert that we've handled them // all. @@ -1183,6 +1247,10 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, .Case("pwr8", ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("pwr9", ArchDefineName | ArchDefinePwr8 | ArchDefinePwr7 + | ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x + | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr + | ArchDefinePpcsq) .Case("power3", ArchDefinePpcgr) .Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) .Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr @@ -1200,6 +1268,10 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, .Case("power8", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("power9", ArchDefinePwr9 | ArchDefinePwr8 | ArchDefinePwr7 + | ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x + | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr + | ArchDefinePpcsq) .Default(ArchDefineNone); if (defs & ArchDefineName) @@ -1228,6 +1300,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("_ARCH_PWR7"); if (defs & ArchDefinePwr8) Builder.defineMacro("_ARCH_PWR8"); + if (defs & ArchDefinePwr9) + Builder.defineMacro("_ARCH_PWR9"); if (defs & ArchDefineA2) Builder.defineMacro("_ARCH_A2"); if (defs & ArchDefineA2q) { @@ -1250,6 +1324,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__CRYPTO__"); if (HasHTM) Builder.defineMacro("__HTM__"); + if (HasFloat128) + Builder.defineMacro("__FLOAT128__"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); @@ -1300,6 +1376,13 @@ static bool ppcUserFeaturesCheck(DiagnosticsEngine &Diags, << "-mno-vsx"; return false; } + + if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") != + FeaturesVec.end()) { + Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128" + << "-mno-vsx"; + return false; + } } return true; @@ -1318,6 +1401,7 @@ bool PPCTargetInfo::initFeatureMap( .Case("pwr6", true) .Case("pwr7", true) .Case("pwr8", true) + .Case("pwr9", true) .Case("ppc64", true) .Case("ppc64le", true) .Default(false); @@ -1325,28 +1409,34 @@ bool PPCTargetInfo::initFeatureMap( Features["qpx"] = (CPU == "a2q"); Features["crypto"] = llvm::StringSwitch<bool>(CPU) .Case("ppc64le", true) + .Case("pwr9", true) .Case("pwr8", true) .Default(false); Features["power8-vector"] = llvm::StringSwitch<bool>(CPU) .Case("ppc64le", true) + .Case("pwr9", true) .Case("pwr8", true) .Default(false); Features["bpermd"] = llvm::StringSwitch<bool>(CPU) .Case("ppc64le", true) + .Case("pwr9", true) .Case("pwr8", true) .Case("pwr7", true) .Default(false); Features["extdiv"] = llvm::StringSwitch<bool>(CPU) .Case("ppc64le", true) + .Case("pwr9", true) .Case("pwr8", true) .Case("pwr7", true) .Default(false); Features["direct-move"] = llvm::StringSwitch<bool>(CPU) .Case("ppc64le", true) + .Case("pwr9", true) .Case("pwr8", true) .Default(false); Features["vsx"] = llvm::StringSwitch<bool>(CPU) .Case("ppc64le", true) + .Case("pwr9", true) .Case("pwr8", true) .Case("pwr7", true) .Default(false); @@ -1368,6 +1458,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const { .Case("htm", HasHTM) .Case("bpermd", HasBPERMD) .Case("extdiv", HasExtDiv) + .Case("float128", HasFloat128) .Default(false); } @@ -1377,19 +1468,19 @@ 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 == "vsx") { - Features[Name] = true; - } else if (Name == "direct-move") { + if (Name == "direct-move") { Features[Name] = Features["vsx"] = true; } else if (Name == "power8-vector") { Features[Name] = Features["vsx"] = true; + } else if (Name == "float128") { + Features[Name] = Features["vsx"] = true; } else { Features[Name] = true; } } else { if (Name == "vsx") { Features[Name] = Features["direct-move"] = Features["power8-vector"] = - false; + Features["float128"] = false; } else { Features[Name] = false; } @@ -1497,8 +1588,9 @@ ArrayRef<TargetInfo::GCCRegAlias> PPCTargetInfo::getGCCRegAliases() const { class PPC32TargetInfo : public PPCTargetInfo { public: - PPC32TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) { - DataLayoutString = "E-m:e-p:32:32-i64:64-n32"; + PPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : PPCTargetInfo(Triple, Opts) { + resetDataLayout("E-m:e-p:32:32-i64:64-n32"); switch (getTriple().getOS()) { case llvm::Triple::Linux: @@ -1531,16 +1623,17 @@ public: // TargetInfo for little endian. class PPC64TargetInfo : public PPCTargetInfo { public: - PPC64TargetInfo(const llvm::Triple &Triple) : PPCTargetInfo(Triple) { + PPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : PPCTargetInfo(Triple, Opts) { LongWidth = LongAlign = PointerWidth = PointerAlign = 64; IntMaxType = SignedLong; Int64Type = SignedLong; if ((Triple.getArch() == llvm::Triple::ppc64le)) { - DataLayoutString = "e-m:e-i64:64-n32:64"; + resetDataLayout("e-m:e-i64:64-n32:64"); ABI = "elfv2"; } else { - DataLayoutString = "E-m:e-i64:64-n32:64"; + resetDataLayout("E-m:e-i64:64-n32:64"); ABI = "elfv1"; } @@ -1573,31 +1666,29 @@ public: } }; -class DarwinPPC32TargetInfo : - public DarwinTargetInfo<PPC32TargetInfo> { +class DarwinPPC32TargetInfo : public DarwinTargetInfo<PPC32TargetInfo> { public: - DarwinPPC32TargetInfo(const llvm::Triple &Triple) - : DarwinTargetInfo<PPC32TargetInfo>(Triple) { + DarwinPPC32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : DarwinTargetInfo<PPC32TargetInfo>(Triple, Opts) { HasAlignMac68kSupport = true; BoolWidth = BoolAlign = 32; //XXX support -mone-byte-bool? PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726 LongLongAlign = 32; SuitableAlign = 128; - DataLayoutString = "E-m:o-p:32:32-f64:32:64-n32"; + resetDataLayout("E-m:o-p:32:32-f64:32:64-n32"); } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } }; -class DarwinPPC64TargetInfo : - public DarwinTargetInfo<PPC64TargetInfo> { +class DarwinPPC64TargetInfo : public DarwinTargetInfo<PPC64TargetInfo> { public: - DarwinPPC64TargetInfo(const llvm::Triple &Triple) - : DarwinTargetInfo<PPC64TargetInfo>(Triple) { + DarwinPPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : DarwinTargetInfo<PPC64TargetInfo>(Triple, Opts) { HasAlignMac68kSupport = true; SuitableAlign = 128; - DataLayoutString = "E-m:o-i64:64-n32:64"; + resetDataLayout("E-m:o-i64:64-n32:64"); } }; @@ -1615,19 +1706,11 @@ static const unsigned NVPTXAddrSpaceMap[] = { class NVPTXTargetInfo : public TargetInfo { static const char *const GCCRegNames[]; static const Builtin::Info BuiltinInfo[]; - - // The GPU profiles supported by the NVPTX backend - enum GPUKind { - GK_NONE, - GK_SM20, - GK_SM21, - GK_SM30, - GK_SM35, - GK_SM37, - } GPU; + CudaArch GPU; public: - NVPTXTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : TargetInfo(Triple) { BigEndian = false; TLSSupported = false; LongWidth = LongAlign = 64; @@ -1636,8 +1719,66 @@ public: // Define available target features // These must be defined in sorted order! NoAsmVariants = true; - // Set the default GPU to sm20 - GPU = GK_SM20; + GPU = CudaArch::SM_20; + + // 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 (!HostTarget) { + return; + } + + PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0); + PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0); + BoolWidth = HostTarget->getBoolWidth(); + BoolAlign = HostTarget->getBoolAlign(); + IntWidth = HostTarget->getIntWidth(); + IntAlign = HostTarget->getIntAlign(); + HalfWidth = HostTarget->getHalfWidth(); + HalfAlign = HostTarget->getHalfAlign(); + FloatWidth = HostTarget->getFloatWidth(); + FloatAlign = HostTarget->getFloatAlign(); + DoubleWidth = HostTarget->getDoubleWidth(); + DoubleAlign = HostTarget->getDoubleAlign(); + LongWidth = HostTarget->getLongWidth(); + LongAlign = HostTarget->getLongAlign(); + LongLongWidth = HostTarget->getLongLongWidth(); + LongLongAlign = HostTarget->getLongLongAlign(); + MinGlobalAlign = HostTarget->getMinGlobalAlign(); + DefaultAlignForAttributeAligned = + HostTarget->getDefaultAlignForAttributeAligned(); + SizeType = HostTarget->getSizeType(); + IntMaxType = HostTarget->getIntMaxType(); + PtrDiffType = HostTarget->getPtrDiffType(/* AddrSpace = */ 0); + IntPtrType = HostTarget->getIntPtrType(); + WCharType = HostTarget->getWCharType(); + WIntType = HostTarget->getWIntType(); + Char16Type = HostTarget->getChar16Type(); + Char32Type = HostTarget->getChar32Type(); + Int64Type = HostTarget->getInt64Type(); + SigAtomicType = HostTarget->getSigAtomicType(); + ProcessIDType = HostTarget->getProcessIDType(); + + UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment(); + UseZeroLengthBitfieldAlignment = + HostTarget->useZeroLengthBitfieldAlignment(); + UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment(); + ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary(); + + // Properties intentionally not copied from host: + // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the + // host/device boundary. + // - SuitableAlign: Not visible across the host/device boundary, and may + // correctly be different on host/device, e.g. if host has wider vector + // types than device. + // - LongDoubleWidth, LongDoubleAlign: nvptx's long double type is the same + // as its double type, but that's not necessarily true on the host. + // TODO: nvcc emits a warning when using long double on device; we should + // do the same. } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -1645,26 +1786,38 @@ public: Builder.defineMacro("__NVPTX__"); if (Opts.CUDAIsDevice) { // Set __CUDA_ARCH__ for the GPU specified. - std::string CUDAArchCode; - switch (GPU) { - case GK_SM20: - CUDAArchCode = "200"; - break; - case GK_SM21: - CUDAArchCode = "210"; - break; - case GK_SM30: - CUDAArchCode = "300"; - break; - case GK_SM35: - CUDAArchCode = "350"; - break; - case GK_SM37: - CUDAArchCode = "370"; - break; - default: - llvm_unreachable("Unhandled target CPU"); - } + std::string CUDAArchCode = [this] { + switch (GPU) { + case CudaArch::UNKNOWN: + assert(false && "No GPU arch when compiling CUDA device code."); + return ""; + case CudaArch::SM_20: + return "200"; + case CudaArch::SM_21: + return "210"; + case CudaArch::SM_30: + return "300"; + case CudaArch::SM_32: + return "320"; + case CudaArch::SM_35: + return "350"; + case CudaArch::SM_37: + return "370"; + case CudaArch::SM_50: + return "500"; + case CudaArch::SM_52: + return "520"; + case CudaArch::SM_53: + return "530"; + case CudaArch::SM_60: + return "600"; + case CudaArch::SM_61: + return "610"; + case CudaArch::SM_62: + return "620"; + } + llvm_unreachable("unhandled CudaArch"); + }(); Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode); } } @@ -1705,15 +1858,21 @@ public: return TargetInfo::CharPtrBuiltinVaList; } bool setCPU(const std::string &Name) override { - GPU = llvm::StringSwitch<GPUKind>(Name) - .Case("sm_20", GK_SM20) - .Case("sm_21", GK_SM21) - .Case("sm_30", GK_SM30) - .Case("sm_35", GK_SM35) - .Case("sm_37", GK_SM37) - .Default(GK_NONE); - - return GPU != GK_NONE; + GPU = StringToCudaArch(Name); + return GPU != CudaArch::UNKNOWN; + } + 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.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; } }; @@ -1733,24 +1892,26 @@ ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const { class NVPTX32TargetInfo : public NVPTXTargetInfo { public: - NVPTX32TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) { + 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; - DataLayoutString = "e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"; + resetDataLayout("e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"); } }; class NVPTX64TargetInfo : public NVPTXTargetInfo { public: - NVPTX64TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) { + NVPTX64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : NVPTXTargetInfo(Triple, Opts) { PointerWidth = PointerAlign = 64; SizeType = TargetInfo::UnsignedLong; PtrDiffType = TargetInfo::SignedLong; IntPtrType = TargetInfo::SignedLong; - DataLayoutString = "e-i64:64-v16:16-v32:32-n16:32:64"; + resetDataLayout("e-i64:64-v16:16-v32:32-n16:32:64"); } }; @@ -1771,16 +1932,12 @@ static const char *const DataLayoutStringR600 = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; -static const char *const DataLayoutStringR600DoubleOps = - "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" - "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; - static const char *const DataLayoutStringSI = - "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-p24:64:64" + "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32" "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; -class AMDGPUTargetInfo : public TargetInfo { +class AMDGPUTargetInfo final : public TargetInfo { static const Builtin::Info BuiltinInfo[]; static const char * const GCCRegNames[]; @@ -1804,23 +1961,26 @@ class AMDGPUTargetInfo : public TargetInfo { bool hasFMAF:1; bool hasLDEXPF:1; -public: - AMDGPUTargetInfo(const llvm::Triple &Triple) - : TargetInfo(Triple) { + static bool isAMDGCN(const llvm::Triple &TT) { + return TT.getArch() == llvm::Triple::amdgcn; + } - if (Triple.getArch() == llvm::Triple::amdgcn) { - DataLayoutString = DataLayoutStringSI; - GPU = GK_SOUTHERN_ISLANDS; +public: + AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) , + GPU(isAMDGCN(Triple) ? GK_SOUTHERN_ISLANDS : GK_R600), + hasFP64(false), + hasFMAF(false), + hasLDEXPF(false) { + if (getTriple().getArch() == llvm::Triple::amdgcn) { hasFP64 = true; hasFMAF = true; hasLDEXPF = true; - } else { - DataLayoutString = DataLayoutStringR600; - GPU = GK_R600; - hasFP64 = false; - hasFMAF = false; - hasLDEXPF = false; } + + resetDataLayout(getTriple().getArch() == llvm::Triple::amdgcn ? + DataLayoutStringSI : DataLayoutStringR600); + AddrSpaceMap = &AMDGPUAddrSpaceMap; UseAddrSpaceMapMangling = true; } @@ -1861,6 +2021,10 @@ public: return false; } + bool initFeatureMap(llvm::StringMap<bool> &Features, + DiagnosticsEngine &Diags, StringRef CPU, + const std::vector<std::string> &FeatureVec) const override; + ArrayRef<Builtin::Info> getTargetBuiltins() const override { return llvm::makeArrayRef(BuiltinInfo, clang::AMDGPU::LastTSBuiltin - Builtin::FirstTSBuiltin); @@ -1868,30 +2032,25 @@ public: void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { - Builder.defineMacro("__R600__"); + if (getTriple().getArch() == llvm::Triple::amdgcn) + Builder.defineMacro("__AMDGCN__"); + else + Builder.defineMacro("__R600__"); + if (hasFMAF) Builder.defineMacro("__HAS_FMAF__"); if (hasLDEXPF) Builder.defineMacro("__HAS_LDEXPF__"); - if (hasFP64 && Opts.OpenCL) - Builder.defineMacro("cl_khr_fp64"); - if (Opts.OpenCL) { - if (GPU >= GK_NORTHERN_ISLANDS) { - Builder.defineMacro("cl_khr_byte_addressable_store"); - Builder.defineMacro("cl_khr_global_int32_base_atomics"); - Builder.defineMacro("cl_khr_global_int32_extended_atomics"); - Builder.defineMacro("cl_khr_local_int32_base_atomics"); - Builder.defineMacro("cl_khr_local_int32_extended_atomics"); - } - } + if (hasFP64) + Builder.defineMacro("__HAS_FP64__"); } BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } - bool setCPU(const std::string &Name) override { - GPU = llvm::StringSwitch<GPUKind>(Name) + static GPUKind parseR600Name(StringRef Name) { + return llvm::StringSwitch<GPUKind>(Name) .Case("r600" , GK_R600) .Case("rv610", GK_R600) .Case("rv620", GK_R600) @@ -1917,63 +2076,78 @@ public: .Case("caicos", GK_NORTHERN_ISLANDS) .Case("cayman", GK_CAYMAN) .Case("aruba", GK_CAYMAN) - .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) .Default(GK_NONE); + } - if (GPU == GK_NONE) { - return false; - } + 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) + .Default(GK_NONE); + } - // Set the correct data layout - switch (GPU) { - case GK_NONE: - case GK_R600: - case GK_R700: - case GK_EVERGREEN: - case GK_NORTHERN_ISLANDS: - DataLayoutString = DataLayoutStringR600; - hasFP64 = false; - hasFMAF = false; - hasLDEXPF = false; - break; - case GK_R600_DOUBLE_OPS: - case GK_R700_DOUBLE_OPS: - case GK_EVERGREEN_DOUBLE_OPS: - case GK_CAYMAN: - DataLayoutString = DataLayoutStringR600DoubleOps; - hasFP64 = true; - hasFMAF = true; - hasLDEXPF = false; - break; - case GK_SOUTHERN_ISLANDS: - case GK_SEA_ISLANDS: - case GK_VOLCANIC_ISLANDS: - DataLayoutString = DataLayoutStringSI; - hasFP64 = true; - hasFMAF = true; - hasLDEXPF = true; - break; + bool setCPU(const std::string &Name) override { + if (getTriple().getArch() == llvm::Triple::amdgcn) + GPU = parseAMDGCNName(Name); + else + GPU = parseR600Name(Name); + + return GPU != GK_NONE; + } + + void setSupportedOpenCLOpts() override { + auto &Opts = getSupportedOpenCLOpts(); + Opts.cl_clang_storage_class_specifiers = 1; + Opts.cl_khr_icd = 1; + + if (hasFP64) + Opts.cl_khr_fp64 = 1; + 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; } + 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; + } + } - return true; + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + default: + return CCCR_Warning; + case CC_C: + case CC_OpenCLKernel: + return CCCR_OK; + } } }; const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = { #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 }, #include "clang/Basic/BuiltinsAMDGPU.def" }; const char * const AMDGPUTargetInfo::GCCRegNames[] = { @@ -2024,15 +2198,66 @@ const char * const AMDGPUTargetInfo::GCCRegNames[] = { "s96", "s97", "s98", "s99", "s100", "s101", "s102", "s103", "s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111", "s112", "s113", "s114", "s115", "s116", "s117", "s118", "s119", - "s120", "s121", "s122", "s123", "s124", "s125", "s126", "s127" - "exec", "vcc", "scc", "m0", "flat_scr", "exec_lo", "exec_hi", - "vcc_lo", "vcc_hi", "flat_scr_lo", "flat_scr_hi" + "s120", "s121", "s122", "s123", "s124", "s125", "s126", "s127", + "exec", "vcc", "scc", "m0", "flat_scratch", "exec_lo", "exec_hi", + "vcc_lo", "vcc_hi", "flat_scratch_lo", "flat_scratch_hi" }; ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const { return llvm::makeArrayRef(GCCRegNames); } +bool AMDGPUTargetInfo::initFeatureMap( + llvm::StringMap<bool> &Features, + DiagnosticsEngine &Diags, StringRef CPU, + const std::vector<std::string> &FeatureVec) const { + + // XXX - What does the member GPU mean if device name string passed here? + if (getTriple().getArch() == llvm::Triple::amdgcn) { + if (CPU.empty()) + CPU = "tahiti"; + + switch (parseAMDGCNName(CPU)) { + case GK_SOUTHERN_ISLANDS: + case GK_SEA_ISLANDS: + break; + + case GK_VOLCANIC_ISLANDS: + Features["s-memrealtime"] = true; + Features["16-bit-insts"] = true; + break; + + case GK_NONE: + return false; + default: + llvm_unreachable("unhandled subtarget"); + } + } else { + if (CPU.empty()) + CPU = "r600"; + + switch (parseR600Name(CPU)) { + case GK_R600: + case GK_R700: + case GK_EVERGREEN: + case GK_NORTHERN_ISLANDS: + break; + case GK_R600_DOUBLE_OPS: + case GK_R700_DOUBLE_OPS: + case GK_EVERGREEN_DOUBLE_OPS: + case GK_CAYMAN: + Features["fp64"] = true; + break; + case GK_NONE: + return false; + default: + llvm_unreachable("unhandled subtarget"); + } + } + + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec); +} + // Namespace for x86 abstract base class const Builtin::Info BuiltinInfo[] = { #define BUILTIN(ID, TYPE, ATTRS) \ @@ -2054,6 +2279,14 @@ static const char* const GCCRegNames[] = { "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15", + "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23", + "xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31", + "ymm16", "ymm17", "ymm18", "ymm19", "ymm20", "ymm21", "ymm22", "ymm23", + "ymm24", "ymm25", "ymm26", "ymm27", "ymm28", "ymm29", "ymm30", "ymm31", + "zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7", + "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15", + "zmm16", "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", + "zmm24", "zmm25", "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31", }; const TargetInfo::AddlRegName AddlRegNames[] = { @@ -2112,14 +2345,25 @@ class X86TargetInfo : public TargetInfo { bool HasAVX512DQ = false; bool HasAVX512BW = false; bool HasAVX512VL = false; + bool HasAVX512VBMI = false; + bool HasAVX512IFMA = false; bool HasSHA = false; + bool HasMPX = false; + bool HasSGX = false; bool HasCX16 = false; bool HasFXSR = false; bool HasXSAVE = false; bool HasXSAVEOPT = false; bool HasXSAVEC = false; bool HasXSAVES = false; + bool HasMWAITX = false; bool HasPKU = false; + bool HasCLFLUSHOPT = false; + bool HasPCOMMIT = false; + bool HasCLWB = false; + bool HasUMIP = false; + bool HasMOVBE = false; + bool HasPREFETCHWT1 = false; /// \brief Enumeration of all of the X86 CPUs supported by Clang. /// @@ -2220,14 +2464,26 @@ class X86TargetInfo : public TargetInfo { /// Broadwell microarchitecture based processors. CK_Broadwell, - /// \name Skylake - /// Skylake microarchitecture based processors. - CK_Skylake, + /// \name Skylake Client + /// Skylake client microarchitecture based processors. + CK_SkylakeClient, + + /// \name Skylake Server + /// Skylake server microarchitecture based processors. + CK_SkylakeServer, + + /// \name Cannonlake Client + /// Cannonlake client microarchitecture based processors. + CK_Cannonlake, /// \name Knights Landing /// Knights Landing processor. CK_KNL, + /// \name Lakemont + /// Lakemont microarchitecture based processors. + CK_Lakemont, + /// \name K6 /// K6 architecture processors. //@{ @@ -2327,9 +2583,12 @@ class X86TargetInfo : public TargetInfo { .Case("haswell", CK_Haswell) .Case("core-avx2", CK_Haswell) // Legacy name. .Case("broadwell", CK_Broadwell) - .Case("skylake", CK_Skylake) - .Case("skx", CK_Skylake) // Legacy name. + .Case("skylake", CK_SkylakeClient) + .Case("skylake-avx512", CK_SkylakeServer) + .Case("skx", CK_SkylakeServer) // Legacy name. + .Case("cannonlake", CK_Cannonlake) .Case("knl", CK_KNL) + .Case("lakemont", CK_Lakemont) .Case("k6", CK_K6) .Case("k6-2", CK_K6_2) .Case("k6-3", CK_K6_3) @@ -2365,7 +2624,8 @@ class X86TargetInfo : public TargetInfo { } FPMath = FP_Default; public: - X86TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + X86TargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { BigEndian = false; LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } @@ -2477,6 +2737,7 @@ public: case CK_C3_2: case CK_Pentium4: case CK_Pentium4M: + case CK_Lakemont: case CK_Prescott: case CK_K6: case CK_K6_2: @@ -2503,7 +2764,9 @@ public: case CK_IvyBridge: case CK_Haswell: case CK_Broadwell: - case CK_Skylake: + case CK_SkylakeClient: + case CK_SkylakeServer: + case CK_Cannonlake: case CK_KNL: case CK_Athlon64: case CK_Athlon64SSE3: @@ -2528,14 +2791,20 @@ public: bool setFPMath(StringRef Name) override; CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { - // We accept all non-ARM calling conventions - return (CC == CC_X86ThisCall || - CC == CC_X86FastCall || - CC == CC_X86StdCall || - CC == CC_X86VectorCall || - CC == CC_C || - CC == CC_X86Pascal || - CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning; + // Most of the non-ARM calling conventions are i386 conventions. + switch (CC) { + case CC_X86ThisCall: + case CC_X86FastCall: + case CC_X86StdCall: + case CC_X86VectorCall: + case CC_C: + case CC_Swift: + case CC_X86Pascal: + case CC_IntelOclBicc: + return CCCR_OK; + default: + return CCCR_Warning; + } } CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override { @@ -2545,6 +2814,10 @@ public: bool hasSjLjLowering() const override { return true; } + + void setSupportedOpenCLOpts() override { + getSupportedOpenCLOpts().setAll(); + } }; bool X86TargetInfo::setFPMath(StringRef Name) { @@ -2567,7 +2840,13 @@ bool X86TargetInfo::initFeatureMap( if (getTriple().getArch() == llvm::Triple::x86_64) setFeatureEnabledImpl(Features, "sse2", true); - switch (getCPUKind(CPU)) { + const CPUKind Kind = getCPUKind(CPU); + + // Enable X87 for all X86 processors but Lakemont. + if (Kind != CK_Lakemont) + setFeatureEnabledImpl(Features, "x87", true); + + switch (Kind) { case CK_Generic: case CK_i386: case CK_i486: @@ -2575,6 +2854,7 @@ bool X86TargetInfo::initFeatureMap( case CK_Pentium: case CK_i686: case CK_PentiumPro: + case CK_Lakemont: break; case CK_PentiumMMX: case CK_Pentium2: @@ -2613,15 +2893,28 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "fxsr", true); setFeatureEnabledImpl(Features, "cx16", true); break; - case CK_Skylake: + case CK_Cannonlake: + setFeatureEnabledImpl(Features, "avx512ifma", true); + setFeatureEnabledImpl(Features, "avx512vbmi", true); + setFeatureEnabledImpl(Features, "sha", true); + setFeatureEnabledImpl(Features, "umip", true); + // FALLTHROUGH + case CK_SkylakeServer: setFeatureEnabledImpl(Features, "avx512f", true); setFeatureEnabledImpl(Features, "avx512cd", true); setFeatureEnabledImpl(Features, "avx512dq", true); setFeatureEnabledImpl(Features, "avx512bw", true); setFeatureEnabledImpl(Features, "avx512vl", true); + setFeatureEnabledImpl(Features, "pku", true); + setFeatureEnabledImpl(Features, "pcommit", true); + setFeatureEnabledImpl(Features, "clwb", true); + // FALLTHROUGH + case CK_SkylakeClient: setFeatureEnabledImpl(Features, "xsavec", true); setFeatureEnabledImpl(Features, "xsaves", true); - setFeatureEnabledImpl(Features, "pku", true); + setFeatureEnabledImpl(Features, "mpx", true); + setFeatureEnabledImpl(Features, "sgx", true); + setFeatureEnabledImpl(Features, "clflushopt", true); // FALLTHROUGH case CK_Broadwell: setFeatureEnabledImpl(Features, "rdseed", true); @@ -2634,6 +2927,7 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "bmi2", true); setFeatureEnabledImpl(Features, "rtm", true); setFeatureEnabledImpl(Features, "fma", true); + setFeatureEnabledImpl(Features, "movbe", true); // FALLTHROUGH case CK_IvyBridge: setFeatureEnabledImpl(Features, "rdrnd", true); @@ -2660,6 +2954,7 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "avx512cd", true); setFeatureEnabledImpl(Features, "avx512er", true); setFeatureEnabledImpl(Features, "avx512pf", true); + setFeatureEnabledImpl(Features, "prefetchwt1", true); setFeatureEnabledImpl(Features, "fxsr", true); setFeatureEnabledImpl(Features, "rdseed", true); setFeatureEnabledImpl(Features, "adx", true); @@ -2676,6 +2971,7 @@ bool X86TargetInfo::initFeatureMap( setFeatureEnabledImpl(Features, "cx16", true); setFeatureEnabledImpl(Features, "xsaveopt", true); setFeatureEnabledImpl(Features, "xsave", true); + setFeatureEnabledImpl(Features, "movbe", true); break; case CK_K6_2: case CK_K6_3: @@ -2735,6 +3031,7 @@ bool X86TargetInfo::initFeatureMap( case CK_BDVER4: setFeatureEnabledImpl(Features, "avx2", true); setFeatureEnabledImpl(Features, "bmi2", true); + setFeatureEnabledImpl(Features, "mwaitx", true); // FALLTHROUGH case CK_BDVER3: setFeatureEnabledImpl(Features, "fsgsbase", true); @@ -2843,7 +3140,8 @@ void X86TargetInfo::setSSELevel(llvm::StringMap<bool> &Features, case AVX512F: Features["avx512f"] = Features["avx512cd"] = Features["avx512er"] = Features["avx512pf"] = Features["avx512dq"] = Features["avx512bw"] = - Features["avx512vl"] = false; + Features["avx512vl"] = Features["avx512vbmi"] = + Features["avx512ifma"] = false; } } @@ -2941,8 +3239,9 @@ void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, setSSELevel(Features, AVX2, Enabled); } else if (Name == "avx512f") { setSSELevel(Features, AVX512F, Enabled); - } else if (Name == "avx512cd" || Name == "avx512er" || Name == "avx512pf" - || Name == "avx512dq" || Name == "avx512bw" || Name == "avx512vl") { + } else if (Name == "avx512cd" || Name == "avx512er" || Name == "avx512pf" || + Name == "avx512dq" || Name == "avx512bw" || Name == "avx512vl" || + Name == "avx512vbmi" || Name == "avx512ifma") { if (Enabled) setSSELevel(Features, AVX512F, Enabled); } else if (Name == "fma") { @@ -2970,15 +3269,11 @@ void X86TargetInfo::setFeatureEnabledImpl(llvm::StringMap<bool> &Features, else setSSELevel(Features, SSE41, Enabled); } else if (Name == "xsave") { - if (Enabled) - setSSELevel(Features, AVX, Enabled); - else + if (!Enabled) Features["xsaveopt"] = false; } else if (Name == "xsaveopt" || Name == "xsavec" || Name == "xsaves") { - if (Enabled) { + if (Enabled) Features["xsave"] = true; - setSSELevel(Features, AVX, Enabled); - } } } @@ -3032,8 +3327,18 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasAVX512BW = true; } else if (Feature == "+avx512vl") { HasAVX512VL = true; + } else if (Feature == "+avx512vbmi") { + HasAVX512VBMI = true; + } else if (Feature == "+avx512ifma") { + HasAVX512IFMA = true; } else if (Feature == "+sha") { HasSHA = true; + } else if (Feature == "+mpx") { + HasMPX = true; + } else if (Feature == "+movbe") { + HasMOVBE = true; + } else if (Feature == "+sgx") { + HasSGX = true; } else if (Feature == "+cx16") { HasCX16 = true; } else if (Feature == "+fxsr") { @@ -3046,8 +3351,20 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasXSAVEC = true; } else if (Feature == "+xsaves") { HasXSAVES = true; + } else if (Feature == "+mwaitx") { + HasMWAITX = true; } else if (Feature == "+pku") { HasPKU = true; + } else if (Feature == "+clflushopt") { + HasCLFLUSHOPT = true; + } else if (Feature == "+pcommit") { + HasPCOMMIT = true; + } else if (Feature == "+clwb") { + HasCLWB = true; + } else if (Feature == "+umip") { + HasUMIP = true; + } else if (Feature == "+prefetchwt1") { + HasPREFETCHWT1 = true; } X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) @@ -3181,21 +3498,23 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case CK_IvyBridge: case CK_Haswell: case CK_Broadwell: + case CK_SkylakeClient: // FIXME: Historically, we defined this legacy name, it would be nice to // remove it at some point. We've never exposed fine-grained names for // recent primary x86 CPUs, and we should keep it that way. defineCPUMacros(Builder, "corei7"); break; - case CK_Skylake: - // FIXME: Historically, we defined this legacy name, it would be nice to - // remove it at some point. This is the only fine-grained CPU macro in the - // main intel CPU line, and it would be better to not have these and force - // people to use ISA macros. + case CK_SkylakeServer: defineCPUMacros(Builder, "skx"); break; + case CK_Cannonlake: + break; case CK_KNL: defineCPUMacros(Builder, "knl"); break; + case CK_Lakemont: + Builder.defineMacro("__tune_lakemont__"); + break; case CK_K6_2: Builder.defineMacro("__k6_2__"); Builder.defineMacro("__tune_k6_2__"); @@ -3306,6 +3625,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasTBM) Builder.defineMacro("__TBM__"); + if (HasMWAITX) + Builder.defineMacro("__MWAITX__"); + switch (XOPLevel) { case XOP: Builder.defineMacro("__XOP__"); @@ -3335,6 +3657,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__AVX512BW__"); if (HasAVX512VL) Builder.defineMacro("__AVX512VL__"); + if (HasAVX512VBMI) + Builder.defineMacro("__AVX512VBMI__"); + if (HasAVX512IFMA) + Builder.defineMacro("__AVX512IFMA__"); if (HasSHA) Builder.defineMacro("__SHA__"); @@ -3433,8 +3759,12 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("avx512dq", HasAVX512DQ) .Case("avx512bw", HasAVX512BW) .Case("avx512vl", HasAVX512VL) + .Case("avx512vbmi", HasAVX512VBMI) + .Case("avx512ifma", HasAVX512IFMA) .Case("bmi", HasBMI) .Case("bmi2", HasBMI2) + .Case("clflushopt", HasCLFLUSHOPT) + .Case("clwb", HasCLWB) .Case("cx16", HasCX16) .Case("f16c", HasF16C) .Case("fma", HasFMA) @@ -3445,12 +3775,18 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("mm3dnow", MMX3DNowLevel >= AMD3DNow) .Case("mm3dnowa", MMX3DNowLevel >= AMD3DNowAthlon) .Case("mmx", MMX3DNowLevel >= MMX) + .Case("movbe", HasMOVBE) + .Case("mpx", HasMPX) .Case("pclmul", HasPCLMUL) + .Case("pcommit", HasPCOMMIT) + .Case("pku", HasPKU) .Case("popcnt", HasPOPCNT) + .Case("prefetchwt1", HasPREFETCHWT1) .Case("prfchw", HasPRFCHW) .Case("rdrnd", HasRDRND) .Case("rdseed", HasRDSEED) .Case("rtm", HasRTM) + .Case("sgx", HasSGX) .Case("sha", HasSHA) .Case("sse", SSELevel >= SSE1) .Case("sse2", SSELevel >= SSE2) @@ -3460,6 +3796,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("sse4.2", SSELevel >= SSE42) .Case("sse4a", XOPLevel >= SSE4A) .Case("tbm", HasTBM) + .Case("umip", HasUMIP) .Case("x86", true) .Case("x86_32", getTriple().getArch() == llvm::Triple::x86) .Case("x86_64", getTriple().getArch() == llvm::Triple::x86_64) @@ -3468,7 +3805,6 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("xsavec", HasXSAVEC) .Case("xsaves", HasXSAVES) .Case("xsaveopt", HasXSAVEOPT) - .Case("pku", HasPKU) .Default(false); } @@ -3485,6 +3821,7 @@ bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { .Case("sse", true) .Case("sse2", true) .Case("sse3", true) + .Case("ssse3", true) .Case("sse4.1", true) .Case("sse4.2", true) .Case("avx", true) @@ -3496,6 +3833,16 @@ bool X86TargetInfo::validateCpuSupports(StringRef FeatureStr) const { .Case("avx512f", true) .Case("bmi", true) .Case("bmi2", true) + .Case("aes", true) + .Case("pclmul", true) + .Case("avx512vl", true) + .Case("avx512bw", true) + .Case("avx512dq", true) + .Case("avx512cd", true) + .Case("avx512er", true) + .Case("avx512pf", true) + .Case("avx512vbmi", true) + .Case("avx512ifma", true) .Default(false); } @@ -3657,12 +4004,13 @@ X86TargetInfo::convertConstraint(const char *&Constraint) const { // X86-32 generic target class X86_32TargetInfo : public X86TargetInfo { public: - X86_32TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) { + X86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : X86TargetInfo(Triple, Opts) { DoubleAlign = LongLongAlign = 32; LongDoubleWidth = 96; LongDoubleAlign = 32; SuitableAlign = 128; - DataLayoutString = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"; + resetDataLayout("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"); SizeType = UnsignedInt; PtrDiffType = SignedInt; IntPtrType = SignedInt; @@ -3711,8 +4059,8 @@ public: class NetBSDI386TargetInfo : public NetBSDTargetInfo<X86_32TargetInfo> { public: - NetBSDI386TargetInfo(const llvm::Triple &Triple) - : NetBSDTargetInfo<X86_32TargetInfo>(Triple) {} + NetBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : NetBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) {} unsigned getFloatEvalMethod() const override { unsigned Major, Minor, Micro; @@ -3727,8 +4075,8 @@ public: class OpenBSDI386TargetInfo : public OpenBSDTargetInfo<X86_32TargetInfo> { public: - OpenBSDI386TargetInfo(const llvm::Triple &Triple) - : OpenBSDTargetInfo<X86_32TargetInfo>(Triple) { + OpenBSDI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OpenBSDTargetInfo<X86_32TargetInfo>(Triple, Opts) { SizeType = UnsignedLong; IntPtrType = SignedLong; PtrDiffType = SignedLong; @@ -3737,8 +4085,8 @@ public: class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> { public: - BitrigI386TargetInfo(const llvm::Triple &Triple) - : BitrigTargetInfo<X86_32TargetInfo>(Triple) { + BitrigI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : BitrigTargetInfo<X86_32TargetInfo>(Triple, Opts) { SizeType = UnsignedLong; IntPtrType = SignedLong; PtrDiffType = SignedLong; @@ -3747,8 +4095,8 @@ public: class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> { public: - DarwinI386TargetInfo(const llvm::Triple &Triple) - : DarwinTargetInfo<X86_32TargetInfo>(Triple) { + DarwinI386TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : DarwinTargetInfo<X86_32TargetInfo>(Triple, Opts) { LongDoubleWidth = 128; LongDoubleAlign = 128; SuitableAlign = 128; @@ -3759,7 +4107,7 @@ public: UseSignedCharForObjCBool = false; SizeType = UnsignedLong; IntPtrType = SignedLong; - DataLayoutString = "e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128"; + resetDataLayout("e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128"); HasAlignMac68kSupport = true; } @@ -3778,15 +4126,15 @@ public: // x86-32 Windows target class WindowsX86_32TargetInfo : public WindowsTargetInfo<X86_32TargetInfo> { public: - WindowsX86_32TargetInfo(const llvm::Triple &Triple) - : WindowsTargetInfo<X86_32TargetInfo>(Triple) { + WindowsX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : WindowsTargetInfo<X86_32TargetInfo>(Triple, Opts) { WCharType = UnsignedShort; DoubleAlign = LongLongAlign = 64; bool IsWinCOFF = getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); - DataLayoutString = IsWinCOFF - ? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" - : "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"; + resetDataLayout(IsWinCOFF + ? "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" + : "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -3797,8 +4145,9 @@ public: // x86-32 Windows Visual Studio target class MicrosoftX86_32TargetInfo : public WindowsX86_32TargetInfo { public: - MicrosoftX86_32TargetInfo(const llvm::Triple &Triple) - : WindowsX86_32TargetInfo(Triple) { + MicrosoftX86_32TargetInfo(const llvm::Triple &Triple, + const TargetOptions &Opts) + : WindowsX86_32TargetInfo(Triple, Opts) { LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble; } @@ -3846,8 +4195,8 @@ static void addMinGWDefines(const LangOptions &Opts, MacroBuilder &Builder) { // x86-32 MinGW target class MinGWX86_32TargetInfo : public WindowsX86_32TargetInfo { public: - MinGWX86_32TargetInfo(const llvm::Triple &Triple) - : WindowsX86_32TargetInfo(Triple) {} + MinGWX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : WindowsX86_32TargetInfo(Triple, Opts) {} void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { WindowsX86_32TargetInfo::getTargetDefines(Opts, Builder); @@ -3861,11 +4210,11 @@ public: // x86-32 Cygwin target class CygwinX86_32TargetInfo : public X86_32TargetInfo { public: - CygwinX86_32TargetInfo(const llvm::Triple &Triple) - : X86_32TargetInfo(Triple) { + CygwinX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : X86_32TargetInfo(Triple, Opts) { WCharType = UnsignedShort; DoubleAlign = LongLongAlign = 64; - DataLayoutString = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"; + resetDataLayout("e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -3881,30 +4230,27 @@ public: }; // x86-32 Haiku target -class HaikuX86_32TargetInfo : public X86_32TargetInfo { +class HaikuX86_32TargetInfo : public HaikuTargetInfo<X86_32TargetInfo> { public: - HaikuX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) { - SizeType = UnsignedLong; - IntPtrType = SignedLong; - PtrDiffType = SignedLong; - ProcessIDType = SignedLong; - this->UserLabelPrefix = ""; - this->TLSSupported = false; + HaikuX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : HaikuTargetInfo<X86_32TargetInfo>(Triple, Opts) { } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { - X86_32TargetInfo::getTargetDefines(Opts, Builder); + HaikuTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder); Builder.defineMacro("__INTEL__"); - Builder.defineMacro("__HAIKU__"); } }; // X86-32 MCU target class MCUX86_32TargetInfo : public X86_32TargetInfo { public: - MCUX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) { + MCUX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : X86_32TargetInfo(Triple, Opts) { LongDoubleWidth = 64; 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; } CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { @@ -3918,6 +4264,10 @@ public: Builder.defineMacro("__iamcu"); Builder.defineMacro("__iamcu__"); } + + bool allowsLargerPreferedTypeAlignment() const override { + return false; + } }; // RTEMS Target @@ -3933,9 +4283,8 @@ protected: } public: - RTEMSTargetInfo(const llvm::Triple &Triple) : OSTargetInfo<Target>(Triple) { - this->UserLabelPrefix = ""; - + RTEMSTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OSTargetInfo<Target>(Triple, Opts) { switch (Triple.getArch()) { default: case llvm::Triple::x86: @@ -3958,11 +4307,11 @@ public: // x86-32 RTEMS target class RTEMSX86_32TargetInfo : public X86_32TargetInfo { public: - RTEMSX86_32TargetInfo(const llvm::Triple &Triple) : X86_32TargetInfo(Triple) { + RTEMSX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : X86_32TargetInfo(Triple, Opts) { SizeType = UnsignedLong; IntPtrType = SignedLong; PtrDiffType = SignedLong; - this->UserLabelPrefix = ""; } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -3975,7 +4324,8 @@ public: // x86-64 generic target class X86_64TargetInfo : public X86TargetInfo { public: - X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) { + X86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : X86TargetInfo(Triple, Opts) { const bool IsX32 = getTriple().getEnvironment() == llvm::Triple::GNUX32; bool IsWinCOFF = getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF(); @@ -3993,10 +4343,10 @@ public: RegParmMax = 6; // Pointers are 32-bit in x32. - DataLayoutString = IsX32 ? "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128" - : IsWinCOFF - ? "e-m:w-i64:64-f80:128-n8:16:32:64-S128" - : "e-m:e-i64:64-f80:128-n8:16:32:64-S128"; + resetDataLayout(IsX32 + ? "e-m:e-p:32:32-i64:64-f80:128-n8:16:32:64-S128" + : IsWinCOFF ? "e-m:w-i64:64-f80:128-n8:16:32:64-S128" + : "e-m:e-i64:64-f80:128-n8:16:32:64-S128"); // Use fpret only for long double. RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble); @@ -4022,10 +4372,18 @@ public: } CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { - return (CC == CC_C || - CC == CC_X86VectorCall || - CC == CC_IntelOclBicc || - CC == CC_X86_64Win64) ? CCCR_OK : CCCR_Warning; + switch (CC) { + case CC_C: + case CC_Swift: + case CC_X86VectorCall: + case CC_IntelOclBicc: + case CC_X86_64Win64: + case CC_PreserveMost: + case CC_PreserveAll: + return CCCR_OK; + default: + return CCCR_Warning; + } } CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override { @@ -4034,6 +4392,8 @@ public: // for x32 we need it here explicitly bool hasInt128Type() const override { return true; } + unsigned getUnwindWordWidth() const override { return 64; } + unsigned getRegisterWidth() const override { return 64; } bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize, @@ -4055,8 +4415,8 @@ public: // x86-64 Windows target class WindowsX86_64TargetInfo : public WindowsTargetInfo<X86_64TargetInfo> { public: - WindowsX86_64TargetInfo(const llvm::Triple &Triple) - : WindowsTargetInfo<X86_64TargetInfo>(Triple) { + WindowsX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : WindowsTargetInfo<X86_64TargetInfo>(Triple, Opts) { WCharType = UnsignedShort; LongWidth = LongAlign = 32; DoubleAlign = LongLongAlign = 64; @@ -4065,7 +4425,6 @@ public: SizeType = UnsignedLongLong; PtrDiffType = SignedLongLong; IntPtrType = SignedLongLong; - this->UserLabelPrefix = ""; } void getTargetDefines(const LangOptions &Opts, @@ -4098,8 +4457,9 @@ public: // x86-64 Windows Visual Studio target class MicrosoftX86_64TargetInfo : public WindowsX86_64TargetInfo { public: - MicrosoftX86_64TargetInfo(const llvm::Triple &Triple) - : WindowsX86_64TargetInfo(Triple) { + MicrosoftX86_64TargetInfo(const llvm::Triple &Triple, + const TargetOptions &Opts) + : WindowsX86_64TargetInfo(Triple, Opts) { LongDoubleWidth = LongDoubleAlign = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble; } @@ -4115,8 +4475,8 @@ public: // x86-64 MinGW target class MinGWX86_64TargetInfo : public WindowsX86_64TargetInfo { public: - MinGWX86_64TargetInfo(const llvm::Triple &Triple) - : WindowsX86_64TargetInfo(Triple) { + MinGWX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : WindowsX86_64TargetInfo(Triple, Opts) { // Mingw64 rounds long double size and alignment up to 16 bytes, but sticks // with x86 FP ops. Weird. LongDoubleWidth = LongDoubleAlign = 128; @@ -4139,8 +4499,8 @@ public: // x86-64 Cygwin target class CygwinX86_64TargetInfo : public X86_64TargetInfo { public: - CygwinX86_64TargetInfo(const llvm::Triple &Triple) - : X86_64TargetInfo(Triple) { + CygwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : X86_64TargetInfo(Triple, Opts) { TLSSupported = false; WCharType = UnsignedShort; } @@ -4163,14 +4523,14 @@ public: class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> { public: - DarwinX86_64TargetInfo(const llvm::Triple &Triple) - : DarwinTargetInfo<X86_64TargetInfo>(Triple) { + DarwinX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : DarwinTargetInfo<X86_64TargetInfo>(Triple, Opts) { Int64Type = SignedLongLong; // The 64-bit iOS simulator uses the builtin bool type for Objective-C. llvm::Triple T = llvm::Triple(Triple); if (T.isiOS()) UseSignedCharForObjCBool = false; - DataLayoutString = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"; + resetDataLayout("e-m:o-i64:64-f80:128-n8:16:32:64-S128"); } bool handleTargetFeatures(std::vector<std::string> &Features, @@ -4187,8 +4547,8 @@ public: class OpenBSDX86_64TargetInfo : public OpenBSDTargetInfo<X86_64TargetInfo> { public: - OpenBSDX86_64TargetInfo(const llvm::Triple &Triple) - : OpenBSDTargetInfo<X86_64TargetInfo>(Triple) { + OpenBSDX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : OpenBSDTargetInfo<X86_64TargetInfo>(Triple, Opts) { IntMaxType = SignedLongLong; Int64Type = SignedLongLong; } @@ -4196,8 +4556,8 @@ public: class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> { public: - BitrigX86_64TargetInfo(const llvm::Triple &Triple) - : BitrigTargetInfo<X86_64TargetInfo>(Triple) { + BitrigX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : BitrigTargetInfo<X86_64TargetInfo>(Triple, Opts) { IntMaxType = SignedLongLong; Int64Type = SignedLongLong; } @@ -4309,26 +4669,26 @@ class ARMTargetInfo : public TargetInfo { // Thumb1 add sp, #imm requires the immediate value be multiple of 4, // so set preferred for small types to 32. if (T.isOSBinFormatMachO()) { - DataLayoutString = - BigEndian ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" - : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"; + resetDataLayout(BigEndian + ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" + : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"); } else if (T.isOSWindows()) { assert(!BigEndian && "Windows on ARM does not support big endian"); - DataLayoutString = "e" - "-m:w" - "-p:32:32" - "-i64:64" - "-v128:64:128" - "-a:0:32" - "-n32" - "-S64"; + resetDataLayout("e" + "-m:w" + "-p:32:32" + "-i64:64" + "-v128:64:128" + "-a:0:32" + "-n32" + "-S64"); } else if (T.isOSNaCl()) { assert(!BigEndian && "NaCl on ARM does not support big endian"); - DataLayoutString = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128"; + resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128"); } else { - DataLayoutString = - BigEndian ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" - : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"; + resetDataLayout(BigEndian + ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" + : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"); } // FIXME: Enumerated types are variable width in straight AAPCS. @@ -4364,17 +4724,17 @@ class ARMTargetInfo : public TargetInfo { if (T.isOSBinFormatMachO() && IsAAPCS16) { assert(!BigEndian && "AAPCS16 does not support big-endian"); - DataLayoutString = "e-m:o-p:32:32-i64:64-a:0:32-n32-S128"; + resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128"); } else if (T.isOSBinFormatMachO()) - DataLayoutString = + resetDataLayout( BigEndian ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" - : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"; + : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); else - DataLayoutString = + resetDataLayout( BigEndian ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" - : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"; + : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); // FIXME: Override "preferred align" for double and long long. } @@ -4432,7 +4792,8 @@ class ARMTargetInfo : public TargetInfo { } bool supportsThumb2() const { - return CPUAttr.equals("6T2") || ArchVersion >= 7; + return CPUAttr.equals("6T2") || + (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE")); } StringRef getCPUAttr() const { @@ -4457,6 +4818,12 @@ class ARMTargetInfo : public TargetInfo { return "8A"; case llvm::ARM::AK_ARMV8_1A: return "8_1A"; + case llvm::ARM::AK_ARMV8_2A: + return "8_2A"; + case llvm::ARM::AK_ARMV8MBaseline: + return "8M_BASE"; + case llvm::ARM::AK_ARMV8MMainline: + return "8M_MAIN"; } } @@ -4474,9 +4841,10 @@ class ARMTargetInfo : public TargetInfo { } public: - ARMTargetInfo(const llvm::Triple &Triple, bool IsBigEndian) - : TargetInfo(Triple), FPMath(FP_Default), - IsAAPCS(true), LDREX(0), HW_FP(0) { + ARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts, + bool IsBigEndian) + : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0), + HW_FP(0) { BigEndian = IsBigEndian; switch (getTriple().getOS()) { @@ -4505,7 +4873,7 @@ public: Triple.getOS() == llvm::Triple::UnknownOS || StringRef(CPU).startswith("cortex-m")) { setABI("aapcs"); - } else if (Triple.isWatchOS()) { + } else if (Triple.isWatchABI()) { setABI("aapcs16"); } else { setABI("apcs-gnu"); @@ -4519,6 +4887,8 @@ public: case llvm::Triple::Android: case llvm::Triple::GNUEABI: case llvm::Triple::GNUEABIHF: + case llvm::Triple::MuslEABI: + case llvm::Triple::MuslEABIHF: setABI("aapcs-linux"); break; case llvm::Triple::EABIHF: @@ -4548,6 +4918,11 @@ public: // that follows it, `bar', `bar' will be aligned as the type of the // zero length bitfield. UseZeroLengthBitfieldAlignment = true; + + if (Triple.getOS() == llvm::Triple::Linux || + Triple.getOS() == llvm::Triple::UnknownOS) + this->MCountName = + Opts.EABIVersion == "gnu" ? "\01__gnu_mcount_nc" : "\01mcount"; } StringRef getABI() const override { return ABI; } @@ -4638,7 +5013,7 @@ public: } else if (Feature == "+dsp") { DSP = 1; } else if (Feature == "+fp-only-sp") { - HW_FP_remove |= HW_FP_DP; + HW_FP_remove |= HW_FP_DP; } else if (Feature == "+strict-align") { Unaligned = 0; } else if (Feature == "+fp16") { @@ -4715,13 +5090,17 @@ public: // Target identification. Builder.defineMacro("__arm"); Builder.defineMacro("__arm__"); + // For bare-metal none-eabi. + if (getTriple().getOS() == llvm::Triple::UnknownOS && + getTriple().getEnvironment() == llvm::Triple::EABI) + Builder.defineMacro("__ELF__"); // Target properties. Builder.defineMacro("__REGISTER_PREFIX__", ""); // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__. - if (getTriple().isWatchOS()) + if (getTriple().isWatchABI()) Builder.defineMacro("__ARM_ARCH_7K__", "2"); if (!CPUAttr.empty()) @@ -4746,13 +5125,14 @@ public: // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It // is not defined for the M-profile. - // NOTE that the deffault profile is assumed to be 'A' - if (CPUProfile.empty() || CPUProfile != "M") + // NOTE that the default profile is assumed to be 'A' + if (CPUProfile.empty() || ArchProfile != llvm::ARM::PK_M) Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1"); - // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supporst the original - // Thumb ISA (including v6-M). It is set to 2 if the core supports the - // Thumb-2 ISA as found in the v6T2 architecture and all v7 architecture. + // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original + // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the + // core supports the Thumb-2 ISA as found in the v6T2 architecture and all + // v7 and v8 architectures excluding v8-M Baseline. if (supportsThumb2()) Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2"); else if (supportsThumb()) @@ -4794,7 +5174,7 @@ public: Builder.defineMacro("__ARM_FP16_ARGS", "1"); // ACLE 6.5.3 Fused multiply-accumulate (FMA) - if (ArchVersion >= 7 && (CPUProfile != "M" || CPUAttr == "7EM")) + if (ArchVersion >= 7 && (FPU & VFP4FPU)) Builder.defineMacro("__ARM_FEATURE_FMA", "1"); // Subtarget options. @@ -4808,14 +5188,15 @@ public: if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") { // Embedded targets on Darwin follow AAPCS, but not EABI. // Windows on ARM follows AAPCS VFP, but does not conform to EABI. - if (!getTriple().isOSDarwin() && !getTriple().isOSWindows()) + if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows()) Builder.defineMacro("__ARM_EABI__"); Builder.defineMacro("__ARM_PCS", "1"); - - if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp") - Builder.defineMacro("__ARM_PCS_VFP", "1"); } + if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || + ABI == "aapcs16") + Builder.defineMacro("__ARM_PCS_VFP", "1"); + if (SoftFloat) Builder.defineMacro("__SOFTFP__"); @@ -4872,7 +5253,7 @@ public: Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4"); - if (ArchVersion >= 6 && CPUAttr != "6M") { + if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") { Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); @@ -4910,8 +5291,8 @@ public: BuiltinVaListKind getBuiltinVaListKind() const override { return IsAAPCS ? AAPCSABIBuiltinVaList - : (getTriple().isWatchOS() ? TargetInfo::CharPtrBuiltinVaList - : TargetInfo::VoidPtrBuiltinVaList); + : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList + : TargetInfo::VoidPtrBuiltinVaList); } ArrayRef<const char *> getGCCRegNames() const override; ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; @@ -5001,7 +5382,14 @@ public: } CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { - return (CC == CC_AAPCS || CC == CC_AAPCS_VFP) ? CCCR_OK : CCCR_Warning; + switch (CC) { + case CC_AAPCS: + case CC_AAPCS_VFP: + case CC_Swift: + return CCCR_OK; + default: + return CCCR_Warning; + } } int getEHDataRegisterNumber(unsigned RegNo) const override { @@ -5096,8 +5484,8 @@ const Builtin::Info ARMTargetInfo::BuiltinInfo[] = { class ARMleTargetInfo : public ARMTargetInfo { public: - ARMleTargetInfo(const llvm::Triple &Triple) - : ARMTargetInfo(Triple, false) { } + ARMleTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : ARMTargetInfo(Triple, Opts, /*BigEndian=*/false) {} void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { Builder.defineMacro("__ARMEL__"); @@ -5107,8 +5495,8 @@ public: class ARMbeTargetInfo : public ARMTargetInfo { public: - ARMbeTargetInfo(const llvm::Triple &Triple) - : ARMTargetInfo(Triple, true) { } + ARMbeTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : ARMTargetInfo(Triple, Opts, /*BigEndian=*/true) {} void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { Builder.defineMacro("__ARMEB__"); @@ -5120,12 +5508,10 @@ public: class WindowsARMTargetInfo : public WindowsTargetInfo<ARMleTargetInfo> { const llvm::Triple Triple; public: - WindowsARMTargetInfo(const llvm::Triple &Triple) - : WindowsTargetInfo<ARMleTargetInfo>(Triple), Triple(Triple) { - TLSSupported = false; + WindowsARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) { WCharType = UnsignedShort; SizeType = UnsignedInt; - UserLabelPrefix = ""; } void getVisualStudioDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -5167,8 +5553,9 @@ public: // Windows ARM + Itanium C++ ABI Target class ItaniumWindowsARMleTargetInfo : public WindowsARMTargetInfo { public: - ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple) - : WindowsARMTargetInfo(Triple) { + ItaniumWindowsARMleTargetInfo(const llvm::Triple &Triple, + const TargetOptions &Opts) + : WindowsARMTargetInfo(Triple, Opts) { TheCXXABI.set(TargetCXXABI::GenericARM); } @@ -5184,8 +5571,9 @@ public: // Windows ARM, MS (C++) ABI class MicrosoftARMleTargetInfo : public WindowsARMTargetInfo { public: - MicrosoftARMleTargetInfo(const llvm::Triple &Triple) - : WindowsARMTargetInfo(Triple) { + MicrosoftARMleTargetInfo(const llvm::Triple &Triple, + const TargetOptions &Opts) + : WindowsARMTargetInfo(Triple, Opts) { TheCXXABI.set(TargetCXXABI::Microsoft); } @@ -5199,8 +5587,8 @@ public: // ARM MinGW target class MinGWARMTargetInfo : public WindowsARMTargetInfo { public: - MinGWARMTargetInfo(const llvm::Triple &Triple) - : WindowsARMTargetInfo(Triple) { + MinGWARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : WindowsARMTargetInfo(Triple, Opts) { TheCXXABI.set(TargetCXXABI::GenericARM); } @@ -5217,11 +5605,12 @@ public: // ARM Cygwin target class CygwinARMTargetInfo : public ARMleTargetInfo { public: - CygwinARMTargetInfo(const llvm::Triple &Triple) : ARMleTargetInfo(Triple) { + CygwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : ARMleTargetInfo(Triple, Opts) { TLSSupported = false; WCharType = UnsignedShort; DoubleAlign = LongLongAlign = 64; - DataLayoutString = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"; + resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -5235,8 +5624,7 @@ public: } }; -class DarwinARMTargetInfo : - public DarwinTargetInfo<ARMleTargetInfo> { +class DarwinARMTargetInfo : public DarwinTargetInfo<ARMleTargetInfo> { protected: void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple, MacroBuilder &Builder) const override { @@ -5244,15 +5632,15 @@ protected: } public: - DarwinARMTargetInfo(const llvm::Triple &Triple) - : DarwinTargetInfo<ARMleTargetInfo>(Triple) { + DarwinARMTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) { HasAlignMac68kSupport = true; // iOS always has 64-bit atomic instructions. // FIXME: This should be based off of the target features in // ARMleTargetInfo. MaxAtomicInlineWidth = 64; - if (Triple.isWatchOS()) { + if (Triple.isWatchABI()) { // Darwin on iOS uses a variant of the ARM C++ ABI. TheCXXABI.set(TargetCXXABI::WatchOS); @@ -5268,7 +5656,7 @@ public: }; class AArch64TargetInfo : public TargetInfo { - virtual void setDataLayoutString() = 0; + virtual void setDataLayout() = 0; static const TargetInfo::GCCRegAlias GCCRegAliases[]; static const char *const GCCRegNames[]; @@ -5288,9 +5676,8 @@ class AArch64TargetInfo : public TargetInfo { std::string ABI; public: - AArch64TargetInfo(const llvm::Triple &Triple) + AArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : TargetInfo(Triple), ABI("aapcs") { - if (getTriple().getOS() == llvm::Triple::NetBSD) { WCharType = SignedInt; @@ -5325,6 +5712,10 @@ public: // AArch64 targets default to using the ARM C++ ABI. TheCXXABI.set(TargetCXXABI::GenericAArch64); + + if (Triple.getOS() == llvm::Triple::Linux || + Triple.getOS() == llvm::Triple::UnknownOS) + this->MCountName = Opts.EABIVersion == "gnu" ? "\01_mcount" : "mcount"; } StringRef getABI() const override { return ABI; } @@ -5341,7 +5732,10 @@ public: .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; } @@ -5448,11 +5842,23 @@ public: V8_1A = 1; } - setDataLayoutString(); + setDataLayout(); return true; } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + case CC_C: + case CC_Swift: + case CC_PreserveMost: + case CC_PreserveAll: + return CCCR_OK; + default: + return CCCR_Warning; + } + } + bool isCLZForZeroUndef() const override { return false; } BuiltinVaListKind getBuiltinVaListKind() const override { @@ -5598,18 +6004,18 @@ const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { }; class AArch64leTargetInfo : public AArch64TargetInfo { - void setDataLayoutString() override { + void setDataLayout() override { if (getTriple().isOSBinFormatMachO()) - DataLayoutString = "e-m:o-i64:64-i128:128-n32:64-S128"; + resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128"); else - DataLayoutString = "e-m:e-i64:64-i128:128-n32:64-S128"; + resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); } public: - AArch64leTargetInfo(const llvm::Triple &Triple) - : AArch64TargetInfo(Triple) { + AArch64leTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : AArch64TargetInfo(Triple, Opts) { BigEndian = false; - } + } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { Builder.defineMacro("__AARCH64EL__"); @@ -5618,14 +6024,14 @@ public: }; class AArch64beTargetInfo : public AArch64TargetInfo { - void setDataLayoutString() override { + void setDataLayout() override { assert(!getTriple().isOSBinFormatMachO()); - DataLayoutString = "E-m:e-i64:64-i128:128-n32:64-S128"; + resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); } public: - AArch64beTargetInfo(const llvm::Triple &Triple) - : AArch64TargetInfo(Triple) { } + AArch64beTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : AArch64TargetInfo(Triple, Opts) {} void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { Builder.defineMacro("__AARCH64EB__"); @@ -5651,8 +6057,8 @@ protected: } public: - DarwinAArch64TargetInfo(const llvm::Triple &Triple) - : DarwinTargetInfo<AArch64leTargetInfo>(Triple) { + DarwinAArch64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) { Int64Type = SignedLongLong; WCharType = SignedInt; UseSignedCharForObjCBool = false; @@ -5677,11 +6083,15 @@ class HexagonTargetInfo : public TargetInfo { bool HasHVX, HasHVXDouble; public: - HexagonTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + HexagonTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { BigEndian = false; - DataLayoutString = "e-m:e-p:32:32:32-" - "i64:64:64-i32:32:32-i16:16:16-i1:8:8-" - "f64:64:64-f32:32:32-v64:64:64-v32:32:32-a:0-n16:32"; + // 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. + resetDataLayout("e-m:e-p:32:32:32-a:0-n16:32-" + "i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-" + "v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"); SizeType = UnsignedInt; PtrDiffType = SignedInt; IntPtrType = SignedInt; @@ -5704,7 +6114,19 @@ public: bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override { - return true; + switch (*Name) { + case 'v': + case 'q': + if (HasHVX) { + Info.setAllowsRegister(); + return true; + } + break; + case 's': + // Relocatable constant. + return true; + } + return false; } void getTargetDefines(const LangOptions &Opts, @@ -5776,12 +6198,23 @@ void HexagonTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__QDSP6_V5__"); Builder.defineMacro("__QDSP6_ARCH__", "5"); } + } else if (CPU == "hexagonv55") { + Builder.defineMacro("__HEXAGON_V55__"); + Builder.defineMacro("__HEXAGON_ARCH__", "55"); + Builder.defineMacro("__QDSP6_V55__"); + Builder.defineMacro("__QDSP6_ARCH__", "55"); } else if (CPU == "hexagonv60") { Builder.defineMacro("__HEXAGON_V60__"); Builder.defineMacro("__HEXAGON_ARCH__", "60"); Builder.defineMacro("__QDSP6_V60__"); Builder.defineMacro("__QDSP6_ARCH__", "60"); } + + if (hasFeature("hvx")) { + Builder.defineMacro("__HVX__"); + if (hasFeature("hvx-double")) + Builder.defineMacro("__HVXDBL__"); + } } bool HexagonTargetInfo::handleTargetFeatures(std::vector<std::string> &Features, @@ -5842,23 +6275,133 @@ const Builtin::Info HexagonTargetInfo::BuiltinInfo[] = { #include "clang/Basic/BuiltinsHexagon.def" }; +class LanaiTargetInfo : public TargetInfo { + // Class for Lanai (32-bit). + // The CPU profiles supported by the Lanai backend + enum CPUKind { + CK_NONE, + CK_V11, + } CPU; + + static const TargetInfo::GCCRegAlias GCCRegAliases[]; + static const char *const GCCRegNames[]; + +public: + LanaiTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { + // Description string has to be kept in sync with backend. + resetDataLayout("E" // Big endian + "-m:e" // ELF name manging + "-p:32:32" // 32 bit pointers, 32 bit aligned + "-i64:64" // 64 bit integers, 64 bit aligned + "-a:0:32" // 32 bit alignment of objects of aggregate type + "-n32" // 32 bit native integer width + "-S64" // 64 bit natural stack alignment + ); + + // Setting RegParmMax equal to what mregparm was set to in the old + // toolchain + RegParmMax = 4; + + // Set the default CPU to V11 + CPU = CK_V11; + + // Temporary approach to make everything at least word-aligned and allow for + // safely casting between pointers with different alignment requirements. + // TODO: Remove this when there are no more cast align warnings on the + // firmware. + MinGlobalAlign = 32; + } + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override { + // Define __lanai__ when building for target lanai. + Builder.defineMacro("__lanai__"); + + // Set define for the CPU specified. + switch (CPU) { + case CK_V11: + Builder.defineMacro("__LANAI_V11__"); + break; + case CK_NONE: + llvm_unreachable("Unhandled target CPU"); + } + } + + bool setCPU(const std::string &Name) override { + CPU = llvm::StringSwitch<CPUKind>(Name) + .Case("v11", CK_V11) + .Default(CK_NONE); + + return CPU != CK_NONE; + } + + bool hasFeature(StringRef Feature) const override { + return llvm::StringSwitch<bool>(Feature).Case("lanai", true).Default(false); + } + + ArrayRef<const char *> getGCCRegNames() const override; + + ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; + + BuiltinVaListKind getBuiltinVaListKind() const override { + return TargetInfo::VoidPtrBuiltinVaList; + } + + ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } + + bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &info) const override { + return false; + } + + const char *getClobbers() const override { return ""; } +}; + +const char *const LanaiTargetInfo::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", "r26", "r27", "r28", "r29", "r30", "r31"}; + +ArrayRef<const char *> LanaiTargetInfo::getGCCRegNames() const { + return llvm::makeArrayRef(GCCRegNames); +} + +const TargetInfo::GCCRegAlias LanaiTargetInfo::GCCRegAliases[] = { + {{"pc"}, "r2"}, + {{"sp"}, "r4"}, + {{"fp"}, "r5"}, + {{"rv"}, "r8"}, + {{"rr1"}, "r10"}, + {{"rr2"}, "r11"}, + {{"rca"}, "r15"}, +}; + +ArrayRef<TargetInfo::GCCRegAlias> LanaiTargetInfo::getGCCRegAliases() const { + return llvm::makeArrayRef(GCCRegAliases); +} + // Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit). class SparcTargetInfo : public TargetInfo { static const TargetInfo::GCCRegAlias GCCRegAliases[]; static const char * const GCCRegNames[]; bool SoftFloat; public: - SparcTargetInfo(const llvm::Triple &Triple) + SparcTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple), SoftFloat(false) {} + int getEHDataRegisterNumber(unsigned RegNo) const override { + if (RegNo == 0) return 24; + if (RegNo == 1) return 25; + return -1; + } + bool handleTargetFeatures(std::vector<std::string> &Features, DiagnosticsEngine &Diags) override { - // The backend doesn't actually handle soft float yet, but in case someone - // is using the support for the front end continue to support it. + // Check if software floating point is enabled auto Feature = std::find(Features.begin(), Features.end(), "+soft-float"); if (Feature != Features.end()) { SoftFloat = true; - Features.erase(Feature); } return true; } @@ -5878,6 +6421,10 @@ public: .Default(false); } + bool hasSjLjLowering() const override { + return true; + } + ArrayRef<Builtin::Info> getTargetBuiltins() const override { // FIXME: Implement! return None; @@ -5924,7 +6471,17 @@ public: CK_NIAGARA, CK_NIAGARA2, CK_NIAGARA3, - CK_NIAGARA4 + CK_NIAGARA4, + CK_MYRIAD2_1, + CK_MYRIAD2_2, + CK_LEON2, + CK_LEON2_AT697E, + CK_LEON2_AT697F, + CK_LEON3, + CK_LEON3_UT699, + CK_LEON3_GR712RC, + CK_LEON4, + CK_LEON4_GR740 } CPU = CK_GENERIC; enum CPUGeneration { @@ -5943,6 +6500,16 @@ public: case CK_SPARCLITE86X: case CK_SPARCLET: case CK_TSC701: + case CK_MYRIAD2_1: + case CK_MYRIAD2_2: + case CK_LEON2: + case CK_LEON2_AT697E: + case CK_LEON2_AT697F: + case CK_LEON3: + case CK_LEON3_UT699: + case CK_LEON3_GR712RC: + case CK_LEON4: + case CK_LEON4_GR740: return CG_V8; case CK_V9: case CK_ULTRASPARC: @@ -5973,6 +6540,17 @@ 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("leon2", CK_LEON2) + .Case("at697e", CK_LEON2_AT697E) + .Case("at697f", CK_LEON2_AT697F) + .Case("leon3", CK_LEON3) + .Case("ut699", CK_LEON3_UT699) + .Case("gr712rc", CK_LEON3_GR712RC) + .Case("leon4", CK_LEON4) + .Case("gr740", CK_LEON4_GR740) .Default(CK_GENERIC); } @@ -6035,8 +6613,9 @@ ArrayRef<TargetInfo::GCCRegAlias> SparcTargetInfo::getGCCRegAliases() const { // SPARC v8 is the 32-bit mode selected by Triple::sparc. class SparcV8TargetInfo : public SparcTargetInfo { public: - SparcV8TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) { - DataLayoutString = "E-m:e-p:32:32-i64:64-f128:64-n32-S64"; + SparcV8TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : SparcTargetInfo(Triple, Opts) { + resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64"); // NetBSD / OpenBSD use long (same as llvm default); everyone else uses int. switch (getTriple().getOS()) { default: @@ -6051,6 +6630,7 @@ public: PtrDiffType = SignedLong; break; } + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } void getTargetDefines(const LangOptions &Opts, @@ -6070,24 +6650,44 @@ public: } break; } + if (getTriple().getVendor() == llvm::Triple::Myriad) { + switch (CPU) { + case CK_MYRIAD2_1: + Builder.defineMacro("__myriad2", "1"); + Builder.defineMacro("__myriad2__", "1"); + break; + case CK_MYRIAD2_2: + Builder.defineMacro("__myriad2", "2"); + Builder.defineMacro("__myriad2__", "2"); + break; + default: + break; + } + } + } + + bool hasSjLjLowering() const override { + return true; } }; // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel. class SparcV8elTargetInfo : public SparcV8TargetInfo { public: - SparcV8elTargetInfo(const llvm::Triple &Triple) : SparcV8TargetInfo(Triple) { - DataLayoutString = "e-m:e-p:32:32-i64:64-f128:64-n32-S64"; - BigEndian = false; + 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; } }; // SPARC v9 is the 64-bit mode selected by Triple::sparcv9. class SparcV9TargetInfo : public SparcTargetInfo { public: - SparcV9TargetInfo(const llvm::Triple &Triple) : SparcTargetInfo(Triple) { + SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : SparcTargetInfo(Triple, Opts) { // FIXME: Support Sparc quad-precision long double? - DataLayoutString = "E-m:e-i64:64-n32:64-S128"; + resetDataLayout("E-m:e-i64:64-n32:64-S128"); // This is an LP64 platform. LongWidth = LongAlign = PointerWidth = PointerAlign = 64; @@ -6134,7 +6734,7 @@ class SystemZTargetInfo : public TargetInfo { bool HasVector; public: - SystemZTargetInfo(const llvm::Triple &Triple) + SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple), CPU("z10"), HasTransactionalExecution(false), HasVector(false) { IntMaxType = SignedLong; @@ -6148,7 +6748,7 @@ public: LongDoubleFormat = &llvm::APFloat::IEEEquad; DefaultAlignForAttributeAligned = 64; MinGlobalAlign = 16; - DataLayoutString = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"; + resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64"); MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } void getTargetDefines(const LangOptions &Opts, @@ -6223,8 +6823,8 @@ public: // If we use the vector ABI, vector types are 64-bit aligned. if (HasVector) { MaxVectorAlign = 64; - DataLayoutString = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" - "-v128:64-a:8:16-n32:64"; + resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" + "-v128:64-a:8:16-n32:64"); } return true; } @@ -6237,6 +6837,16 @@ public: .Default(false); } + CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { + switch (CC) { + case CC_C: + case CC_Swift: + return CCCR_OK; + default: + return CCCR_Warning; + } + } + StringRef getABI() const override { if (HasVector) return "vector"; @@ -6251,6 +6861,8 @@ public: const Builtin::Info SystemZTargetInfo::BuiltinInfo[] = { #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 }, #include "clang/Basic/BuiltinsSystemZ.def" }; @@ -6298,7 +6910,8 @@ class MSP430TargetInfo : public TargetInfo { static const char *const GCCRegNames[]; public: - MSP430TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + MSP430TargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { BigEndian = false; TLSSupported = false; IntWidth = 16; @@ -6314,7 +6927,7 @@ public: IntPtrType = SignedInt; PtrDiffType = SignedInt; SigAtomicType = SignedLong; - DataLayoutString = "e-m:e-p:16:16-i32:16:32-a:16-n8:16"; + resetDataLayout("e-m:e-p:16:16-i32:16:32-a:16-n8:16"); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -6385,7 +6998,8 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = { class TCETargetInfo : public TargetInfo { public: - TCETargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + TCETargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { TLSSupported = false; IntWidth = 32; LongWidth = LongLongWidth = 32; @@ -6407,8 +7021,8 @@ public: FloatFormat = &llvm::APFloat::IEEEsingle; DoubleFormat = &llvm::APFloat::IEEEsingle; LongDoubleFormat = &llvm::APFloat::IEEEsingle; - DataLayoutString = "E-p:32:32-i8:8:32-i16:16:32-i64:32" - "-f64:32-v64:32-v128:32-a:0:32-n32"; + resetDataLayout("E-p:32:32-i8:8:32-i16:16:32-i64:32" + "-f64:32-v64:32-v128:32-a:0:32-n32"); AddrSpaceMap = &TCEOpenCLAddrSpaceMap; UseAddrSpaceMapMangling = true; } @@ -6438,7 +7052,8 @@ public: class BPFTargetInfo : public TargetInfo { public: - BPFTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + BPFTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { LongWidth = LongAlign = PointerWidth = PointerAlign = 64; SizeType = UnsignedLong; PtrDiffType = SignedLong; @@ -6448,10 +7063,10 @@ public: RegParmMax = 5; if (Triple.getArch() == llvm::Triple::bpfeb) { BigEndian = true; - DataLayoutString = "E-m:e-p:64:64-i64:64-n32:64-S128"; + resetDataLayout("E-m:e-p:64:64-i64:64-n32:64-S128"); } else { BigEndian = false; - DataLayoutString = "e-m:e-p:64:64-i64:64-n32:64-S128"; + resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128"); } MaxAtomicPromoteWidth = 64; MaxAtomicInlineWidth = 64; @@ -6485,8 +7100,25 @@ public: } }; -class MipsTargetInfoBase : public TargetInfo { - virtual void setDataLayoutString() = 0; +class MipsTargetInfo : public TargetInfo { + void setDataLayout() { + StringRef Layout; + + if (ABI == "o32") + Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"; + else if (ABI == "n32") + Layout = "m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"; + else if (ABI == "n64") + Layout = "m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"; + else + llvm_unreachable("Invalid ABI"); + + if (BigEndian) + resetDataLayout(("E-" + Layout).str()); + else + resetDataLayout(("e-" + Layout).str()); + } + static const Builtin::Info BuiltinInfo[]; std::string CPU; @@ -6507,12 +7139,20 @@ protected: std::string ABI; public: - MipsTargetInfoBase(const llvm::Triple &Triple, const std::string &ABIStr, - const std::string &CPUStr) - : TargetInfo(Triple), CPU(CPUStr), IsMips16(false), IsMicromips(false), + MipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple), IsMips16(false), IsMicromips(false), IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat), - DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) { + 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) + ? "o32" + : "n64"); + + CPU = ABI == "o32" ? "mips32r2" : "mips64r2"; } bool isNaN2008Default() const { @@ -6527,22 +7167,99 @@ public: return IsNan2008; } + bool processorSupportsGPR64() const { + return llvm::StringSwitch<bool>(CPU) + .Case("mips3", true) + .Case("mips4", true) + .Case("mips5", true) + .Case("mips64", true) + .Case("mips64r2", true) + .Case("mips64r3", true) + .Case("mips64r5", true) + .Case("mips64r6", true) + .Case("octeon", true) + .Default(false); + return false; + } + StringRef getABI() const override { return ABI; } + bool setABI(const std::string &Name) override { + if (Name == "o32") { + setO32ABITypes(); + ABI = Name; + return true; + } + + if (Name == "n32") { + setN32ABITypes(); + ABI = Name; + return true; + } + if (Name == "n64") { + setN64ABITypes(); + ABI = Name; + return true; + } + return false; + } + + void setO32ABITypes() { + Int64Type = SignedLongLong; + IntMaxType = Int64Type; + LongDoubleFormat = &llvm::APFloat::IEEEdouble; + LongDoubleWidth = LongDoubleAlign = 64; + LongWidth = LongAlign = 32; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; + PointerWidth = PointerAlign = 32; + PtrDiffType = SignedInt; + SizeType = UnsignedInt; + SuitableAlign = 64; + } + + void setN32N64ABITypes() { + LongDoubleWidth = LongDoubleAlign = 128; + LongDoubleFormat = &llvm::APFloat::IEEEquad; + if (getTriple().getOS() == llvm::Triple::FreeBSD) { + LongDoubleWidth = LongDoubleAlign = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble; + } + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + SuitableAlign = 128; + } + + void setN64ABITypes() { + setN32N64ABITypes(); + Int64Type = SignedLong; + IntMaxType = Int64Type; + LongWidth = LongAlign = 64; + PointerWidth = PointerAlign = 64; + PtrDiffType = SignedLong; + SizeType = UnsignedLong; + } + + void setN32ABITypes() { + setN32N64ABITypes(); + Int64Type = SignedLongLong; + IntMaxType = Int64Type; + LongWidth = LongAlign = 32; + PointerWidth = PointerAlign = 32; + PtrDiffType = SignedInt; + SizeType = UnsignedInt; + } + bool setCPU(const std::string &Name) override { - bool IsMips32 = getTriple().getArch() == llvm::Triple::mips || - getTriple().getArch() == llvm::Triple::mipsel; CPU = Name; return llvm::StringSwitch<bool>(Name) - .Case("mips1", IsMips32) - .Case("mips2", IsMips32) + .Case("mips1", true) + .Case("mips2", true) .Case("mips3", true) .Case("mips4", true) .Case("mips5", true) - .Case("mips32", IsMips32) - .Case("mips32r2", IsMips32) - .Case("mips32r3", IsMips32) - .Case("mips32r5", IsMips32) - .Case("mips32r6", IsMips32) + .Case("mips32", true) + .Case("mips32r2", true) + .Case("mips32r3", true) + .Case("mips32r5", true) + .Case("mips32r6", true) .Case("mips64", true) .Case("mips64r2", true) .Case("mips64r3", true) @@ -6557,6 +7274,8 @@ public: initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector<std::string> &FeaturesVec) const override { + if (CPU.empty()) + CPU = getCPU(); if (CPU == "octeon") Features["mips64r2"] = Features["cnmips"] = true; else @@ -6566,11 +7285,54 @@ public: void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { + if (BigEndian) { + DefineStd(Builder, "MIPSEB", Opts); + Builder.defineMacro("_MIPSEB"); + } else { + DefineStd(Builder, "MIPSEL", Opts); + Builder.defineMacro("_MIPSEL"); + } + Builder.defineMacro("__mips__"); Builder.defineMacro("_mips"); if (Opts.GNUMode) Builder.defineMacro("mips"); + if (ABI == "o32") { + Builder.defineMacro("__mips", "32"); + Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32"); + } else { + Builder.defineMacro("__mips", "64"); + Builder.defineMacro("__mips64"); + Builder.defineMacro("__mips64__"); + Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64"); + } + + const std::string ISARev = llvm::StringSwitch<std::string>(getCPU()) + .Cases("mips32", "mips64", "1") + .Cases("mips32r2", "mips64r2", "2") + .Cases("mips32r3", "mips64r3", "3") + .Cases("mips32r5", "mips64r5", "5") + .Cases("mips32r6", "mips64r6", "6") + .Default(""); + if (!ISARev.empty()) + Builder.defineMacro("__mips_isa_rev", ISARev); + + if (ABI == "o32") { + Builder.defineMacro("__mips_o32"); + Builder.defineMacro("_ABIO32", "1"); + Builder.defineMacro("_MIPS_SIM", "_ABIO32"); + } else if (ABI == "n32") { + Builder.defineMacro("__mips_n32"); + Builder.defineMacro("_ABIN32", "2"); + Builder.defineMacro("_MIPS_SIM", "_ABIN32"); + } else if (ABI == "n64") { + Builder.defineMacro("__mips_n64"); + Builder.defineMacro("_ABI64", "3"); + Builder.defineMacro("_MIPS_SIM", "_ABI64"); + } else + llvm_unreachable("Invalid ABI."); + Builder.defineMacro("__REGISTER_PREFIX__", ""); switch (FloatABI) { @@ -6627,6 +7389,13 @@ public: Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); + + // 32-bit MIPS processors don't have the necessary lld/scd instructions + // found in 64-bit processors. In the case of O32 on a 64-bit processor, + // the instructions exist but using them violates the ABI since they + // require 64-bit GPRs and O32 only supports 32-bit GPRs. + if (ABI == "n32" || ABI == "n64") + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } ArrayRef<Builtin::Info> getTargetBuiltins() const override { @@ -6657,7 +7426,8 @@ public: "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", // Hi/lo and condition register names "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4", - "$fcc5","$fcc6","$fcc7", + "$fcc5","$fcc6","$fcc7","$ac1hi","$ac1lo","$ac2hi","$ac2lo", + "$ac3hi","$ac3lo", // MSA register names "$w0", "$w1", "$w2", "$w3", "$w4", "$w5", "$w6", "$w7", "$w8", "$w9", "$w10", "$w11", "$w12", "$w13", "$w14", "$w15", @@ -6669,7 +7439,6 @@ public: }; return llvm::makeArrayRef(GCCRegNames); } - ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override = 0; bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override { switch (*Name) { @@ -6780,7 +7549,7 @@ public: IsNan2008 = false; } - setDataLayoutString(); + setDataLayout(); return true; } @@ -6792,304 +7561,94 @@ public: } bool isCLZForZeroUndef() const override { return false; } -}; - -const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = { -#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 }, -#include "clang/Basic/BuiltinsMips.def" -}; - -class Mips32TargetInfoBase : public MipsTargetInfoBase { -public: - Mips32TargetInfoBase(const llvm::Triple &Triple) - : MipsTargetInfoBase(Triple, "o32", "mips32r2") { - SizeType = UnsignedInt; - PtrDiffType = SignedInt; - Int64Type = SignedLongLong; - IntMaxType = Int64Type; - MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; - } - bool setABI(const std::string &Name) override { - if (Name == "o32" || Name == "eabi") { - ABI = Name; - return true; - } - return false; - } - void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const override { - MipsTargetInfoBase::getTargetDefines(Opts, Builder); - - Builder.defineMacro("__mips", "32"); - Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32"); - - const std::string& CPUStr = getCPU(); - if (CPUStr == "mips32") - Builder.defineMacro("__mips_isa_rev", "1"); - else if (CPUStr == "mips32r2") - Builder.defineMacro("__mips_isa_rev", "2"); - else if (CPUStr == "mips32r3") - Builder.defineMacro("__mips_isa_rev", "3"); - else if (CPUStr == "mips32r5") - Builder.defineMacro("__mips_isa_rev", "5"); - else if (CPUStr == "mips32r6") - Builder.defineMacro("__mips_isa_rev", "6"); - if (ABI == "o32") { - Builder.defineMacro("__mips_o32"); - Builder.defineMacro("_ABIO32", "1"); - Builder.defineMacro("_MIPS_SIM", "_ABIO32"); - } - else if (ABI == "eabi") - Builder.defineMacro("__mips_eabi"); - else - llvm_unreachable("Invalid ABI for Mips32."); - } ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - static const TargetInfo::GCCRegAlias GCCRegAliases[] = { - { { "at" }, "$1" }, - { { "v0" }, "$2" }, - { { "v1" }, "$3" }, - { { "a0" }, "$4" }, - { { "a1" }, "$5" }, - { { "a2" }, "$6" }, - { { "a3" }, "$7" }, - { { "t0" }, "$8" }, - { { "t1" }, "$9" }, - { { "t2" }, "$10" }, - { { "t3" }, "$11" }, - { { "t4" }, "$12" }, - { { "t5" }, "$13" }, - { { "t6" }, "$14" }, - { { "t7" }, "$15" }, - { { "s0" }, "$16" }, - { { "s1" }, "$17" }, - { { "s2" }, "$18" }, - { { "s3" }, "$19" }, - { { "s4" }, "$20" }, - { { "s5" }, "$21" }, - { { "s6" }, "$22" }, - { { "s7" }, "$23" }, - { { "t8" }, "$24" }, - { { "t9" }, "$25" }, - { { "k0" }, "$26" }, - { { "k1" }, "$27" }, - { { "gp" }, "$28" }, - { { "sp","$sp" }, "$29" }, - { { "fp","$fp" }, "$30" }, - { { "ra" }, "$31" } - }; - return llvm::makeArrayRef(GCCRegAliases); - } -}; - -class Mips32EBTargetInfo : public Mips32TargetInfoBase { - void setDataLayoutString() override { - DataLayoutString = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"; - } - -public: - Mips32EBTargetInfo(const llvm::Triple &Triple) - : Mips32TargetInfoBase(Triple) { - } - void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const override { - DefineStd(Builder, "MIPSEB", Opts); - Builder.defineMacro("_MIPSEB"); - Mips32TargetInfoBase::getTargetDefines(Opts, Builder); - } -}; - -class Mips32ELTargetInfo : public Mips32TargetInfoBase { - void setDataLayoutString() override { - DataLayoutString = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"; - } - -public: - Mips32ELTargetInfo(const llvm::Triple &Triple) - : Mips32TargetInfoBase(Triple) { - BigEndian = false; - } - void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const override { - DefineStd(Builder, "MIPSEL", Opts); - Builder.defineMacro("_MIPSEL"); - Mips32TargetInfoBase::getTargetDefines(Opts, Builder); - } -}; - -class Mips64TargetInfoBase : public MipsTargetInfoBase { -public: - Mips64TargetInfoBase(const llvm::Triple &Triple) - : MipsTargetInfoBase(Triple, "n64", "mips64r2") { - LongDoubleWidth = LongDoubleAlign = 128; - LongDoubleFormat = &llvm::APFloat::IEEEquad; - if (getTriple().getOS() == llvm::Triple::FreeBSD) { - LongDoubleWidth = LongDoubleAlign = 64; - LongDoubleFormat = &llvm::APFloat::IEEEdouble; + static const TargetInfo::GCCRegAlias O32RegAliases[] = { + {{"at"}, "$1"}, {{"v0"}, "$2"}, {{"v1"}, "$3"}, + {{"a0"}, "$4"}, {{"a1"}, "$5"}, {{"a2"}, "$6"}, + {{"a3"}, "$7"}, {{"t0"}, "$8"}, {{"t1"}, "$9"}, + {{"t2"}, "$10"}, {{"t3"}, "$11"}, {{"t4"}, "$12"}, + {{"t5"}, "$13"}, {{"t6"}, "$14"}, {{"t7"}, "$15"}, + {{"s0"}, "$16"}, {{"s1"}, "$17"}, {{"s2"}, "$18"}, + {{"s3"}, "$19"}, {{"s4"}, "$20"}, {{"s5"}, "$21"}, + {{"s6"}, "$22"}, {{"s7"}, "$23"}, {{"t8"}, "$24"}, + {{"t9"}, "$25"}, {{"k0"}, "$26"}, {{"k1"}, "$27"}, + {{"gp"}, "$28"}, {{"sp", "$sp"}, "$29"}, {{"fp", "$fp"}, "$30"}, + {{"ra"}, "$31"}}; + static const TargetInfo::GCCRegAlias NewABIRegAliases[] = { + {{"at"}, "$1"}, {{"v0"}, "$2"}, {{"v1"}, "$3"}, + {{"a0"}, "$4"}, {{"a1"}, "$5"}, {{"a2"}, "$6"}, + {{"a3"}, "$7"}, {{"a4"}, "$8"}, {{"a5"}, "$9"}, + {{"a6"}, "$10"}, {{"a7"}, "$11"}, {{"t0"}, "$12"}, + {{"t1"}, "$13"}, {{"t2"}, "$14"}, {{"t3"}, "$15"}, + {{"s0"}, "$16"}, {{"s1"}, "$17"}, {{"s2"}, "$18"}, + {{"s3"}, "$19"}, {{"s4"}, "$20"}, {{"s5"}, "$21"}, + {{"s6"}, "$22"}, {{"s7"}, "$23"}, {{"t8"}, "$24"}, + {{"t9"}, "$25"}, {{"k0"}, "$26"}, {{"k1"}, "$27"}, + {{"gp"}, "$28"}, {{"sp", "$sp"}, "$29"}, {{"fp", "$fp"}, "$30"}, + {{"ra"}, "$31"}}; + if (ABI == "o32") + return llvm::makeArrayRef(O32RegAliases); + return llvm::makeArrayRef(NewABIRegAliases); + } + + bool hasInt128Type() const override { + return ABI == "n32" || ABI == "n64"; + } + + bool validateTarget(DiagnosticsEngine &Diags) const override { + // FIXME: It's valid to use O32 on a 64-bit CPU but the backend can't handle + // this yet. It's better to fail here than on the backend assertion. + if (processorSupportsGPR64() && ABI == "o32") { + Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU; + return false; } - setN64ABITypes(); - SuitableAlign = 128; - MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; - } - void setN64ABITypes() { - LongWidth = LongAlign = 64; - PointerWidth = PointerAlign = 64; - SizeType = UnsignedLong; - PtrDiffType = SignedLong; - Int64Type = SignedLong; - IntMaxType = Int64Type; - } - - void setN32ABITypes() { - LongWidth = LongAlign = 32; - PointerWidth = PointerAlign = 32; - SizeType = UnsignedInt; - PtrDiffType = SignedInt; - Int64Type = SignedLongLong; - IntMaxType = Int64Type; - } - - bool setABI(const std::string &Name) override { - if (Name == "n32") { - setN32ABITypes(); - ABI = Name; - return true; - } - if (Name == "n64") { - setN64ABITypes(); - ABI = Name; - return true; + // 64-bit ABI's require 64-bit CPU's. + if (!processorSupportsGPR64() && (ABI == "n32" || ABI == "n64")) { + Diags.Report(diag::err_target_unsupported_abi) << ABI << CPU; + return false; } - return false; - } - void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const override { - MipsTargetInfoBase::getTargetDefines(Opts, Builder); - - Builder.defineMacro("__mips", "64"); - Builder.defineMacro("__mips64"); - Builder.defineMacro("__mips64__"); - Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64"); - - const std::string& CPUStr = getCPU(); - if (CPUStr == "mips64") - Builder.defineMacro("__mips_isa_rev", "1"); - else if (CPUStr == "mips64r2") - Builder.defineMacro("__mips_isa_rev", "2"); - else if (CPUStr == "mips64r3") - Builder.defineMacro("__mips_isa_rev", "3"); - else if (CPUStr == "mips64r5") - Builder.defineMacro("__mips_isa_rev", "5"); - else if (CPUStr == "mips64r6") - Builder.defineMacro("__mips_isa_rev", "6"); - - if (ABI == "n32") { - Builder.defineMacro("__mips_n32"); - Builder.defineMacro("_ABIN32", "2"); - Builder.defineMacro("_MIPS_SIM", "_ABIN32"); - } - else if (ABI == "n64") { - Builder.defineMacro("__mips_n64"); - Builder.defineMacro("_ABI64", "3"); - Builder.defineMacro("_MIPS_SIM", "_ABI64"); + // FIXME: It's valid to use O32 on a mips64/mips64el triple but the backend + // can't handle this yet. It's better to fail here than on the + // backend assertion. + if ((getTriple().getArch() == llvm::Triple::mips64 || + getTriple().getArch() == llvm::Triple::mips64el) && + ABI == "o32") { + Diags.Report(diag::err_target_unsupported_abi_for_triple) + << ABI << getTriple().str(); + return false; } - else - llvm_unreachable("Invalid ABI for Mips64."); - Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); - } - ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { - static const TargetInfo::GCCRegAlias GCCRegAliases[] = { - { { "at" }, "$1" }, - { { "v0" }, "$2" }, - { { "v1" }, "$3" }, - { { "a0" }, "$4" }, - { { "a1" }, "$5" }, - { { "a2" }, "$6" }, - { { "a3" }, "$7" }, - { { "a4" }, "$8" }, - { { "a5" }, "$9" }, - { { "a6" }, "$10" }, - { { "a7" }, "$11" }, - { { "t0" }, "$12" }, - { { "t1" }, "$13" }, - { { "t2" }, "$14" }, - { { "t3" }, "$15" }, - { { "s0" }, "$16" }, - { { "s1" }, "$17" }, - { { "s2" }, "$18" }, - { { "s3" }, "$19" }, - { { "s4" }, "$20" }, - { { "s5" }, "$21" }, - { { "s6" }, "$22" }, - { { "s7" }, "$23" }, - { { "t8" }, "$24" }, - { { "t9" }, "$25" }, - { { "k0" }, "$26" }, - { { "k1" }, "$27" }, - { { "gp" }, "$28" }, - { { "sp","$sp" }, "$29" }, - { { "fp","$fp" }, "$30" }, - { { "ra" }, "$31" } - }; - return llvm::makeArrayRef(GCCRegAliases); - } - - bool hasInt128Type() const override { return true; } -}; - -class Mips64EBTargetInfo : public Mips64TargetInfoBase { - void setDataLayoutString() override { - if (ABI == "n32") - DataLayoutString = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"; - else - DataLayoutString = "E-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128"; - - } + // FIXME: It's valid to use N32/N64 on a mips/mipsel triple but the backend + // can't handle this yet. It's better to fail here than on the + // backend assertion. + if ((getTriple().getArch() == llvm::Triple::mips || + getTriple().getArch() == llvm::Triple::mipsel) && + (ABI == "n32" || ABI == "n64")) { + Diags.Report(diag::err_target_unsupported_abi_for_triple) + << ABI << getTriple().str(); + return false; + } -public: - Mips64EBTargetInfo(const llvm::Triple &Triple) - : Mips64TargetInfoBase(Triple) {} - void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const override { - DefineStd(Builder, "MIPSEB", Opts); - Builder.defineMacro("_MIPSEB"); - Mips64TargetInfoBase::getTargetDefines(Opts, Builder); + return true; } }; -class Mips64ELTargetInfo : public Mips64TargetInfoBase { - void setDataLayoutString() override { - if (ABI == "n32") - DataLayoutString = "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"; - else - DataLayoutString = "e-m:m-i8:8:32-i16:16:32-i64:64-n32:64-S128"; - } -public: - Mips64ELTargetInfo(const llvm::Triple &Triple) - : Mips64TargetInfoBase(Triple) { - // Default ABI is n64. - BigEndian = false; - } - void getTargetDefines(const LangOptions &Opts, - MacroBuilder &Builder) const override { - DefineStd(Builder, "MIPSEL", Opts); - Builder.defineMacro("_MIPSEL"); - Mips64TargetInfoBase::getTargetDefines(Opts, Builder); - } +const Builtin::Info MipsTargetInfo::BuiltinInfo[] = { +#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 }, +#include "clang/Basic/BuiltinsMips.def" }; class PNaClTargetInfo : public TargetInfo { public: - PNaClTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + PNaClTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : TargetInfo(Triple) { BigEndian = false; - this->UserLabelPrefix = ""; this->LongAlign = 32; this->LongWidth = 32; this->PointerAlign = 32; @@ -7141,11 +7700,10 @@ ArrayRef<TargetInfo::GCCRegAlias> PNaClTargetInfo::getGCCRegAliases() const { } // We attempt to use PNaCl (le32) frontend and Mips32EL backend. -class NaClMips32ELTargetInfo : public Mips32ELTargetInfo { +class NaClMips32TargetInfo : public MipsTargetInfo { public: - NaClMips32ELTargetInfo(const llvm::Triple &Triple) : - Mips32ELTargetInfo(Triple) { - } + NaClMips32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : MipsTargetInfo(Triple, Opts) {} BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::PNaClABIBuiltinVaList; @@ -7156,12 +7714,13 @@ class Le64TargetInfo : public TargetInfo { static const Builtin::Info BuiltinInfo[]; public: - Le64TargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + Le64TargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { BigEndian = false; NoAsmVariants = true; LongWidth = LongAlign = PointerWidth = PointerAlign = 64; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; - DataLayoutString = "e-m:e-v128:32-v16:16-v32:32-v96:32-n8:16:32:64-S128"; + resetDataLayout("e-m:e-v128:32-v16:16-v32:32-v96:32-n8:16:32:64-S128"); } void getTargetDefines(const LangOptions &Opts, @@ -7201,7 +7760,7 @@ class WebAssemblyTargetInfo : public TargetInfo { } SIMDLevel; public: - explicit WebAssemblyTargetInfo(const llvm::Triple &T) + explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &) : TargetInfo(T), SIMDLevel(NoSIMD) { BigEndian = false; NoAsmVariants = true; @@ -7307,10 +7866,11 @@ const Builtin::Info WebAssemblyTargetInfo::BuiltinInfo[] = { class WebAssembly32TargetInfo : public WebAssemblyTargetInfo { public: - explicit WebAssembly32TargetInfo(const llvm::Triple &T) - : WebAssemblyTargetInfo(T) { + explicit WebAssembly32TargetInfo(const llvm::Triple &T, + const TargetOptions &Opts) + : WebAssemblyTargetInfo(T, Opts) { MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; - DataLayoutString = "e-m:e-p:32:32-i64:64-n32:64-S128"; + resetDataLayout("e-m:e-p:32:32-i64:64-n32:64-S128"); } protected: @@ -7323,12 +7883,13 @@ protected: class WebAssembly64TargetInfo : public WebAssemblyTargetInfo { public: - explicit WebAssembly64TargetInfo(const llvm::Triple &T) - : WebAssemblyTargetInfo(T) { + explicit WebAssembly64TargetInfo(const llvm::Triple &T, + const TargetOptions &Opts) + : WebAssemblyTargetInfo(T, Opts) { LongAlign = LongWidth = 64; PointerAlign = PointerWidth = 64; MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; - DataLayoutString = "e-m:e-p:64:64-i64:64-n32:64-S128"; + resetDataLayout("e-m:e-p:64:64-i64:64-n32:64-S128"); } protected: @@ -7356,7 +7917,8 @@ static const unsigned SPIRAddrSpaceMap[] = { }; class SPIRTargetInfo : public TargetInfo { public: - SPIRTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { assert(getTriple().getOS() == llvm::Triple::UnknownOS && "SPIR target must use unknown OS"); assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && @@ -7393,23 +7955,30 @@ public: } CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { - return (CC == CC_SpirFunction || CC == CC_SpirKernel) ? CCCR_OK - : CCCR_Warning; + return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK + : CCCR_Warning; } CallingConv getDefaultCallingConv(CallingConvMethodType MT) const override { return CC_SpirFunction; } + + void setSupportedOpenCLOpts() override { + // Assume all OpenCL extensions and optional core features are supported + // for SPIR since it is a generic target. + getSupportedOpenCLOpts().setAll(); + } }; class SPIR32TargetInfo : public SPIRTargetInfo { public: - SPIR32TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) { + SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : SPIRTargetInfo(Triple, Opts) { PointerWidth = PointerAlign = 32; SizeType = TargetInfo::UnsignedInt; PtrDiffType = IntPtrType = TargetInfo::SignedInt; - DataLayoutString = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-" - "v96:128-v192:256-v256:256-v512:512-v1024:1024"; + resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-" + "v96:128-v192:256-v256:256-v512:512-v1024:1024"); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -7419,12 +7988,13 @@ public: class SPIR64TargetInfo : public SPIRTargetInfo { public: - SPIR64TargetInfo(const llvm::Triple &Triple) : SPIRTargetInfo(Triple) { + SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : SPIRTargetInfo(Triple, Opts) { PointerWidth = PointerAlign = 64; SizeType = TargetInfo::UnsignedLong; PtrDiffType = IntPtrType = TargetInfo::SignedLong; - DataLayoutString = "e-i64:64-v16:16-v24:32-v32:32-v48:64-" - "v96:128-v192:256-v256:256-v512:512-v1024:1024"; + resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-" + "v96:128-v192:256-v256:256-v512:512-v1024:1024"); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -7435,7 +8005,8 @@ public: class XCoreTargetInfo : public TargetInfo { static const Builtin::Info BuiltinInfo[]; public: - XCoreTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + XCoreTargetInfo(const llvm::Triple &Triple, const TargetOptions &) + : TargetInfo(Triple) { BigEndian = false; NoAsmVariants = true; LongLongAlign = 32; @@ -7447,8 +8018,8 @@ public: WCharType = UnsignedChar; WIntType = UnsignedInt; UseZeroLengthBitfieldAlignment = true; - DataLayoutString = "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32" - "-f64:32-a:0:32-n32"; + resetDataLayout("e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:32" + "-f64:32-a:0:32-n32"); } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override { @@ -7482,6 +8053,9 @@ public: // R0=ExceptionPointerRegister R1=ExceptionSelectorRegister return (RegNo < 2)? RegNo : -1; } + bool allowsLargerPreferedTypeAlignment() const override { + return false; + } }; const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = { @@ -7495,8 +8069,8 @@ const Builtin::Info XCoreTargetInfo::BuiltinInfo[] = { // x86_32 Android target class AndroidX86_32TargetInfo : public LinuxTargetInfo<X86_32TargetInfo> { public: - AndroidX86_32TargetInfo(const llvm::Triple &Triple) - : LinuxTargetInfo<X86_32TargetInfo>(Triple) { + AndroidX86_32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts) { SuitableAlign = 32; LongDoubleWidth = 64; LongDoubleFormat = &llvm::APFloat::IEEEdouble; @@ -7506,8 +8080,8 @@ public: // x86_64 Android target class AndroidX86_64TargetInfo : public LinuxTargetInfo<X86_64TargetInfo> { public: - AndroidX86_64TargetInfo(const llvm::Triple &Triple) - : LinuxTargetInfo<X86_64TargetInfo>(Triple) { + AndroidX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + : LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts) { LongDoubleFormat = &llvm::APFloat::IEEEquad; } @@ -7515,13 +8089,50 @@ public: return true; } }; + +// 32-bit RenderScript is armv7 with width and align of 'long' set to 8-bytes +class RenderScript32TargetInfo : public ARMleTargetInfo { +public: + RenderScript32TargetInfo(const llvm::Triple &Triple, + const TargetOptions &Opts) + : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(), + Triple.getOSName(), + Triple.getEnvironmentName()), + Opts) { + LongWidth = LongAlign = 64; + } + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override { + Builder.defineMacro("__RENDERSCRIPT__"); + ARMleTargetInfo::getTargetDefines(Opts, Builder); + } +}; + +// 64-bit RenderScript is aarch64 +class RenderScript64TargetInfo : public AArch64leTargetInfo { +public: + RenderScript64TargetInfo(const llvm::Triple &Triple, + const TargetOptions &Opts) + : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(), + Triple.getOSName(), + Triple.getEnvironmentName()), + Opts) {} + + void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const override { + Builder.defineMacro("__RENDERSCRIPT__"); + AArch64leTargetInfo::getTargetDefines(Opts, Builder); + } +}; + } // end anonymous namespace //===----------------------------------------------------------------------===// // Driver code //===----------------------------------------------------------------------===// -static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { +static TargetInfo *AllocateTarget(const llvm::Triple &Triple, + const TargetOptions &Opts) { llvm::Triple::OSType os = Triple.getOS(); switch (Triple.getArch()) { @@ -7529,414 +8140,426 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple) { return nullptr; case llvm::Triple::xcore: - return new XCoreTargetInfo(Triple); + return new XCoreTargetInfo(Triple, Opts); case llvm::Triple::hexagon: - return new HexagonTargetInfo(Triple); + return new HexagonTargetInfo(Triple, Opts); + + case llvm::Triple::lanai: + return new LanaiTargetInfo(Triple, Opts); case llvm::Triple::aarch64: if (Triple.isOSDarwin()) - return new DarwinAArch64TargetInfo(Triple); + return new DarwinAArch64TargetInfo(Triple, Opts); switch (os) { case llvm::Triple::CloudABI: - return new CloudABITargetInfo<AArch64leTargetInfo>(Triple); + return new CloudABITargetInfo<AArch64leTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple); + return new FreeBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo<AArch64leTargetInfo>(Triple); + return new LinuxTargetInfo<AArch64leTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple); + return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple, Opts); default: - return new AArch64leTargetInfo(Triple); + return new AArch64leTargetInfo(Triple, Opts); } case llvm::Triple::aarch64_be: switch (os) { case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple); + return new FreeBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo<AArch64beTargetInfo>(Triple); + return new LinuxTargetInfo<AArch64beTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple); + return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple, Opts); default: - return new AArch64beTargetInfo(Triple); + return new AArch64beTargetInfo(Triple, Opts); } case llvm::Triple::arm: case llvm::Triple::thumb: if (Triple.isOSBinFormatMachO()) - return new DarwinARMTargetInfo(Triple); + return new DarwinARMTargetInfo(Triple, Opts); switch (os) { + case llvm::Triple::CloudABI: + return new CloudABITargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::Linux: - return new LinuxTargetInfo<ARMleTargetInfo>(Triple); + return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple); + return new FreeBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<ARMleTargetInfo>(Triple); + return new NetBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple); + return new OpenBSDTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::Bitrig: - return new BitrigTargetInfo<ARMleTargetInfo>(Triple); + return new BitrigTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<ARMleTargetInfo>(Triple); + return new RTEMSTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::NaCl: - return new NaClTargetInfo<ARMleTargetInfo>(Triple); + return new NaClTargetInfo<ARMleTargetInfo>(Triple, Opts); case llvm::Triple::Win32: switch (Triple.getEnvironment()) { case llvm::Triple::Cygnus: - return new CygwinARMTargetInfo(Triple); + return new CygwinARMTargetInfo(Triple, Opts); case llvm::Triple::GNU: - return new MinGWARMTargetInfo(Triple); + return new MinGWARMTargetInfo(Triple, Opts); case llvm::Triple::Itanium: - return new ItaniumWindowsARMleTargetInfo(Triple); + return new ItaniumWindowsARMleTargetInfo(Triple, Opts); case llvm::Triple::MSVC: default: // Assume MSVC for unknown environments - return new MicrosoftARMleTargetInfo(Triple); + return new MicrosoftARMleTargetInfo(Triple, Opts); } default: - return new ARMleTargetInfo(Triple); + return new ARMleTargetInfo(Triple, Opts); } case llvm::Triple::armeb: case llvm::Triple::thumbeb: if (Triple.isOSDarwin()) - return new DarwinARMTargetInfo(Triple); + return new DarwinARMTargetInfo(Triple, Opts); switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<ARMbeTargetInfo>(Triple); + return new LinuxTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple); + return new FreeBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple); + return new NetBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple); + return new OpenBSDTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::Bitrig: - return new BitrigTargetInfo<ARMbeTargetInfo>(Triple); + return new BitrigTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple); + return new RTEMSTargetInfo<ARMbeTargetInfo>(Triple, Opts); case llvm::Triple::NaCl: - return new NaClTargetInfo<ARMbeTargetInfo>(Triple); + return new NaClTargetInfo<ARMbeTargetInfo>(Triple, Opts); default: - return new ARMbeTargetInfo(Triple); + return new ARMbeTargetInfo(Triple, Opts); } case llvm::Triple::bpfeb: case llvm::Triple::bpfel: - return new BPFTargetInfo(Triple); + return new BPFTargetInfo(Triple, Opts); case llvm::Triple::msp430: - return new MSP430TargetInfo(Triple); + return new MSP430TargetInfo(Triple, Opts); case llvm::Triple::mips: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<Mips32EBTargetInfo>(Triple); + return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<Mips32EBTargetInfo>(Triple); + return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<Mips32EBTargetInfo>(Triple); + return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<Mips32EBTargetInfo>(Triple); + return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); default: - return new Mips32EBTargetInfo(Triple); + return new MipsTargetInfo(Triple, Opts); } case llvm::Triple::mipsel: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<Mips32ELTargetInfo>(Triple); + return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<Mips32ELTargetInfo>(Triple); + return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<Mips32ELTargetInfo>(Triple); + return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<Mips32ELTargetInfo>(Triple); + return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::NaCl: - return new NaClTargetInfo<NaClMips32ELTargetInfo>(Triple); + return new NaClTargetInfo<NaClMips32TargetInfo>(Triple, Opts); default: - return new Mips32ELTargetInfo(Triple); + return new MipsTargetInfo(Triple, Opts); } case llvm::Triple::mips64: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<Mips64EBTargetInfo>(Triple); + return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<Mips64EBTargetInfo>(Triple); + return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<Mips64EBTargetInfo>(Triple); + return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<Mips64EBTargetInfo>(Triple); + return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<Mips64EBTargetInfo>(Triple); + return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts); default: - return new Mips64EBTargetInfo(Triple); + return new MipsTargetInfo(Triple, Opts); } case llvm::Triple::mips64el: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<Mips64ELTargetInfo>(Triple); + return new LinuxTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<Mips64ELTargetInfo>(Triple); + return new RTEMSTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<Mips64ELTargetInfo>(Triple); + return new FreeBSDTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<Mips64ELTargetInfo>(Triple); + return new NetBSDTargetInfo<MipsTargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<Mips64ELTargetInfo>(Triple); + return new OpenBSDTargetInfo<MipsTargetInfo>(Triple, Opts); default: - return new Mips64ELTargetInfo(Triple); + return new MipsTargetInfo(Triple, Opts); } case llvm::Triple::le32: switch (os) { case llvm::Triple::NaCl: - return new NaClTargetInfo<PNaClTargetInfo>(Triple); + return new NaClTargetInfo<PNaClTargetInfo>(Triple, Opts); default: return nullptr; } case llvm::Triple::le64: - return new Le64TargetInfo(Triple); + return new Le64TargetInfo(Triple, Opts); case llvm::Triple::ppc: if (Triple.isOSDarwin()) - return new DarwinPPC32TargetInfo(Triple); + return new DarwinPPC32TargetInfo(Triple, Opts); switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<PPC32TargetInfo>(Triple); + return new LinuxTargetInfo<PPC32TargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple); + return new FreeBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<PPC32TargetInfo>(Triple); + return new NetBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple); + return new OpenBSDTargetInfo<PPC32TargetInfo>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<PPC32TargetInfo>(Triple); + return new RTEMSTargetInfo<PPC32TargetInfo>(Triple, Opts); default: - return new PPC32TargetInfo(Triple); + return new PPC32TargetInfo(Triple, Opts); } case llvm::Triple::ppc64: if (Triple.isOSDarwin()) - return new DarwinPPC64TargetInfo(Triple); + return new DarwinPPC64TargetInfo(Triple, Opts); switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<PPC64TargetInfo>(Triple); + return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts); case llvm::Triple::Lv2: - return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple); + return new PS3PPUTargetInfo<PPC64TargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple); + return new FreeBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<PPC64TargetInfo>(Triple); + return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); default: - return new PPC64TargetInfo(Triple); + return new PPC64TargetInfo(Triple, Opts); } case llvm::Triple::ppc64le: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<PPC64TargetInfo>(Triple); + return new LinuxTargetInfo<PPC64TargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<PPC64TargetInfo>(Triple); + return new NetBSDTargetInfo<PPC64TargetInfo>(Triple, Opts); default: - return new PPC64TargetInfo(Triple); + return new PPC64TargetInfo(Triple, Opts); } case llvm::Triple::nvptx: - return new NVPTX32TargetInfo(Triple); + return new NVPTX32TargetInfo(Triple, Opts); case llvm::Triple::nvptx64: - return new NVPTX64TargetInfo(Triple); + return new NVPTX64TargetInfo(Triple, Opts); case llvm::Triple::amdgcn: case llvm::Triple::r600: - return new AMDGPUTargetInfo(Triple); + return new AMDGPUTargetInfo(Triple, Opts); case llvm::Triple::sparc: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SparcV8TargetInfo>(Triple); + return new LinuxTargetInfo<SparcV8TargetInfo>(Triple, Opts); case llvm::Triple::Solaris: - return new SolarisTargetInfo<SparcV8TargetInfo>(Triple); + return new SolarisTargetInfo<SparcV8TargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple); + return new NetBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<SparcV8TargetInfo>(Triple); + return new OpenBSDTargetInfo<SparcV8TargetInfo>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple); + return new RTEMSTargetInfo<SparcV8TargetInfo>(Triple, Opts); default: - return new SparcV8TargetInfo(Triple); + return new SparcV8TargetInfo(Triple, Opts); } // The 'sparcel' architecture copies all the above cases except for Solaris. case llvm::Triple::sparcel: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple); + return new LinuxTargetInfo<SparcV8elTargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple); + return new NetBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<SparcV8elTargetInfo>(Triple); + return new OpenBSDTargetInfo<SparcV8elTargetInfo>(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple); + return new RTEMSTargetInfo<SparcV8elTargetInfo>(Triple, Opts); default: - return new SparcV8elTargetInfo(Triple); + return new SparcV8elTargetInfo(Triple, Opts); } case llvm::Triple::sparcv9: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SparcV9TargetInfo>(Triple); + return new LinuxTargetInfo<SparcV9TargetInfo>(Triple, Opts); case llvm::Triple::Solaris: - return new SolarisTargetInfo<SparcV9TargetInfo>(Triple); + return new SolarisTargetInfo<SparcV9TargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple); + return new NetBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple); + return new OpenBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple); + return new FreeBSDTargetInfo<SparcV9TargetInfo>(Triple, Opts); default: - return new SparcV9TargetInfo(Triple); + return new SparcV9TargetInfo(Triple, Opts); } case llvm::Triple::systemz: switch (os) { case llvm::Triple::Linux: - return new LinuxTargetInfo<SystemZTargetInfo>(Triple); + return new LinuxTargetInfo<SystemZTargetInfo>(Triple, Opts); default: - return new SystemZTargetInfo(Triple); + return new SystemZTargetInfo(Triple, Opts); } case llvm::Triple::tce: - return new TCETargetInfo(Triple); + return new TCETargetInfo(Triple, Opts); case llvm::Triple::x86: if (Triple.isOSDarwin()) - return new DarwinI386TargetInfo(Triple); + return new DarwinI386TargetInfo(Triple, Opts); switch (os) { case llvm::Triple::CloudABI: - return new CloudABITargetInfo<X86_32TargetInfo>(Triple); + return new CloudABITargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::Linux: { switch (Triple.getEnvironment()) { default: - return new LinuxTargetInfo<X86_32TargetInfo>(Triple); + return new LinuxTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::Android: - return new AndroidX86_32TargetInfo(Triple); + return new AndroidX86_32TargetInfo(Triple, Opts); } } case llvm::Triple::DragonFly: - return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple); + return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDI386TargetInfo(Triple); + return new NetBSDI386TargetInfo(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDI386TargetInfo(Triple); + return new OpenBSDI386TargetInfo(Triple, Opts); case llvm::Triple::Bitrig: - return new BitrigI386TargetInfo(Triple); + return new BitrigI386TargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple); + return new FreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::KFreeBSD: - return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple); + return new KFreeBSDTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::Minix: - return new MinixTargetInfo<X86_32TargetInfo>(Triple); + return new MinixTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::Solaris: - return new SolarisTargetInfo<X86_32TargetInfo>(Triple); + return new SolarisTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::Win32: { switch (Triple.getEnvironment()) { case llvm::Triple::Cygnus: - return new CygwinX86_32TargetInfo(Triple); + return new CygwinX86_32TargetInfo(Triple, Opts); case llvm::Triple::GNU: - return new MinGWX86_32TargetInfo(Triple); + return new MinGWX86_32TargetInfo(Triple, Opts); case llvm::Triple::Itanium: case llvm::Triple::MSVC: default: // Assume MSVC for unknown environments - return new MicrosoftX86_32TargetInfo(Triple); + return new MicrosoftX86_32TargetInfo(Triple, Opts); } } case llvm::Triple::Haiku: - return new HaikuX86_32TargetInfo(Triple); + return new HaikuX86_32TargetInfo(Triple, Opts); case llvm::Triple::RTEMS: - return new RTEMSX86_32TargetInfo(Triple); + return new RTEMSX86_32TargetInfo(Triple, Opts); case llvm::Triple::NaCl: - return new NaClTargetInfo<X86_32TargetInfo>(Triple); + return new NaClTargetInfo<X86_32TargetInfo>(Triple, Opts); case llvm::Triple::ELFIAMCU: - return new MCUX86_32TargetInfo(Triple); + return new MCUX86_32TargetInfo(Triple, Opts); default: - return new X86_32TargetInfo(Triple); + return new X86_32TargetInfo(Triple, Opts); } case llvm::Triple::x86_64: if (Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) - return new DarwinX86_64TargetInfo(Triple); + return new DarwinX86_64TargetInfo(Triple, Opts); switch (os) { case llvm::Triple::CloudABI: - return new CloudABITargetInfo<X86_64TargetInfo>(Triple); + return new CloudABITargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::Linux: { switch (Triple.getEnvironment()) { default: - return new LinuxTargetInfo<X86_64TargetInfo>(Triple); + return new LinuxTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::Android: - return new AndroidX86_64TargetInfo(Triple); + return new AndroidX86_64TargetInfo(Triple, Opts); } } case llvm::Triple::DragonFly: - return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple); + return new DragonFlyBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::NetBSD: - return new NetBSDTargetInfo<X86_64TargetInfo>(Triple); + return new NetBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::OpenBSD: - return new OpenBSDX86_64TargetInfo(Triple); + return new OpenBSDX86_64TargetInfo(Triple, Opts); case llvm::Triple::Bitrig: - return new BitrigX86_64TargetInfo(Triple); + return new BitrigX86_64TargetInfo(Triple, Opts); case llvm::Triple::FreeBSD: - return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple); + return new FreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::KFreeBSD: - return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple); + return new KFreeBSDTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::Solaris: - return new SolarisTargetInfo<X86_64TargetInfo>(Triple); + return new SolarisTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::Win32: { switch (Triple.getEnvironment()) { case llvm::Triple::Cygnus: - return new CygwinX86_64TargetInfo(Triple); + return new CygwinX86_64TargetInfo(Triple, Opts); case llvm::Triple::GNU: - return new MinGWX86_64TargetInfo(Triple); + return new MinGWX86_64TargetInfo(Triple, Opts); case llvm::Triple::MSVC: default: // Assume MSVC for unknown environments - return new MicrosoftX86_64TargetInfo(Triple); + return new MicrosoftX86_64TargetInfo(Triple, Opts); } } + case llvm::Triple::Haiku: + return new HaikuTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::NaCl: - return new NaClTargetInfo<X86_64TargetInfo>(Triple); + return new NaClTargetInfo<X86_64TargetInfo>(Triple, Opts); case llvm::Triple::PS4: - return new PS4OSTargetInfo<X86_64TargetInfo>(Triple); + return new PS4OSTargetInfo<X86_64TargetInfo>(Triple, Opts); default: - return new X86_64TargetInfo(Triple); + return new X86_64TargetInfo(Triple, Opts); } case llvm::Triple::spir: { if (Triple.getOS() != llvm::Triple::UnknownOS || Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) return nullptr; - return new SPIR32TargetInfo(Triple); + return new SPIR32TargetInfo(Triple, Opts); } case llvm::Triple::spir64: { if (Triple.getOS() != llvm::Triple::UnknownOS || Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) return nullptr; - return new SPIR64TargetInfo(Triple); + return new SPIR64TargetInfo(Triple, Opts); } case llvm::Triple::wasm32: if (!(Triple == llvm::Triple("wasm32-unknown-unknown"))) return nullptr; - return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple); + return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts); case llvm::Triple::wasm64: if (!(Triple == llvm::Triple("wasm64-unknown-unknown"))) return nullptr; - return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple); + return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts); + + case llvm::Triple::renderscript32: + return new LinuxTargetInfo<RenderScript32TargetInfo>(Triple, Opts); + case llvm::Triple::renderscript64: + return new LinuxTargetInfo<RenderScript64TargetInfo>(Triple, Opts); } } @@ -7948,7 +8571,7 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, llvm::Triple Triple(Opts->Triple); // Construct the target - std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple)); + std::unique_ptr<TargetInfo> Target(AllocateTarget(Triple, *Opts)); if (!Target) { Diags.Report(diag::err_target_unknown_triple) << Triple.str(); return nullptr; @@ -7988,5 +8611,10 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, if (!Target->handleTargetFeatures(Opts->Features, Diags)) return nullptr; + Target->setSupportedOpenCLOpts(); + + if (!Target->validateTarget(Diags)) + return nullptr; + return Target.release(); } diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp index 2b5014e..4fa52b4 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_380/final/lib/Basic/Version.cpp $"); + StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_391/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 6977f40..8ace2b3 100644 --- a/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/VirtualFileSystem.cpp @@ -16,13 +16,16 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/Errc.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Process.h" #include "llvm/Support/YAMLParser.h" -#include "llvm/Config/llvm-config.h" #include <atomic> #include <memory> +#include <utility> // For chdir. #ifdef LLVM_ON_WIN32 @@ -99,6 +102,9 @@ FileSystem::getBufferForFile(const llvm::Twine &Name, int64_t FileSize, } std::error_code FileSystem::makeAbsolute(SmallVectorImpl<char> &Path) const { + if (llvm::sys::path::is_absolute(Path)) + return std::error_code(); + auto WorkingDir = getCurrentWorkingDirectory(); if (!WorkingDir) return WorkingDir.getError(); @@ -111,6 +117,20 @@ bool FileSystem::exists(const Twine &Path) { return Status && Status->exists(); } +#ifndef NDEBUG +static bool isTraversalComponent(StringRef Component) { + return Component.equals("..") || Component.equals("."); +} + +static bool pathHasTraversal(StringRef Path) { + using namespace llvm::sys; + for (StringRef Comp : llvm::make_range(path::begin(Path), path::end(Path))) + if (isTraversalComponent(Comp)) + return true; + return false; +} +#endif + //===-----------------------------------------------------------------------===/ // RealFileSystem implementation //===-----------------------------------------------------------------------===/ @@ -120,16 +140,19 @@ namespace { class RealFile : public File { int FD; Status S; + std::string RealName; friend class RealFileSystem; - RealFile(int FD, StringRef NewName) + RealFile(int FD, StringRef NewName, StringRef NewRealPathName) : FD(FD), S(NewName, {}, {}, {}, {}, {}, - llvm::sys::fs::file_type::status_error, {}) { + llvm::sys::fs::file_type::status_error, {}), + RealName(NewRealPathName.str()) { assert(FD >= 0 && "Invalid or inactive file descriptor"); } public: ~RealFile() override; ErrorOr<Status> status() override; + ErrorOr<std::string> getName() override; ErrorOr<std::unique_ptr<MemoryBuffer>> getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, @@ -150,6 +173,10 @@ ErrorOr<Status> RealFile::status() { return S; } +ErrorOr<std::string> RealFile::getName() { + return RealName.empty() ? S.getName().str() : RealName; +} + ErrorOr<std::unique_ptr<MemoryBuffer>> RealFile::getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) { @@ -158,21 +185,10 @@ RealFile::getBuffer(const Twine &Name, int64_t FileSize, IsVolatile); } -// FIXME: This is terrible, we need this for ::close. -#if !defined(_MSC_VER) && !defined(__MINGW32__) -#include <unistd.h> -#include <sys/uio.h> -#else -#include <io.h> -#ifndef S_ISFIFO -#define S_ISFIFO(x) (0) -#endif -#endif std::error_code RealFile::close() { - if (::close(FD)) - return std::error_code(errno, std::generic_category()); + std::error_code EC = sys::Process::SafelyCloseFileDescriptor(FD); FD = -1; - return std::error_code(); + return EC; } namespace { @@ -198,9 +214,10 @@ ErrorOr<Status> RealFileSystem::status(const Twine &Path) { ErrorOr<std::unique_ptr<File>> RealFileSystem::openFileForRead(const Twine &Name) { int FD; - if (std::error_code EC = sys::fs::openFileForRead(Name, FD)) + SmallString<256> RealName; + if (std::error_code EC = sys::fs::openFileForRead(Name, FD, &RealName)) return EC; - return std::unique_ptr<File>(new RealFile(FD, Name.str())); + return std::unique_ptr<File>(new RealFile(FD, Name.str(), RealName.str())); } llvm::ErrorOr<std::string> RealFileSystem::getCurrentWorkingDirectory() const { @@ -271,7 +288,7 @@ directory_iterator RealFileSystem::dir_begin(const Twine &Dir, // OverlayFileSystem implementation //===-----------------------------------------------------------------------===/ OverlayFileSystem::OverlayFileSystem(IntrusiveRefCntPtr<FileSystem> BaseFS) { - FSList.push_back(BaseFS); + FSList.push_back(std::move(BaseFS)); } void OverlayFileSystem::pushOverlay(IntrusiveRefCntPtr<FileSystem> FS) { @@ -711,7 +728,13 @@ public: Status S) : Entry(EK_Directory, Name), Contents(std::move(Contents)), S(std::move(S)) {} + RedirectingDirectoryEntry(StringRef Name, Status S) + : Entry(EK_Directory, Name), S(std::move(S)) {} Status getStatus() { return S; } + void addContent(std::unique_ptr<Entry> Content) { + Contents.push_back(std::move(Content)); + } + Entry *getLastContent() const { return Contents.back().get(); } typedef decltype(Contents)::iterator iterator; iterator contents_begin() { return Contents.begin(); } iterator contents_end() { return Contents.end(); } @@ -739,6 +762,7 @@ public: return UseName == NK_NotSet ? GlobalUseExternalName : (UseName == NK_External); } + NameKind getUseName() const { return UseName; } static bool classof(const Entry *E) { return E->getKind() == EK_File; } }; @@ -776,6 +800,7 @@ public: /// All configuration options are optional. /// 'case-sensitive': <boolean, default=true> /// 'use-external-names': <boolean, default=true> +/// 'overlay-relative': <boolean, default=false> /// /// Virtual directories are represented as /// \verbatim @@ -815,6 +840,10 @@ class RedirectingFileSystem : public vfs::FileSystem { std::vector<std::unique_ptr<Entry>> Roots; /// \brief The file system to use for external references. IntrusiveRefCntPtr<FileSystem> ExternalFS; + /// If IsRelativeOverlay is set, this represents the directory + /// path that should be prefixed to each 'external-contents' entry + /// when reading from YAML files. + std::string ExternalContentsPrefixDir; /// @name Configuration /// @{ @@ -822,18 +851,32 @@ class RedirectingFileSystem : public vfs::FileSystem { /// \brief Whether to perform case-sensitive comparisons. /// /// Currently, case-insensitive matching only works correctly with ASCII. - bool CaseSensitive; + bool CaseSensitive = true; + + /// IsRelativeOverlay marks whether a IsExternalContentsPrefixDir path must + /// be prefixed in every 'external-contents' when reading from YAML files. + bool IsRelativeOverlay = false; /// \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; + bool UseExternalNames = true; /// @} + /// Virtual file paths and external files could be canonicalized without "..", + /// "." and "./" in their paths. FIXME: some unittests currently fail on + /// win32 when using remove_dots and remove_leading_dotslash on paths. + bool UseCanonicalizedPaths = +#ifdef LLVM_ON_WIN32 + false; +#else + true; +#endif + friend class RedirectingFileSystemParser; private: RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS) - : ExternalFS(ExternalFS), CaseSensitive(true), UseExternalNames(true) {} + : ExternalFS(std::move(ExternalFS)) {} /// \brief Looks up \p Path in \c Roots. ErrorOr<Entry *> lookupPath(const Twine &Path); @@ -851,8 +894,8 @@ public: /// returns a virtual file system representing its contents. static RedirectingFileSystem * create(std::unique_ptr<MemoryBuffer> Buffer, - SourceMgr::DiagHandlerTy DiagHandler, void *DiagContext, - IntrusiveRefCntPtr<FileSystem> ExternalFS); + SourceMgr::DiagHandlerTy DiagHandler, StringRef YAMLFilePath, + void *DiagContext, IntrusiveRefCntPtr<FileSystem> ExternalFS); ErrorOr<Status> status(const Twine &Path) override; ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override; @@ -885,6 +928,38 @@ public: return directory_iterator(std::make_shared<VFSFromYamlDirIterImpl>(Dir, *this, D->contents_begin(), D->contents_end(), EC)); } + + void setExternalContentsPrefixDir(StringRef PrefixDir) { + ExternalContentsPrefixDir = PrefixDir.str(); + } + + StringRef getExternalContentsPrefixDir() const { + return ExternalContentsPrefixDir; + } + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +LLVM_DUMP_METHOD void dump() const { + for (const std::unique_ptr<Entry> &Root : Roots) + dumpEntry(Root.get()); + } + +LLVM_DUMP_METHOD void dumpEntry(Entry *E, int NumSpaces = 0) const { + StringRef Name = E->getName(); + for (int i = 0, e = NumSpaces; i < e; ++i) + dbgs() << " "; + dbgs() << "'" << Name.str().c_str() << "'" << "\n"; + + if (E->getKind() == EK_Directory) { + auto *DE = dyn_cast<RedirectingDirectoryEntry>(E); + assert(DE && "Should be a directory"); + + for (std::unique_ptr<Entry> &SubEntry : + llvm::make_range(DE->contents_begin(), DE->contents_end())) + dumpEntry(SubEntry.get(), NumSpaces+2); + } + } +#endif + }; /// \brief A helper class to hold the common YAML parsing state. @@ -964,7 +1039,71 @@ class RedirectingFileSystemParser { return true; } - std::unique_ptr<Entry> parseEntry(yaml::Node *N) { + Entry *lookupOrCreateEntry(RedirectingFileSystem *FS, StringRef Name, + Entry *ParentEntry = nullptr) { + if (!ParentEntry) { // Look for a existent root + for (const std::unique_ptr<Entry> &Root : FS->Roots) { + if (Name.equals(Root->getName())) { + ParentEntry = Root.get(); + return ParentEntry; + } + } + } else { // Advance to the next component + auto *DE = dyn_cast<RedirectingDirectoryEntry>(ParentEntry); + for (std::unique_ptr<Entry> &Content : + llvm::make_range(DE->contents_begin(), DE->contents_end())) { + auto *DirContent = dyn_cast<RedirectingDirectoryEntry>(Content.get()); + if (DirContent && Name.equals(Content->getName())) + return DirContent; + } + } + + // ... 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)); + + if (!ParentEntry) { // Add a new root to the overlay + FS->Roots.push_back(std::move(E)); + ParentEntry = FS->Roots.back().get(); + return ParentEntry; + } + + auto *DE = dyn_cast<RedirectingDirectoryEntry>(ParentEntry); + DE->addContent(std::move(E)); + return DE->getLastContent(); + } + + void uniqueOverlayTree(RedirectingFileSystem *FS, Entry *SrcE, + Entry *NewParentE = nullptr) { + StringRef Name = SrcE->getName(); + switch (SrcE->getKind()) { + case EK_Directory: { + auto *DE = dyn_cast<RedirectingDirectoryEntry>(SrcE); + assert(DE && "Must be a directory"); + // Empty directories could be present in the YAML as a way to + // describe a file for a current directory after some of its subdir + // is parsed. This only leads to redundant walks, ignore it. + if (!Name.empty()) + NewParentE = lookupOrCreateEntry(FS, Name, NewParentE); + for (std::unique_ptr<Entry> &SubEntry : + llvm::make_range(DE->contents_begin(), DE->contents_end())) + uniqueOverlayTree(FS, SubEntry.get(), NewParentE); + break; + } + case EK_File: { + auto *FE = dyn_cast<RedirectingFileEntry>(SrcE); + assert(FE && "Must be a file"); + assert(NewParentE && "Parent entry must exist"); + auto *DE = dyn_cast<RedirectingDirectoryEntry>(NewParentE); + DE->addContent(llvm::make_unique<RedirectingFileEntry>( + Name, FE->getExternalContentsPath(), FE->getUseName())); + break; + } + } + } + + std::unique_ptr<Entry> parseEntry(yaml::Node *N, RedirectingFileSystem *FS) { yaml::MappingNode *M = dyn_cast<yaml::MappingNode>(N); if (!M) { error(N, "expected mapping node for file or directory entry"); @@ -1004,7 +1143,17 @@ class RedirectingFileSystemParser { if (Key == "name") { if (!parseScalarString(I->getValue(), Value, Buffer)) return nullptr; - Name = Value; + + if (FS->UseCanonicalizedPaths) { + SmallString<256> Path(Value); + // Guarantee that old YAML files containing paths with ".." and "." + // are properly canonicalized before read into the VFS. + Path = sys::path::remove_leading_dotslash(Path); + sys::path::remove_dots(Path, /*remove_dot_dot=*/true); + Name = Path.str(); + } else { + Name = Value; + } } else if (Key == "type") { if (!parseScalarString(I->getValue(), Value, Buffer)) return nullptr; @@ -1034,7 +1183,7 @@ class RedirectingFileSystemParser { for (yaml::SequenceNode::iterator I = Contents->begin(), E = Contents->end(); I != E; ++I) { - if (std::unique_ptr<Entry> E = parseEntry(&*I)) + if (std::unique_ptr<Entry> E = parseEntry(&*I, FS)) EntryArrayContents.push_back(std::move(E)); else return nullptr; @@ -1048,7 +1197,24 @@ class RedirectingFileSystemParser { HasContents = true; if (!parseScalarString(I->getValue(), Value, Buffer)) return nullptr; - ExternalContentsPath = Value; + + SmallString<256> FullPath; + if (FS->IsRelativeOverlay) { + FullPath = FS->getExternalContentsPrefixDir(); + assert(!FullPath.empty() && + "External contents prefix directory must exist"); + llvm::sys::path::append(FullPath, Value); + } else { + FullPath = Value; + } + + if (FS->UseCanonicalizedPaths) { + // Guarantee that old YAML files containing paths with ".." and "." + // are properly canonicalized before read into the VFS. + FullPath = sys::path::remove_leading_dotslash(FullPath); + sys::path::remove_dots(FullPath, /*remove_dot_dot=*/true); + } + ExternalContentsPath = FullPath.str(); } else if (Key == "use-external-name") { bool Val; if (!parseScalarBool(I->getValue(), Val)) @@ -1134,10 +1300,12 @@ public: KeyStatusPair("version", true), KeyStatusPair("case-sensitive", false), KeyStatusPair("use-external-names", false), + KeyStatusPair("overlay-relative", false), KeyStatusPair("roots", true), }; DenseMap<StringRef, KeyStatus> Keys(std::begin(Fields), std::end(Fields)); + std::vector<std::unique_ptr<Entry>> RootEntries; // Parse configuration and 'roots' for (yaml::MappingNode::iterator I = Top->begin(), E = Top->end(); I != E; @@ -1159,8 +1327,8 @@ public: for (yaml::SequenceNode::iterator I = Roots->begin(), E = Roots->end(); I != E; ++I) { - if (std::unique_ptr<Entry> E = parseEntry(&*I)) - FS->Roots.push_back(std::move(E)); + if (std::unique_ptr<Entry> E = parseEntry(&*I, FS)) + RootEntries.push_back(std::move(E)); else return false; } @@ -1185,6 +1353,9 @@ public: } else if (Key == "case-sensitive") { if (!parseScalarBool(I->getValue(), FS->CaseSensitive)) return false; + } else if (Key == "overlay-relative") { + if (!parseScalarBool(I->getValue(), FS->IsRelativeOverlay)) + return false; } else if (Key == "use-external-names") { if (!parseScalarBool(I->getValue(), FS->UseExternalNames)) return false; @@ -1198,6 +1369,13 @@ public: if (!checkMissingKeys(Top, Keys)) return false; + + // Now that we sucessefully parsed the YAML file, canonicalize the internal + // representation to a proper directory tree so that we can search faster + // inside the VFS. + for (std::unique_ptr<Entry> &E : RootEntries) + uniqueOverlayTree(FS, E.get()); + return true; } }; @@ -1205,9 +1383,11 @@ public: Entry::~Entry() = default; -RedirectingFileSystem *RedirectingFileSystem::create( - std::unique_ptr<MemoryBuffer> Buffer, SourceMgr::DiagHandlerTy DiagHandler, - void *DiagContext, IntrusiveRefCntPtr<FileSystem> ExternalFS) { +RedirectingFileSystem * +RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer, + SourceMgr::DiagHandlerTy DiagHandler, + StringRef YAMLFilePath, void *DiagContext, + IntrusiveRefCntPtr<FileSystem> ExternalFS) { SourceMgr SM; yaml::Stream Stream(Buffer->getMemBufferRef(), SM); @@ -1223,7 +1403,24 @@ RedirectingFileSystem *RedirectingFileSystem::create( RedirectingFileSystemParser P(Stream); std::unique_ptr<RedirectingFileSystem> FS( - new RedirectingFileSystem(ExternalFS)); + new RedirectingFileSystem(std::move(ExternalFS))); + + if (!YAMLFilePath.empty()) { + // Use the YAML path from -ivfsoverlay to compute the dir to be prefixed + // to each 'external-contents' path. + // + // Example: + // -ivfsoverlay dummy.cache/vfs/vfs.yaml + // yields: + // FS->ExternalContentsPrefixDir => /<absolute_path_to>/dummy.cache/vfs + // + SmallString<256> OverlayAbsDir = sys::path::parent_path(YAMLFilePath); + std::error_code EC = llvm::sys::fs::make_absolute(OverlayAbsDir); + assert(!EC && "Overlay dir final path must be absolute"); + (void)EC; + FS->setExternalContentsPrefixDir(OverlayAbsDir); + } + if (!P.parse(Root, FS.get())) return nullptr; @@ -1238,6 +1435,14 @@ ErrorOr<Entry *> RedirectingFileSystem::lookupPath(const Twine &Path_) { if (std::error_code EC = makeAbsolute(Path)) return EC; + // Canonicalize path by removing ".", "..", "./", etc components. This is + // a VFS request, do bot bother about symlinks in the path components + // but canonicalize in order to perform the correct entry search. + if (UseCanonicalizedPaths) { + Path = sys::path::remove_leading_dotslash(Path); + sys::path::remove_dots(Path, /*remove_dot_dot=*/true); + } + if (Path.empty()) return make_error_code(llvm::errc::invalid_argument); @@ -1254,20 +1459,32 @@ ErrorOr<Entry *> RedirectingFileSystem::lookupPath(const Twine &Path_) { ErrorOr<Entry *> RedirectingFileSystem::lookupPath(sys::path::const_iterator Start, sys::path::const_iterator End, Entry *From) { +#ifndef LLVM_ON_WIN32 + assert(!isTraversalComponent(*Start) && + !isTraversalComponent(From->getName()) && + "Paths should not contain traversal components"); +#else + // FIXME: this is here to support windows, remove it once canonicalized + // paths become globally default. if (Start->equals(".")) ++Start; +#endif - // FIXME: handle .. - if (CaseSensitive ? !Start->equals(From->getName()) - : !Start->equals_lower(From->getName())) - // failure to match - return make_error_code(llvm::errc::no_such_file_or_directory); + StringRef FromName = From->getName(); - ++Start; + // Forward the search to the next component in case this is an empty one. + if (!FromName.empty()) { + if (CaseSensitive ? !Start->equals(FromName) + : !Start->equals_lower(FromName)) + // failure to match + return make_error_code(llvm::errc::no_such_file_or_directory); - if (Start == End) { - // Match! - return From; + ++Start; + + if (Start == End) { + // Match! + return From; + } } auto *DE = dyn_cast<RedirectingDirectoryEntry>(From); @@ -1322,7 +1539,7 @@ class FileWithFixedStatus : public File { public: FileWithFixedStatus(std::unique_ptr<File> InnerFile, Status S) - : InnerFile(std::move(InnerFile)), S(S) {} + : InnerFile(std::move(InnerFile)), S(std::move(S)) {} ErrorOr<Status> status() override { return S; } ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> @@ -1362,10 +1579,13 @@ RedirectingFileSystem::openFileForRead(const Twine &Path) { IntrusiveRefCntPtr<FileSystem> vfs::getVFSFromYAML(std::unique_ptr<MemoryBuffer> Buffer, - SourceMgr::DiagHandlerTy DiagHandler, void *DiagContext, + SourceMgr::DiagHandlerTy DiagHandler, + StringRef YAMLFilePath, + void *DiagContext, IntrusiveRefCntPtr<FileSystem> ExternalFS) { return RedirectingFileSystem::create(std::move(Buffer), DiagHandler, - DiagContext, ExternalFS); + YAMLFilePath, DiagContext, + std::move(ExternalFS)); } UniqueID vfs::getNextVirtualUniqueID() { @@ -1376,16 +1596,6 @@ UniqueID vfs::getNextVirtualUniqueID() { return UniqueID(std::numeric_limits<uint64_t>::max(), ID); } -#ifndef NDEBUG -static bool pathHasTraversal(StringRef Path) { - using namespace llvm::sys; - for (StringRef Comp : llvm::make_range(path::begin(Path), path::end(Path))) - if (Comp == "." || Comp == "..") - return true; - return false; -} -#endif - void YAMLVFSWriter::addFileMapping(StringRef VirtualPath, StringRef RealPath) { assert(sys::path::is_absolute(VirtualPath) && "virtual path not absolute"); assert(sys::path::is_absolute(RealPath) && "real path not absolute"); @@ -1407,7 +1617,9 @@ class JSONWriter { public: JSONWriter(llvm::raw_ostream &OS) : OS(OS) {} - void write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> IsCaseSensitive); + void write(ArrayRef<YAMLVFSEntry> Entries, Optional<bool> UseExternalNames, + Optional<bool> IsCaseSensitive, Optional<bool> IsOverlayRelative, + StringRef OverlayDir); }; } @@ -1460,7 +1672,10 @@ void JSONWriter::writeEntry(StringRef VPath, StringRef RPath) { } void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, - Optional<bool> IsCaseSensitive) { + Optional<bool> UseExternalNames, + Optional<bool> IsCaseSensitive, + Optional<bool> IsOverlayRelative, + StringRef OverlayDir) { using namespace llvm::sys; OS << "{\n" @@ -1468,12 +1683,30 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, if (IsCaseSensitive.hasValue()) OS << " 'case-sensitive': '" << (IsCaseSensitive.getValue() ? "true" : "false") << "',\n"; + if (UseExternalNames.hasValue()) + OS << " 'use-external-names': '" + << (UseExternalNames.getValue() ? "true" : "false") << "',\n"; + bool UseOverlayRelative = false; + if (IsOverlayRelative.hasValue()) { + UseOverlayRelative = IsOverlayRelative.getValue(); + OS << " 'overlay-relative': '" + << (UseOverlayRelative ? "true" : "false") << "',\n"; + } OS << " 'roots': [\n"; if (!Entries.empty()) { const YAMLVFSEntry &Entry = Entries.front(); startDirectory(path::parent_path(Entry.VPath)); - writeEntry(path::filename(Entry.VPath), Entry.RPath); + + StringRef RPath = Entry.RPath; + if (UseOverlayRelative) { + unsigned OverlayDirLen = OverlayDir.size(); + assert(RPath.substr(0, OverlayDirLen) == OverlayDir && + "Overlay dir must be contained in RPath"); + RPath = RPath.slice(OverlayDirLen, RPath.size()); + } + + writeEntry(path::filename(Entry.VPath), RPath); for (const auto &Entry : Entries.slice(1)) { StringRef Dir = path::parent_path(Entry.VPath); @@ -1487,7 +1720,14 @@ void JSONWriter::write(ArrayRef<YAMLVFSEntry> Entries, OS << ",\n"; startDirectory(Dir); } - writeEntry(path::filename(Entry.VPath), Entry.RPath); + StringRef RPath = Entry.RPath; + if (UseOverlayRelative) { + unsigned OverlayDirLen = OverlayDir.size(); + assert(RPath.substr(0, OverlayDirLen) == OverlayDir && + "Overlay dir must be contained in RPath"); + RPath = RPath.slice(OverlayDirLen, RPath.size()); + } + writeEntry(path::filename(Entry.VPath), RPath); } while (!DirStack.empty()) { @@ -1507,7 +1747,8 @@ void YAMLVFSWriter::write(llvm::raw_ostream &OS) { return LHS.VPath < RHS.VPath; }); - JSONWriter(OS).write(Mappings, IsCaseSensitive); + JSONWriter(OS).write(Mappings, UseExternalNames, IsCaseSensitive, + IsOverlayRelative, OverlayDir); } VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl( |