Skip to content

Commit

Permalink
Merged master:9b5b3050237d into amd-gfx:02a8883052a4
Browse files Browse the repository at this point in the history
Local branch amd-gfx 02a8883 Merged master:e0dc3dba3bd1 into amd-gfx:ae92c01db53a
Remote branch master 9b5b305 Temporarily revert "[ThinLTO] Re-order modules for optimal multi-threaded processing"
  • Loading branch information
Sw authored and Sw committed Oct 9, 2020
2 parents 02a8883 + 9b5b305 commit 201734f
Show file tree
Hide file tree
Showing 29 changed files with 650 additions and 362 deletions.
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/BuiltinsWebAssembly.def
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ TARGET_BUILTIN(__builtin_wasm_max_u_i32x4, "V4UiV4UiV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_avgr_u_i8x16, "V16UcV16UcV16Uc", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_avgr_u_i16x8, "V8UsV8UsV8Us", "nc", "simd128")

TARGET_BUILTIN(__builtin_wasm_q15mulr_saturate_s_i8x16, "V8sV8sV8s", "nc", "simd128")

TARGET_BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_shuffle_v8x16, "V16ScV16ScV16ScIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi", "nc", "simd128")

Expand Down
7 changes: 7 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16545,6 +16545,13 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
ConvertType(E->getType()));
return Builder.CreateCall(Callee, {LHS, RHS});
}
case WebAssembly::BI__builtin_wasm_q15mulr_saturate_s_i8x16: {
Value *LHS = EmitScalarExpr(E->getArg(0));
Value *RHS = EmitScalarExpr(E->getArg(1));
Function *Callee =
CGM.getIntrinsic(Intrinsic::wasm_q15mulr_saturate_signed);
return Builder.CreateCall(Callee, {LHS, RHS});
}
case WebAssembly::BI__builtin_wasm_bitselect: {
Value *V1 = EmitScalarExpr(E->getArg(0));
Value *V2 = EmitScalarExpr(E->getArg(1));
Expand Down
278 changes: 259 additions & 19 deletions clang/lib/DirectoryWatcher/windows/DirectoryWatcher-windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,12 @@
//
//===----------------------------------------------------------------------===//

// TODO: This is not yet an implementation, but it will make it so Windows
// builds don't fail.

#include "DirectoryScanner.h"
#include "clang/DirectoryWatcher/DirectoryWatcher.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Path.h"
#include <atomic>
#include "llvm/Support/Windows/WindowsSupport.h"
#include <condition_variable>
#include <mutex>
#include <queue>
Expand All @@ -28,23 +21,270 @@

namespace {

using DirectoryWatcherCallback =
std::function<void(llvm::ArrayRef<clang::DirectoryWatcher::Event>, bool)>;

using namespace llvm;
using namespace clang;

class DirectoryWatcherWindows : public clang::DirectoryWatcher {
OVERLAPPED Overlapped;

std::vector<DWORD> Notifications;

std::thread WatcherThread;
std::thread HandlerThread;
std::function<void(ArrayRef<DirectoryWatcher::Event>, bool)> Callback;
SmallString<MAX_PATH> Path;
HANDLE Terminate;

class EventQueue {
std::mutex M;
std::queue<DirectoryWatcher::Event> Q;
std::condition_variable CV;

public:
void emplace(DirectoryWatcher::Event::EventKind Kind, StringRef Path) {
{
std::unique_lock<std::mutex> L(M);
Q.emplace(Kind, Path);
}
CV.notify_one();
}

DirectoryWatcher::Event pop_front() {
std::unique_lock<std::mutex> L(M);
while (true) {
if (!Q.empty()) {
DirectoryWatcher::Event E = Q.front();
Q.pop();
return E;
}
CV.wait(L, [this]() { return !Q.empty(); });
}
}
} Q;

public:
~DirectoryWatcherWindows() override { }
void InitialScan() { }
void EventReceivingLoop() { }
void StopWork() { }
DirectoryWatcherWindows(HANDLE DirectoryHandle, bool WaitForInitialSync,
DirectoryWatcherCallback Receiver);

~DirectoryWatcherWindows() override;

void InitialScan();
void WatcherThreadProc(HANDLE DirectoryHandle);
void NotifierThreadProc(bool WaitForInitialSync);
};

DirectoryWatcherWindows::DirectoryWatcherWindows(
HANDLE DirectoryHandle, bool WaitForInitialSync,
DirectoryWatcherCallback Receiver)
: Callback(Receiver), Terminate(INVALID_HANDLE_VALUE) {
// Pre-compute the real location as we will be handing over the directory
// handle to the watcher and performing synchronous operations.
{
DWORD Length = GetFinalPathNameByHandleW(DirectoryHandle, NULL, 0, 0);

std::vector<WCHAR> Buffer;
Buffer.resize(Length);

Length = GetFinalPathNameByHandleW(DirectoryHandle, Buffer.data(),
Buffer.size(), 0);
Buffer.resize(Length);

llvm::sys::windows::UTF16ToUTF8(Buffer.data(), Buffer.size(), Path);
}

Notifications.resize(4 * (sizeof(FILE_NOTIFY_INFORMATION) +
MAX_PATH * sizeof(WCHAR)));

memset(&Overlapped, 0, sizeof(Overlapped));
Overlapped.hEvent =
CreateEventW(NULL, /*bManualReset=*/TRUE, /*bInitialState=*/FALSE, NULL);
assert(Overlapped.hEvent && "unable to create event");

Terminate = CreateEventW(NULL, /*bManualReset=*/TRUE,
/*bInitialState=*/FALSE, NULL);

WatcherThread = std::thread([this, DirectoryHandle]() {
this->WatcherThreadProc(DirectoryHandle);
});

if (WaitForInitialSync)
InitialScan();

HandlerThread = std::thread([this, WaitForInitialSync]() {
this->NotifierThreadProc(WaitForInitialSync);
});
}

DirectoryWatcherWindows::~DirectoryWatcherWindows() {
// Signal the Watcher to exit.
SetEvent(Terminate);
HandlerThread.join();
WatcherThread.join();
CloseHandle(Terminate);
CloseHandle(Overlapped.hEvent);
}

void DirectoryWatcherWindows::InitialScan() {
Callback(getAsFileEvents(scanDirectory(Path.data())), /*IsInitial=*/true);
}

void DirectoryWatcherWindows::WatcherThreadProc(HANDLE DirectoryHandle) {
while (true) {
// We do not guarantee subdirectories, but macOS already provides
// subdirectories, might as well as ...
BOOL WatchSubtree = TRUE;
DWORD NotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME
| FILE_NOTIFY_CHANGE_DIR_NAME
| FILE_NOTIFY_CHANGE_SIZE
| FILE_NOTIFY_CHANGE_LAST_ACCESS
| FILE_NOTIFY_CHANGE_LAST_WRITE
| FILE_NOTIFY_CHANGE_CREATION;

DWORD BytesTransferred;
if (!ReadDirectoryChangesW(DirectoryHandle, Notifications.data(),
Notifications.size(), WatchSubtree,
NotifyFilter, &BytesTransferred, &Overlapped,
NULL)) {
Q.emplace(DirectoryWatcher::Event::EventKind::WatcherGotInvalidated,
"");
break;
}

HANDLE Handles[2] = { Terminate, Overlapped.hEvent };
switch (WaitForMultipleObjects(2, Handles, FALSE, INFINITE)) {
case WAIT_OBJECT_0: // Terminate Request
case WAIT_FAILED: // Failure
Q.emplace(DirectoryWatcher::Event::EventKind::WatcherGotInvalidated,
"");
(void)CloseHandle(DirectoryHandle);
return;
case WAIT_TIMEOUT: // Spurious wakeup?
continue;
case WAIT_OBJECT_0 + 1: // Directory change
break;
}

if (!GetOverlappedResult(DirectoryHandle, &Overlapped, &BytesTransferred,
FALSE)) {
Q.emplace(DirectoryWatcher::Event::EventKind::WatchedDirRemoved,
"");
Q.emplace(DirectoryWatcher::Event::EventKind::WatcherGotInvalidated,
"");
break;
}

// There was a buffer underrun on the kernel side. We may have lost
// events, please re-synchronize.
if (BytesTransferred == 0) {
Q.emplace(DirectoryWatcher::Event::EventKind::WatcherGotInvalidated,
"");
break;
}

for (FILE_NOTIFY_INFORMATION *I =
(FILE_NOTIFY_INFORMATION *)Notifications.data();
I;
I = I->NextEntryOffset
? (FILE_NOTIFY_INFORMATION *)((CHAR *)I + I->NextEntryOffset)
: NULL) {
DirectoryWatcher::Event::EventKind Kind =
DirectoryWatcher::Event::EventKind::WatcherGotInvalidated;
switch (I->Action) {
case FILE_ACTION_MODIFIED:
Kind = DirectoryWatcher::Event::EventKind::Modified;
break;
case FILE_ACTION_ADDED:
Kind = DirectoryWatcher::Event::EventKind::Modified;
break;
case FILE_ACTION_REMOVED:
Kind = DirectoryWatcher::Event::EventKind::Removed;
break;
case FILE_ACTION_RENAMED_OLD_NAME:
Kind = DirectoryWatcher::Event::EventKind::Removed;
break;
case FILE_ACTION_RENAMED_NEW_NAME:
Kind = DirectoryWatcher::Event::EventKind::Modified;
break;
}

SmallString<MAX_PATH> filename;
sys::windows::UTF16ToUTF8(I->FileName, I->FileNameLength / 2,
filename);
Q.emplace(Kind, filename);
}
}

(void)CloseHandle(DirectoryHandle);
}

void DirectoryWatcherWindows::NotifierThreadProc(bool WaitForInitialSync) {
// If we did not wait for the initial sync, then we should perform the
// scan when we enter the thread.
if (!WaitForInitialSync)
this->InitialScan();

while (true) {
DirectoryWatcher::Event E = Q.pop_front();
Callback(E, /*IsInitial=*/false);
if (E.Kind == DirectoryWatcher::Event::EventKind::WatcherGotInvalidated)
break;
}
}

auto error(DWORD ErrorCode) {
DWORD Flags = FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS;

LPSTR Buffer;
if (!FormatMessageA(Flags, NULL, ErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&Buffer,
0, NULL)) {
return make_error<llvm::StringError>("error " + utostr(ErrorCode),
inconvertibleErrorCode());
}
std::string Message{Buffer};
LocalFree(Buffer);
return make_error<llvm::StringError>(Message, inconvertibleErrorCode());
}

} // namespace

llvm::Expected<std::unique_ptr<DirectoryWatcher>>
clang::DirectoryWatcher::create(
StringRef Path,
std::function<void(llvm::ArrayRef<DirectoryWatcher::Event>, bool)> Receiver,
bool WaitForInitialSync) {
return llvm::Expected<std::unique_ptr<DirectoryWatcher>>(
llvm::errorCodeToError(std::make_error_code(std::errc::not_supported)));
clang::DirectoryWatcher::create(StringRef Path,
DirectoryWatcherCallback Receiver,
bool WaitForInitialSync) {
if (Path.empty())
llvm::report_fatal_error(
"DirectoryWatcher::create can not accept an empty Path.");

if (!sys::fs::is_directory(Path))
llvm::report_fatal_error(
"DirectoryWatcher::create can not accept a filepath.");

SmallVector<wchar_t, MAX_PATH> WidePath;
if (sys::windows::UTF8ToUTF16(Path, WidePath))
return llvm::make_error<llvm::StringError>(
"unable to convert path to UTF-16", llvm::inconvertibleErrorCode());

DWORD DesiredAccess = FILE_LIST_DIRECTORY;
DWORD ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
DWORD CreationDisposition = OPEN_EXISTING;
DWORD FlagsAndAttributes = FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED;

HANDLE DirectoryHandle =
CreateFileW(WidePath.data(), DesiredAccess, ShareMode,
/*lpSecurityAttributes=*/NULL, CreationDisposition,
FlagsAndAttributes, NULL);
if (DirectoryHandle == INVALID_HANDLE_VALUE)
return error(GetLastError());

// NOTE: We use the watcher instance as a RAII object to discard the handles
// for the directory and the IOCP in case of an error. Hence, this is early
// allocated, with the state being written directly to the watcher.
return std::make_unique<DirectoryWatcherWindows>(
DirectoryHandle, WaitForInitialSync, Receiver);
}
7 changes: 7 additions & 0 deletions clang/test/CodeGen/builtins-wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,13 @@ u16x8 avgr_u_i16x8(u16x8 x, u16x8 y) {
// WEBASSEMBLY-NEXT: ret
}

i16x8 q15mulr_saturate_s_i16x8(i16x8 x, i16x8 y) {
return __builtin_wasm_q15mulr_saturate_s_i8x16(x, y);
// WEBASSEMBLY: call <8 x i16> @llvm.wasm.q15mulr.saturate.signed(
// WEBASSEMBLY-SAME: <8 x i16> %x, <8 x i16> %y)
// WEBASSEMBLY-NEXT: ret
}

i32x4 dot_i16x8_s(i16x8 x, i16x8 y) {
return __builtin_wasm_dot_s_i32x4_i16x8(x, y);
// WEBASSEMBLY: call <4 x i32> @llvm.wasm.dot(<8 x i16> %x, <8 x i16> %y)
Expand Down
2 changes: 1 addition & 1 deletion clang/unittests/DirectoryWatcher/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Linux")
if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME STREQUAL Windows)

set(LLVM_LINK_COMPONENTS
Support
Expand Down
17 changes: 0 additions & 17 deletions libcxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -262,23 +262,6 @@ option(LIBCXX_GENERATE_COVERAGE "Enable generating code coverage." OFF)
set(LIBCXX_COVERAGE_LIBRARY "" CACHE STRING
"The Profile-rt library used to build with code coverage")

# Don't allow a user to accidentally overwrite the system libc++ installation on Darwin.
# If the user specifies -DCMAKE_INSTALL_PREFIX=/usr the install rules for libc++
# will not be generated and a warning will be issued.
option(LIBCXX_OVERRIDE_DARWIN_INSTALL "Enable overwriting darwins libc++ installation." OFF)
mark_as_advanced(LIBCXX_OVERRIDE_DARWIN_INSTALL) # Don't show this option by default.

if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT LIBCXX_OVERRIDE_DARWIN_INSTALL)
if ("${CMAKE_INSTALL_PREFIX}" STREQUAL "/usr")
message(WARNING "Disabling libc++ install rules because installation would "
"overwrite the systems installation. Configure with "
"-DLIBCXX_OVERRIDE_DARWIN_INSTALL=ON to suppress this behaviour.")
mark_as_advanced(CLEAR LIBCXX_OVERRIDE_DARWIN_INSTALL) # Show the override option.
set(LIBCXX_INSTALL_HEADERS OFF)
set(LIBCXX_INSTALL_LIBRARY OFF)
endif()
endif()

set(LIBCXX_CONFIGURE_IDE_DEFAULT OFF)
if (XCODE OR MSVC_IDE)
set(LIBCXX_CONFIGURE_IDE_DEFAULT ON)
Expand Down
Loading

0 comments on commit 201734f

Please sign in to comment.