10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
19 void SingleWorkItemBarrierCheck::registerMatchers(MatchFinder *Finder) {
29 hasAttr(attr::Kind::OpenCLKernel),
31 forEachDescendant(callExpr(callee(functionDecl(hasAnyName(
32 "barrier",
"work_group_barrier"))))
35 unless(hasDescendant(callExpr(callee(functionDecl(
36 hasAnyName(
"get_global_id",
"get_local_id",
"get_group_id",
37 "get_local_linear_id"))))))))
43 const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>(
"function");
44 const auto *MatchedBarrier = Result.Nodes.getNodeAs<CallExpr>(
"barrier");
45 if (AOCVersion < 1701) {
47 diag(MatchedDecl->getLocation(),
48 "kernel function %0 does not call 'get_global_id' or 'get_local_id' "
49 "and will be treated as a single work-item")
51 diag(MatchedBarrier->getBeginLoc(),
52 "barrier call is in a single work-item and may error out",
57 bool IsNDRange =
false;
58 if (MatchedDecl->hasAttr<ReqdWorkGroupSizeAttr>()) {
59 const auto *Attribute = MatchedDecl->getAttr<ReqdWorkGroupSizeAttr>();
60 if (Attribute->getXDim() > 1 || Attribute->getYDim() > 1 ||
61 Attribute->getZDim() > 1)
66 diag(MatchedDecl->getLocation(),
67 "kernel function %0 does not call an ID function and may be a viable "
68 "single work-item, but will be forced to execute as an NDRange")
70 diag(MatchedBarrier->getBeginLoc(),
71 "barrier call will force NDRange execution; if single work-item "
72 "semantics are desired a mem_fence may be more efficient",
77 void SingleWorkItemBarrierCheck::storeOptions(
79 Options.store(Opts,
"AOCVersion", AOCVersion);