2009-07-28 00:33:38 +00:00
|
|
|
//===---- StmtProfile.cpp - Profile implementation for Stmt ASTs ----------===//
|
|
|
|
//
|
2019-01-19 08:50:56 +00: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
|
2009-07-28 00:33:38 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the Stmt::Profile method, which builds a unique bit
|
2009-07-28 16:39:25 +00:00
|
|
|
// representation that identifies a statement/expression.
|
2009-07-28 00:33:38 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/AST/ASTContext.h"
|
2009-07-28 14:44:31 +00:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
|
|
|
#include "clang/AST/DeclObjC.h"
|
2009-07-28 00:33:38 +00:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
|
|
|
#include "clang/AST/Expr.h"
|
|
|
|
#include "clang/AST/ExprCXX.h"
|
|
|
|
#include "clang/AST/ExprObjC.h"
|
2015-08-25 14:24:04 +00:00
|
|
|
#include "clang/AST/ExprOpenMP.h"
|
2017-02-22 22:22:42 +00:00
|
|
|
#include "clang/AST/ODRHash.h"
|
2020-02-10 14:30:39 -05:00
|
|
|
#include "clang/AST/OpenMPClause.h"
|
2009-07-28 00:33:38 +00:00
|
|
|
#include "clang/AST/StmtVisitor.h"
|
|
|
|
#include "llvm/ADT/FoldingSet.h"
|
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
namespace {
|
2011-06-16 06:47:06 +00:00
|
|
|
class StmtProfiler : public ConstStmtVisitor<StmtProfiler> {
|
2017-02-22 22:22:42 +00:00
|
|
|
protected:
|
2009-07-28 00:33:38 +00:00
|
|
|
llvm::FoldingSetNodeID &ID;
|
|
|
|
bool Canonical;
|
2023-07-11 16:12:19 +08:00
|
|
|
bool ProfileLambdaExpr;
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2009-07-28 00:33:38 +00:00
|
|
|
public:
|
2023-07-11 16:12:19 +08:00
|
|
|
StmtProfiler(llvm::FoldingSetNodeID &ID, bool Canonical,
|
|
|
|
bool ProfileLambdaExpr)
|
|
|
|
: ID(ID), Canonical(Canonical), ProfileLambdaExpr(ProfileLambdaExpr) {}
|
2017-02-22 22:22:42 +00:00
|
|
|
|
|
|
|
virtual ~StmtProfiler() {}
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void VisitStmt(const Stmt *S);
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2022-02-15 17:55:35 -08:00
|
|
|
void VisitStmtNoChildren(const Stmt *S) {
|
|
|
|
HandleStmtClass(S->getStmtClass());
|
|
|
|
}
|
|
|
|
|
2018-02-22 05:32:25 +00:00
|
|
|
virtual void HandleStmtClass(Stmt::StmtClass SC) = 0;
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
#define STMT(Node, Base) void Visit##Node(const Node *S);
|
2010-05-05 15:24:00 +00:00
|
|
|
#include "clang/AST/StmtNodes.inc"
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Visit a declaration that is referenced within an expression
|
2009-07-28 00:33:38 +00:00
|
|
|
/// or statement.
|
2017-02-22 22:22:42 +00:00
|
|
|
virtual void VisitDecl(const Decl *D) = 0;
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Visit a type that is referenced within an expression or
|
2009-07-28 00:33:38 +00:00
|
|
|
/// statement.
|
2017-02-22 22:22:42 +00:00
|
|
|
virtual void VisitType(QualType T) = 0;
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Visit a name that occurs within an expression or statement.
|
2018-02-22 05:32:25 +00:00
|
|
|
virtual void VisitName(DeclarationName Name, bool TreatAsDecl = false) = 0;
|
2017-02-22 22:22:42 +00:00
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Visit identifiers that are not in Decl's or Type's.
|
2024-04-11 00:33:40 +00:00
|
|
|
virtual void VisitIdentifierInfo(const IdentifierInfo *II) = 0;
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Visit a nested-name-specifier that occurs within an expression
|
2009-07-28 00:33:38 +00:00
|
|
|
/// or statement.
|
2017-02-22 22:22:42 +00:00
|
|
|
virtual void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) = 0;
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Visit a template name that occurs within an expression or
|
2009-07-28 00:33:38 +00:00
|
|
|
/// statement.
|
2017-02-22 22:22:42 +00:00
|
|
|
virtual void VisitTemplateName(TemplateName Name) = 0;
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Visit template arguments that occur within an expression or
|
2009-07-28 00:33:38 +00:00
|
|
|
/// statement.
|
2011-06-16 06:47:06 +00:00
|
|
|
void VisitTemplateArguments(const TemplateArgumentLoc *Args,
|
|
|
|
unsigned NumArgs);
|
2009-10-29 08:12:44 +00:00
|
|
|
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Visit a single template argument.
|
2009-10-29 08:12:44 +00:00
|
|
|
void VisitTemplateArgument(const TemplateArgument &Arg);
|
2009-07-28 00:33:38 +00:00
|
|
|
};
|
2017-02-22 22:22:42 +00:00
|
|
|
|
|
|
|
class StmtProfilerWithPointers : public StmtProfiler {
|
|
|
|
const ASTContext &Context;
|
|
|
|
|
|
|
|
public:
|
|
|
|
StmtProfilerWithPointers(llvm::FoldingSetNodeID &ID,
|
2023-07-11 16:12:19 +08:00
|
|
|
const ASTContext &Context, bool Canonical,
|
|
|
|
bool ProfileLambdaExpr)
|
|
|
|
: StmtProfiler(ID, Canonical, ProfileLambdaExpr), Context(Context) {}
|
|
|
|
|
2017-02-22 22:22:42 +00:00
|
|
|
private:
|
2018-02-22 05:32:25 +00:00
|
|
|
void HandleStmtClass(Stmt::StmtClass SC) override {
|
|
|
|
ID.AddInteger(SC);
|
|
|
|
}
|
|
|
|
|
2017-02-22 22:22:42 +00:00
|
|
|
void VisitDecl(const Decl *D) override {
|
|
|
|
ID.AddInteger(D ? D->getKind() : 0);
|
|
|
|
|
|
|
|
if (Canonical && D) {
|
|
|
|
if (const NonTypeTemplateParmDecl *NTTP =
|
|
|
|
dyn_cast<NonTypeTemplateParmDecl>(D)) {
|
|
|
|
ID.AddInteger(NTTP->getDepth());
|
|
|
|
ID.AddInteger(NTTP->getIndex());
|
|
|
|
ID.AddBoolean(NTTP->isParameterPack());
|
2023-03-30 13:04:02 -07:00
|
|
|
// C++20 [temp.over.link]p6:
|
|
|
|
// Two template-parameters are equivalent under the following
|
|
|
|
// conditions: [...] if they declare non-type template parameters,
|
|
|
|
// they have equivalent types ignoring the use of type-constraints
|
|
|
|
// for placeholder types
|
|
|
|
//
|
|
|
|
// TODO: Why do we need to include the type in the profile? It's not
|
|
|
|
// part of the mangling.
|
|
|
|
VisitType(Context.getUnconstrainedType(NTTP->getType()));
|
2017-02-22 22:22:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) {
|
|
|
|
// The Itanium C++ ABI uses the type, scope depth, and scope
|
|
|
|
// index of a parameter when mangling expressions that involve
|
|
|
|
// function parameters, so we will use the parameter's type for
|
|
|
|
// establishing function parameter identity. That way, our
|
|
|
|
// definition of "equivalent" (per C++ [temp.over.link]) is at
|
|
|
|
// least as strong as the definition of "equivalent" used for
|
|
|
|
// name mangling.
|
2023-03-30 13:04:02 -07:00
|
|
|
//
|
|
|
|
// TODO: The Itanium C++ ABI only uses the top-level cv-qualifiers,
|
|
|
|
// not the entirety of the type.
|
2017-02-22 22:22:42 +00:00
|
|
|
VisitType(Parm->getType());
|
|
|
|
ID.AddInteger(Parm->getFunctionScopeDepth());
|
|
|
|
ID.AddInteger(Parm->getFunctionScopeIndex());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const TemplateTypeParmDecl *TTP =
|
|
|
|
dyn_cast<TemplateTypeParmDecl>(D)) {
|
|
|
|
ID.AddInteger(TTP->getDepth());
|
|
|
|
ID.AddInteger(TTP->getIndex());
|
|
|
|
ID.AddBoolean(TTP->isParameterPack());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const TemplateTemplateParmDecl *TTP =
|
|
|
|
dyn_cast<TemplateTemplateParmDecl>(D)) {
|
|
|
|
ID.AddInteger(TTP->getDepth());
|
|
|
|
ID.AddInteger(TTP->getIndex());
|
|
|
|
ID.AddBoolean(TTP->isParameterPack());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ID.AddPointer(D ? D->getCanonicalDecl() : nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisitType(QualType T) override {
|
2017-03-04 02:42:41 +00:00
|
|
|
if (Canonical && !T.isNull())
|
2017-02-22 22:22:42 +00:00
|
|
|
T = Context.getCanonicalType(T);
|
|
|
|
|
|
|
|
ID.AddPointer(T.getAsOpaquePtr());
|
|
|
|
}
|
|
|
|
|
2018-02-22 05:32:25 +00:00
|
|
|
void VisitName(DeclarationName Name, bool /*TreatAsDecl*/) override {
|
2017-02-22 22:22:42 +00:00
|
|
|
ID.AddPointer(Name.getAsOpaquePtr());
|
|
|
|
}
|
|
|
|
|
2024-04-11 00:33:40 +00:00
|
|
|
void VisitIdentifierInfo(const IdentifierInfo *II) override {
|
2017-02-22 22:22:42 +00:00
|
|
|
ID.AddPointer(II);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
|
|
|
|
if (Canonical)
|
|
|
|
NNS = Context.getCanonicalNestedNameSpecifier(NNS);
|
|
|
|
ID.AddPointer(NNS);
|
|
|
|
}
|
|
|
|
|
|
|
|
void VisitTemplateName(TemplateName Name) override {
|
|
|
|
if (Canonical)
|
|
|
|
Name = Context.getCanonicalTemplateName(Name);
|
|
|
|
|
|
|
|
Name.Profile(ID);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class StmtProfilerWithoutPointers : public StmtProfiler {
|
|
|
|
ODRHash &Hash;
|
|
|
|
public:
|
|
|
|
StmtProfilerWithoutPointers(llvm::FoldingSetNodeID &ID, ODRHash &Hash)
|
2023-07-11 16:12:19 +08:00
|
|
|
: StmtProfiler(ID, /*Canonical=*/false, /*ProfileLambdaExpr=*/false),
|
|
|
|
Hash(Hash) {}
|
2017-02-22 22:22:42 +00:00
|
|
|
|
|
|
|
private:
|
2018-02-22 05:32:25 +00:00
|
|
|
void HandleStmtClass(Stmt::StmtClass SC) override {
|
|
|
|
if (SC == Stmt::UnresolvedLookupExprClass) {
|
|
|
|
// Pretend that the name looked up is a Decl due to how templates
|
|
|
|
// handle some Decl lookups.
|
|
|
|
ID.AddInteger(Stmt::DeclRefExprClass);
|
|
|
|
} else {
|
|
|
|
ID.AddInteger(SC);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-22 22:22:42 +00:00
|
|
|
void VisitType(QualType T) override {
|
|
|
|
Hash.AddQualType(T);
|
|
|
|
}
|
|
|
|
|
2018-02-22 05:32:25 +00:00
|
|
|
void VisitName(DeclarationName Name, bool TreatAsDecl) override {
|
|
|
|
if (TreatAsDecl) {
|
|
|
|
// A Decl can be null, so each Decl is preceded by a boolean to
|
|
|
|
// store its nullness. Add a boolean here to match.
|
|
|
|
ID.AddBoolean(true);
|
|
|
|
}
|
2018-09-04 22:53:19 +00:00
|
|
|
Hash.AddDeclarationName(Name, TreatAsDecl);
|
2017-02-22 22:22:42 +00:00
|
|
|
}
|
2024-04-11 00:33:40 +00:00
|
|
|
void VisitIdentifierInfo(const IdentifierInfo *II) override {
|
2017-02-22 22:22:42 +00:00
|
|
|
ID.AddBoolean(II);
|
|
|
|
if (II) {
|
|
|
|
Hash.AddIdentifierInfo(II);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void VisitDecl(const Decl *D) override {
|
|
|
|
ID.AddBoolean(D);
|
|
|
|
if (D) {
|
|
|
|
Hash.AddDecl(D);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void VisitTemplateName(TemplateName Name) override {
|
|
|
|
Hash.AddTemplateName(Name);
|
|
|
|
}
|
|
|
|
void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
|
2017-07-01 02:00:05 +00:00
|
|
|
ID.AddBoolean(NNS);
|
|
|
|
if (NNS) {
|
|
|
|
Hash.AddNestedNameSpecifier(NNS);
|
|
|
|
}
|
2017-02-22 22:22:42 +00:00
|
|
|
}
|
|
|
|
};
|
2015-06-22 23:07:51 +00:00
|
|
|
}
|
2009-07-28 00:33:38 +00:00
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitStmt(const Stmt *S) {
|
2016-06-10 04:52:09 +00:00
|
|
|
assert(S && "Requires non-null Stmt pointer");
|
2018-02-22 05:32:25 +00:00
|
|
|
|
2022-02-15 17:55:35 -08:00
|
|
|
VisitStmtNoChildren(S);
|
2018-02-22 05:32:25 +00:00
|
|
|
|
2015-07-02 21:03:14 +00:00
|
|
|
for (const Stmt *SubStmt : S->children()) {
|
|
|
|
if (SubStmt)
|
|
|
|
Visit(SubStmt);
|
2012-03-01 16:34:31 +00:00
|
|
|
else
|
|
|
|
ID.AddInteger(0);
|
|
|
|
}
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitDeclStmt(const DeclStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
2014-03-14 17:01:24 +00:00
|
|
|
for (const auto *D : S->decls())
|
|
|
|
VisitDecl(D);
|
2009-07-28 15:27:13 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitNullStmt(const NullStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCompoundStmt(const CompoundStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCaseStmt(const CaseStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitDefaultStmt(const DefaultStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitLabelStmt(const LabelStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
2011-02-17 07:39:24 +00:00
|
|
|
VisitDecl(S->getDecl());
|
2009-07-28 15:27:13 +00:00
|
|
|
}
|
|
|
|
|
2012-04-14 00:33:13 +00:00
|
|
|
void StmtProfiler::VisitAttributedStmt(const AttributedStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
// TODO: maybe visit attributes?
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitIfStmt(const IfStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
2009-11-25 00:27:52 +00:00
|
|
|
VisitDecl(S->getConditionVariable());
|
2009-07-28 15:27:13 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitSwitchStmt(const SwitchStmt *S) {
|
2009-07-29 16:09:57 +00:00
|
|
|
VisitStmt(S);
|
2009-11-25 00:27:52 +00:00
|
|
|
VisitDecl(S->getConditionVariable());
|
2009-07-29 16:09:57 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitWhileStmt(const WhileStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
2009-11-25 00:27:52 +00:00
|
|
|
VisitDecl(S->getConditionVariable());
|
2009-07-28 15:27:13 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitDoStmt(const DoStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitForStmt(const ForStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitGotoStmt(const GotoStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
2011-02-17 07:39:24 +00:00
|
|
|
VisitDecl(S->getLabel());
|
2009-07-28 15:27:13 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitIndirectGotoStmt(const IndirectGotoStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitContinueStmt(const ContinueStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitBreakStmt(const BreakStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitReturnStmt(const ReturnStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2012-08-25 00:11:56 +00:00
|
|
|
void StmtProfiler::VisitGCCAsmStmt(const GCCAsmStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
ID.AddBoolean(S->isVolatile());
|
|
|
|
ID.AddBoolean(S->isSimple());
|
|
|
|
VisitStringLiteral(S->getAsmString());
|
|
|
|
ID.AddInteger(S->getNumOutputs());
|
|
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
|
|
|
ID.AddString(S->getOutputName(I));
|
|
|
|
VisitStringLiteral(S->getOutputConstraintLiteral(I));
|
|
|
|
}
|
|
|
|
ID.AddInteger(S->getNumInputs());
|
|
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
|
|
|
ID.AddString(S->getInputName(I));
|
|
|
|
VisitStringLiteral(S->getInputConstraintLiteral(I));
|
|
|
|
}
|
|
|
|
ID.AddInteger(S->getNumClobbers());
|
|
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
|
2012-08-27 23:28:41 +00:00
|
|
|
VisitStringLiteral(S->getClobberStringLiteral(I));
|
2019-06-03 15:57:25 +00:00
|
|
|
ID.AddInteger(S->getNumLabels());
|
|
|
|
for (auto *L : S->labels())
|
|
|
|
VisitDecl(L->getLabel());
|
2009-07-28 15:27:13 +00:00
|
|
|
}
|
|
|
|
|
2012-06-11 20:47:18 +00:00
|
|
|
void StmtProfiler::VisitMSAsmStmt(const MSAsmStmt *S) {
|
|
|
|
// FIXME: Implement MS style inline asm statement profiler.
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXCatchStmt(const CXXCatchStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
VisitType(S->getCaughtType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXTryStmt(const CXXTryStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
|
2011-04-14 22:09:26 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-10-25 01:33:02 +00:00
|
|
|
void StmtProfiler::VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
ID.AddBoolean(S->isIfExists());
|
|
|
|
VisitNestedNameSpecifier(S->getQualifierLoc().getNestedNameSpecifier());
|
|
|
|
VisitName(S->getNameInfo().getName());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitSEHTryStmt(const SEHTryStmt *S) {
|
2011-04-28 01:08:34 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitSEHFinallyStmt(const SEHFinallyStmt *S) {
|
2011-04-28 01:08:34 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitSEHExceptStmt(const SEHExceptStmt *S) {
|
2011-04-28 01:08:34 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2014-07-07 00:12:30 +00:00
|
|
|
void StmtProfiler::VisitSEHLeaveStmt(const SEHLeaveStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2013-04-16 18:53:08 +00:00
|
|
|
void StmtProfiler::VisitCapturedStmt(const CapturedStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
[SYCL] AST support for SYCL kernel entry point functions. (#122379)
A SYCL kernel entry point function is a non-member function or a static
member function declared with the `sycl_kernel_entry_point` attribute.
Such functions define a pattern for an offload kernel entry point
function to be generated to enable execution of a SYCL kernel on a
device. A SYCL library implementation orchestrates the invocation of
these functions with corresponding SYCL kernel arguments in response to
calls to SYCL kernel invocation functions specified by the SYCL 2020
specification.
The offload kernel entry point function (sometimes referred to as the
SYCL kernel caller function) is generated from the SYCL kernel entry
point function by a transformation of the function parameters followed
by a transformation of the function body to replace references to the
original parameters with references to the transformed ones. Exactly how
parameters are transformed will be explained in a future change that
implements non-trivial transformations. For now, it suffices to state
that a given parameter of the SYCL kernel entry point function may be
transformed to multiple parameters of the offload kernel entry point as
needed to satisfy offload kernel argument passing requirements.
Parameters that are decomposed in this way are reconstituted as local
variables in the body of the generated offload kernel entry point
function.
For example, given the following SYCL kernel entry point function
definition:
```
template<typename KernelNameType, typename KernelType>
[[clang::sycl_kernel_entry_point(KernelNameType)]]
void sycl_kernel_entry_point(KernelType kernel) {
kernel();
}
```
and the following call:
```
struct Kernel {
int dm1;
int dm2;
void operator()() const;
};
Kernel k;
sycl_kernel_entry_point<class kernel_name>(k);
```
the corresponding offload kernel entry point function that is generated
might look as follows (assuming `Kernel` is a type that requires
decomposition):
```
void offload_kernel_entry_point_for_kernel_name(int dm1, int dm2) {
Kernel kernel{dm1, dm2};
kernel();
}
```
Other details of the generated offload kernel entry point function, such
as its name and calling convention, are implementation details that need
not be reflected in the AST and may differ across target devices. For
that reason, only the transformation described above is represented in
the AST; other details will be filled in during code generation.
These transformations are represented using new AST nodes introduced
with this change. `OutlinedFunctionDecl` holds a sequence of
`ImplicitParamDecl` nodes and a sequence of statement nodes that
correspond to the transformed parameters and function body.
`SYCLKernelCallStmt` wraps the original function body and associates it
with an `OutlinedFunctionDecl` instance. For the example above, the AST
generated for the `sycl_kernel_entry_point<kernel_name>` specialization
would look as follows:
```
FunctionDecl 'sycl_kernel_entry_point<kernel_name>(Kernel)'
TemplateArgument type 'kernel_name'
TemplateArgument type 'Kernel'
ParmVarDecl kernel 'Kernel'
SYCLKernelCallStmt
CompoundStmt
<original statements>
OutlinedFunctionDecl
ImplicitParamDecl 'dm1' 'int'
ImplicitParamDecl 'dm2' 'int'
CompoundStmt
VarDecl 'kernel' 'Kernel'
<initialization of 'kernel' with 'dm1' and 'dm2'>
<transformed statements with redirected references of 'kernel'>
```
Any ODR-use of the SYCL kernel entry point function will (with future
changes) suffice for the offload kernel entry point to be emitted. An
actual call to the SYCL kernel entry point function will result in a
call to the function. However, evaluation of a `SYCLKernelCallStmt`
statement is a no-op, so such calls will have no effect other than to
trigger emission of the offload kernel entry point.
Additionally, as a related change inspired by code review feedback,
these changes disallow use of the `sycl_kernel_entry_point` attribute
with functions defined with a _function-try-block_. The SYCL 2020
specification prohibits the use of C++ exceptions in device functions.
Even if exceptions were not prohibited, it is unclear what the semantics
would be for an exception that escapes the SYCL kernel entry point
function; the boundary between host and device code could be an implicit
noexcept boundary that results in program termination if violated, or
the exception could perhaps be propagated to host code via the SYCL
library. Pending support for C++ exceptions in device code and clear
semantics for handling them at the host-device boundary, this change
makes use of the `sycl_kernel_entry_point` attribute with a function
defined with a _function-try-block_ an error.
2025-01-22 16:39:08 -05:00
|
|
|
void StmtProfiler::VisitSYCLKernelCallStmt(const SYCLKernelCallStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
ID.AddBoolean(S->hasEllipsis());
|
|
|
|
if (S->getCatchParamDecl())
|
|
|
|
VisitType(S->getCatchParamDecl()->getType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCAtFinallyStmt(const ObjCAtFinallyStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCAtTryStmt(const ObjCAtTryStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCAtThrowStmt(const ObjCAtThrowStmt *S) {
|
2009-07-28 15:27:13 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitObjCAutoreleasePoolStmt(const ObjCAutoreleasePoolStmt *S) {
|
2011-06-15 23:02:42 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2013-07-19 03:13:43 +00:00
|
|
|
namespace {
|
|
|
|
class OMPClauseProfiler : public ConstOMPClauseVisitor<OMPClauseProfiler> {
|
|
|
|
StmtProfiler *Profiler;
|
2018-05-09 01:00:01 +00:00
|
|
|
/// Process clauses with list of variables.
|
2013-09-24 03:17:45 +00:00
|
|
|
template <typename T>
|
|
|
|
void VisitOMPClauseList(T *Node);
|
2015-12-09 07:52:46 +00:00
|
|
|
|
2013-07-19 03:13:43 +00:00
|
|
|
public:
|
|
|
|
OMPClauseProfiler(StmtProfiler *P) : Profiler(P) { }
|
2020-12-17 14:07:29 -05:00
|
|
|
#define GEN_CLANG_CLAUSE_CLASS
|
|
|
|
#define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
|
|
|
|
#include "llvm/Frontend/OpenMP/OMP.inc"
|
2016-02-16 11:18:12 +00:00
|
|
|
void VistOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
|
2016-02-25 05:25:57 +00:00
|
|
|
void VistOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
|
2013-07-19 03:13:43 +00:00
|
|
|
};
|
|
|
|
|
2016-02-16 11:18:12 +00:00
|
|
|
void OMPClauseProfiler::VistOMPClauseWithPreInit(
|
|
|
|
const OMPClauseWithPreInit *C) {
|
|
|
|
if (auto *S = C->getPreInitStmt())
|
|
|
|
Profiler->VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2016-02-25 05:25:57 +00:00
|
|
|
void OMPClauseProfiler::VistOMPClauseWithPostUpdate(
|
|
|
|
const OMPClauseWithPostUpdate *C) {
|
2016-03-04 07:21:16 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2016-02-25 05:25:57 +00:00
|
|
|
if (auto *E = C->getPostUpdateExpr())
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
|
2014-02-13 05:29:23 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPIfClause(const OMPIfClause *C) {
|
2017-01-18 20:40:48 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2014-02-13 05:29:23 +00:00
|
|
|
if (C->getCondition())
|
|
|
|
Profiler->VisitStmt(C->getCondition());
|
|
|
|
}
|
|
|
|
|
2014-07-17 07:32:53 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPFinalClause(const OMPFinalClause *C) {
|
2019-10-15 19:37:05 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2014-07-17 07:32:53 +00:00
|
|
|
if (C->getCondition())
|
|
|
|
Profiler->VisitStmt(C->getCondition());
|
|
|
|
}
|
|
|
|
|
2014-03-06 06:15:19 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
|
2017-01-25 00:57:16 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2014-03-06 06:15:19 +00:00
|
|
|
if (C->getNumThreads())
|
|
|
|
Profiler->VisitStmt(C->getNumThreads());
|
|
|
|
}
|
|
|
|
|
2021-11-09 07:33:39 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPAlignClause(const OMPAlignClause *C) {
|
|
|
|
if (C->getAlignment())
|
|
|
|
Profiler->VisitStmt(C->getAlignment());
|
|
|
|
}
|
|
|
|
|
2014-03-21 04:51:18 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPSafelenClause(const OMPSafelenClause *C) {
|
|
|
|
if (C->getSafelen())
|
|
|
|
Profiler->VisitStmt(C->getSafelen());
|
2015-08-21 11:14:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void OMPClauseProfiler::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
|
|
|
|
if (C->getSimdlen())
|
|
|
|
Profiler->VisitStmt(C->getSimdlen());
|
2014-03-21 04:51:18 +00:00
|
|
|
}
|
|
|
|
|
2021-02-12 11:26:59 -08:00
|
|
|
void OMPClauseProfiler::VisitOMPSizesClause(const OMPSizesClause *C) {
|
2022-09-03 23:27:27 -07:00
|
|
|
for (auto *E : C->getSizesRefs())
|
2021-02-12 11:26:59 -08:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
2024-10-09 14:56:43 +02:00
|
|
|
void OMPClauseProfiler::VisitOMPPermutationClause(
|
|
|
|
const OMPPermutationClause *C) {
|
|
|
|
for (Expr *E : C->getArgsRefs())
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
2021-06-10 14:24:17 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPFullClause(const OMPFullClause *C) {}
|
|
|
|
|
|
|
|
void OMPClauseProfiler::VisitOMPPartialClause(const OMPPartialClause *C) {
|
|
|
|
if (const Expr *Factor = C->getFactor())
|
|
|
|
Profiler->VisitExpr(Factor);
|
|
|
|
}
|
|
|
|
|
2019-03-12 18:52:33 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
|
|
|
|
if (C->getAllocator())
|
|
|
|
Profiler->VisitStmt(C->getAllocator());
|
|
|
|
}
|
|
|
|
|
2014-05-27 15:12:19 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPCollapseClause(const OMPCollapseClause *C) {
|
|
|
|
if (C->getNumForLoops())
|
|
|
|
Profiler->VisitStmt(C->getNumForLoops());
|
|
|
|
}
|
|
|
|
|
2020-03-17 09:17:42 -04:00
|
|
|
void OMPClauseProfiler::VisitOMPDetachClause(const OMPDetachClause *C) {
|
|
|
|
if (Expr *Evt = C->getEventHandler())
|
|
|
|
Profiler->VisitStmt(Evt);
|
|
|
|
}
|
|
|
|
|
2021-03-31 12:26:47 -07:00
|
|
|
void OMPClauseProfiler::VisitOMPNovariantsClause(const OMPNovariantsClause *C) {
|
|
|
|
VistOMPClauseWithPreInit(C);
|
|
|
|
if (C->getCondition())
|
|
|
|
Profiler->VisitStmt(C->getCondition());
|
|
|
|
}
|
|
|
|
|
2021-04-03 11:09:25 -07:00
|
|
|
void OMPClauseProfiler::VisitOMPNocontextClause(const OMPNocontextClause *C) {
|
|
|
|
VistOMPClauseWithPreInit(C);
|
|
|
|
if (C->getCondition())
|
|
|
|
Profiler->VisitStmt(C->getCondition());
|
|
|
|
}
|
|
|
|
|
2013-07-19 03:13:43 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
|
2013-09-24 03:17:45 +00:00
|
|
|
|
2014-05-06 06:04:14 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
|
|
|
|
|
2018-09-26 04:28:39 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPUnifiedAddressClause(
|
|
|
|
const OMPUnifiedAddressClause *C) {}
|
|
|
|
|
2018-10-01 13:47:43 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPUnifiedSharedMemoryClause(
|
|
|
|
const OMPUnifiedSharedMemoryClause *C) {}
|
|
|
|
|
2018-10-03 20:07:58 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPReverseOffloadClause(
|
|
|
|
const OMPReverseOffloadClause *C) {}
|
|
|
|
|
2018-10-11 14:41:10 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPDynamicAllocatorsClause(
|
|
|
|
const OMPDynamicAllocatorsClause *C) {}
|
|
|
|
|
2018-11-02 12:18:11 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPAtomicDefaultMemOrderClause(
|
|
|
|
const OMPAtomicDefaultMemOrderClause *C) {}
|
|
|
|
|
2022-11-10 18:12:35 -08:00
|
|
|
void OMPClauseProfiler::VisitOMPAtClause(const OMPAtClause *C) {}
|
|
|
|
|
2022-11-16 13:29:14 -08:00
|
|
|
void OMPClauseProfiler::VisitOMPSeverityClause(const OMPSeverityClause *C) {}
|
|
|
|
|
2022-11-17 22:03:00 -08:00
|
|
|
void OMPClauseProfiler::VisitOMPMessageClause(const OMPMessageClause *C) {
|
|
|
|
if (C->getMessageString())
|
|
|
|
Profiler->VisitStmt(C->getMessageString());
|
|
|
|
}
|
|
|
|
|
2014-06-20 07:16:17 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
|
2016-02-16 11:18:12 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
|
|
|
if (auto *S = C->getChunkSize())
|
|
|
|
Profiler->VisitStmt(S);
|
2014-06-20 07:16:17 +00:00
|
|
|
}
|
|
|
|
|
2015-07-30 11:36:16 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPOrderedClause(const OMPOrderedClause *C) {
|
|
|
|
if (auto *Num = C->getNumForLoops())
|
|
|
|
Profiler->VisitStmt(Num);
|
|
|
|
}
|
2014-06-20 09:44:06 +00:00
|
|
|
|
2014-06-20 11:19:47 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPNowaitClause(const OMPNowaitClause *) {}
|
|
|
|
|
2014-07-17 12:19:31 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPUntiedClause(const OMPUntiedClause *) {}
|
|
|
|
|
2014-07-17 12:47:03 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPMergeableClause(const OMPMergeableClause *) {}
|
|
|
|
|
2014-07-23 02:27:21 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPReadClause(const OMPReadClause *) {}
|
|
|
|
|
2014-07-23 07:46:59 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPWriteClause(const OMPWriteClause *) {}
|
|
|
|
|
2014-07-23 10:25:33 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPUpdateClause(const OMPUpdateClause *) {}
|
|
|
|
|
2014-07-24 06:46:57 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPCaptureClause(const OMPCaptureClause *) {}
|
|
|
|
|
2021-12-24 08:16:33 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPCompareClause(const OMPCompareClause *) {}
|
|
|
|
|
2023-11-26 13:33:36 -06:00
|
|
|
void OMPClauseProfiler::VisitOMPFailClause(const OMPFailClause *) {}
|
|
|
|
|
2024-08-05 12:37:07 +01:00
|
|
|
void OMPClauseProfiler::VisitOMPAbsentClause(const OMPAbsentClause *) {}
|
|
|
|
|
|
|
|
void OMPClauseProfiler::VisitOMPHoldsClause(const OMPHoldsClause *) {}
|
|
|
|
|
|
|
|
void OMPClauseProfiler::VisitOMPContainsClause(const OMPContainsClause *) {}
|
|
|
|
|
|
|
|
void OMPClauseProfiler::VisitOMPNoOpenMPClause(const OMPNoOpenMPClause *) {}
|
|
|
|
|
|
|
|
void OMPClauseProfiler::VisitOMPNoOpenMPRoutinesClause(
|
|
|
|
const OMPNoOpenMPRoutinesClause *) {}
|
|
|
|
|
2025-02-06 12:41:10 -08:00
|
|
|
void OMPClauseProfiler::VisitOMPNoOpenMPConstructsClause(
|
|
|
|
const OMPNoOpenMPConstructsClause *) {}
|
|
|
|
|
2024-08-05 12:37:07 +01:00
|
|
|
void OMPClauseProfiler::VisitOMPNoParallelismClause(
|
|
|
|
const OMPNoParallelismClause *) {}
|
|
|
|
|
2014-07-24 08:55:34 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
|
|
|
|
|
2020-02-06 16:30:23 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
|
|
|
|
|
2020-02-10 14:30:39 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPAcquireClause(const OMPAcquireClause *) {}
|
|
|
|
|
2020-02-10 15:49:05 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPReleaseClause(const OMPReleaseClause *) {}
|
|
|
|
|
2020-02-11 11:10:43 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
|
|
|
|
|
2024-01-31 17:02:06 +05:30
|
|
|
void OMPClauseProfiler::VisitOMPWeakClause(const OMPWeakClause *) {}
|
|
|
|
|
2015-09-25 10:37:12 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {}
|
|
|
|
|
2015-09-28 06:39:35 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {}
|
|
|
|
|
2015-12-07 10:51:44 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPNogroupClause(const OMPNogroupClause *) {}
|
|
|
|
|
2021-03-15 13:09:46 -07:00
|
|
|
void OMPClauseProfiler::VisitOMPInitClause(const OMPInitClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
|
|
|
|
2021-03-17 13:04:08 -07:00
|
|
|
void OMPClauseProfiler::VisitOMPUseClause(const OMPUseClause *C) {
|
|
|
|
if (C->getInteropVar())
|
|
|
|
Profiler->VisitStmt(C->getInteropVar());
|
|
|
|
}
|
|
|
|
|
2021-03-17 16:43:47 -07:00
|
|
|
void OMPClauseProfiler::VisitOMPDestroyClause(const OMPDestroyClause *C) {
|
|
|
|
if (C->getInteropVar())
|
|
|
|
Profiler->VisitStmt(C->getInteropVar());
|
|
|
|
}
|
2020-03-02 14:21:20 -05:00
|
|
|
|
2021-04-09 14:00:36 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPFilterClause(const OMPFilterClause *C) {
|
|
|
|
VistOMPClauseWithPreInit(C);
|
|
|
|
if (C->getThreadID())
|
|
|
|
Profiler->VisitStmt(C->getThreadID());
|
|
|
|
}
|
|
|
|
|
2013-09-24 03:17:45 +00:00
|
|
|
template<typename T>
|
|
|
|
void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
|
2024-07-30 08:11:09 -05:00
|
|
|
for (auto *E : Node->varlist()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2014-10-21 03:16:40 +00:00
|
|
|
}
|
2013-09-24 03:17:45 +00:00
|
|
|
}
|
2013-07-19 03:13:43 +00:00
|
|
|
|
|
|
|
void OMPClauseProfiler::VisitOMPPrivateClause(const OMPPrivateClause *C) {
|
2013-09-24 03:17:45 +00:00
|
|
|
VisitOMPClauseList(C);
|
2014-10-21 03:16:40 +00:00
|
|
|
for (auto *E : C->private_copies()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2014-10-21 03:16:40 +00:00
|
|
|
}
|
2013-07-19 03:13:43 +00:00
|
|
|
}
|
2014-10-08 14:01:46 +00:00
|
|
|
void
|
|
|
|
OMPClauseProfiler::VisitOMPFirstprivateClause(const OMPFirstprivateClause *C) {
|
2013-10-01 05:32:34 +00:00
|
|
|
VisitOMPClauseList(C);
|
2016-02-17 13:19:37 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2014-10-08 14:01:46 +00:00
|
|
|
for (auto *E : C->private_copies()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2014-10-08 14:01:46 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->inits()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2014-10-08 14:01:46 +00:00
|
|
|
}
|
2013-10-01 05:32:34 +00:00
|
|
|
}
|
2014-06-04 13:06:39 +00:00
|
|
|
void
|
|
|
|
OMPClauseProfiler::VisitOMPLastprivateClause(const OMPLastprivateClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
2016-02-25 05:25:57 +00:00
|
|
|
VistOMPClauseWithPostUpdate(C);
|
2015-04-16 04:54:05 +00:00
|
|
|
for (auto *E : C->source_exprs()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 04:54:05 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->destination_exprs()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 04:54:05 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->assignment_ops()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 04:54:05 +00:00
|
|
|
}
|
2014-06-04 13:06:39 +00:00
|
|
|
}
|
2013-09-06 18:03:48 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause *C) {
|
2013-09-24 03:17:45 +00:00
|
|
|
VisitOMPClauseList(C);
|
2013-09-06 18:03:48 +00:00
|
|
|
}
|
2014-06-16 07:08:35 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPReductionClause(
|
|
|
|
const OMPReductionClause *C) {
|
|
|
|
Profiler->VisitNestedNameSpecifier(
|
|
|
|
C->getQualifierLoc().getNestedNameSpecifier());
|
2017-07-18 20:17:46 +00:00
|
|
|
Profiler->VisitName(C->getNameInfo().getName());
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
VistOMPClauseWithPostUpdate(C);
|
|
|
|
for (auto *E : C->privates()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
for (auto *E : C->lhs_exprs()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
for (auto *E : C->rhs_exprs()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
for (auto *E : C->reduction_ops()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
2020-05-04 16:19:31 -04:00
|
|
|
if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
|
|
|
|
for (auto *E : C->copy_ops()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
for (auto *E : C->copy_array_temps()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
for (auto *E : C->copy_array_elems()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
}
|
2017-07-18 20:17:46 +00:00
|
|
|
}
|
|
|
|
void OMPClauseProfiler::VisitOMPTaskReductionClause(
|
|
|
|
const OMPTaskReductionClause *C) {
|
|
|
|
Profiler->VisitNestedNameSpecifier(
|
|
|
|
C->getQualifierLoc().getNestedNameSpecifier());
|
2017-07-21 18:48:21 +00:00
|
|
|
Profiler->VisitName(C->getNameInfo().getName());
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
VistOMPClauseWithPostUpdate(C);
|
|
|
|
for (auto *E : C->privates()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
for (auto *E : C->lhs_exprs()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
for (auto *E : C->rhs_exprs()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
for (auto *E : C->reduction_ops()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void OMPClauseProfiler::VisitOMPInReductionClause(
|
|
|
|
const OMPInReductionClause *C) {
|
|
|
|
Profiler->VisitNestedNameSpecifier(
|
|
|
|
C->getQualifierLoc().getNestedNameSpecifier());
|
2014-06-16 07:08:35 +00:00
|
|
|
Profiler->VisitName(C->getNameInfo().getName());
|
|
|
|
VisitOMPClauseList(C);
|
2016-03-02 04:57:40 +00:00
|
|
|
VistOMPClauseWithPostUpdate(C);
|
2015-10-08 09:10:53 +00:00
|
|
|
for (auto *E : C->privates()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-10-08 09:10:53 +00:00
|
|
|
}
|
[OPENMP] Codegen for 'reduction' clause in 'parallel' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:
static kmp_critical_name lock = { 0 };
void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
...
*(Type<i> *)lhs[i] = RedOp<i>(*(Type<i> *)lhs[i], *(Type<i> *)rhs[i]);
...
}
... void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n> - 1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
...
<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
...
__kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
break;
case 2:
...
Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
...
break;
default:
;
}
Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
Differential Revision: http://reviews.llvm.org/D8915
llvm-svn: 234583
2015-04-10 10:43:45 +00:00
|
|
|
for (auto *E : C->lhs_exprs()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
[OPENMP] Codegen for 'reduction' clause in 'parallel' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:
static kmp_critical_name lock = { 0 };
void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
...
*(Type<i> *)lhs[i] = RedOp<i>(*(Type<i> *)lhs[i], *(Type<i> *)rhs[i]);
...
}
... void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n> - 1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
...
<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
...
__kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
break;
case 2:
...
Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
...
break;
default:
;
}
Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
Differential Revision: http://reviews.llvm.org/D8915
llvm-svn: 234583
2015-04-10 10:43:45 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->rhs_exprs()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
[OPENMP] Codegen for 'reduction' clause in 'parallel' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:
static kmp_critical_name lock = { 0 };
void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
...
*(Type<i> *)lhs[i] = RedOp<i>(*(Type<i> *)lhs[i], *(Type<i> *)rhs[i]);
...
}
... void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n> - 1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
...
<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
...
__kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
break;
case 2:
...
Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
...
break;
default:
;
}
Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
Differential Revision: http://reviews.llvm.org/D8915
llvm-svn: 234583
2015-04-10 10:43:45 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->reduction_ops()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
[OPENMP] Codegen for 'reduction' clause in 'parallel' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:
static kmp_critical_name lock = { 0 };
void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
...
*(Type<i> *)lhs[i] = RedOp<i>(*(Type<i> *)lhs[i], *(Type<i> *)rhs[i]);
...
}
... void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n> - 1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
...
<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
...
__kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
break;
case 2:
...
Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
...
break;
default:
;
}
Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
Differential Revision: http://reviews.llvm.org/D8915
llvm-svn: 234583
2015-04-10 10:43:45 +00:00
|
|
|
}
|
2017-07-27 13:20:36 +00:00
|
|
|
for (auto *E : C->taskgroup_descriptors()) {
|
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
2014-06-16 07:08:35 +00:00
|
|
|
}
|
2014-04-22 13:09:42 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
2016-03-09 09:49:00 +00:00
|
|
|
VistOMPClauseWithPostUpdate(C);
|
2015-08-18 06:47:21 +00:00
|
|
|
for (auto *E : C->privates()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-08-18 06:47:21 +00:00
|
|
|
}
|
2015-03-21 10:12:56 +00:00
|
|
|
for (auto *E : C->inits()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-21 10:12:56 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->updates()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-21 10:12:56 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->finals()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-21 10:12:56 +00:00
|
|
|
}
|
2016-06-10 04:52:09 +00:00
|
|
|
if (C->getStep())
|
|
|
|
Profiler->VisitStmt(C->getStep());
|
|
|
|
if (C->getCalcStep())
|
|
|
|
Profiler->VisitStmt(C->getCalcStep());
|
2014-04-22 13:09:42 +00:00
|
|
|
}
|
2014-05-29 14:36:25 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
2016-06-10 04:52:09 +00:00
|
|
|
if (C->getAlignment())
|
|
|
|
Profiler->VisitStmt(C->getAlignment());
|
2014-05-29 14:36:25 +00:00
|
|
|
}
|
2014-03-31 03:36:38 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
2015-04-16 05:39:01 +00:00
|
|
|
for (auto *E : C->source_exprs()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 05:39:01 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->destination_exprs()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 05:39:01 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->assignment_ops()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-04-16 05:39:01 +00:00
|
|
|
}
|
2014-03-31 03:36:38 +00:00
|
|
|
}
|
2014-06-27 10:37:06 +00:00
|
|
|
void
|
|
|
|
OMPClauseProfiler::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
2015-03-23 06:18:07 +00:00
|
|
|
for (auto *E : C->source_exprs()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-23 06:18:07 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->destination_exprs()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-23 06:18:07 +00:00
|
|
|
}
|
|
|
|
for (auto *E : C->assignment_ops()) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (E)
|
|
|
|
Profiler->VisitStmt(E);
|
2015-03-23 06:18:07 +00:00
|
|
|
}
|
2014-06-27 10:37:06 +00:00
|
|
|
}
|
2014-07-21 11:26:11 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPFlushClause(const OMPFlushClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2020-02-28 09:52:15 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPDepobjClause(const OMPDepobjClause *C) {
|
|
|
|
if (const Expr *Depobj = C->getDepobj())
|
|
|
|
Profiler->VisitStmt(Depobj);
|
|
|
|
}
|
2015-06-23 14:25:19 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPDependClause(const OMPDependClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2015-08-07 16:16:36 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPDeviceClause(const OMPDeviceClause *C) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (C->getDevice())
|
|
|
|
Profiler->VisitStmt(C->getDevice());
|
2015-08-07 16:16:36 +00:00
|
|
|
}
|
2015-11-23 05:32:03 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPMapClause(const OMPMapClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2019-03-27 14:14:31 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPAllocateClause(const OMPAllocateClause *C) {
|
|
|
|
if (Expr *Allocator = C->getAllocator())
|
|
|
|
Profiler->VisitStmt(Allocator);
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2015-11-24 20:50:12 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
|
2024-08-06 10:55:15 -04:00
|
|
|
VisitOMPClauseList(C);
|
2017-01-25 11:28:18 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2015-11-24 20:50:12 +00:00
|
|
|
}
|
2015-11-27 18:47:36 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPThreadLimitClause(
|
|
|
|
const OMPThreadLimitClause *C) {
|
2024-08-10 09:54:58 -04:00
|
|
|
VisitOMPClauseList(C);
|
2017-01-25 11:44:35 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2015-11-27 18:47:36 +00:00
|
|
|
}
|
2015-12-01 10:17:31 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPPriorityClause(const OMPPriorityClause *C) {
|
2019-10-16 18:09:37 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2016-06-10 04:52:09 +00:00
|
|
|
if (C->getPriority())
|
|
|
|
Profiler->VisitStmt(C->getPriority());
|
2015-12-01 10:17:31 +00:00
|
|
|
}
|
2015-12-07 12:52:51 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
|
2019-10-14 19:29:52 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2016-06-10 04:52:09 +00:00
|
|
|
if (C->getGrainsize())
|
|
|
|
Profiler->VisitStmt(C->getGrainsize());
|
2015-12-07 12:52:51 +00:00
|
|
|
}
|
2015-12-08 12:06:20 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
|
2019-10-14 20:44:34 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
2016-06-10 04:52:09 +00:00
|
|
|
if (C->getNumTasks())
|
|
|
|
Profiler->VisitStmt(C->getNumTasks());
|
2015-12-08 12:06:20 +00:00
|
|
|
}
|
2015-12-15 08:19:24 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPHintClause(const OMPHintClause *C) {
|
2016-06-10 04:52:09 +00:00
|
|
|
if (C->getHint())
|
|
|
|
Profiler->VisitStmt(C->getHint());
|
2015-12-15 08:19:24 +00:00
|
|
|
}
|
2016-05-26 17:39:58 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPToClause(const OMPToClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2016-05-26 17:49:04 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPFromClause(const OMPFromClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2016-07-13 15:37:16 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPUseDevicePtrClause(
|
|
|
|
const OMPUseDevicePtrClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2020-05-21 08:30:23 -04:00
|
|
|
void OMPClauseProfiler::VisitOMPUseDeviceAddrClause(
|
|
|
|
const OMPUseDeviceAddrClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2016-07-13 17:16:49 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPIsDevicePtrClause(
|
|
|
|
const OMPIsDevicePtrClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2022-04-06 20:30:44 -07:00
|
|
|
void OMPClauseProfiler::VisitOMPHasDeviceAddrClause(
|
|
|
|
const OMPHasDeviceAddrClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2019-12-19 10:01:10 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPNontemporalClause(
|
|
|
|
const OMPNontemporalClause *C) {
|
2019-12-16 15:54:17 -05:00
|
|
|
VisitOMPClauseList(C);
|
2019-12-19 10:01:10 -05:00
|
|
|
for (auto *E : C->private_refs())
|
|
|
|
Profiler->VisitStmt(E);
|
2019-12-16 15:54:17 -05:00
|
|
|
}
|
2020-03-20 09:41:22 -04:00
|
|
|
void OMPClauseProfiler::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2020-03-23 10:41:08 -04:00
|
|
|
void OMPClauseProfiler::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2020-04-21 13:21:00 -04:00
|
|
|
void OMPClauseProfiler::VisitOMPUsesAllocatorsClause(
|
|
|
|
const OMPUsesAllocatorsClause *C) {
|
|
|
|
for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
|
|
|
|
OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
|
|
|
|
Profiler->VisitStmt(D.Allocator);
|
|
|
|
if (D.AllocatorTraits)
|
|
|
|
Profiler->VisitStmt(D.AllocatorTraits);
|
|
|
|
}
|
|
|
|
}
|
2020-05-18 13:37:53 -04:00
|
|
|
void OMPClauseProfiler::VisitOMPAffinityClause(const OMPAffinityClause *C) {
|
|
|
|
if (const Expr *Modifier = C->getModifier())
|
|
|
|
Profiler->VisitStmt(Modifier);
|
2024-07-30 08:11:09 -05:00
|
|
|
for (const Expr *E : C->varlist())
|
2020-05-18 13:37:53 -04:00
|
|
|
Profiler->VisitStmt(E);
|
|
|
|
}
|
2020-01-31 16:09:26 -05:00
|
|
|
void OMPClauseProfiler::VisitOMPOrderClause(const OMPOrderClause *C) {}
|
2021-11-03 14:57:01 -07:00
|
|
|
void OMPClauseProfiler::VisitOMPBindClause(const OMPBindClause *C) {}
|
2023-01-07 16:14:48 -08:00
|
|
|
void OMPClauseProfiler::VisitOMPXDynCGroupMemClause(
|
|
|
|
const OMPXDynCGroupMemClause *C) {
|
|
|
|
VistOMPClauseWithPreInit(C);
|
|
|
|
if (Expr *Size = C->getSize())
|
|
|
|
Profiler->VisitStmt(Size);
|
|
|
|
}
|
2023-06-21 16:26:35 -07:00
|
|
|
void OMPClauseProfiler::VisitOMPDoacrossClause(const OMPDoacrossClause *C) {
|
|
|
|
VisitOMPClauseList(C);
|
|
|
|
}
|
2023-07-25 09:37:49 -07:00
|
|
|
void OMPClauseProfiler::VisitOMPXAttributeClause(const OMPXAttributeClause *C) {
|
|
|
|
}
|
Introduce the initial support for OpenMP kernel language (#66844)
This patch starts the support for OpenMP kernel language, basically to write
OpenMP target region in SIMT style, similar to kernel languages such as CUDA.
What included in this first patch is the `ompx_bare` clause for `target teams`
directive. When `ompx_bare` exists, globalization is disabled such that local
variables will not be globalized. The runtime init/deinit function calls will
not be emitted. That being said, almost all OpenMP executable directives are
not supported in the region, such as parallel, task. This patch doesn't include
the Sema checks for that, so the use of them is UB. Simple directives, such as
atomic, can be used. We provide a set of APIs (for C, they are prefix with
`ompx_`; for C++, they are in `ompx` namespace) to get thread id, block id, etc.
Please refer to
https://tianshilei.me/wp-content/uploads/llvm-hpc-2023.pdf for more details.
2023-10-05 17:34:40 -04:00
|
|
|
void OMPClauseProfiler::VisitOMPXBareClause(const OMPXBareClause *C) {}
|
2019-12-19 10:01:10 -05:00
|
|
|
} // namespace
|
2013-07-19 03:13:43 +00:00
|
|
|
|
|
|
|
void
|
2014-02-27 08:29:12 +00:00
|
|
|
StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) {
|
2013-07-19 03:13:43 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
OMPClauseProfiler P(this);
|
|
|
|
ArrayRef<OMPClause *> Clauses = S->clauses();
|
|
|
|
for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
|
|
|
|
I != E; ++I)
|
|
|
|
if (*I)
|
|
|
|
P.Visit(*I);
|
|
|
|
}
|
|
|
|
|
2021-03-03 17:15:32 -06:00
|
|
|
void StmtProfiler::VisitOMPCanonicalLoop(const OMPCanonicalLoop *L) {
|
|
|
|
VisitStmt(L);
|
|
|
|
}
|
|
|
|
|
2021-02-12 11:26:59 -08:00
|
|
|
void StmtProfiler::VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *S) {
|
2014-08-19 11:27:13 +00:00
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2021-02-12 11:26:59 -08:00
|
|
|
void StmtProfiler::VisitOMPLoopDirective(const OMPLoopDirective *S) {
|
|
|
|
VisitOMPLoopBasedDirective(S);
|
|
|
|
}
|
|
|
|
|
2021-09-17 16:03:01 -05:00
|
|
|
void StmtProfiler::VisitOMPMetaDirective(const OMPMetaDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-02-27 08:29:12 +00:00
|
|
|
void StmtProfiler::VisitOMPParallelDirective(const OMPParallelDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitOMPSimdDirective(const OMPSimdDirective *S) {
|
2014-08-19 11:27:13 +00:00
|
|
|
VisitOMPLoopDirective(S);
|
2014-02-27 08:29:12 +00:00
|
|
|
}
|
|
|
|
|
2021-10-06 10:02:27 -05:00
|
|
|
void StmtProfiler::VisitOMPLoopTransformationDirective(
|
|
|
|
const OMPLoopTransformationDirective *S) {
|
2021-02-12 11:26:59 -08:00
|
|
|
VisitOMPLoopBasedDirective(S);
|
|
|
|
}
|
|
|
|
|
2021-10-06 10:02:27 -05:00
|
|
|
void StmtProfiler::VisitOMPTileDirective(const OMPTileDirective *S) {
|
|
|
|
VisitOMPLoopTransformationDirective(S);
|
|
|
|
}
|
|
|
|
|
2025-02-13 07:14:36 -05:00
|
|
|
void StmtProfiler::VisitOMPStripeDirective(const OMPStripeDirective *S) {
|
|
|
|
VisitOMPLoopTransformationDirective(S);
|
|
|
|
}
|
|
|
|
|
2021-06-10 14:24:17 -05:00
|
|
|
void StmtProfiler::VisitOMPUnrollDirective(const OMPUnrollDirective *S) {
|
2021-10-06 10:02:27 -05:00
|
|
|
VisitOMPLoopTransformationDirective(S);
|
2021-06-10 14:24:17 -05:00
|
|
|
}
|
|
|
|
|
2024-07-18 10:35:32 +02:00
|
|
|
void StmtProfiler::VisitOMPReverseDirective(const OMPReverseDirective *S) {
|
|
|
|
VisitOMPLoopTransformationDirective(S);
|
|
|
|
}
|
|
|
|
|
2024-07-19 09:24:40 +02:00
|
|
|
void StmtProfiler::VisitOMPInterchangeDirective(
|
|
|
|
const OMPInterchangeDirective *S) {
|
|
|
|
VisitOMPLoopTransformationDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-06-18 04:14:57 +00:00
|
|
|
void StmtProfiler::VisitOMPForDirective(const OMPForDirective *S) {
|
2014-08-19 11:27:13 +00:00
|
|
|
VisitOMPLoopDirective(S);
|
2014-06-18 04:14:57 +00:00
|
|
|
}
|
|
|
|
|
2014-09-18 05:12:34 +00:00
|
|
|
void StmtProfiler::VisitOMPForSimdDirective(const OMPForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-06-25 11:44:49 +00:00
|
|
|
void StmtProfiler::VisitOMPSectionsDirective(const OMPSectionsDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-06-26 08:21:58 +00:00
|
|
|
void StmtProfiler::VisitOMPSectionDirective(const OMPSectionDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2023-08-09 15:28:09 -07:00
|
|
|
void StmtProfiler::VisitOMPScopeDirective(const OMPScopeDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-06-26 12:05:45 +00:00
|
|
|
void StmtProfiler::VisitOMPSingleDirective(const OMPSingleDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-17 08:54:58 +00:00
|
|
|
void StmtProfiler::VisitOMPMasterDirective(const OMPMasterDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-21 09:42:05 +00:00
|
|
|
void StmtProfiler::VisitOMPCriticalDirective(const OMPCriticalDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
VisitName(S->getDirectiveName().getName());
|
|
|
|
}
|
|
|
|
|
2014-07-07 13:01:15 +00:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitOMPParallelForDirective(const OMPParallelForDirective *S) {
|
2014-08-19 11:27:13 +00:00
|
|
|
VisitOMPLoopDirective(S);
|
2014-07-07 13:01:15 +00:00
|
|
|
}
|
|
|
|
|
2014-09-23 09:33:00 +00:00
|
|
|
void StmtProfiler::VisitOMPParallelForSimdDirective(
|
|
|
|
const OMPParallelForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2019-12-05 13:43:48 -05:00
|
|
|
void StmtProfiler::VisitOMPParallelMasterDirective(
|
|
|
|
const OMPParallelMasterDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2022-06-16 16:32:30 -07:00
|
|
|
void StmtProfiler::VisitOMPParallelMaskedDirective(
|
|
|
|
const OMPParallelMaskedDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-08 08:12:03 +00:00
|
|
|
void StmtProfiler::VisitOMPParallelSectionsDirective(
|
|
|
|
const OMPParallelSectionsDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-11 11:25:16 +00:00
|
|
|
void StmtProfiler::VisitOMPTaskDirective(const OMPTaskDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-18 07:47:19 +00:00
|
|
|
void StmtProfiler::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-18 09:11:51 +00:00
|
|
|
void StmtProfiler::VisitOMPBarrierDirective(const OMPBarrierDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-18 10:17:07 +00:00
|
|
|
void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2024-08-05 12:37:07 +01:00
|
|
|
void StmtProfiler::VisitOMPAssumeDirective(const OMPAssumeDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2022-11-01 14:46:12 -07:00
|
|
|
void StmtProfiler::VisitOMPErrorDirective(const OMPErrorDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
2015-06-18 12:14:09 +00:00
|
|
|
void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
2017-07-25 15:53:26 +00:00
|
|
|
if (const Expr *E = S->getReductionRef())
|
|
|
|
VisitStmt(E);
|
2015-06-18 12:14:09 +00:00
|
|
|
}
|
|
|
|
|
2014-07-21 11:26:11 +00:00
|
|
|
void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2020-02-28 09:52:15 -05:00
|
|
|
void StmtProfiler::VisitOMPDepobjDirective(const OMPDepobjDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2020-03-20 07:03:01 -04:00
|
|
|
void StmtProfiler::VisitOMPScanDirective(const OMPScanDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-22 06:45:04 +00:00
|
|
|
void StmtProfiler::VisitOMPOrderedDirective(const OMPOrderedDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-07-22 10:10:35 +00:00
|
|
|
void StmtProfiler::VisitOMPAtomicDirective(const OMPAtomicDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-09-19 08:19:49 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetDirective(const OMPTargetDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-07-21 13:44:28 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetDataDirective(const OMPTargetDataDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-01-19 19:15:56 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetEnterDataDirective(
|
|
|
|
const OMPTargetEnterDataDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-01-19 20:04:50 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetExitDataDirective(
|
|
|
|
const OMPTargetExitDataDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-01-26 18:48:41 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetParallelDirective(
|
|
|
|
const OMPTargetParallelDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-02-03 15:46:42 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetParallelForDirective(
|
|
|
|
const OMPTargetParallelForDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2014-10-09 04:18:56 +00:00
|
|
|
void StmtProfiler::VisitOMPTeamsDirective(const OMPTeamsDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-07-01 06:57:41 +00:00
|
|
|
void StmtProfiler::VisitOMPCancellationPointDirective(
|
|
|
|
const OMPCancellationPointDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-07-02 11:25:17 +00:00
|
|
|
void StmtProfiler::VisitOMPCancelDirective(const OMPCancelDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-12-01 04:18:41 +00:00
|
|
|
void StmtProfiler::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-12-03 09:40:15 +00:00
|
|
|
void StmtProfiler::VisitOMPTaskLoopSimdDirective(
|
|
|
|
const OMPTaskLoopSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2019-10-10 20:13:02 +00:00
|
|
|
void StmtProfiler::VisitOMPMasterTaskLoopDirective(
|
|
|
|
const OMPMasterTaskLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
2022-06-24 08:42:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitOMPMaskedTaskLoopDirective(
|
|
|
|
const OMPMaskedTaskLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
2019-10-10 20:13:02 +00:00
|
|
|
}
|
|
|
|
|
2019-10-18 16:47:35 +00:00
|
|
|
void StmtProfiler::VisitOMPMasterTaskLoopSimdDirective(
|
|
|
|
const OMPMasterTaskLoopSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2022-06-28 14:35:43 -07:00
|
|
|
void StmtProfiler::VisitOMPMaskedTaskLoopSimdDirective(
|
|
|
|
const OMPMaskedTaskLoopSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2019-10-14 17:17:41 +00:00
|
|
|
void StmtProfiler::VisitOMPParallelMasterTaskLoopDirective(
|
|
|
|
const OMPParallelMasterTaskLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2022-06-30 10:59:33 -07:00
|
|
|
void StmtProfiler::VisitOMPParallelMaskedTaskLoopDirective(
|
|
|
|
const OMPParallelMaskedTaskLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2019-10-25 10:27:13 -04:00
|
|
|
void StmtProfiler::VisitOMPParallelMasterTaskLoopSimdDirective(
|
|
|
|
const OMPParallelMasterTaskLoopSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2022-06-30 17:08:17 -07:00
|
|
|
void StmtProfiler::VisitOMPParallelMaskedTaskLoopSimdDirective(
|
|
|
|
const OMPParallelMaskedTaskLoopSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2015-12-14 14:51:25 +00:00
|
|
|
void StmtProfiler::VisitOMPDistributeDirective(
|
|
|
|
const OMPDistributeDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-01-15 18:50:31 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPDistScheduleClause(
|
|
|
|
const OMPDistScheduleClause *C) {
|
2016-02-16 11:18:12 +00:00
|
|
|
VistOMPClauseWithPreInit(C);
|
|
|
|
if (auto *S = C->getChunkSize())
|
|
|
|
Profiler->VisitStmt(S);
|
2016-01-15 18:50:31 +00:00
|
|
|
}
|
|
|
|
|
2016-01-26 16:37:23 +00:00
|
|
|
void OMPClauseProfiler::VisitOMPDefaultmapClause(const OMPDefaultmapClause *) {}
|
|
|
|
|
2016-05-26 17:30:50 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetUpdateDirective(
|
|
|
|
const OMPTargetUpdateDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-06-27 14:55:37 +00:00
|
|
|
void StmtProfiler::VisitOMPDistributeParallelForDirective(
|
|
|
|
const OMPDistributeParallelForDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-07-05 05:00:15 +00:00
|
|
|
void StmtProfiler::VisitOMPDistributeParallelForSimdDirective(
|
|
|
|
const OMPDistributeParallelForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-07-06 04:45:38 +00:00
|
|
|
void StmtProfiler::VisitOMPDistributeSimdDirective(
|
|
|
|
const OMPDistributeSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-07-14 02:54:56 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetParallelForSimdDirective(
|
|
|
|
const OMPTargetParallelForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-07-20 22:57:10 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetSimdDirective(
|
|
|
|
const OMPTargetSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-08-05 14:37:37 +00:00
|
|
|
void StmtProfiler::VisitOMPTeamsDistributeDirective(
|
|
|
|
const OMPTeamsDistributeDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-10-25 12:50:55 +00:00
|
|
|
void StmtProfiler::VisitOMPTeamsDistributeSimdDirective(
|
|
|
|
const OMPTeamsDistributeSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-11-30 23:51:03 +00:00
|
|
|
void StmtProfiler::VisitOMPTeamsDistributeParallelForSimdDirective(
|
|
|
|
const OMPTeamsDistributeParallelForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-12-09 03:24:30 +00:00
|
|
|
void StmtProfiler::VisitOMPTeamsDistributeParallelForDirective(
|
|
|
|
const OMPTeamsDistributeParallelForDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-12-17 05:48:59 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsDirective(
|
|
|
|
const OMPTargetTeamsDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-12-25 04:52:54 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsDistributeDirective(
|
|
|
|
const OMPTargetTeamsDistributeDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2016-12-29 22:16:30 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForDirective(
|
|
|
|
const OMPTargetTeamsDistributeParallelForDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2017-01-03 05:23:48 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
|
|
|
|
const OMPTargetTeamsDistributeParallelForSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2017-01-10 18:08:18 +00:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsDistributeSimdDirective(
|
|
|
|
const OMPTargetTeamsDistributeSimdDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2021-03-15 13:09:46 -07:00
|
|
|
void StmtProfiler::VisitOMPInteropDirective(const OMPInteropDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2021-03-22 18:13:29 -07:00
|
|
|
void StmtProfiler::VisitOMPDispatchDirective(const OMPDispatchDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2021-04-09 14:00:36 -05:00
|
|
|
void StmtProfiler::VisitOMPMaskedDirective(const OMPMaskedDirective *S) {
|
|
|
|
VisitOMPExecutableDirective(S);
|
|
|
|
}
|
|
|
|
|
2021-10-28 08:10:40 -07:00
|
|
|
void StmtProfiler::VisitOMPGenericLoopDirective(
|
|
|
|
const OMPGenericLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2022-03-15 08:35:59 -07:00
|
|
|
void StmtProfiler::VisitOMPTeamsGenericLoopDirective(
|
|
|
|
const OMPTeamsGenericLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2022-03-18 11:02:02 -07:00
|
|
|
void StmtProfiler::VisitOMPTargetTeamsGenericLoopDirective(
|
|
|
|
const OMPTargetTeamsGenericLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2022-03-22 10:55:21 -07:00
|
|
|
void StmtProfiler::VisitOMPParallelGenericLoopDirective(
|
|
|
|
const OMPParallelGenericLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2022-03-23 15:37:06 -07:00
|
|
|
void StmtProfiler::VisitOMPTargetParallelGenericLoopDirective(
|
|
|
|
const OMPTargetParallelGenericLoopDirective *S) {
|
|
|
|
VisitOMPLoopDirective(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitExpr(const Expr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2018-10-31 03:48:47 +00:00
|
|
|
void StmtProfiler::VisitConstantExpr(const ConstantExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
2010-07-13 08:37:11 +00:00
|
|
|
if (!Canonical)
|
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitDecl(S->getDecl());
|
2018-02-13 19:53:40 +00:00
|
|
|
if (!Canonical) {
|
|
|
|
ID.AddBoolean(S->hasExplicitTemplateArgs());
|
|
|
|
if (S->hasExplicitTemplateArgs())
|
|
|
|
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
|
|
|
|
}
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2021-04-23 08:22:35 -07:00
|
|
|
void StmtProfiler::VisitSYCLUniqueStableNameExpr(
|
|
|
|
const SYCLUniqueStableNameExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitType(S->getTypeSourceInfo()->getType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
2023-11-05 15:36:50 +03:00
|
|
|
ID.AddInteger(llvm::to_underlying(S->getIdentKind()));
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2024-10-03 08:34:43 -07:00
|
|
|
void StmtProfiler::VisitOpenACCAsteriskSizeExpr(
|
|
|
|
const OpenACCAsteriskSizeExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitIntegerLiteral(const IntegerLiteral *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
S->getValue().Profile(ID);
|
2023-09-20 05:06:45 -05:00
|
|
|
|
|
|
|
QualType T = S->getType();
|
2023-10-02 10:03:32 +02:00
|
|
|
if (Canonical)
|
|
|
|
T = T.getCanonicalType();
|
2023-09-20 05:06:45 -05:00
|
|
|
ID.AddInteger(T->getTypeClass());
|
|
|
|
if (auto BitIntT = T->getAs<BitIntType>())
|
|
|
|
BitIntT->Profile(ID);
|
|
|
|
else
|
|
|
|
ID.AddInteger(T->castAs<BuiltinType>()->getKind());
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2018-06-20 17:19:40 +00:00
|
|
|
void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
S->getValue().Profile(ID);
|
|
|
|
ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
2023-11-05 13:35:38 +03:00
|
|
|
ID.AddInteger(llvm::to_underlying(S->getKind()));
|
2009-07-28 00:33:38 +00:00
|
|
|
ID.AddInteger(S->getValue());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitFloatingLiteral(const FloatingLiteral *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
S->getValue().Profile(ID);
|
|
|
|
ID.AddBoolean(S->isExact());
|
2014-11-20 03:37:32 +00:00
|
|
|
ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitImaginaryLiteral(const ImaginaryLiteral *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitStringLiteral(const StringLiteral *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
2011-11-02 17:26:05 +00:00
|
|
|
ID.AddString(S->getBytes());
|
2023-11-05 12:27:31 +03:00
|
|
|
ID.AddInteger(llvm::to_underlying(S->getKind()));
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitParenExpr(const ParenExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitParenListExpr(const ParenListExpr *S) {
|
2009-08-10 23:49:36 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitUnaryOperator(const UnaryOperator *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getOpcode());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitOffsetOfExpr(const OffsetOfExpr *S) {
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-28 22:16:22 +00:00
|
|
|
VisitType(S->getTypeSourceInfo()->getType());
|
|
|
|
unsigned n = S->getNumComponents();
|
|
|
|
for (unsigned i = 0; i < n; ++i) {
|
2015-12-29 22:31:18 +00:00
|
|
|
const OffsetOfNode &ON = S->getComponent(i);
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-28 22:16:22 +00:00
|
|
|
ID.AddInteger(ON.getKind());
|
|
|
|
switch (ON.getKind()) {
|
2015-12-29 22:31:18 +00:00
|
|
|
case OffsetOfNode::Array:
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-28 22:16:22 +00:00
|
|
|
// Expressions handled below.
|
|
|
|
break;
|
|
|
|
|
2015-12-29 22:31:18 +00:00
|
|
|
case OffsetOfNode::Field:
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-28 22:16:22 +00:00
|
|
|
VisitDecl(ON.getField());
|
|
|
|
break;
|
|
|
|
|
2015-12-29 22:31:18 +00:00
|
|
|
case OffsetOfNode::Identifier:
|
2017-02-22 22:22:42 +00:00
|
|
|
VisitIdentifierInfo(ON.getFieldName());
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-28 22:16:22 +00:00
|
|
|
break;
|
2015-12-29 22:31:18 +00:00
|
|
|
|
|
|
|
case OffsetOfNode::Base:
|
2010-04-29 00:18:15 +00:00
|
|
|
// These nodes are implicit, and therefore don't need profiling.
|
|
|
|
break;
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-28 22:16:22 +00:00
|
|
|
}
|
|
|
|
}
|
2017-02-22 22:22:42 +00:00
|
|
|
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-28 22:16:22 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
2011-03-11 19:24:49 +00:00
|
|
|
ID.AddInteger(S->getKind());
|
2009-07-28 00:33:38 +00:00
|
|
|
if (S->isArgumentType())
|
|
|
|
VisitType(S->getArgumentType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitArraySubscriptExpr(const ArraySubscriptExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
[Matrix] Implement matrix index expressions ([][]).
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
2020-06-01 19:42:03 +01:00
|
|
|
void StmtProfiler::VisitMatrixSubscriptExpr(const MatrixSubscriptExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2024-04-25 10:22:03 -07:00
|
|
|
void StmtProfiler::VisitArraySectionExpr(const ArraySectionExpr *S) {
|
2015-08-25 14:24:04 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
[OPENMP50]Add basic support for array-shaping operation.
Summary:
Added basic representation and parsing/sema handling of array-shaping
operations. Array shaping expression is an expression of form ([s0]..[sn])base,
where s0, ..., sn must be a positive integer, base - a pointer. This
expression is a kind of cast operation that converts pointer expression
into an array-like kind of expression.
Reviewers: rjmccall, rsmith, jdoerfert
Subscribers: guansong, arphaman, cfe-commits, caomhin, kkwli0
Tags: #clang
Differential Revision: https://reviews.llvm.org/D74144
2020-02-05 09:33:05 -05:00
|
|
|
void StmtProfiler::VisitOMPArrayShapingExpr(const OMPArrayShapingExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2020-04-01 15:06:38 -04:00
|
|
|
void StmtProfiler::VisitOMPIteratorExpr(const OMPIteratorExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
for (unsigned I = 0, E = S->numOfIterators(); I < E; ++I)
|
|
|
|
VisitDecl(S->getIteratorDecl(I));
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCallExpr(const CallExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitMemberExpr(const MemberExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getMemberDecl());
|
2010-07-13 08:37:11 +00:00
|
|
|
if (!Canonical)
|
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2009-07-28 00:33:38 +00:00
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCompoundLiteralExpr(const CompoundLiteralExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isFileScope());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCastExpr(const CastExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitImplicitCastExpr(const ImplicitCastExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitCastExpr(S);
|
2010-08-25 10:28:54 +00:00
|
|
|
ID.AddInteger(S->getValueKind());
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitExplicitCastExpr(const ExplicitCastExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitCastExpr(S);
|
|
|
|
VisitType(S->getTypeAsWritten());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCStyleCastExpr(const CStyleCastExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExplicitCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitBinaryOperator(const BinaryOperator *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getOpcode());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitCompoundAssignOperator(const CompoundAssignOperator *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitBinaryOperator(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitConditionalOperator(const ConditionalOperator *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitBinaryConditionalOperator(
|
2011-06-21 23:26:32 +00:00
|
|
|
const BinaryConditionalOperator *S) {
|
2011-02-17 10:25:35 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitAddrLabelExpr(const AddrLabelExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
2011-02-17 07:39:24 +00:00
|
|
|
VisitDecl(S->getLabel());
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitStmtExpr(const StmtExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitShuffleVectorExpr(const ShuffleVectorExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2013-09-18 03:29:45 +00:00
|
|
|
void StmtProfiler::VisitConvertVectorExpr(const ConvertVectorExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitChooseExpr(const ChooseExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitGNUNullExpr(const GNUNullExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitVAArgExpr(const VAArgExpr *S) {
|
2009-07-29 16:09:57 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
if (S->getSyntacticForm()) {
|
|
|
|
VisitInitListExpr(S->getSyntacticForm());
|
|
|
|
return;
|
|
|
|
}
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->usesGNUSyntax());
|
2023-03-02 12:08:07 -08:00
|
|
|
for (const DesignatedInitExpr::Designator &D : S->designators()) {
|
2016-06-23 00:15:04 +00:00
|
|
|
if (D.isFieldDesignator()) {
|
2009-07-28 00:33:38 +00:00
|
|
|
ID.AddInteger(0);
|
2016-06-23 00:15:04 +00:00
|
|
|
VisitName(D.getFieldName());
|
2009-07-28 00:33:38 +00:00
|
|
|
continue;
|
|
|
|
}
|
2009-09-09 15:08:12 +00:00
|
|
|
|
2016-06-23 00:15:04 +00:00
|
|
|
if (D.isArrayDesignator()) {
|
2009-07-28 00:33:38 +00:00
|
|
|
ID.AddInteger(1);
|
|
|
|
} else {
|
2016-06-23 00:15:04 +00:00
|
|
|
assert(D.isArrayRangeDesignator());
|
2009-07-28 00:33:38 +00:00
|
|
|
ID.AddInteger(2);
|
|
|
|
}
|
2023-04-04 16:17:52 -07:00
|
|
|
ID.AddInteger(D.getArrayIndex());
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-10 00:27:52 +00:00
|
|
|
// Seems that if VisitInitListExpr() only works on the syntactic form of an
|
|
|
|
// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
|
|
|
|
void StmtProfiler::VisitDesignatedInitUpdateExpr(
|
|
|
|
const DesignatedInitUpdateExpr *S) {
|
|
|
|
llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
|
|
|
|
"initializer");
|
|
|
|
}
|
|
|
|
|
2016-12-12 02:53:20 +00:00
|
|
|
void StmtProfiler::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2015-06-10 00:27:52 +00:00
|
|
|
void StmtProfiler::VisitNoInitExpr(const NoInitExpr *S) {
|
|
|
|
llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitExtVectorElementExpr(const ExtVectorElementExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitName(&S->getAccessor());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitBlockExpr(const BlockExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getBlockDecl());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
|
2011-04-15 00:35:48 +00:00
|
|
|
VisitExpr(S);
|
2019-11-12 20:46:19 +01:00
|
|
|
for (const GenericSelectionExpr::ConstAssociation Assoc :
|
2019-01-29 12:57:11 +00:00
|
|
|
S->associations()) {
|
|
|
|
QualType T = Assoc.getType();
|
2011-04-15 00:35:48 +00:00
|
|
|
if (T.isNull())
|
2014-05-12 05:36:57 +00:00
|
|
|
ID.AddPointer(nullptr);
|
2011-04-15 00:35:48 +00:00
|
|
|
else
|
|
|
|
VisitType(T);
|
2019-01-29 12:57:11 +00:00
|
|
|
VisitExpr(Assoc.getAssociationExpr());
|
2011-04-15 00:35:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-06 09:01:30 +00:00
|
|
|
void StmtProfiler::VisitPseudoObjectExpr(const PseudoObjectExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
for (PseudoObjectExpr::const_semantics_iterator
|
|
|
|
i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i)
|
|
|
|
// Normally, we would not profile the source expressions of OVEs.
|
|
|
|
if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(*i))
|
|
|
|
Visit(OVE->getSourceExpr());
|
|
|
|
}
|
|
|
|
|
2011-10-11 02:20:01 +00:00
|
|
|
void StmtProfiler::VisitAtomicExpr(const AtomicExpr *S) {
|
|
|
|
VisitExpr(S);
|
2011-10-14 20:59:01 +00:00
|
|
|
ID.AddInteger(S->getOp());
|
2011-10-11 02:20:01 +00:00
|
|
|
}
|
|
|
|
|
2019-10-15 15:24:26 +00:00
|
|
|
void StmtProfiler::VisitConceptSpecializationExpr(
|
|
|
|
const ConceptSpecializationExpr *S) {
|
|
|
|
VisitExpr(S);
|
2020-01-16 13:35:20 +02:00
|
|
|
VisitDecl(S->getNamedConcept());
|
|
|
|
for (const TemplateArgument &Arg : S->getTemplateArguments())
|
|
|
|
VisitTemplateArgument(Arg);
|
2019-10-15 15:24:26 +00:00
|
|
|
}
|
|
|
|
|
2020-01-18 09:11:43 +02:00
|
|
|
void StmtProfiler::VisitRequiresExpr(const RequiresExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getLocalParameters().size());
|
|
|
|
for (ParmVarDecl *LocalParam : S->getLocalParameters())
|
|
|
|
VisitDecl(LocalParam);
|
|
|
|
ID.AddInteger(S->getRequirements().size());
|
|
|
|
for (concepts::Requirement *Req : S->getRequirements()) {
|
|
|
|
if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
|
|
|
|
ID.AddInteger(concepts::Requirement::RK_Type);
|
|
|
|
ID.AddBoolean(TypeReq->isSubstitutionFailure());
|
|
|
|
if (!TypeReq->isSubstitutionFailure())
|
|
|
|
VisitType(TypeReq->getType()->getType());
|
|
|
|
} else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
|
|
|
|
ID.AddInteger(concepts::Requirement::RK_Compound);
|
|
|
|
ID.AddBoolean(ExprReq->isExprSubstitutionFailure());
|
|
|
|
if (!ExprReq->isExprSubstitutionFailure())
|
|
|
|
Visit(ExprReq->getExpr());
|
|
|
|
// C++2a [expr.prim.req.compound]p1 Example:
|
|
|
|
// [...] The compound-requirement in C1 requires that x++ is a valid
|
|
|
|
// expression. It is equivalent to the simple-requirement x++; [...]
|
|
|
|
// We therefore do not profile isSimple() here.
|
|
|
|
ID.AddBoolean(ExprReq->getNoexceptLoc().isValid());
|
|
|
|
const concepts::ExprRequirement::ReturnTypeRequirement &RetReq =
|
|
|
|
ExprReq->getReturnTypeRequirement();
|
|
|
|
if (RetReq.isEmpty()) {
|
|
|
|
ID.AddInteger(0);
|
|
|
|
} else if (RetReq.isTypeConstraint()) {
|
|
|
|
ID.AddInteger(1);
|
|
|
|
Visit(RetReq.getTypeConstraint()->getImmediatelyDeclaredConstraint());
|
|
|
|
} else {
|
|
|
|
assert(RetReq.isSubstitutionFailure());
|
|
|
|
ID.AddInteger(2);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ID.AddInteger(concepts::Requirement::RK_Nested);
|
|
|
|
auto *NestedReq = cast<concepts::NestedRequirement>(Req);
|
2022-11-29 14:05:53 +01:00
|
|
|
ID.AddBoolean(NestedReq->hasInvalidConstraint());
|
|
|
|
if (!NestedReq->hasInvalidConstraint())
|
2020-01-18 09:11:43 +02:00
|
|
|
Visit(NestedReq->getConstraintExpr());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
|
2010-08-25 11:45:40 +00:00
|
|
|
UnaryOperatorKind &UnaryOp,
|
2023-07-10 17:42:19 -07:00
|
|
|
BinaryOperatorKind &BinaryOp,
|
|
|
|
unsigned &NumArgs) {
|
2010-05-19 04:13:23 +00:00
|
|
|
switch (S->getOperator()) {
|
|
|
|
case OO_None:
|
|
|
|
case OO_New:
|
|
|
|
case OO_Delete:
|
|
|
|
case OO_Array_New:
|
|
|
|
case OO_Array_Delete:
|
|
|
|
case OO_Arrow:
|
|
|
|
case OO_Conditional:
|
|
|
|
case NUM_OVERLOADED_OPERATORS:
|
|
|
|
llvm_unreachable("Invalid operator call kind");
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_Plus:
|
2023-07-10 17:42:19 -07:00
|
|
|
if (NumArgs == 1) {
|
2010-08-25 11:45:40 +00:00
|
|
|
UnaryOp = UO_Plus;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
}
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_Add;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_Minus:
|
2023-07-10 17:42:19 -07:00
|
|
|
if (NumArgs == 1) {
|
2010-08-25 11:45:40 +00:00
|
|
|
UnaryOp = UO_Minus;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
}
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_Sub;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Star:
|
2023-07-10 17:42:19 -07:00
|
|
|
if (NumArgs == 1) {
|
2014-06-05 22:43:40 +00:00
|
|
|
UnaryOp = UO_Deref;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
}
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2014-06-05 22:43:40 +00:00
|
|
|
BinaryOp = BO_Mul;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Slash:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_Div;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_Percent:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_Rem;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Caret:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_Xor;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Amp:
|
2023-07-10 17:42:19 -07:00
|
|
|
if (NumArgs == 1) {
|
2010-08-25 11:45:40 +00:00
|
|
|
UnaryOp = UO_AddrOf;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
}
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_And;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_Pipe:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_Or;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Tilde:
|
2010-08-25 11:45:40 +00:00
|
|
|
UnaryOp = UO_Not;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Exclaim:
|
2010-08-25 11:45:40 +00:00
|
|
|
UnaryOp = UO_LNot;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Equal:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_Assign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Less:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_LT;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Greater:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_GT;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_PlusEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_AddAssign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_MinusEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_SubAssign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_StarEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_MulAssign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_SlashEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_DivAssign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_PercentEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_RemAssign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_CaretEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_XorAssign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_AmpEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_AndAssign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_PipeEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_OrAssign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_LessLess:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_Shl;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_GreaterGreater:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_Shr;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_LessLessEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_ShlAssign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_GreaterGreaterEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_ShrAssign;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::CompoundAssignOperatorClass;
|
|
|
|
|
|
|
|
case OO_EqualEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_EQ;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_ExclaimEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_NE;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_LessEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_LE;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_GreaterEqual:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_GE;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2017-12-01 02:13:10 +00:00
|
|
|
|
|
|
|
case OO_Spaceship:
|
2020-02-04 18:28:36 -08:00
|
|
|
BinaryOp = BO_Cmp;
|
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_AmpAmp:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_LAnd;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_PipePipe:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_LOr;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_PlusPlus:
|
2023-07-10 17:42:19 -07:00
|
|
|
UnaryOp = NumArgs == 1 ? UO_PreInc : UO_PostInc;
|
|
|
|
NumArgs = 1;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_MinusMinus:
|
2023-07-10 17:42:19 -07:00
|
|
|
UnaryOp = NumArgs == 1 ? UO_PreDec : UO_PostDec;
|
|
|
|
NumArgs = 1;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::UnaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_Comma:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_Comma;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
|
|
|
|
|
|
|
case OO_ArrowStar:
|
2010-08-25 11:45:40 +00:00
|
|
|
BinaryOp = BO_PtrMemI;
|
2010-05-19 04:13:23 +00:00
|
|
|
return Stmt::BinaryOperatorClass;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
case OO_Subscript:
|
|
|
|
return Stmt::ArraySubscriptExprClass;
|
2018-07-31 00:47:41 +00:00
|
|
|
|
2020-05-18 17:22:59 +02:00
|
|
|
case OO_Call:
|
|
|
|
return Stmt::CallExprClass;
|
|
|
|
|
2018-07-31 00:47:41 +00:00
|
|
|
case OO_Coawait:
|
|
|
|
UnaryOp = UO_Coawait;
|
|
|
|
return Stmt::UnaryOperatorClass;
|
2010-05-19 04:13:23 +00:00
|
|
|
}
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
llvm_unreachable("Invalid overloaded operator expression");
|
|
|
|
}
|
2014-06-05 22:43:40 +00:00
|
|
|
|
2017-10-13 16:18:32 +00:00
|
|
|
#if defined(_MSC_VER) && !defined(__clang__)
|
2017-07-24 16:54:11 +00:00
|
|
|
#if _MSC_VER == 1911
|
|
|
|
// Work around https://developercommunity.visualstudio.com/content/problem/84002/clang-cl-when-built-with-vc-2017-crashes-cause-vc.html
|
|
|
|
// MSVC 2017 update 3 miscompiles this function, and a clang built with it
|
|
|
|
// will crash in stage 2 of a bootstrap build.
|
|
|
|
#pragma optimize("", off)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
|
2010-05-19 04:13:23 +00:00
|
|
|
if (S->isTypeDependent()) {
|
|
|
|
// Type-dependent operator calls are profiled like their underlying
|
|
|
|
// syntactic operator.
|
2016-10-24 18:47:04 +00:00
|
|
|
//
|
|
|
|
// An operator call to operator-> is always implicit, so just skip it. The
|
|
|
|
// enclosing MemberExpr will profile the actual member access.
|
|
|
|
if (S->getOperator() == OO_Arrow)
|
|
|
|
return Visit(S->getArg(0));
|
|
|
|
|
2010-08-25 11:45:40 +00:00
|
|
|
UnaryOperatorKind UnaryOp = UO_Extension;
|
|
|
|
BinaryOperatorKind BinaryOp = BO_Comma;
|
2023-07-10 17:42:19 -07:00
|
|
|
unsigned NumArgs = S->getNumArgs();
|
|
|
|
Stmt::StmtClass SC = DecodeOperatorCall(S, UnaryOp, BinaryOp, NumArgs);
|
2014-06-05 22:43:40 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
ID.AddInteger(SC);
|
2023-07-10 17:42:19 -07:00
|
|
|
for (unsigned I = 0; I != NumArgs; ++I)
|
2010-05-19 04:13:23 +00:00
|
|
|
Visit(S->getArg(I));
|
|
|
|
if (SC == Stmt::UnaryOperatorClass)
|
|
|
|
ID.AddInteger(UnaryOp);
|
2018-07-30 19:24:48 +00:00
|
|
|
else if (SC == Stmt::BinaryOperatorClass ||
|
2010-05-19 04:13:23 +00:00
|
|
|
SC == Stmt::CompoundAssignOperatorClass)
|
|
|
|
ID.AddInteger(BinaryOp);
|
|
|
|
else
|
2020-05-18 17:22:59 +02:00
|
|
|
assert(SC == Stmt::ArraySubscriptExprClass || SC == Stmt::CallExprClass);
|
2014-06-05 22:43:40 +00:00
|
|
|
|
2010-05-19 04:13:23 +00:00
|
|
|
return;
|
|
|
|
}
|
2014-06-05 22:43:40 +00:00
|
|
|
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitCallExpr(S);
|
|
|
|
ID.AddInteger(S->getOperator());
|
|
|
|
}
|
|
|
|
|
2019-10-19 00:04:38 +00:00
|
|
|
void StmtProfiler::VisitCXXRewrittenBinaryOperator(
|
|
|
|
const CXXRewrittenBinaryOperator *S) {
|
|
|
|
// If a rewritten operator were ever to be type-dependent, we should profile
|
|
|
|
// it following its syntactic operator.
|
|
|
|
assert(!S->isTypeDependent() &&
|
|
|
|
"resolved rewritten operator should never be type-dependent");
|
|
|
|
ID.AddBoolean(S->isReversed());
|
|
|
|
VisitExpr(S->getSemanticForm());
|
|
|
|
}
|
|
|
|
|
2017-10-13 16:18:32 +00:00
|
|
|
#if defined(_MSC_VER) && !defined(__clang__)
|
2017-07-24 16:54:11 +00:00
|
|
|
#if _MSC_VER == 1911
|
|
|
|
#pragma optimize("", on)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXMemberCallExpr(const CXXMemberCallExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitCallExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCUDAKernelCallExpr(const CUDAKernelCallExpr *S) {
|
2011-02-09 21:07:24 +00:00
|
|
|
VisitCallExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitAsTypeExpr(const AsTypeExpr *S) {
|
2011-06-04 00:47:47 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXNamedCastExpr(const CXXNamedCastExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExplicitCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitCXXNamedCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitCXXNamedCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitCXXNamedCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXConstCastExpr(const CXXConstCastExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitCXXNamedCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2019-07-02 18:28:13 +00:00
|
|
|
void StmtProfiler::VisitBuiltinBitCastExpr(const BuiltinBitCastExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitType(S->getTypeInfoAsWritten()->getType());
|
|
|
|
}
|
|
|
|
|
2020-05-18 11:02:01 +01:00
|
|
|
void StmtProfiler::VisitCXXAddrspaceCastExpr(const CXXAddrspaceCastExpr *S) {
|
|
|
|
VisitCXXNamedCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2012-03-07 08:35:16 +00:00
|
|
|
void StmtProfiler::VisitUserDefinedLiteral(const UserDefinedLiteral *S) {
|
|
|
|
VisitCallExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->getValue());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *S) {
|
2009-07-29 16:09:57 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2013-06-12 22:31:48 +00:00
|
|
|
void StmtProfiler::VisitCXXStdInitializerListExpr(
|
|
|
|
const CXXStdInitializerListExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXTypeidExpr(const CXXTypeidExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
if (S->isTypeOperand())
|
2013-09-27 07:04:31 +00:00
|
|
|
VisitType(S->getTypeOperandSourceInfo()->getType());
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXUuidofExpr(const CXXUuidofExpr *S) {
|
2010-09-08 12:20:18 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
if (S->isTypeOperand())
|
2013-09-27 07:04:31 +00:00
|
|
|
VisitType(S->getTypeOperandSourceInfo()->getType());
|
2010-09-08 12:20:18 +00:00
|
|
|
}
|
|
|
|
|
2013-04-16 07:28:30 +00:00
|
|
|
void StmtProfiler::VisitMSPropertyRefExpr(const MSPropertyRefExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getPropertyDecl());
|
|
|
|
}
|
|
|
|
|
2015-11-25 12:01:00 +00:00
|
|
|
void StmtProfiler::VisitMSPropertySubscriptExpr(
|
|
|
|
const MSPropertySubscriptExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXThisExpr(const CXXThisExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
2012-04-16 07:05:22 +00:00
|
|
|
ID.AddBoolean(S->isImplicit());
|
[Clang] [Sema] Fix dependence of DREs in lambdas with an explicit object parameter (#84473)
This fixes some problems wrt dependence of captures in lambdas with
an explicit object parameter.
[temp.dep.expr] states that
> An id-expression is type-dependent if [...] its terminal name is
> - associated by name lookup with an entity captured by copy
> ([expr.prim.lambda.capture]) in a lambda-expression that has
> an explicit object parameter whose type is dependent [dcl.fct].
There were several issues with our implementation of this:
1. we were treating by-reference captures as dependent rather than
by-value captures;
2. tree transform wasn't checking whether referring to such a
by-value capture should make a DRE dependent;
3. when checking whether a DRE refers to such a by-value capture, we
were only looking at the immediately enclosing lambda, and not
at any parent lambdas;
4. we also forgot to check for implicit by-value captures;
5. lastly, we were attempting to determine whether a lambda has an
explicit object parameter by checking the `LambdaScopeInfo`'s
`ExplicitObjectParameter`, but it seems that that simply wasn't
set (yet) by the time we got to the check.
All of these should be fixed now.
This fixes #70604, #79754, #84163, #84425, #86054, #86398, and #86399.
2024-04-09 14:52:52 +02:00
|
|
|
ID.AddBoolean(S->isCapturedByCopyInLambdaWithExplicitObjectParameter());
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXThrowExpr(const CXXThrowExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getParam());
|
|
|
|
}
|
|
|
|
|
2013-04-20 22:23:05 +00:00
|
|
|
void StmtProfiler::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getField());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(
|
|
|
|
const_cast<CXXDestructorDecl *>(S->getTemporary()->getDestructor()));
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXConstructExpr(const CXXConstructExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getConstructor());
|
|
|
|
ID.AddBoolean(S->isElidable());
|
|
|
|
}
|
|
|
|
|
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into
C++ last year as a DR against C++11.
Instead of synthesizing a set of derived class constructors for each inherited
base class constructor, we make the constructors of the base class visible to
constructor lookup in the derived class, using the normal rules for
using-declarations.
For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived
class that tracks the requisite additional information. We create shadow
constructors (not found by name lookup) in the derived class to model the
actual initialization, and have a new expression node,
CXXInheritedCtorInitExpr, to model the initialization of a base class from such
a constructor. (This initialization is special because it performs real perfect
forwarding of arguments.)
In cases where argument forwarding is not possible (for inalloca calls,
variadic calls, and calls with callee parameter cleanup), the shadow inheriting
constructor is not emitted and instead we directly emit the initialization code
into the caller of the inherited constructor.
Note that this new model is not perfectly compatible with the old model in some
corner cases. In particular:
* if B inherits a private constructor from A, and C uses that constructor to
construct a B, then we previously required that A befriends B and B
befriends C, but the new rules require A to befriend C directly, and
* if a derived class has its own constructors (and so its implicit default
constructor is suppressed), it may still inherit a default constructor from
a base class
llvm-svn: 274049
2016-06-28 19:03:57 +00:00
|
|
|
void StmtProfiler::VisitCXXInheritedCtorInitExpr(
|
|
|
|
const CXXInheritedCtorInitExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getConstructor());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExplicitCastExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitCXXConstructExpr(S);
|
|
|
|
}
|
|
|
|
|
2012-02-07 10:09:13 +00:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
|
2023-07-11 16:12:19 +08:00
|
|
|
if (!ProfileLambdaExpr) {
|
|
|
|
// Do not recursively visit the children of this expression. Profiling the
|
|
|
|
// body would result in unnecessary work, and is not safe to do during
|
|
|
|
// deserialization.
|
|
|
|
VisitStmtNoChildren(S);
|
|
|
|
|
|
|
|
// C++20 [temp.over.link]p5:
|
|
|
|
// Two lambda-expressions are never considered equivalent.
|
|
|
|
VisitDecl(S->getLambdaClass());
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2022-02-15 17:55:35 -08:00
|
|
|
|
2023-07-11 16:12:19 +08:00
|
|
|
CXXRecordDecl *Lambda = S->getLambdaClass();
|
|
|
|
for (const auto &Capture : Lambda->captures()) {
|
|
|
|
ID.AddInteger(Capture.getCaptureKind());
|
|
|
|
if (Capture.capturesVariable())
|
|
|
|
VisitDecl(Capture.getCapturedVar());
|
|
|
|
}
|
2024-04-16 14:37:38 +08:00
|
|
|
|
|
|
|
// Profiling the body of the lambda may be dangerous during deserialization.
|
|
|
|
// So we'd like only to profile the signature here.
|
|
|
|
ODRHash Hasher;
|
|
|
|
// FIXME: We can't get the operator call easily by
|
|
|
|
// `CXXRecordDecl::getLambdaCallOperator()` if we're in deserialization.
|
|
|
|
// So we have to do something raw here.
|
|
|
|
for (auto *SubDecl : Lambda->decls()) {
|
|
|
|
FunctionDecl *Call = nullptr;
|
|
|
|
if (auto *FTD = dyn_cast<FunctionTemplateDecl>(SubDecl))
|
|
|
|
Call = FTD->getTemplatedDecl();
|
|
|
|
else if (auto *FD = dyn_cast<FunctionDecl>(SubDecl))
|
|
|
|
Call = FD;
|
|
|
|
|
|
|
|
if (!Call)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
Hasher.AddFunctionDecl(Call, /*SkipBody=*/true);
|
|
|
|
}
|
|
|
|
ID.AddInteger(Hasher.CalculateHash());
|
2012-02-07 10:09:13 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isGlobalDelete());
|
|
|
|
ID.AddBoolean(S->isArrayForm());
|
|
|
|
VisitDecl(S->getOperatorDelete());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXNewExpr(const CXXNewExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitType(S->getAllocatedType());
|
|
|
|
VisitDecl(S->getOperatorNew());
|
|
|
|
VisitDecl(S->getOperatorDelete());
|
|
|
|
ID.AddBoolean(S->isArray());
|
|
|
|
ID.AddInteger(S->getNumPlacementArgs());
|
|
|
|
ID.AddBoolean(S->isGlobalNew());
|
|
|
|
ID.AddBoolean(S->isParenTypeId());
|
2023-11-06 21:06:05 +04:00
|
|
|
ID.AddInteger(llvm::to_underlying(S->getInitializationStyle()));
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void
|
|
|
|
StmtProfiler::VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *S) {
|
2009-09-04 17:36:40 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2014-05-12 05:36:57 +00:00
|
|
|
ID.AddBoolean(S->getScopeTypeInfo() != nullptr);
|
2013-08-09 23:37:05 +00:00
|
|
|
if (S->getScopeTypeInfo())
|
|
|
|
VisitType(S->getScopeTypeInfo()->getType());
|
2014-05-12 05:36:57 +00:00
|
|
|
ID.AddBoolean(S->getDestroyedTypeInfo() != nullptr);
|
2013-08-09 23:37:05 +00:00
|
|
|
if (S->getDestroyedTypeInfo())
|
|
|
|
VisitType(S->getDestroyedType());
|
|
|
|
else
|
2017-02-22 22:22:42 +00:00
|
|
|
VisitIdentifierInfo(S->getDestroyedTypeIdentifier());
|
2009-09-04 17:36:40 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitOverloadExpr(const OverloadExpr *S) {
|
2010-08-15 20:53:20 +00:00
|
|
|
VisitExpr(S);
|
2009-11-24 19:00:30 +00:00
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2018-02-22 05:32:25 +00:00
|
|
|
VisitName(S->getName(), /*TreatAsDecl*/ true);
|
2009-11-24 19:00:30 +00:00
|
|
|
ID.AddBoolean(S->hasExplicitTemplateArgs());
|
|
|
|
if (S->hasExplicitTemplateArgs())
|
2015-12-24 02:59:37 +00:00
|
|
|
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
|
2010-08-15 01:15:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-06-16 06:47:06 +00:00
|
|
|
StmtProfiler::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *S) {
|
2010-08-15 01:15:38 +00:00
|
|
|
VisitOverloadExpr(S);
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2012-02-24 07:38:34 +00:00
|
|
|
void StmtProfiler::VisitTypeTraitExpr(const TypeTraitExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getTrait());
|
|
|
|
ID.AddInteger(S->getNumArgs());
|
|
|
|
for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
|
|
|
|
VisitType(S->getArg(I)->getType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *S) {
|
2011-04-28 00:16:57 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getTrait());
|
|
|
|
VisitType(S->getQueriedType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitExpressionTraitExpr(const ExpressionTraitExpr *S) {
|
2011-04-25 06:54:41 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getTrait());
|
|
|
|
VisitExpr(S->getQueriedExpression());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitDependentScopeDeclRefExpr(
|
|
|
|
const DependentScopeDeclRefExpr *S) {
|
2009-07-28 00:33:38 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitName(S->getDeclName());
|
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2009-11-24 19:00:30 +00:00
|
|
|
ID.AddBoolean(S->hasExplicitTemplateArgs());
|
|
|
|
if (S->hasExplicitTemplateArgs())
|
|
|
|
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitExprWithCleanups(const ExprWithCleanups *S) {
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXUnresolvedConstructExpr(
|
|
|
|
const CXXUnresolvedConstructExpr *S) {
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitType(S->getTypeAsWritten());
|
2017-08-23 22:12:08 +00:00
|
|
|
ID.AddInteger(S->isListInitialization());
|
2009-07-28 14:44:31 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXDependentScopeMemberExpr(
|
|
|
|
const CXXDependentScopeMemberExpr *S) {
|
2009-12-01 22:10:20 +00:00
|
|
|
ID.AddBoolean(S->isImplicitAccess());
|
|
|
|
if (!S->isImplicitAccess()) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
}
|
2009-09-03 16:14:30 +00:00
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitName(S->getMember());
|
2009-12-01 22:10:20 +00:00
|
|
|
ID.AddBoolean(S->hasExplicitTemplateArgs());
|
|
|
|
if (S->hasExplicitTemplateArgs())
|
2009-11-30 22:42:35 +00:00
|
|
|
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *S) {
|
2009-12-01 22:10:20 +00:00
|
|
|
ID.AddBoolean(S->isImplicitAccess());
|
|
|
|
if (!S->isImplicitAccess()) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
}
|
2009-11-30 22:42:35 +00:00
|
|
|
VisitNestedNameSpecifier(S->getQualifier());
|
|
|
|
VisitName(S->getMemberName());
|
|
|
|
ID.AddBoolean(S->hasExplicitTemplateArgs());
|
|
|
|
if (S->hasExplicitTemplateArgs())
|
|
|
|
VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs());
|
2009-07-28 14:44:31 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitCXXNoexceptExpr(const CXXNoexceptExpr *S) {
|
2010-09-10 20:55:43 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitPackExpansionExpr(const PackExpansionExpr *S) {
|
2011-01-03 17:17:50 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitSizeOfPackExpr(const SizeOfPackExpr *S) {
|
2011-01-04 17:33:58 +00:00
|
|
|
VisitExpr(S);
|
2015-09-23 21:41:42 +00:00
|
|
|
if (S->isPartiallySubstituted()) {
|
|
|
|
auto Args = S->getPartialArguments();
|
|
|
|
ID.AddInteger(Args.size());
|
|
|
|
for (const auto &TA : Args)
|
|
|
|
VisitTemplateArgument(TA);
|
|
|
|
} else {
|
2025-01-27 23:04:57 +08:00
|
|
|
VisitDecl(S->getPack());
|
2015-09-23 21:41:42 +00:00
|
|
|
ID.AddInteger(0);
|
|
|
|
}
|
2011-01-04 17:33:58 +00:00
|
|
|
}
|
|
|
|
|
2024-01-27 10:23:38 +01:00
|
|
|
void StmtProfiler::VisitPackIndexingExpr(const PackIndexingExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
VisitExpr(E->getPackIdExpression());
|
|
|
|
VisitExpr(E->getIndexExpr());
|
|
|
|
}
|
|
|
|
|
2011-01-15 01:15:58 +00:00
|
|
|
void StmtProfiler::VisitSubstNonTypeTemplateParmPackExpr(
|
2011-06-16 06:47:06 +00:00
|
|
|
const SubstNonTypeTemplateParmPackExpr *S) {
|
2011-01-15 01:15:58 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getParameterPack());
|
|
|
|
VisitTemplateArgument(S->getArgumentPack());
|
|
|
|
}
|
|
|
|
|
2011-07-15 05:09:51 +00:00
|
|
|
void StmtProfiler::VisitSubstNonTypeTemplateParmExpr(
|
|
|
|
const SubstNonTypeTemplateParmExpr *E) {
|
|
|
|
// Profile exactly as the replacement expression.
|
|
|
|
Visit(E->getReplacement());
|
|
|
|
}
|
|
|
|
|
2012-09-12 00:56:43 +00:00
|
|
|
void StmtProfiler::VisitFunctionParmPackExpr(const FunctionParmPackExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getParameterPack());
|
|
|
|
ID.AddInteger(S->getNumExpansions());
|
|
|
|
for (FunctionParmPackExpr::iterator I = S->begin(), E = S->end(); I != E; ++I)
|
|
|
|
VisitDecl(*I);
|
|
|
|
}
|
|
|
|
|
2011-06-21 17:03:29 +00:00
|
|
|
void StmtProfiler::VisitMaterializeTemporaryExpr(
|
|
|
|
const MaterializeTemporaryExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2014-11-08 05:07:16 +00:00
|
|
|
void StmtProfiler::VisitCXXFoldExpr(const CXXFoldExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddInteger(S->getOperator());
|
|
|
|
}
|
|
|
|
|
2023-01-04 15:12:00 -08:00
|
|
|
void StmtProfiler::VisitCXXParenListInitExpr(const CXXParenListInitExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2015-10-27 06:02:45 +00:00
|
|
|
void StmtProfiler::VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitCoreturnStmt(const CoreturnStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitCoawaitExpr(const CoawaitExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2017-03-06 23:38:15 +00:00
|
|
|
void StmtProfiler::VisitDependentCoawaitExpr(const DependentCoawaitExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2015-10-27 06:02:45 +00:00
|
|
|
void StmtProfiler::VisitCoyieldExpr(const CoyieldExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
|
2018-07-30 19:24:48 +00:00
|
|
|
VisitExpr(E);
|
2010-11-15 23:31:06 +00:00
|
|
|
}
|
|
|
|
|
2014-10-27 18:07:20 +00:00
|
|
|
void StmtProfiler::VisitTypoExpr(const TypoExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
Implement __builtin_LINE() et. al. to support source location capture.
Summary:
This patch implements the source location builtins `__builtin_LINE(), `__builtin_FUNCTION()`, `__builtin_FILE()` and `__builtin_COLUMN()`. These builtins are needed to implement [`std::experimental::source_location`](https://rawgit.com/cplusplus/fundamentals-ts/v2/main.html#reflection.src_loc.creation).
With the exception of `__builtin_COLUMN`, GCC also implements these builtins, and Clangs behavior is intended to match as closely as possible.
Reviewers: rsmith, joerg, aaron.ballman, bogner, majnemer, shafik, martong
Reviewed By: rsmith
Subscribers: rnkovacs, loskutov, riccibruno, mgorny, kunitoki, alexr, majnemer, hfinkel, cfe-commits
Differential Revision: https://reviews.llvm.org/D37035
llvm-svn: 360937
2019-05-16 21:04:15 +00:00
|
|
|
void StmtProfiler::VisitSourceLocExpr(const SourceLocExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
2024-06-20 14:38:46 +02:00
|
|
|
void StmtProfiler::VisitEmbedExpr(const EmbedExpr *E) { VisitExpr(E); }
|
|
|
|
|
[AST] Add RecoveryExpr to retain expressions on semantic errors
Normally clang avoids creating expressions when it encounters semantic
errors, even if the parser knows which expression to produce.
This works well for the compiler. However, this is not ideal for
source-level tools that have to deal with broken code, e.g. clangd is
not able to provide navigation features even for names that compiler
knows how to resolve.
The new RecoveryExpr aims to capture the minimal set of information
useful for the tools that need to deal with incorrect code:
source range of the expression being dropped,
subexpressions of the expression.
We aim to make constructing RecoveryExprs as simple as possible to
ensure writing code to avoid dropping expressions is easy.
Producing RecoveryExprs can result in new code paths being taken in the
frontend. In particular, clang can produce some new diagnostics now and
we aim to suppress bogus ones based on Expr::containsErrors.
We deliberately produce RecoveryExprs only in the parser for now to
minimize the code affected by this patch. Producing RecoveryExprs in
Sema potentially allows to preserve more information (e.g. type of an
expression), but also results in more code being affected. E.g.
SFINAE checks will have to take presence of RecoveryExprs into account.
Initial implementation only works in C++ mode, as it relies on compiler
postponing diagnostics on dependent expressions. C and ObjC often do not
do this, so they require more work to make sure we do not produce too
many bogus diagnostics on the new expressions.
See documentation of RecoveryExpr for more details.
original patch from Ilya
This change is based on https://reviews.llvm.org/D61722
Reviewers: sammccall, rsmith
Reviewed By: sammccall, rsmith
Tags: #clang
Differential Revision: https://reviews.llvm.org/D69330
2020-03-19 16:30:40 +01:00
|
|
|
void StmtProfiler::VisitRecoveryExpr(const RecoveryExpr *E) { VisitExpr(E); }
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCStringLiteral(const ObjCStringLiteral *S) {
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2012-04-19 00:25:12 +00:00
|
|
|
void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
|
2012-03-06 20:05:56 +00:00
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitObjCArrayLiteral(const ObjCArrayLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCEncodeExpr(const ObjCEncodeExpr *S) {
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitType(S->getEncodedType());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCSelectorExpr(const ObjCSelectorExpr *S) {
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitName(S->getSelector());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCProtocolExpr(const ObjCProtocolExpr *S) {
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getProtocol());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *S) {
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getDecl());
|
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
ID.AddBoolean(S->isFreeIvar());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *S) {
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitExpr(S);
|
2010-12-02 01:19:52 +00:00
|
|
|
if (S->isImplicitProperty()) {
|
|
|
|
VisitDecl(S->getImplicitPropertyGetter());
|
|
|
|
VisitDecl(S->getImplicitPropertySetter());
|
|
|
|
} else {
|
|
|
|
VisitDecl(S->getExplicitProperty());
|
2010-10-14 16:04:05 +00:00
|
|
|
}
|
|
|
|
if (S->isSuperReceiver()) {
|
|
|
|
ID.AddBoolean(S->isSuperReceiver());
|
2010-12-02 01:19:52 +00:00
|
|
|
VisitType(S->getSuperReceiverType());
|
2010-10-14 16:04:05 +00:00
|
|
|
}
|
2009-07-28 14:44:31 +00:00
|
|
|
}
|
|
|
|
|
2012-03-06 20:05:56 +00:00
|
|
|
void StmtProfiler::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
VisitDecl(S->getAtIndexMethodDecl());
|
|
|
|
VisitDecl(S->setAtIndexMethodDecl());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCMessageExpr(const ObjCMessageExpr *S) {
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
VisitName(S->getSelector());
|
|
|
|
VisitDecl(S->getMethodDecl());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCIsaExpr(const ObjCIsaExpr *S) {
|
2009-07-28 14:44:31 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->isArrow());
|
|
|
|
}
|
|
|
|
|
2012-03-06 20:05:56 +00:00
|
|
|
void StmtProfiler::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->getValue());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCIndirectCopyRestoreExpr(
|
|
|
|
const ObjCIndirectCopyRestoreExpr *S) {
|
2011-06-15 23:02:42 +00:00
|
|
|
VisitExpr(S);
|
|
|
|
ID.AddBoolean(S->shouldCopy());
|
|
|
|
}
|
|
|
|
|
2011-06-16 06:47:06 +00:00
|
|
|
void StmtProfiler::VisitObjCBridgedCastExpr(const ObjCBridgedCastExpr *S) {
|
2011-06-15 23:02:42 +00:00
|
|
|
VisitExplicitCastExpr(S);
|
|
|
|
ID.AddBoolean(S->getBridgeKind());
|
|
|
|
}
|
|
|
|
|
2016-07-16 00:35:23 +00:00
|
|
|
void StmtProfiler::VisitObjCAvailabilityCheckExpr(
|
|
|
|
const ObjCAvailabilityCheckExpr *S) {
|
|
|
|
VisitExpr(S);
|
|
|
|
}
|
|
|
|
|
2009-10-29 08:12:44 +00:00
|
|
|
void StmtProfiler::VisitTemplateArguments(const TemplateArgumentLoc *Args,
|
2009-07-28 00:33:38 +00:00
|
|
|
unsigned NumArgs) {
|
|
|
|
ID.AddInteger(NumArgs);
|
2009-10-29 08:12:44 +00:00
|
|
|
for (unsigned I = 0; I != NumArgs; ++I)
|
|
|
|
VisitTemplateArgument(Args[I].getArgument());
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitTemplateArgument(const TemplateArgument &Arg) {
|
|
|
|
// Mostly repetitive with TemplateArgument::Profile!
|
|
|
|
ID.AddInteger(Arg.getKind());
|
|
|
|
switch (Arg.getKind()) {
|
|
|
|
case TemplateArgument::Null:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TemplateArgument::Type:
|
|
|
|
VisitType(Arg.getAsType());
|
|
|
|
break;
|
|
|
|
|
2009-11-11 01:00:40 +00:00
|
|
|
case TemplateArgument::Template:
|
2011-01-05 18:58:31 +00:00
|
|
|
case TemplateArgument::TemplateExpansion:
|
|
|
|
VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
|
2009-11-11 01:00:40 +00:00
|
|
|
break;
|
2018-07-30 19:24:48 +00:00
|
|
|
|
2009-10-29 08:12:44 +00:00
|
|
|
case TemplateArgument::Declaration:
|
2020-11-14 17:37:25 -08:00
|
|
|
VisitType(Arg.getParamTypeForDecl());
|
|
|
|
// FIXME: Do we need to recursively decompose template parameter objects?
|
2009-10-29 08:12:44 +00:00
|
|
|
VisitDecl(Arg.getAsDecl());
|
|
|
|
break;
|
|
|
|
|
2012-09-26 02:36:12 +00:00
|
|
|
case TemplateArgument::NullPtr:
|
|
|
|
VisitType(Arg.getNullPtrType());
|
|
|
|
break;
|
|
|
|
|
2009-10-29 08:12:44 +00:00
|
|
|
case TemplateArgument::Integral:
|
2020-12-14 14:03:38 +01:00
|
|
|
VisitType(Arg.getIntegralType());
|
2020-11-14 17:37:25 -08:00
|
|
|
Arg.getAsIntegral().Profile(ID);
|
2009-10-29 08:12:44 +00:00
|
|
|
break;
|
|
|
|
|
2024-01-21 23:28:57 +03:00
|
|
|
case TemplateArgument::StructuralValue:
|
|
|
|
VisitType(Arg.getStructuralValueType());
|
|
|
|
// FIXME: Do we need to recursively decompose this ourselves?
|
|
|
|
Arg.getAsStructuralValue().Profile(ID);
|
|
|
|
break;
|
|
|
|
|
2009-10-29 08:12:44 +00:00
|
|
|
case TemplateArgument::Expression:
|
|
|
|
Visit(Arg.getAsExpr());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TemplateArgument::Pack:
|
2014-07-15 21:32:31 +00:00
|
|
|
for (const auto &P : Arg.pack_elements())
|
|
|
|
VisitTemplateArgument(P);
|
2009-10-29 08:12:44 +00:00
|
|
|
break;
|
2009-07-28 00:33:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-05 10:06:44 -07:00
|
|
|
namespace {
|
|
|
|
class OpenACCClauseProfiler
|
|
|
|
: public OpenACCClauseVisitor<OpenACCClauseProfiler> {
|
2024-04-12 14:13:31 -07:00
|
|
|
StmtProfiler &Profiler;
|
2024-04-05 10:06:44 -07:00
|
|
|
|
|
|
|
public:
|
2024-04-12 14:13:31 -07:00
|
|
|
OpenACCClauseProfiler(StmtProfiler &P) : Profiler(P) {}
|
2024-04-05 10:06:44 -07:00
|
|
|
|
|
|
|
void VisitOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses) {
|
|
|
|
for (const OpenACCClause *Clause : Clauses) {
|
|
|
|
// TODO OpenACC: When we have clauses with expressions, we should
|
|
|
|
// profile them too.
|
|
|
|
Visit(Clause);
|
|
|
|
}
|
|
|
|
}
|
2024-04-12 14:13:31 -07:00
|
|
|
|
2024-12-16 09:07:10 -08:00
|
|
|
void VisitClauseWithVarList(const OpenACCClauseWithVarList &Clause) {
|
|
|
|
for (auto *E : Clause.getVarList())
|
|
|
|
Profiler.VisitStmt(E);
|
|
|
|
}
|
|
|
|
|
2024-04-12 14:13:31 -07:00
|
|
|
#define VISIT_CLAUSE(CLAUSE_NAME) \
|
2024-04-12 14:44:20 -07:00
|
|
|
void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
|
2024-04-12 14:13:31 -07:00
|
|
|
|
|
|
|
#include "clang/Basic/OpenACCClauses.def"
|
2024-04-05 10:06:44 -07:00
|
|
|
};
|
2024-04-10 07:10:24 -07:00
|
|
|
|
|
|
|
/// Nothing to do here, there are no sub-statements.
|
2024-04-12 14:41:20 -07:00
|
|
|
void OpenACCClauseProfiler::VisitDefaultClause(
|
2024-04-10 07:10:24 -07:00
|
|
|
const OpenACCDefaultClause &Clause) {}
|
2024-04-12 14:13:31 -07:00
|
|
|
|
2024-04-12 14:44:20 -07:00
|
|
|
void OpenACCClauseProfiler::VisitIfClause(const OpenACCIfClause &Clause) {
|
2024-04-12 14:13:31 -07:00
|
|
|
assert(Clause.hasConditionExpr() &&
|
|
|
|
"if clause requires a valid condition expr");
|
|
|
|
Profiler.VisitStmt(Clause.getConditionExpr());
|
|
|
|
}
|
[OpenACC] Implement `self` clause for compute constructs (#88760)
`self` clauses on compute constructs take an optional condition
expression. We again limit the implementation to ONLY compute constructs
to ensure we get all the rules correct for others. However, this one
will be particularly complicated, as it takes a `var-list` for `update`,
so when we get to that construct/clause combination, we need to do that
as well.
This patch also furthers uses of the `OpenACCClauses.def` as it became
useful while implementing this (as well as some other minor refactors as
I went through).
Finally, `self` and `if` clauses have an interaction with each other, if
an `if` clause evaluates to `true`, the `self` clause has no effect.
While this is intended and can be used 'meaningfully', we are warning on
this with a very granular warning, so that this edge case will be
noticed by newer users, but can be disabled trivially.
2024-04-16 06:57:36 -07:00
|
|
|
|
2024-05-02 10:49:14 -07:00
|
|
|
void OpenACCClauseProfiler::VisitCopyClause(const OpenACCCopyClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-05-02 10:49:14 -07:00
|
|
|
}
|
2025-01-21 11:27:23 -08:00
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitLinkClause(const OpenACCLinkClause &Clause) {
|
|
|
|
VisitClauseWithVarList(Clause);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitDeviceResidentClause(
|
|
|
|
const OpenACCDeviceResidentClause &Clause) {
|
|
|
|
VisitClauseWithVarList(Clause);
|
|
|
|
}
|
|
|
|
|
2024-05-02 14:11:17 -07:00
|
|
|
void OpenACCClauseProfiler::VisitCopyInClause(
|
|
|
|
const OpenACCCopyInClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-05-02 14:11:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitCopyOutClause(
|
|
|
|
const OpenACCCopyOutClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-05-02 14:11:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitCreateClause(
|
|
|
|
const OpenACCCreateClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-05-02 14:11:17 -07:00
|
|
|
}
|
2024-05-02 10:49:14 -07:00
|
|
|
|
2025-01-09 07:15:05 -08:00
|
|
|
void OpenACCClauseProfiler::VisitHostClause(const OpenACCHostClause &Clause) {
|
|
|
|
VisitClauseWithVarList(Clause);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitDeviceClause(
|
|
|
|
const OpenACCDeviceClause &Clause) {
|
|
|
|
VisitClauseWithVarList(Clause);
|
|
|
|
}
|
|
|
|
|
[OpenACC] Implement `self` clause for compute constructs (#88760)
`self` clauses on compute constructs take an optional condition
expression. We again limit the implementation to ONLY compute constructs
to ensure we get all the rules correct for others. However, this one
will be particularly complicated, as it takes a `var-list` for `update`,
so when we get to that construct/clause combination, we need to do that
as well.
This patch also furthers uses of the `OpenACCClauses.def` as it became
useful while implementing this (as well as some other minor refactors as
I went through).
Finally, `self` and `if` clauses have an interaction with each other, if
an `if` clause evaluates to `true`, the `self` clause has no effect.
While this is intended and can be used 'meaningfully', we are warning on
this with a very granular warning, so that this edge case will be
noticed by newer users, but can be disabled trivially.
2024-04-16 06:57:36 -07:00
|
|
|
void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) {
|
2025-01-08 10:42:40 -08:00
|
|
|
if (Clause.isConditionExprClause()) {
|
|
|
|
if (Clause.hasConditionExpr())
|
|
|
|
Profiler.VisitStmt(Clause.getConditionExpr());
|
|
|
|
} else {
|
|
|
|
for (auto *E : Clause.getVarList())
|
|
|
|
Profiler.VisitStmt(E);
|
|
|
|
}
|
[OpenACC] Implement `self` clause for compute constructs (#88760)
`self` clauses on compute constructs take an optional condition
expression. We again limit the implementation to ONLY compute constructs
to ensure we get all the rules correct for others. However, this one
will be particularly complicated, as it takes a `var-list` for `update`,
so when we get to that construct/clause combination, we need to do that
as well.
This patch also furthers uses of the `OpenACCClauses.def` as it became
useful while implementing this (as well as some other minor refactors as
I went through).
Finally, `self` and `if` clauses have an interaction with each other, if
an `if` clause evaluates to `true`, the `self` clause has no effect.
While this is intended and can be used 'meaningfully', we are warning on
this with a very granular warning, so that this edge case will be
noticed by newer users, but can be disabled trivially.
2024-04-16 06:57:36 -07:00
|
|
|
}
|
2024-04-18 12:42:22 -07:00
|
|
|
|
2024-12-13 09:34:25 -08:00
|
|
|
void OpenACCClauseProfiler::VisitFinalizeClause(
|
|
|
|
const OpenACCFinalizeClause &Clause) {}
|
|
|
|
|
2024-12-13 10:55:34 -08:00
|
|
|
void OpenACCClauseProfiler::VisitIfPresentClause(
|
|
|
|
const OpenACCIfPresentClause &Clause) {}
|
|
|
|
|
2024-04-22 08:57:25 -07:00
|
|
|
void OpenACCClauseProfiler::VisitNumGangsClause(
|
|
|
|
const OpenACCNumGangsClause &Clause) {
|
|
|
|
for (auto *E : Clause.getIntExprs())
|
|
|
|
Profiler.VisitStmt(E);
|
|
|
|
}
|
|
|
|
|
2024-10-03 08:34:43 -07:00
|
|
|
void OpenACCClauseProfiler::VisitTileClause(const OpenACCTileClause &Clause) {
|
|
|
|
for (auto *E : Clause.getSizeExprs())
|
|
|
|
Profiler.VisitStmt(E);
|
|
|
|
}
|
|
|
|
|
2024-04-18 12:42:22 -07:00
|
|
|
void OpenACCClauseProfiler::VisitNumWorkersClause(
|
|
|
|
const OpenACCNumWorkersClause &Clause) {
|
|
|
|
assert(Clause.hasIntExpr() && "num_workers clause requires a valid int expr");
|
|
|
|
Profiler.VisitStmt(Clause.getIntExpr());
|
|
|
|
}
|
|
|
|
|
2024-10-01 06:40:21 -07:00
|
|
|
void OpenACCClauseProfiler::VisitCollapseClause(
|
|
|
|
const OpenACCCollapseClause &Clause) {
|
|
|
|
assert(Clause.getLoopCount() && "collapse clause requires a valid int expr");
|
|
|
|
Profiler.VisitStmt(Clause.getLoopCount());
|
|
|
|
}
|
|
|
|
|
2024-04-30 11:28:37 -07:00
|
|
|
void OpenACCClauseProfiler::VisitPrivateClause(
|
|
|
|
const OpenACCPrivateClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-05-02 07:13:24 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitFirstPrivateClause(
|
|
|
|
const OpenACCFirstPrivateClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-05-02 08:10:57 -07:00
|
|
|
}
|
|
|
|
|
2024-05-03 08:54:06 -07:00
|
|
|
void OpenACCClauseProfiler::VisitAttachClause(
|
|
|
|
const OpenACCAttachClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-05-03 08:54:06 -07:00
|
|
|
}
|
|
|
|
|
2024-12-13 13:49:02 -08:00
|
|
|
void OpenACCClauseProfiler::VisitDetachClause(
|
|
|
|
const OpenACCDetachClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-12-13 13:49:02 -08:00
|
|
|
}
|
|
|
|
|
2024-12-16 06:27:59 -08:00
|
|
|
void OpenACCClauseProfiler::VisitDeleteClause(
|
|
|
|
const OpenACCDeleteClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-12-16 06:27:59 -08:00
|
|
|
}
|
|
|
|
|
2024-05-03 08:54:06 -07:00
|
|
|
void OpenACCClauseProfiler::VisitDevicePtrClause(
|
|
|
|
const OpenACCDevicePtrClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-05-03 08:54:06 -07:00
|
|
|
}
|
|
|
|
|
2024-05-02 08:10:57 -07:00
|
|
|
void OpenACCClauseProfiler::VisitNoCreateClause(
|
|
|
|
const OpenACCNoCreateClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-05-02 08:10:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitPresentClause(
|
|
|
|
const OpenACCPresentClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitUseDeviceClause(
|
|
|
|
const OpenACCUseDeviceClause &Clause) {
|
|
|
|
VisitClauseWithVarList(Clause);
|
2024-04-30 11:28:37 -07:00
|
|
|
}
|
|
|
|
|
2024-04-18 12:42:22 -07:00
|
|
|
void OpenACCClauseProfiler::VisitVectorLengthClause(
|
|
|
|
const OpenACCVectorLengthClause &Clause) {
|
|
|
|
assert(Clause.hasIntExpr() &&
|
|
|
|
"vector_length clause requires a valid int expr");
|
|
|
|
Profiler.VisitStmt(Clause.getIntExpr());
|
|
|
|
}
|
2024-05-06 12:02:15 -07:00
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitAsyncClause(const OpenACCAsyncClause &Clause) {
|
|
|
|
if (Clause.hasIntExpr())
|
|
|
|
Profiler.VisitStmt(Clause.getIntExpr());
|
2024-10-14 09:08:24 -07:00
|
|
|
}
|
|
|
|
|
2024-12-19 09:41:07 -08:00
|
|
|
void OpenACCClauseProfiler::VisitDeviceNumClause(
|
|
|
|
const OpenACCDeviceNumClause &Clause) {
|
|
|
|
Profiler.VisitStmt(Clause.getIntExpr());
|
2025-01-06 10:31:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitDefaultAsyncClause(
|
|
|
|
const OpenACCDefaultAsyncClause &Clause) {
|
|
|
|
Profiler.VisitStmt(Clause.getIntExpr());
|
2024-12-19 09:41:07 -08:00
|
|
|
}
|
|
|
|
|
2024-10-14 09:08:24 -07:00
|
|
|
void OpenACCClauseProfiler::VisitWorkerClause(
|
|
|
|
const OpenACCWorkerClause &Clause) {
|
|
|
|
if (Clause.hasIntExpr())
|
|
|
|
Profiler.VisitStmt(Clause.getIntExpr());
|
2024-10-15 06:12:19 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitVectorClause(
|
|
|
|
const OpenACCVectorClause &Clause) {
|
|
|
|
if (Clause.hasIntExpr())
|
|
|
|
Profiler.VisitStmt(Clause.getIntExpr());
|
2024-05-06 12:02:15 -07:00
|
|
|
}
|
2024-05-07 13:30:07 -07:00
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitWaitClause(const OpenACCWaitClause &Clause) {
|
|
|
|
if (Clause.hasDevNumExpr())
|
|
|
|
Profiler.VisitStmt(Clause.getDevNumExpr());
|
|
|
|
for (auto *E : Clause.getQueueIdExprs())
|
|
|
|
Profiler.VisitStmt(E);
|
|
|
|
}
|
2025-03-03 10:26:53 -08:00
|
|
|
|
2024-05-13 08:43:15 -07:00
|
|
|
/// Nothing to do here, there are no sub-statements.
|
|
|
|
void OpenACCClauseProfiler::VisitDeviceTypeClause(
|
|
|
|
const OpenACCDeviceTypeClause &Clause) {}
|
2024-05-21 06:51:25 -07:00
|
|
|
|
2024-05-31 07:57:24 -07:00
|
|
|
void OpenACCClauseProfiler::VisitAutoClause(const OpenACCAutoClause &Clause) {}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitIndependentClause(
|
|
|
|
const OpenACCIndependentClause &Clause) {}
|
|
|
|
|
|
|
|
void OpenACCClauseProfiler::VisitSeqClause(const OpenACCSeqClause &Clause) {}
|
|
|
|
|
2024-10-11 09:05:19 -07:00
|
|
|
void OpenACCClauseProfiler::VisitGangClause(const OpenACCGangClause &Clause) {
|
|
|
|
for (unsigned I = 0; I < Clause.getNumExprs(); ++I) {
|
|
|
|
Profiler.VisitStmt(Clause.getExpr(I).second);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-21 06:51:25 -07:00
|
|
|
void OpenACCClauseProfiler::VisitReductionClause(
|
|
|
|
const OpenACCReductionClause &Clause) {
|
2024-12-16 09:07:10 -08:00
|
|
|
VisitClauseWithVarList(Clause);
|
2024-05-21 06:51:25 -07:00
|
|
|
}
|
2024-04-05 10:06:44 -07:00
|
|
|
} // namespace
|
|
|
|
|
[OpenACC] Implement AST for OpenACC Compute Constructs (#81188)
'serial', 'parallel', and 'kernel' constructs are all considered
'Compute' constructs. This patch creates the AST type, plus the required
infrastructure for such a type, plus some base types that will be useful
in the future for breaking this up.
The only difference between the three is the 'kind'( plus some minor
clause legalization rules, but those can be differentiated easily
enough), so rather than representing them as separate AST nodes, it
seems
to make sense to make them the same.
Additionally, no clause AST functionality is being implemented yet, as
that fits better in a separate patch, and this is enough to get the
'naked' constructs implemented.
This is otherwise an 'NFC' patch, as it doesn't alter execution at all,
so there aren't any tests. I did this to break up the review workload
and to get feedback on the layout.
2024-02-13 06:02:13 -08:00
|
|
|
void StmtProfiler::VisitOpenACCComputeConstruct(
|
|
|
|
const OpenACCComputeConstruct *S) {
|
|
|
|
// VisitStmt handles children, so the AssociatedStmt is handled.
|
|
|
|
VisitStmt(S);
|
2024-04-05 10:06:44 -07:00
|
|
|
|
2024-04-12 14:13:31 -07:00
|
|
|
OpenACCClauseProfiler P{*this};
|
2024-04-05 10:06:44 -07:00
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
[OpenACC] Implement AST for OpenACC Compute Constructs (#81188)
'serial', 'parallel', and 'kernel' constructs are all considered
'Compute' constructs. This patch creates the AST type, plus the required
infrastructure for such a type, plus some base types that will be useful
in the future for breaking this up.
The only difference between the three is the 'kind'( plus some minor
clause legalization rules, but those can be differentiated easily
enough), so rather than representing them as separate AST nodes, it
seems
to make sense to make them the same.
Additionally, no clause AST functionality is being implemented yet, as
that fits better in a separate patch, and this is enough to get the
'naked' constructs implemented.
This is otherwise an 'NFC' patch, as it doesn't alter execution at all,
so there aren't any tests. I did this to break up the review workload
and to get feedback on the layout.
2024-02-13 06:02:13 -08:00
|
|
|
}
|
|
|
|
|
2024-06-05 06:21:48 -07:00
|
|
|
void StmtProfiler::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) {
|
|
|
|
// VisitStmt handles children, so the Loop is handled.
|
|
|
|
VisitStmt(S);
|
|
|
|
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
2024-11-07 14:17:55 -08:00
|
|
|
void StmtProfiler::VisitOpenACCCombinedConstruct(
|
|
|
|
const OpenACCCombinedConstruct *S) {
|
|
|
|
// VisitStmt handles children, so the Loop is handled.
|
|
|
|
VisitStmt(S);
|
|
|
|
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
2024-12-10 12:55:15 -08:00
|
|
|
void StmtProfiler::VisitOpenACCDataConstruct(const OpenACCDataConstruct *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitOpenACCEnterDataConstruct(
|
|
|
|
const OpenACCEnterDataConstruct *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitOpenACCExitDataConstruct(
|
|
|
|
const OpenACCExitDataConstruct *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitOpenACCHostDataConstruct(
|
|
|
|
const OpenACCHostDataConstruct *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
2024-12-17 07:39:20 -08:00
|
|
|
void StmtProfiler::VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *S) {
|
|
|
|
// VisitStmt covers 'children', so the exprs inside of it are covered.
|
|
|
|
VisitStmt(S);
|
|
|
|
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
2025-03-03 10:26:53 -08:00
|
|
|
void StmtProfiler::VisitOpenACCCacheConstruct(const OpenACCCacheConstruct *S) {
|
|
|
|
// VisitStmt covers 'children', so the exprs inside of it are covered.
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2024-12-19 06:11:36 -08:00
|
|
|
void StmtProfiler::VisitOpenACCInitConstruct(const OpenACCInitConstruct *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
|
|
|
void StmtProfiler::VisitOpenACCShutdownConstruct(
|
|
|
|
const OpenACCShutdownConstruct *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
2025-01-03 10:00:12 -08:00
|
|
|
void StmtProfiler::VisitOpenACCSetConstruct(const OpenACCSetConstruct *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
2025-01-06 11:59:04 -08:00
|
|
|
void StmtProfiler::VisitOpenACCUpdateConstruct(
|
|
|
|
const OpenACCUpdateConstruct *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
OpenACCClauseProfiler P{*this};
|
|
|
|
P.VisitOpenACCClauseList(S->clauses());
|
|
|
|
}
|
|
|
|
|
2025-01-22 12:22:03 -08:00
|
|
|
void StmtProfiler::VisitOpenACCAtomicConstruct(
|
|
|
|
const OpenACCAtomicConstruct *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2024-08-31 10:59:08 -05:00
|
|
|
void StmtProfiler::VisitHLSLOutArgExpr(const HLSLOutArgExpr *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
}
|
|
|
|
|
2011-01-12 09:06:06 +00:00
|
|
|
void Stmt::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
|
2023-07-11 16:12:19 +08:00
|
|
|
bool Canonical, bool ProfileLambdaExpr) const {
|
|
|
|
StmtProfilerWithPointers Profiler(ID, Context, Canonical, ProfileLambdaExpr);
|
2017-02-22 22:22:42 +00:00
|
|
|
Profiler.Visit(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Stmt::ProcessODRHash(llvm::FoldingSetNodeID &ID,
|
|
|
|
class ODRHash &Hash) const {
|
|
|
|
StmtProfilerWithoutPointers Profiler(ID, Hash);
|
2009-07-28 00:33:38 +00:00
|
|
|
Profiler.Visit(this);
|
|
|
|
}
|