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