[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
//===--- SIMDIntrinsicsCheck.cpp - clang-tidy------------------------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "SIMDIntrinsicsCheck.h"
|
|
|
|
#include "clang/AST/ASTContext.h"
|
|
|
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
2020-03-12 11:43:59 +08:00
|
|
|
#include "clang/Basic/TargetInfo.h"
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
|
|
#include "llvm/ADT/Triple.h"
|
|
|
|
#include "llvm/Support/Regex.h"
|
|
|
|
|
|
|
|
using namespace clang::ast_matchers;
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace tidy {
|
2018-03-08 00:57:42 +08:00
|
|
|
namespace portability {
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
// If the callee has parameter of VectorType or pointer to VectorType,
|
|
|
|
// or the return type is VectorType, we consider it a vector function
|
|
|
|
// and a candidate for checking.
|
|
|
|
AST_MATCHER(FunctionDecl, isVectorFunction) {
|
|
|
|
bool IsVector = Node.getReturnType()->isVectorType();
|
|
|
|
for (const ParmVarDecl *Parm : Node.parameters()) {
|
|
|
|
QualType Type = Parm->getType();
|
|
|
|
if (Type->isPointerType())
|
|
|
|
Type = Type->getPointeeType();
|
|
|
|
if (Type->isVectorType())
|
|
|
|
IsVector = true;
|
|
|
|
}
|
|
|
|
return IsVector;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
static StringRef TrySuggestPPC(StringRef Name) {
|
|
|
|
if (!Name.consume_front("vec_"))
|
|
|
|
return {};
|
|
|
|
|
2020-04-26 23:23:30 +08:00
|
|
|
return llvm::StringSwitch<StringRef>(Name)
|
|
|
|
// [simd.alg]
|
|
|
|
.Case("max", "$std::max")
|
|
|
|
.Case("min", "$std::min")
|
|
|
|
// [simd.binary]
|
|
|
|
.Case("add", "operator+ on $simd objects")
|
|
|
|
.Case("sub", "operator- on $simd objects")
|
|
|
|
.Case("mul", "operator* on $simd objects")
|
|
|
|
.Default({});
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static StringRef TrySuggestX86(StringRef Name) {
|
|
|
|
if (!(Name.consume_front("_mm_") || Name.consume_front("_mm256_") ||
|
|
|
|
Name.consume_front("_mm512_")))
|
|
|
|
return {};
|
|
|
|
|
|
|
|
// [simd.alg]
|
|
|
|
if (Name.startswith("max_"))
|
|
|
|
return "$simd::max";
|
|
|
|
if (Name.startswith("min_"))
|
|
|
|
return "$simd::min";
|
|
|
|
|
|
|
|
// [simd.binary]
|
|
|
|
if (Name.startswith("add_"))
|
|
|
|
return "operator+ on $simd objects";
|
|
|
|
if (Name.startswith("sub_"))
|
|
|
|
return "operator- on $simd objects";
|
|
|
|
if (Name.startswith("mul_"))
|
|
|
|
return "operator* on $simd objects";
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
SIMDIntrinsicsCheck::SIMDIntrinsicsCheck(StringRef Name,
|
|
|
|
ClangTidyContext *Context)
|
2018-03-08 00:57:42 +08:00
|
|
|
: ClangTidyCheck(Name, Context), Std(Options.get("Std", "")),
|
2020-04-10 05:47:09 +08:00
|
|
|
Suggest(Options.get("Suggest", false)) {}
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
|
|
|
|
void SIMDIntrinsicsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
2020-10-18 22:56:39 +08:00
|
|
|
Options.store(Opts, "Std", Std);
|
|
|
|
Options.store(Opts, "Suggest", Suggest);
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void SIMDIntrinsicsCheck::registerMatchers(MatchFinder *Finder) {
|
2018-03-08 00:57:42 +08:00
|
|
|
// If Std is not specified, infer it from the language options.
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
// libcxx implementation backports it to C++11 std::experimental::simd.
|
2018-03-08 00:57:42 +08:00
|
|
|
if (Std.empty())
|
2020-04-22 03:37:19 +08:00
|
|
|
Std = getLangOpts().CPlusPlus20 ? "std" : "std::experimental";
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
|
2018-11-25 10:41:01 +08:00
|
|
|
Finder->addMatcher(callExpr(callee(functionDecl(
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
matchesName("^::(_mm_|_mm256_|_mm512_|vec_)"),
|
2018-11-25 10:41:01 +08:00
|
|
|
isVectorFunction())),
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
unless(isExpansionInSystemHeader()))
|
|
|
|
.bind("call"),
|
|
|
|
this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SIMDIntrinsicsCheck::check(const MatchFinder::MatchResult &Result) {
|
|
|
|
const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call");
|
|
|
|
assert(Call != nullptr);
|
|
|
|
const FunctionDecl *Callee = Call->getDirectCallee();
|
|
|
|
if (!Callee)
|
|
|
|
return;
|
|
|
|
|
|
|
|
StringRef Old = Callee->getName();
|
|
|
|
StringRef New;
|
|
|
|
llvm::Triple::ArchType Arch =
|
|
|
|
Result.Context->getTargetInfo().getTriple().getArch();
|
|
|
|
|
2018-03-08 00:57:42 +08:00
|
|
|
// We warn or suggest if this SIMD intrinsic function has a std::simd
|
|
|
|
// replacement.
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
switch (Arch) {
|
2018-03-08 00:57:42 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
case llvm::Triple::ppc:
|
|
|
|
case llvm::Triple::ppc64:
|
|
|
|
case llvm::Triple::ppc64le:
|
|
|
|
New = TrySuggestPPC(Old);
|
|
|
|
break;
|
|
|
|
case llvm::Triple::x86:
|
|
|
|
case llvm::Triple::x86_64:
|
|
|
|
New = TrySuggestX86(Old);
|
|
|
|
break;
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
}
|
|
|
|
|
2018-03-08 00:57:42 +08:00
|
|
|
// We have found a std::simd replacement.
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
if (!New.empty()) {
|
|
|
|
std::string Message;
|
|
|
|
// If Suggest is true, give a P0214 alternative, otherwise point it out it
|
|
|
|
// is non-portable.
|
|
|
|
if (Suggest) {
|
|
|
|
Message = (Twine("'") + Old + "' can be replaced by " + New).str();
|
|
|
|
Message = llvm::Regex("\\$std").sub(Std, Message);
|
2018-03-08 00:57:42 +08:00
|
|
|
Message =
|
|
|
|
llvm::Regex("\\$simd").sub((Std.str() + "::simd").str(), Message);
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
} else {
|
|
|
|
Message = (Twine("'") + Old + "' is a non-portable " +
|
|
|
|
llvm::Triple::getArchTypeName(Arch) + " intrinsic function")
|
|
|
|
.str();
|
|
|
|
}
|
|
|
|
diag(Call->getExprLoc(), Message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-08 00:57:42 +08:00
|
|
|
} // namespace portability
|
[clang-tidy] Add `readability-simd-intrinsics` check.
Summary:
Many architectures provide SIMD operations (e.g. x86 SSE/AVX, Power AltiVec/VSX,
ARM NEON). It is common that SIMD code implementing the same algorithm, is
written in multiple target-dispatching pieces to optimize for different
architectures or micro-architectures.
The C++ standard proposal P0214 and its extensions cover many common SIMD
operations. By migrating from target-dependent intrinsics to P0214 operations,
the SIMD code can be simplified and pieces for different targets can be unified.
Refer to http://wg21.link/p0214 for introduction and motivation for the
data-parallel standard library.
Subscribers: klimek, aemerson, mgorny, xazax.hun, kristof.beyls, hintonda, cfe-commits
Differential Revision: https://reviews.llvm.org/D42983
llvm-svn: 325272
2018-02-16 01:56:43 +08:00
|
|
|
} // namespace tidy
|
|
|
|
} // namespace clang
|