From af732203b8f7f006927528db5497f5cbc4c4742a Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 13 Jun 2021 21:31:46 +0200 Subject: Merge llvm-project 12.0.1 release and follow-up fixes Merge llvm-project main llvmorg-12-init-17869-g8e464dd76bef This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-12-init-17869-g8e464dd76bef, the last commit before the upstream release/12.x branch was created. PR: 255570 (cherry picked from commit e8d8bef961a50d4dc22501cde4fb9fb0be1b2532) Merge llvm-project 12.0.0 release This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-12.0.0-0-gd28af7c654d8, a.k.a. 12.0.0 release. PR: 255570 (cherry picked from commit d409305fa3838fb39b38c26fc085fb729b8766d5) Disable strict-fp for powerpcspe, as it does not work properly yet Merge commit 5c18d1136665 from llvm git (by Qiu Chaofan) [SPE] Disable strict-fp for SPE by default As discussed in PR50385, strict-fp on PowerPC SPE has not been handled well. This patch disables it by default for SPE. Reviewed By: nemanjai, vit9696, jhibbits Differential Revision: https://reviews.llvm.org/D103235 PR: 255570 (cherry picked from commit 715df83abc049b23d9acddc81f2480bd4c056d64) Apply upstream libc++ fix to allow building with devel/xxx-xtoolchain-gcc Merge commit 52e9d80d5db2 from llvm git (by Jason Liu): [libc++] add `inline` for __open's definition in ifstream and ofstream Summary: When building with gcc on AIX, it seems that gcc does not like the `always_inline` without the `inline` keyword. So adding the inline keywords in for __open in ifstream and ofstream. That will also make it consistent with __open in basic_filebuf (it seems we added `inline` there before for gcc build as well). Differential Revision: https://reviews.llvm.org/D99422 PR: 255570 (cherry picked from commit d099db25464b826c5724cf2fb5b22292bbe15f6e) Undefine HAVE_(DE)REGISTER_FRAME in llvm's config.h on arm Otherwise, the lli tool (enable by WITH_CLANG_EXTRAS) won't link on arm, stating that __register_frame is undefined. This function is normally provided by libunwind, but explicitly not for the ARM Exception ABI. Reported by: oh PR: 255570 (cherry picked from commit f336b45e943c7f9a90ffcea1a6c4c7039e54c73c) Merge llvm-project 12.0.1 rc2 This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-12.0.1-rc2-0-ge7dac564cd0e, a.k.a. 12.0.1 rc2. PR: 255570 (cherry picked from commit 23408297fbf3089f0388a8873b02fa75ab3f5bb9) Revert libunwind change to fix backtrace segfault on aarch64 Revert commit 22b615a96593 from llvm git (by Daniel Kiss): [libunwind] Support for leaf function unwinding. Unwinding leaf function is useful in cases when the backtrace finds a leaf function for example when it caused a signal. This patch also add the support for the DW_CFA_undefined because it marks the end of the frames. Ryan Prichard provided code for the tests. Reviewed By: #libunwind, mstorsjo Differential Revision: https://reviews.llvm.org/D83573 Reland with limit the test to the x86_64-linux target. Bisection has shown that this particular upstream commit causes programs using backtrace(3) on aarch64 to segfault. This affects the lang/rust port, for instance. Until we can upstream to fix this problem, revert the commit for now. Reported by: mikael PR: 256864 (cherry picked from commit 5866c369e4fd917c0d456f0f10b92ee354b82279) Merge llvm-project 12.0.1 release This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-12.0.1-0-gfed41342a82f, a.k.a. 12.0.1 release. PR: 255570 (cherry picked from commit 4652422eb477731f284b1345afeefef7f269da50) compilert-rt: build out-of-line LSE atomics helpers for aarch64 Both clang >= 12 and gcc >= 10.1 now default to -moutline-atomics for aarch64. This requires a bunch of helper functions in libcompiler_rt.a, to avoid link errors like "undefined symbol: __aarch64_ldadd8_acq_rel". (Note: of course you can use -mno-outline-atomics as a workaround too, but this would negate the potential performance benefit of the faster LSE instructions.) Bump __FreeBSD_version so ports maintainers can easily detect this. PR: 257392 (cherry picked from commit cc55ee8009a550810d38777fd6ace9abf3a2f6b4) --- .../llvm-project/clang/lib/Basic/FileManager.cpp | 181 +++++++++++++-------- 1 file changed, 115 insertions(+), 66 deletions(-) (limited to 'contrib/llvm-project/clang/lib/Basic/FileManager.cpp') diff --git a/contrib/llvm-project/clang/lib/Basic/FileManager.cpp b/contrib/llvm-project/clang/lib/Basic/FileManager.cpp index e92e9d5911c0..6e9d5d7fb422 100644 --- a/contrib/llvm-project/clang/lib/Basic/FileManager.cpp +++ b/contrib/llvm-project/clang/lib/Basic/FileManager.cpp @@ -69,21 +69,22 @@ void FileManager::clearStatCache() { StatCache.reset(); } /// Retrieve the directory that the given file name resides in. /// Filename can point to either a real file or a virtual file. -static llvm::ErrorOr +static llvm::Expected getDirectoryFromFile(FileManager &FileMgr, StringRef Filename, bool CacheFailure) { if (Filename.empty()) - return std::errc::no_such_file_or_directory; + return llvm::errorCodeToError( + make_error_code(std::errc::no_such_file_or_directory)); if (llvm::sys::path::is_separator(Filename[Filename.size() - 1])) - return std::errc::is_a_directory; + return llvm::errorCodeToError(make_error_code(std::errc::is_a_directory)); StringRef DirName = llvm::sys::path::parent_path(Filename); // Use the current directory if file has no path component. if (DirName.empty()) DirName = "."; - return FileMgr.getDirectory(DirName, CacheFailure); + return FileMgr.getDirectoryRef(DirName, CacheFailure); } /// Add all ancestors of the given path (pointing to either a file or @@ -141,7 +142,7 @@ FileManager::getDirectoryRef(StringRef DirName, bool CacheFailure) { SeenDirEntries.insert({DirName, std::errc::no_such_file_or_directory}); if (!SeenDirInsertResult.second) { if (SeenDirInsertResult.first->second) - return DirectoryEntryRef(&*SeenDirInsertResult.first); + return DirectoryEntryRef(*SeenDirInsertResult.first); return llvm::errorCodeToError(SeenDirInsertResult.first->second.getError()); } @@ -180,7 +181,7 @@ FileManager::getDirectoryRef(StringRef DirName, bool CacheFailure) { UDE.Name = InterndDirName; } - return DirectoryEntryRef(&NamedDirEnt); + return DirectoryEntryRef(NamedDirEnt); } llvm::ErrorOr @@ -212,11 +213,11 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) { SeenFileInsertResult.first->second.getError()); // Construct and return and FileEntryRef, unless it's a redirect to another // filename. - SeenFileEntryOrRedirect Value = *SeenFileInsertResult.first->second; - FileEntry *FE; - if (LLVM_LIKELY(FE = Value.dyn_cast())) - return FileEntryRef(SeenFileInsertResult.first->first(), *FE); - return getFileRef(*Value.get(), openFile, CacheFailure); + FileEntryRef::MapValue Value = *SeenFileInsertResult.first->second; + if (LLVM_LIKELY(Value.V.is())) + return FileEntryRef(*SeenFileInsertResult.first); + return FileEntryRef(*reinterpret_cast( + Value.V.get())); } // We've not seen this before. Fill it in. @@ -235,14 +236,15 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) { // without a 'sys' subdir will get a cached failure result. auto DirInfoOrErr = getDirectoryFromFile(*this, Filename, CacheFailure); if (!DirInfoOrErr) { // Directory doesn't exist, file can't exist. + std::error_code Err = errorToErrorCode(DirInfoOrErr.takeError()); if (CacheFailure) - NamedFileEnt->second = DirInfoOrErr.getError(); + NamedFileEnt->second = Err; else SeenFileEntries.erase(Filename); - return llvm::errorCodeToError(DirInfoOrErr.getError()); + return llvm::errorCodeToError(Err); } - const DirectoryEntry *DirInfo = *DirInfoOrErr; + DirectoryEntryRef DirInfo = *DirInfoOrErr; // FIXME: Use the directory info to prune this, before doing the stat syscall. // FIXME: This will reduce the # syscalls. @@ -268,26 +270,30 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) { // This occurs when one dir is symlinked to another, for example. FileEntry &UFE = UniqueRealFiles[Status.getUniqueID()]; - NamedFileEnt->second = &UFE; - - // If the name returned by getStatValue is different than Filename, re-intern - // the name. - if (Status.getName() != Filename) { - auto &NewNamedFileEnt = - *SeenFileEntries.insert({Status.getName(), &UFE}).first; - assert((*NewNamedFileEnt.second).get() == &UFE && + if (Status.getName() == Filename) { + // The name matches. Set the FileEntry. + NamedFileEnt->second = FileEntryRef::MapValue(UFE, DirInfo); + } else { + // Name mismatch. We need a redirect. First grab the actual entry we want + // to return. + auto &Redirection = + *SeenFileEntries + .insert({Status.getName(), FileEntryRef::MapValue(UFE, DirInfo)}) + .first; + assert(Redirection.second->V.is() && + "filename redirected to a non-canonical filename?"); + assert(Redirection.second->V.get() == &UFE && "filename from getStatValue() refers to wrong file"); - InterndFileName = NewNamedFileEnt.first().data(); - // In addition to re-interning the name, construct a redirecting seen file - // entry, that will point to the name the filesystem actually wants to use. - StringRef *Redirect = new (CanonicalNameStorage) StringRef(InterndFileName); - auto SeenFileInsertResultIt = SeenFileEntries.find(Filename); - assert(SeenFileInsertResultIt != SeenFileEntries.end() && - "unexpected SeenFileEntries cache miss"); - SeenFileInsertResultIt->second = Redirect; - NamedFileEnt = &*SeenFileInsertResultIt; + + // Cache the redirection in the previously-inserted entry, still available + // in the tentative return value. + NamedFileEnt->second = FileEntryRef::MapValue(Redirection); + + // Fix the tentative return value. + NamedFileEnt = &Redirection; } + FileEntryRef ReturnedRef(*NamedFileEnt); if (UFE.isValid()) { // Already have an entry with this inode, return it. // FIXME: this hack ensures that if we look up a file by a virtual path in @@ -296,26 +302,26 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) { // module's structure when its headers/module map are mapped in the VFS. // We should remove this as soon as we can properly support a file having // multiple names. - if (DirInfo != UFE.Dir && Status.IsVFSMapped) - UFE.Dir = DirInfo; + if (&DirInfo.getDirEntry() != UFE.Dir && Status.IsVFSMapped) + UFE.Dir = &DirInfo.getDirEntry(); - // Always update the name to use the last name by which a file was accessed. - // FIXME: Neither this nor always using the first name is correct; we want - // to switch towards a design where we return a FileName object that + // Always update LastRef to the last name by which a file was accessed. + // FIXME: Neither this nor always using the first reference is correct; we + // want to switch towards a design where we return a FileName object that // encapsulates both the name by which the file was accessed and the // corresponding FileEntry. - // FIXME: The Name should be removed from FileEntry once all clients - // adopt FileEntryRef. - UFE.Name = InterndFileName; + // FIXME: LastRef should be removed from FileEntry once all clients adopt + // FileEntryRef. + UFE.LastRef = ReturnedRef; - return FileEntryRef(InterndFileName, UFE); + return ReturnedRef; } // Otherwise, we don't have this file yet, add it. - UFE.Name = InterndFileName; + UFE.LastRef = ReturnedRef; UFE.Size = Status.getSize(); UFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); - UFE.Dir = DirInfo; + UFE.Dir = &DirInfo.getDirEntry(); UFE.UID = NextFileUID++; UFE.UniqueID = Status.getUniqueID(); UFE.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; @@ -329,24 +335,46 @@ FileManager::getFileRef(StringRef Filename, bool openFile, bool CacheFailure) { // We should still fill the path even if we aren't opening the file. fillRealPathName(&UFE, InterndFileName); } - return FileEntryRef(InterndFileName, UFE); + return ReturnedRef; +} + +llvm::Expected FileManager::getSTDIN() { + // Only read stdin once. + if (STDIN) + return *STDIN; + + std::unique_ptr Content; + if (auto ContentOrError = llvm::MemoryBuffer::getSTDIN()) + Content = std::move(*ContentOrError); + else + return llvm::errorCodeToError(ContentOrError.getError()); + + STDIN = getVirtualFileRef(Content->getBufferIdentifier(), + Content->getBufferSize(), 0); + FileEntry &FE = const_cast(STDIN->getFileEntry()); + FE.Content = std::move(Content); + FE.IsNamedPipe = true; + return *STDIN; } -const FileEntry * -FileManager::getVirtualFile(StringRef Filename, off_t Size, - time_t ModificationTime) { +const FileEntry *FileManager::getVirtualFile(StringRef Filename, off_t Size, + time_t ModificationTime) { + return &getVirtualFileRef(Filename, Size, ModificationTime).getFileEntry(); +} + +FileEntryRef FileManager::getVirtualFileRef(StringRef Filename, off_t Size, + time_t ModificationTime) { ++NumFileLookups; // See if there is already an entry in the map for an existing file. auto &NamedFileEnt = *SeenFileEntries.insert( {Filename, std::errc::no_such_file_or_directory}).first; if (NamedFileEnt.second) { - SeenFileEntryOrRedirect Value = *NamedFileEnt.second; - FileEntry *FE; - if (LLVM_LIKELY(FE = Value.dyn_cast())) - return FE; - return getVirtualFile(*Value.get(), Size, - ModificationTime); + FileEntryRef::MapValue Value = *NamedFileEnt.second; + if (LLVM_LIKELY(Value.V.is())) + return FileEntryRef(NamedFileEnt); + return FileEntryRef(*reinterpret_cast( + Value.V.get())); } // We've not seen this before, or the file is cached as non-existent. @@ -357,7 +385,8 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, // Now that all ancestors of Filename are in the cache, the // following call is guaranteed to find the DirectoryEntry from the // cache. - auto DirInfo = getDirectoryFromFile(*this, Filename, /*CacheFailure=*/true); + auto DirInfo = expectedToOptional( + getDirectoryFromFile(*this, Filename, /*CacheFailure=*/true)); assert(DirInfo && "The directory of a virtual file should already be in the cache."); @@ -372,7 +401,7 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, Status.getUser(), Status.getGroup(), Size, Status.getType(), Status.getPermissions()); - NamedFileEnt.second = UFE; + NamedFileEnt.second = FileEntryRef::MapValue(*UFE, *DirInfo); // If we had already opened this file, close it now so we don't // leak the descriptor. We're not going to use the file @@ -381,8 +410,11 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, UFE->closeFile(); // If we already have an entry with this inode, return it. + // + // FIXME: Surely this should add a reference by the new name, and return + // it instead... if (UFE->isValid()) - return UFE; + return FileEntryRef(NamedFileEnt); UFE->UniqueID = Status.getUniqueID(); UFE->IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file; @@ -390,17 +422,17 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, } else { VirtualFileEntries.push_back(std::make_unique()); UFE = VirtualFileEntries.back().get(); - NamedFileEnt.second = UFE; + NamedFileEnt.second = FileEntryRef::MapValue(*UFE, *DirInfo); } - UFE->Name = InterndFileName; + UFE->LastRef = FileEntryRef(NamedFileEnt); UFE->Size = Size; UFE->ModTime = ModificationTime; - UFE->Dir = *DirInfo; + UFE->Dir = &DirInfo->getDirEntry(); UFE->UID = NextFileUID++; UFE->IsValid = true; UFE->File.reset(); - return UFE; + return FileEntryRef(NamedFileEnt); } llvm::Optional FileManager::getBypassFile(FileEntryRef VF) { @@ -409,17 +441,30 @@ llvm::Optional FileManager::getBypassFile(FileEntryRef VF) { if (getStatValue(VF.getName(), Status, /*isFile=*/true, /*F=*/nullptr)) return None; - // Fill it in from the stat. + if (!SeenBypassFileEntries) + SeenBypassFileEntries = std::make_unique< + llvm::StringMap>>(); + + // If we've already bypassed just use the existing one. + auto Insertion = SeenBypassFileEntries->insert( + {VF.getName(), std::errc::no_such_file_or_directory}); + if (!Insertion.second) + return FileEntryRef(*Insertion.first); + + // Fill in the new entry from the stat. BypassFileEntries.push_back(std::make_unique()); const FileEntry &VFE = VF.getFileEntry(); FileEntry &BFE = *BypassFileEntries.back(); - BFE.Name = VFE.getName(); + Insertion.first->second = FileEntryRef::MapValue(BFE, VF.getDir()); + BFE.LastRef = FileEntryRef(*Insertion.first); BFE.Size = Status.getSize(); BFE.Dir = VFE.Dir; BFE.ModTime = llvm::sys::toTimeT(Status.getLastModificationTime()); BFE.UID = NextFileUID++; BFE.IsValid = true; - return FileEntryRef(VF.getName(), BFE); + + // Save the entry in the bypass table and return. + return FileEntryRef(*Insertion.first); } bool FileManager::FixupRelativePath(SmallVectorImpl &path) const { @@ -460,10 +505,14 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) { llvm::ErrorOr> FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile, bool RequiresNullTerminator) { + // If the content is living on the file entry, return a reference to it. + if (Entry->Content) + return llvm::MemoryBuffer::getMemBuffer(Entry->Content->getMemBufferRef()); + uint64_t FileSize = Entry->getSize(); // If there's a high enough chance that the file have changed since we // got its size, force a stat before opening it. - if (isVolatile) + if (isVolatile || Entry->isNamedPipe()) FileSize = -1; StringRef Filename = Entry->getName(); @@ -534,13 +583,13 @@ void FileManager::GetUniqueIDMapping( UIDToFiles.resize(NextFileUID); // Map file entries - for (llvm::StringMap, + for (llvm::StringMap, llvm::BumpPtrAllocator>::const_iterator FE = SeenFileEntries.begin(), FEEnd = SeenFileEntries.end(); FE != FEEnd; ++FE) - if (llvm::ErrorOr Entry = FE->getValue()) { - if (const auto *FE = (*Entry).dyn_cast()) + if (llvm::ErrorOr Entry = FE->getValue()) { + if (const auto *FE = Entry->V.dyn_cast()) UIDToFiles[FE->getUID()] = FE; } -- cgit v1.2.3