yaxunl created this revision.
yaxunl added reviewers: rsmith, aaron.ballman, tra.
Herald added a project: All.
yaxunl requested review of this revision.
Depending on whether a target feature is enabled or not,
programs may choose different algorithm or different
builtin functions to use.

Instead of let each target to emit predefined macros
for specific target feature, this patch introduce a
function-like builtin macro __has_target_feature.


https://reviews.llvm.org/D125555

Files:
  clang/docs/LanguageExtensions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Lex/Preprocessor.h
  clang/lib/Lex/PPMacroExpansion.cpp
  clang/test/Lexer/has_target_feature.cpp

Index: clang/test/Lexer/has_target_feature.cpp
===================================================================
--- /dev/null
+++ clang/test/Lexer/has_target_feature.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple amdgcn -target-cpu gfx906 -E %s -o - | FileCheck %s
+
+// CHECK: has_s_memtime_inst
+#if __has_target_feature("s-memtime-inst")
+  int has_s_memtime_inst;
+#endif
+
+// CHECK-NOT: has_gfx10_inst
+#if __has_target_feature("gfx10-inst")
+  int has_gfx10_inst;
+#endif
Index: clang/lib/Lex/PPMacroExpansion.cpp
===================================================================
--- clang/lib/Lex/PPMacroExpansion.cpp
+++ clang/lib/Lex/PPMacroExpansion.cpp
@@ -370,7 +370,9 @@
   Ident__has_feature      = RegisterBuiltinMacro(*this, "__has_feature");
   Ident__has_extension    = RegisterBuiltinMacro(*this, "__has_extension");
   Ident__has_builtin      = RegisterBuiltinMacro(*this, "__has_builtin");
-  Ident__has_attribute    = RegisterBuiltinMacro(*this, "__has_attribute");
+  Ident__has_builtin      = RegisterBuiltinMacro(*this, "__has_builtin");
+  Ident__has_target_feature =
+      RegisterBuiltinMacro(*this, "__has_target_feature");
   if (!getLangOpts().CPlusPlus)
     Ident__has_c_attribute = RegisterBuiltinMacro(*this, "__has_c_attribute");
   else
@@ -1618,6 +1620,20 @@
                                            diag::err_feature_check_malformed);
         return II && HasFeature(*this, II->getName());
       });
+  } else if (II == Ident__has_target_feature) {
+    EvaluateFeatureLikeBuiltinMacro(
+        OS, Tok, II, *this, false,
+        [this](Token &Tok, bool &HasLexedNextToken) -> int {
+          std::string TargetFeatureName;
+          HasLexedNextToken = Tok.is(tok::string_literal);
+          if (!FinishLexStringLiteral(Tok, TargetFeatureName,
+                                      "'__has_target_feature'",
+                                      /*AllowMacroExpansion=*/false))
+            return false;
+          auto FeatureMap = getTargetInfo().getTargetOpts().FeatureMap;
+          auto Loc = FeatureMap.find(TargetFeatureName);
+          return Loc != FeatureMap.end() && Loc->second;
+        });
   } else if (II == Ident__has_extension) {
     EvaluateFeatureLikeBuiltinMacro(OS, Tok, II, *this, false,
       [this](Token &Tok, bool &HasLexedNextToken) -> int {
Index: clang/include/clang/Lex/Preprocessor.h
===================================================================
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -166,6 +166,7 @@
   IdentifierInfo *Ident__has_feature;              // __has_feature
   IdentifierInfo *Ident__has_extension;            // __has_extension
   IdentifierInfo *Ident__has_builtin;              // __has_builtin
+  IdentifierInfo *Ident__has_target_feature;       // __has_target_feature
   IdentifierInfo *Ident__has_attribute;            // __has_attribute
   IdentifierInfo *Ident__has_include;              // __has_include
   IdentifierInfo *Ident__has_include_next;         // __has_include_next
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -68,6 +68,9 @@
 
       Randomizing structure layout is a C-only feature.
 
+- Clang now supports function-like macro __has_target_feature which returns 1
+  if the specified target feature is enabled.
+
 Bug Fixes
 ------------------
 - ``CXXNewExpr::getArraySize()`` previously returned a ``llvm::Optional``
Index: clang/docs/LanguageExtensions.rst
===================================================================
--- clang/docs/LanguageExtensions.rst
+++ clang/docs/LanguageExtensions.rst
@@ -257,6 +257,28 @@
   __wchar_t WideCharacter;
   ...
 
+``__has_target_feature``
+------------------------
+
+This function-like macro takes a single string literal argument that is the name of
+a target feature. It evaluates to 1 if the target feature is enabled or 0 if not.
+It can be used like this:
+
+.. code-block:: c++
+
+  #ifndef __has_target_feature         // Optional of course.
+    #define __has_target_feature(x) 0  // Compatibility with non-clang compilers.
+  #endif
+
+  ...
+  // On amdgcn target
+  #if __has_target_feature("s-memtime-inst")
+    x = __builtin_amdgcn_s_memtime();
+  #else
+    x = __builtin_readcyclecounter();
+  #endif
+  ...
+
 Include File Checking Macros
 ============================
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to