r246195 - Rewrite the code generation handling for function feature and cpu attributes.

Eric Christopher via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 27 12:59:35 PDT 2015


Author: echristo
Date: Thu Aug 27 14:59:34 2015
New Revision: 246195

URL: http://llvm.org/viewvc/llvm-project?rev=246195&view=rev
Log:
Rewrite the code generation handling for function feature and cpu attributes.

A couple of changes here:

a) Do less work in the case where we don't have a target attribute on the
function. We've already canonicalized the attributes for the function -
no need to do more work.

b) Use the newer canonicalized feature adding functions from TargetInfo
to do the work when we do have a target attribute. This enables us to diagnose
some warnings in the case of conflicting written attributes (only ppc does
this today) and also make sure to get all of the features for a cpu that's
listed rather than just change the cpu.

Updated all testcases accordingly and added a new testcase to verify that we'll
error out on ppc if we have some incompatible options using the existing diagnosis
framework there.

Added:
    cfe/trunk/test/CodeGen/attr-target-ppc.c
Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/test/CodeGen/attr-target.c

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=246195&r1=246194&r2=246195&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Thu Aug 27 14:59:34 2015
@@ -1496,70 +1496,78 @@ void CodeGenModule::ConstructAttributeLi
     // we have a decl for the function and it has a target attribute then
     // parse that and add it to the feature set.
     StringRef TargetCPU = getTarget().getTargetOpts().CPU;
-
-    // TODO: Features gets us the features on the command line including
-    // feature dependencies. For canonicalization purposes we might want to
-    // avoid putting features in the target-features set if we know it'll be
-    // one of the default features in the backend, e.g. corei7-avx and +avx or
-    // figure out non-explicit dependencies.
-    // Canonicalize the existing features in a new feature map.
-    // TODO: Migrate the existing backends to keep the map around rather than
-    // the vector.
-    llvm::StringMap<bool> FeatureMap;
-    for (auto F : getTarget().getTargetOpts().Features) {
-      const char *Name = F.c_str();
-      bool Enabled = Name[0] == '+';
-      getTarget().setFeatureEnabled(FeatureMap, Name + 1, Enabled);
-    }
-
     const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
-    if (FD) {
-      if (const auto *TD = FD->getAttr<TargetAttr>()) {
-        StringRef FeaturesStr = TD->getFeatures();
-        SmallVector<StringRef, 1> AttrFeatures;
-        FeaturesStr.split(AttrFeatures, ",");
-
-        // Grab the various features and prepend a "+" to turn on the feature to
-        // the backend and add them to our existing set of features.
-        for (auto &Feature : AttrFeatures) {
-          // Go ahead and trim whitespace rather than either erroring or
-          // accepting it weirdly.
-          Feature = Feature.trim();
-
-          // While we're here iterating check for a different target cpu.
-          if (Feature.startswith("arch="))
-            TargetCPU = Feature.split("=").second.trim();
-          else if (Feature.startswith("tune="))
-            // We don't support cpu tuning this way currently.
-            ;
-          else if (Feature.startswith("fpmath="))
-            // TODO: Support the fpmath option this way. It will require checking
-            // overall feature validity for the function with the rest of the
-            // attributes on the function.
-            ;
-          else if (Feature.startswith("mno-"))
-            getTarget().setFeatureEnabled(FeatureMap, Feature.split("-").second,
-                                          false);
-          else
-            getTarget().setFeatureEnabled(FeatureMap, Feature, true);
-        }
+    if (FD && FD->getAttr<TargetAttr>()) {
+      llvm::StringMap<bool> FeatureMap;
+      const auto *TD = FD->getAttr<TargetAttr>();
+
+      // Make a copy of the features as passed on the command line.
+      std::vector<std::string> FnFeatures(
+          getTarget().getTargetOpts().FeaturesAsWritten);
+
+      // Grab the target attribute string.
+      StringRef FeaturesStr = TD->getFeatures();
+      SmallVector<StringRef, 1> AttrFeatures;
+      FeaturesStr.split(AttrFeatures, ",");
+
+      // Grab the various features and prepend a "+" to turn on the feature to
+      // the backend and add them to our existing set of features.
+      for (auto &Feature : AttrFeatures) {
+        // Go ahead and trim whitespace rather than either erroring or
+        // accepting it weirdly.
+        Feature = Feature.trim();
+
+        // While we're here iterating check for a different target cpu.
+        if (Feature.startswith("arch="))
+          TargetCPU = Feature.split("=").second.trim();
+        else if (Feature.startswith("tune="))
+          // We don't support cpu tuning this way currently.
+          ;
+        else if (Feature.startswith("fpmath="))
+          // TODO: Support the fpmath option this way. It will require checking
+          // overall feature validity for the function with the rest of the
+          // attributes on the function.
+          ;
+        else if (Feature.startswith("mno-"))
+          FnFeatures.push_back("-" + Feature.split("-").second.str());
+        else
+          FnFeatures.push_back("+" + Feature.str());
+      }
+      // Now populate the feature map, first with the TargetCPU which is either
+      // the default or a new one from the target attribute string. Then we'll
+      // use the passed in features (FeaturesAsWritten) along with the new ones
+      // from the attribute.
+      getTarget().initDefaultFeatures(FeatureMap, TargetCPU);
+      getTarget().handleUserFeatures(FeatureMap, FnFeatures, Diags);
+
+      // Produce the canonical string for this set of features.
+      std::vector<std::string> Features;
+      for (llvm::StringMap<bool>::const_iterator it = FeatureMap.begin(),
+                                                 ie = FeatureMap.end();
+           it != ie; ++it)
+        Features.push_back((it->second ? "+" : "-") + it->first().str());
+
+      // Now add the target-cpu and target-features to the function.
+      if (TargetCPU != "")
+        FuncAttrs.addAttribute("target-cpu", TargetCPU);
+      if (!Features.empty()) {
+        std::sort(Features.begin(), Features.end());
+        FuncAttrs.addAttribute(
+            "target-features",
+            llvm::join(Features.begin(), Features.end(), ","));
+      }
+    } else {
+      // Otherwise just add the existing target cpu and target features to the
+      // function.
+      std::vector<std::string> &Features = getTarget().getTargetOpts().Features;
+      if (TargetCPU != "")
+        FuncAttrs.addAttribute("target-cpu", TargetCPU);
+      if (!Features.empty()) {
+        std::sort(Features.begin(), Features.end());
+        FuncAttrs.addAttribute(
+            "target-features",
+            llvm::join(Features.begin(), Features.end(), ","));
       }
-    }
-
-    // Produce the canonical string for this set of features.
-    std::vector<std::string> Features;
-    for (llvm::StringMap<bool>::const_iterator it = FeatureMap.begin(),
-                                               ie = FeatureMap.end();
-         it != ie; ++it)
-      Features.push_back((it->second ? "+" : "-") + it->first().str());
-
-    // Now add the target-cpu and target-features to the function.
-    if (TargetCPU != "")
-      FuncAttrs.addAttribute("target-cpu", TargetCPU);
-    if (!Features.empty()) {
-      std::sort(Features.begin(), Features.end());
-      FuncAttrs.addAttribute("target-features",
-                             llvm::join(Features.begin(), Features.end(), ","));
     }
   }
 

Added: cfe/trunk/test/CodeGen/attr-target-ppc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attr-target-ppc.c?rev=246195&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/attr-target-ppc.c (added)
+++ cfe/trunk/test/CodeGen/attr-target-ppc.c Thu Aug 27 14:59:34 2015
@@ -0,0 +1,4 @@
+// RUN: not %clang_cc1 -triple powerpc64le-linux-gnu -emit-llvm %s -o -
+
+long __attribute__((target("power8-vector,mno-vsx"))) foo (void) { return 0; }  // expected-error {{option '-mpower8-vector' cannot be specified with '-mno-vsx'}}
+

Modified: cfe/trunk/test/CodeGen/attr-target.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attr-target.c?rev=246195&r1=246194&r2=246195&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/attr-target.c (original)
+++ cfe/trunk/test/CodeGen/attr-target.c Thu Aug 27 14:59:34 2015
@@ -14,6 +14,7 @@ int __attribute__((target("sse4"))) pand
 int bar(int a) { return baz(a) + foo(a); }
 
 int __attribute__((target("avx,      sse4.2,      arch=   ivybridge"))) qux(int a) { return 4; }
+int __attribute__((target("mno-aes, arch=ivybridge"))) qax(int a) { return 4; }
 
 // Check that we emit the additional subtarget and cpu features for foo and not for baz or bar.
 // CHECK: baz{{.*}} #0
@@ -25,7 +26,9 @@ int __attribute__((target("avx,      sse
 // CHECK: echidna{{.*}} #2
 // CHECK: bar{{.*}} #0
 // CHECK: qux{{.*}} #1
+// CHECK: qax{{.*}} #4
 // CHECK: #0 = {{.*}}"target-cpu"="x86-64" "target-features"="+sse,+sse2"
-// CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3"
+// CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+aes,+avx,+cx16,+f16c,+fsgsbase,+pclmul,+rdrnd,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3"
 // CHECK: #2 = {{.*}}"target-cpu"="x86-64" "target-features"="+sse,-aes,-avx,-avx2,-avx512bw,-avx512cd,-avx512dq,-avx512er,-avx512f,-avx512pf,-avx512vl,-f16c,-fma,-fma4,-pclmul,-sha,-sse2,-sse3,-sse4.1,-sse4.2,-sse4a,-ssse3,-xop"
 // CHECK: #3 = {{.*}}"target-cpu"="x86-64" "target-features"="+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3"
+// CHECK: #4 = {{.*}}"target-cpu"="ivybridge" "target-features"="+avx,+cx16,+f16c,+fsgsbase,+pclmul,+rdrnd,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,-aes"




More information about the cfe-commits mailing list