Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -453,7 +453,9 @@ virtual bool SupportsEmbeddedBitcode() const { return false; } /// getThreadModel() - Which thread model does this target use? - virtual std::string getThreadModel() const { return "posix"; } + virtual std::string getThreadModel(const llvm::opt::ArgList &) const { + return "posix"; + } /// isThreadModelSupported() - Does this target support a thread model? virtual bool isThreadModelSupported(const StringRef Model) const; Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -1528,7 +1528,7 @@ if (TC.isThreadModelSupported(A->getValue())) OS << "Thread model: " << A->getValue(); } else - OS << "Thread model: " << TC.getThreadModel(); + OS << "Thread model: " << TC.getThreadModel(C.getArgs()); OS << '\n'; // Print out the install directory. Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3823,7 +3823,7 @@ CmdArgs.push_back(A->getValue()); } else - CmdArgs.push_back(Args.MakeArgString(TC.getThreadModel())); + CmdArgs.push_back(Args.MakeArgString(TC.getThreadModel(Args))); Args.AddLastArg(CmdArgs, options::OPT_fveclib); Index: lib/Driver/ToolChains/WebAssembly.h =================================================================== --- lib/Driver/ToolChains/WebAssembly.h +++ lib/Driver/ToolChains/WebAssembly.h @@ -64,7 +64,7 @@ llvm::opt::ArgStringList &CC1Args) const override; void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; - std::string getThreadModel() const override; + std::string getThreadModel(const llvm::opt::ArgList &) const override; const char *getDefaultLinker() const override { return "wasm-ld"; } Index: lib/Driver/ToolChains/WebAssembly.cpp =================================================================== --- lib/Driver/ToolChains/WebAssembly.cpp +++ lib/Driver/ToolChains/WebAssembly.cpp @@ -62,7 +62,9 @@ if (ToolChain.ShouldLinkCXXStdlib(Args)) ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); - if (Args.hasArg(options::OPT_pthread)) + if (Args.hasFlag(clang::driver::options::OPT_pthread, + clang::driver::options::OPT_no_pthread), + false) CmdArgs.push_back("-lpthread"); CmdArgs.push_back("-lc"); @@ -123,6 +125,13 @@ if (DriverArgs.hasFlag(clang::driver::options::OPT_fuse_init_array, options::OPT_fno_use_init_array, true)) CC1Args.push_back("-fuse-init-array"); + bool HasAtomics = + DriverArgs.hasFlag(clang::driver::options::OPT_matomics, + clang::driver::options::OPT_mno_atomics, false); + bool HasPthread = DriverArgs.hasFlag(clang::driver::options::OPT_pthread, + clang::driver::options::OPT_no_pthread); + if (HasAtomics || HasPthread) + CC1Args.push_back("-target-feature +atomics"); } ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const { @@ -180,11 +189,16 @@ } } -std::string WebAssembly::getThreadModel() const { - // The WebAssembly MVP does not yet support threads; for now, use the - // "single" threading model, which lowers atomics to non-atomic operations. - // When threading support is standardized and implemented in popular engines, - // this override should be removed. +std::string WebAssembly::getThreadModel(const ArgList &DriverArgs) const { + // The WebAssembly MVP does not yet support threads. We set this to "posix" + // only when we have atomics target feature on or '-pthread' is set. + bool HasAtomics = + DriverArgs.hasFlag(clang::driver::options::OPT_matomics, + clang::driver::options::OPT_mno_atomics, false); + bool HasPthread = DriverArgs.hasFlag(clang::driver::options::OPT_pthread, + clang::driver::options::OPT_no_pthread); + if (HasAtomics || HasPthread) + return "posix"; return "single"; } Index: test/Driver/wasm-toolchain.c =================================================================== --- test/Driver/wasm-toolchain.c +++ test/Driver/wasm-toolchain.c @@ -38,3 +38,17 @@ // RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=COMPILE %s // COMPILE: clang{{.*}}" "-cc1" {{.*}} "-internal-isystem" "/foo/include/wasm32-wasi-musl" "-internal-isystem" "/foo/include" + +// Thread-related command line tests. +// - '-matomics' sets '-mthread-model posix' +// - '-mthread-model' sets '-matomics' +// - '-phread' sets both '-matomics' and '-mthread-model posix' + +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 -matomics | FileCheck -check-prefix=ATOMICS %s +// ATOMICS: clang{{.*}}" "-cc1" {{.*}} "-mthread-model" "posix" + +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 -mthread-model posix | FileCheck -check-prefix=POSIX %s +// POSIX: clang{{.*}}" "-cc1" {{.*}} "-target-feature +atomics" + +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 -pthread | FileCheck -check-prefix=PTHREAD %s +// PTHREAD: clang{{.*}}" "-cc1" {{.*}} "-mthread-model" "posix" {{.*}} "-target-feature +atomics" Index: test/Driver/wasm-toolchain.cpp =================================================================== --- test/Driver/wasm-toolchain.cpp +++ test/Driver/wasm-toolchain.cpp @@ -38,3 +38,17 @@ // RUN: %clangxx -### -no-canonical-prefixes -target wasm32-unknown-wasi-musl --sysroot=/foo --stdlib=c++ %s 2>&1 | FileCheck -check-prefix=COMPILE %s // COMPILE: clang{{.*}}" "-cc1" {{.*}} "-internal-isystem" "/foo/include/wasm32-wasi-musl/c++/v1" "-internal-isystem" "/foo/include/c++/v1" "-internal-isystem" "/foo/include/wasm32-wasi-musl" "-internal-isystem" "/foo/include" + +// Thread-related command line tests. +// - '-matomics' sets '-mthread-model posix' +// - '-mthread-model' sets '-matomics' +// - '-phread' sets both '-matomics' and '-mthread-model posix' + +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 -matomics | FileCheck -check-prefix=ATOMICS %s +// ATOMICS: clang{{.*}}" "-cc1" {{.*}} "-mthread-model" "posix" + +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 -mthread-model posix | FileCheck -check-prefix=POSIX %s +// POSIX: clang{{.*}}" "-cc1" {{.*}} "-target-feature +atomics" + +// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 -pthread | FileCheck -check-prefix=PTHREAD %s +// PTHREAD: clang{{.*}}" "-cc1" {{.*}} "-mthread-model" "posix" {{.*}} "-target-feature +atomics"