diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticDriverKinds.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Driver/Options.td | 3 | ||||
-rw-r--r-- | clang/include/clang/Driver/ToolChain.h | 6 | ||||
-rw-r--r-- | clang/include/clang/Frontend/CodeGenOptions.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Driver/Driver.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChain.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 5 | ||||
-rw-r--r-- | clang/test/Driver/thread-model.c | 15 |
10 files changed, 72 insertions, 5 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 720254830b4..f0920a8e166 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -22,6 +22,8 @@ def err_drv_unknown_stdin_type_clang_cl : Error< def err_drv_unknown_language : Error<"language not recognized: '%0'">; def err_drv_invalid_arch_name : Error< "invalid arch name '%0'">; +def err_drv_invalid_thread_model_for_target : Error< + "invalid thread model '%0' in '%1' for this target">; def err_drv_invalid_linker_name : Error< "invalid linker name in argument '%0'">; def err_drv_invalid_rtlib_name : Error< diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index db611b6ed81..1d2ef6f988c 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1088,6 +1088,9 @@ def mstackrealign : Flag<["-"], "mstackrealign">, Group<m_Group>, Flags<[CC1Opti HelpText<"Force realign the stack at entry to every function">; def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"Set the stack alignment">; +def mthread_model : Separate<["-"], "mthread-model">, Group<m_Group>, Flags<[CC1Option]>, + HelpText<"The thread model to use, e.g. posix, single (posix by default)">; + def mmmx : Flag<["-"], "mmmx">, Group<m_x86_Features_Group>; def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>; def mno_3dnow : Flag<["-"], "mno-3dnow">, Group<m_x86_Features_Group>; diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index e9fbe6cd77f..9b23b47cb22 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -251,6 +251,12 @@ public: /// UseSEHExceptions - Does this tool chain use SEH exceptions. virtual bool UseSEHExceptions() const { return false; } + /// getThreadModel() - Which thread model does this target use? + virtual std::string getThreadModel() const { return "posix"; } + + /// supportsThreadModel() - Does this target support a thread model? + virtual bool isThreadModelSupported(const StringRef Model) const; + /// ComputeLLVMTriple - Return the LLVM target triple to use, after taking /// command line arguments into account. virtual std::string diff --git a/clang/include/clang/Frontend/CodeGenOptions.h b/clang/include/clang/Frontend/CodeGenOptions.h index 3d532cea343..aa4b1216b3b 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.h +++ b/clang/include/clang/Frontend/CodeGenOptions.h @@ -134,6 +134,9 @@ public: /// The name of the relocation model to use. std::string RelocationModel; + /// The thread model to use + std::string ThreadModel; + /// Path to blacklist file for sanitizers. std::string SanitizerBlacklistFile; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index e28f504020e..6db952613d2 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -425,6 +425,11 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { llvm::TargetOptions Options; + Options.ThreadModel = + llvm::StringSwitch<llvm::ThreadModel::Model>(CodeGenOpts.ThreadModel) + .Case("posix", llvm::ThreadModel::POSIX) + .Case("single", llvm::ThreadModel::Single); + if (CodeGenOpts.DisableIntegratedAS) Options.DisableIntegratedAS = true; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 8b097755064..89713f59ea6 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -684,9 +684,13 @@ void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const { OS << "Target: " << TC.getTripleString() << '\n'; // Print the threading model. - // - // FIXME: Implement correctly. - OS << "Thread model: " << "posix" << '\n'; + if (Arg *A = C.getArgs().getLastArg(options::OPT_mthread_model)) { + // Don't print if the ToolChain would have barfed on it already + if (TC.isThreadModelSupported(A->getValue())) + OS << "Thread model: " << A->getValue(); + } else + OS << "Thread model: " << TC.getThreadModel(); + OS << '\n'; } /// PrintDiagnosticCategories - Implement the --print-diagnostic-categories diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 65dd4d4e2d8..6734ce7d709 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -27,8 +27,13 @@ using namespace clang; using namespace llvm::opt; ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, - const ArgList &A) - : D(D), Triple(T), Args(A) { + const ArgList &Args) + : D(D), Triple(T), Args(Args) { + if (Arg *A = Args.getLastArg(options::OPT_mthread_model)) + if (!isThreadModelSupported(A->getValue())) + D.Diag(diag::err_drv_invalid_thread_model_for_target) + << A->getValue() + << A->getAsString(Args); } ToolChain::~ToolChain() { @@ -201,6 +206,19 @@ ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const { VersionTuple()); } +bool ToolChain::isThreadModelSupported(const StringRef Model) const { + if (Model == "single") { + // FIXME: 'single' is only supported on ARM so far. + return Triple.getArch() == llvm::Triple::arm || + Triple.getArch() == llvm::Triple::armeb || + Triple.getArch() == llvm::Triple::thumb || + Triple.getArch() == llvm::Triple::thumbeb; + } else if (Model == "posix") + return true; + + return false; +} + std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, types::ID InputType) const { switch (getTriple().getArch()) { diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 99e34e4be0c..c09d48906e5 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -2753,6 +2753,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + CmdArgs.push_back("-mthread-model"); + if (Arg *A = Args.getLastArg(options::OPT_mthread_model)) + CmdArgs.push_back(A->getValue()); + else + CmdArgs.push_back(Args.MakeArgString(getToolChain().getThreadModel())); + if (!Args.hasFlag(options::OPT_fmerge_all_constants, options::OPT_fno_merge_all_constants)) CmdArgs.push_back("-fno-merge-all-constants"); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 0dde41acf2e..043141ad673 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -440,6 +440,11 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_cl_fast_relaxed_math); Opts.UnwindTables = Args.hasArg(OPT_munwind_tables); Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic"); + Opts.ThreadModel = Args.getLastArgValue(OPT_mthread_model, "posix"); + if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single") + Diags.Report(diag::err_drv_invalid_value) + << Args.getLastArg(OPT_mthread_model)->getAsString(Args) + << Opts.ThreadModel; Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ); Opts.UseInitArray = Args.hasArg(OPT_fuse_init_array); diff --git a/clang/test/Driver/thread-model.c b/clang/test/Driver/thread-model.c new file mode 100644 index 00000000000..9702c2231a2 --- /dev/null +++ b/clang/test/Driver/thread-model.c @@ -0,0 +1,15 @@ +// RUN: %clang -### -target arm-unknown-linux-gnu -c %s -mthread-model posix -v 2>&1 | FileCheck -check-prefix=CHECK-POSIX %s +// RUN: %clang -### -target arm-unknown-linux-gnu -c %s -mthread-model single -v 2>&1 | FileCheck -check-prefix=CHECK-SINGLE %s +// RUN: not %clang -target arm-unknown-linux-gnu -c %s -mthread-model silly -v 2>&1 | FileCheck -check-prefix=CHECK-INVALID %s +// CHECK-POSIX: "-mthread-model" "posix" +// CHECK-SINGLE: "-mthread-model" "single" +// CHECK-INVALID: error: invalid thread model 'silly' in '-mthread-model silly' for this target + +// RUN: %clang -### -target arm-unknown-linux-gnu -c %s -v 2>&1 | FileCheck -check-prefix=CHECK-LINUX-POSIX %s +// RUN: %clang -### -target arm-unknown-linux-gnu -c %s -v -mthread-model single 2>&1 | FileCheck -check-prefix=CHECK-LINUX-SINGLE %s +// RUN: %clang -### -target arm-unknown-linux-gnu -c %s -v -mthread-model silly 2>&1 | FileCheck -check-prefix=CHECK-LINUX-INVALID %s +// CHECK-LINUX-POSIX: Thread model: posix +// CHECK-LINUX-POSIX: "-mthread-model" "posix" +// CHECK-LINUX-SINGLE: Thread model: single +// CHECK-LINUX-SINGLE: "-mthread-model" "single" +// CHECK-LINUX-INVALID-NOT: Thread model: |