]> granicus.if.org Git - clang/commitdiff
CFE Knob for: Add a thread-model knob for lowering atomics on baremetal & single...
authorJonathan Roelofs <jonathan@codesourcery.com>
Fri, 3 Oct 2014 21:57:44 +0000 (21:57 +0000)
committerJonathan Roelofs <jonathan@codesourcery.com>
Fri, 3 Oct 2014 21:57:44 +0000 (21:57 +0000)
http://reviews.llvm.org/D4985

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219027 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticDriverKinds.td
include/clang/Driver/Options.td
include/clang/Driver/ToolChain.h
include/clang/Frontend/CodeGenOptions.h
lib/CodeGen/BackendUtil.cpp
lib/Driver/Driver.cpp
lib/Driver/ToolChain.cpp
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
test/Driver/thread-model.c [new file with mode: 0644]

index 720254830b4b370100ecc75e4401d0f86d897e5b..f0920a8e166c7dd9cb30e976cd5f0af871662199 100644 (file)
@@ -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<
index db611b6ed8133c1fb7e031f1c5f13a0fa1b24250..1d2ef6f988c19a3a2a74e03ef40807d262ab84e7 100644 (file)
@@ -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>;
index e9fbe6cd77f43443335b682052c138ebabfb7947..9b23b47cb22d21ee1c986e4fbc87df73bee589b8 100644 (file)
@@ -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
index 3d532cea3431368ae6a1043227d2915918fbed7e..aa4b1216b3b66c95600f1cabafacd613080acc0c 100644 (file)
@@ -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;
 
index e28f504020ed4eb079f88e59d047e7be4ec11787..6db952613d206d3ad3036a8c015384f456414ee6 100644 (file)
@@ -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;
 
index 8b097755064df577da461205d4efc7eda0800852..89713f59ea6e2850c6145531b3ac56328723b1e9 100644 (file)
@@ -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
index 65dd4d4e2d8a0d4d1f55e5147374512b80035dba..6734ce7d709904f0d3a9477194faadd7b0c7677a 100644 (file)
@@ -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()) {
index 99e34e4be0cf8e5eb73caba87c5fe14fbe2db1b1..c09d48906e59a766860f3aa3e96d7652dec5df72 100644 (file)
@@ -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");
index 0dde41acf2e525e9f5a5205654ac3e05aed7220e..043141ad673bc841357046def3056a0dd375df84 100644 (file)
@@ -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/test/Driver/thread-model.c b/test/Driver/thread-model.c
new file mode 100644 (file)
index 0000000..9702c22
--- /dev/null
@@ -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: