]> granicus.if.org Git - clang/commitdiff
[Driver][CodeGen] Add -mprefer-vector-width driver option and attribute during CodeGen.
authorCraig Topper <craig.topper@intel.com>
Mon, 11 Dec 2017 21:09:19 +0000 (21:09 +0000)
committerCraig Topper <craig.topper@intel.com>
Mon, 11 Dec 2017 21:09:19 +0000 (21:09 +0000)
This adds a new command line option -mprefer-vector-width to specify a preferred vector width for the vectorizers. Valid values are 'none' and unsigned integers. The driver will check that it meets those constraints. Specific supported integers will be managed by the targets in the backend.

Clang will take the value and add it as a new function attribute during CodeGen.

This represents the alternate direction proposed by Sanjay in this RFC: http://lists.llvm.org/pipermail/llvm-dev/2017-November/118734.html

The syntax here matches gcc, though gcc treats it as an x86 specific command line argument. gcc only allows values of 128, 256, and 512. I'm not having clang check any values.

Differential Revision: https://reviews.llvm.org/D40230

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

docs/ClangCommandLineReference.rst
include/clang/Driver/Options.td
include/clang/Frontend/CodeGenOptions.h
lib/CodeGen/CGCall.cpp
lib/Driver/ToolChains/Clang.cpp
lib/Frontend/CompilerInvocation.cpp
test/CodeGen/attr-mprefer-vector-width.c [new file with mode: 0644]
test/Driver/mprefer-vector-width.c [new file with mode: 0644]

index 9755efa2b8a581e07b6ef0a3ed85a6362beb41e4..4d095883a4b791d146121bdc762105bfbba9e125 100644 (file)
@@ -2120,6 +2120,10 @@ Omit frame pointer setup for leaf functions
 
 Use copy relocations support for PIE builds
 
+.. option:: -mprefer-vector-width=<arg>
+
+Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.
+
 .. option:: -mqdsp6-compat
 
 Enable hexagon-qdsp6 backward compatibility
index d155d703a7969321427b3bfd1abd43d4cdd3cf52..1ed4fd2dab707c3697fe6acf95281bbe7299d0fa 100644 (file)
@@ -1954,6 +1954,8 @@ def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>,
 def mimplicit_float : Flag<["-"], "mimplicit-float">, Group<m_Group>;
 def mrecip : Flag<["-"], "mrecip">, Group<m_Group>;
 def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group<m_Group>, Flags<[CC1Option]>;
+def mprefer_vector_width_EQ : Joined<["-"], "mprefer-vector-width=">, Group<m_Group>, Flags<[CC1Option]>,
+  HelpText<"Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions.">;
 def mpie_copy_relocations : Flag<["-"], "mpie-copy-relocations">, Group<m_Group>,
   Flags<[CC1Option]>,
   HelpText<"Use copy relocations support for PIE builds">;
index 425db0359e3f8f540b8a352eadf6c5daf32215a4..6b8d2b935fdd2c48f8ce5faf2b8cbce3b46db308 100644 (file)
@@ -253,6 +253,11 @@ public:
 
   std::vector<std::string> Reciprocals;
 
+  /// The preferred width for auto-vectorization transforms. This is intended to
+  /// override default transforms based on the width of the architected vector
+  /// registers.
+  std::string PreferVectorWidth;
+
 public:
   // Define accessors/mutators for code generation options of enumeration type.
 #define CODEGENOPT(Name, Bits, Default)
index 15c8553249b26b0c23de08155471eb055dfaf329..c3709bf2e447e990662aca9607bc8c0364875c7e 100644 (file)
@@ -1744,6 +1744,11 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
       FuncAttrs.addAttribute("reciprocal-estimates",
                              llvm::join(Recips, ","));
 
+    if (!CodeGenOpts.PreferVectorWidth.empty() &&
+        CodeGenOpts.PreferVectorWidth != "none")
+      FuncAttrs.addAttribute("prefer-vector-width",
+                             CodeGenOpts.PreferVectorWidth);
+
     if (CodeGenOpts.StackRealignment)
       FuncAttrs.addAttribute("stackrealign");
     if (CodeGenOpts.Backchain)
index 2d6ac642f0f35137e8272e729ffc0e42858508c2..706ac5bee294d89edfae53ae64390f1a7d1d8fb8 100644 (file)
@@ -274,6 +274,27 @@ static void ParseMRecip(const Driver &D, const ArgList &Args,
   OutStrings.push_back(Args.MakeArgString(Out));
 }
 
+/// The -mprefer-vector-width option accepts either a positive integer
+/// or the string "none".
+static void ParseMPreferVectorWidth(const Driver &D, const ArgList &Args,
+                                    ArgStringList &CmdArgs) {
+  Arg *A = Args.getLastArg(options::OPT_mprefer_vector_width_EQ);
+  if (!A)
+    return;
+
+  StringRef Value = A->getValue();
+  if (Value == "none") {
+    CmdArgs.push_back("-mprefer-vector-width=none");
+  } else {
+    unsigned Width;
+    if (Value.getAsInteger(10, Width)) {
+      D.Diag(diag::err_drv_invalid_value) << A->getOption().getName() << Value;
+      return;
+    }
+    CmdArgs.push_back(Args.MakeArgString("-mprefer-vector-width=" + Value));
+  }
+}
+
 static void getWebAssemblyTargetFeatures(const ArgList &Args,
                                          std::vector<StringRef> &Features) {
   handleTargetFeaturesGroup(Args, Features, options::OPT_m_wasm_Features_Group);
@@ -4333,6 +4354,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                    options::OPT_fno_slp_vectorize, EnableSLPVec))
     CmdArgs.push_back("-vectorize-slp");
 
+  ParseMPreferVectorWidth(D, Args, CmdArgs);
+
   if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ))
     A->render(Args, CmdArgs);
 
index 2ebdc2a62aabaf9988d7d391cfd30d4b898d82ae..3aa615b490fd959c76d766cde2c1d512f19d2de8 100644 (file)
@@ -713,6 +713,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
   Opts.VectorizeLoop = Args.hasArg(OPT_vectorize_loops);
   Opts.VectorizeSLP = Args.hasArg(OPT_vectorize_slp);
 
+  Opts.PreferVectorWidth = Args.getLastArgValue(OPT_mprefer_vector_width_EQ);
+
   Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name);
   Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
 
diff --git a/test/CodeGen/attr-mprefer-vector-width.c b/test/CodeGen/attr-mprefer-vector-width.c
new file mode 100644 (file)
index 0000000..30edba5
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -mprefer-vector-width=128 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK128
+// RUN: %clang_cc1 -mprefer-vector-width=256 -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK256
+// RUN: %clang_cc1 -mprefer-vector-width=none -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECKNONE
+
+int baz(int a) { return 4; }
+
+// CHECK128: baz{{.*}} #0
+// CHECK128: #0 = {{.*}}"prefer-vector-width"="128"
+
+// CHECK256: baz{{.*}} #0
+// CHECK256: #0 = {{.*}}"prefer-vector-width"="256"
+
+// CHECKNONE: baz{{.*}} #0
+// CHECKNONE-NOT: #0 = {{.*}}"prefer-vector-width"="none"
diff --git a/test/Driver/mprefer-vector-width.c b/test/Driver/mprefer-vector-width.c
new file mode 100644 (file)
index 0000000..d927b35
--- /dev/null
@@ -0,0 +1,24 @@
+////
+//// Verify that valid options for the -mprefer-vector-width flag are passed through and invalid options cause an error.
+////
+
+//// If there are no options, convert to 'all'.
+
+// RUN: %clang -### -S %s -mprefer-vector-width=none  2>&1 | FileCheck --check-prefix=WIDTHNONE %s
+// WIDTHNONE: "-mprefer-vector-width=none"
+
+//// Check options that cover all types.
+
+// RUN: %clang -### -S %s -mprefer-vector-width=128  2>&1 | FileCheck --check-prefix=WIDTH128 %s
+// WIDTH128: "-mprefer-vector-width=128"
+
+//// Check invalid parameters.
+
+// RUN: %clang -### -S %s -mprefer-vector-width=one  2>&1 | FileCheck --check-prefix=WIDTHONE %s
+// WIDTHONE: invalid value 'one' in 'mprefer-vector-width='
+
+// RUN: %clang -### -S %s -mprefer-vector-width=128.5  2>&1 | FileCheck --check-prefix=WIDTH128p5 %s
+// WIDTH128p5: invalid value '128.5' in 'mprefer-vector-width='
+
+// RUN: %clang -### -S %s -mprefer-vector-width=-128  2>&1 | FileCheck --check-prefix=WIDTHNEG128 %s
+// WIDTHNEG128: invalid value '-128' in 'mprefer-vector-width='