Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9240a18
Add support for host kernel launch stmt generation
Fznamznon Aug 20, 2025
e0bb6e9
Remove a fixme from SemaSYCL
Fznamznon Sep 3, 2025
ad0065b
Do not crash if original body was invalid
Fznamznon Sep 3, 2025
145e850
Add AST test for skep-attributed member
Fznamznon Sep 3, 2025
9c91fce
Fix a warning
Fznamznon Sep 3, 2025
07967ea
Extend codegen test a bit
Fznamznon Sep 3, 2025
520a4e6
Find and replace
Fznamznon Sep 10, 2025
319caa5
Implement the thing
Fznamznon Sep 12, 2025
2c89c01
One more find and replace
Fznamznon Sep 12, 2025
aa02c24
I don't know how it looks like
Fznamznon Sep 12, 2025
c3d3035
Find and replace again
Fznamznon Sep 16, 2025
cb314fe
Switch to UnresolvedSYCLKernelEntryPointStmt
Fznamznon Sep 17, 2025
76d904b
Apply suggestions from code review
Fznamznon Sep 18, 2025
6f2541b
Remove log.txt
Fznamznon Sep 18, 2025
db002bb
Implement visiting
Fznamznon Sep 18, 2025
345e7b7
Add tests
Fznamznon Sep 19, 2025
2c155ef
Apply suggestions from code review
Fznamznon Sep 19, 2025
6d7e4c1
IdExpr -> KernelLaunchIdExpr
Fznamznon Sep 19, 2025
7e3a0bf
Don't rely on compound
Fznamznon Sep 19, 2025
b48996e
UnresolvedSYCLKernelEntryPointStmt -> UnresolvedSYCLKernelCall
Fznamznon Sep 19, 2025
1193734
Fix warnings
Fznamznon Sep 24, 2025
c83509b
Rename sycl_enqueue_kernel_launch -> sycl_kernel_launch
Fznamznon Sep 24, 2025
cb21a34
Apply suggestions from code review
Fznamznon Sep 24, 2025
07402a9
Remove array decay
Fznamznon Sep 25, 2025
1b2d1dd
Add windows run line to the sema test
Fznamznon Sep 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/AST/ComputeDependence.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class CXXParenListInitExpr;
class TypeTraitExpr;
class ConceptSpecializationExpr;
class SYCLUniqueStableNameExpr;
class UnresolvedSYCLKernelLaunchExpr;
class PredefinedExpr;
class CallExpr;
class OffsetOfExpr;
Expand Down Expand Up @@ -179,6 +180,7 @@ ExprDependence computeDependence(ConceptSpecializationExpr *E,
bool ValueDependent);

ExprDependence computeDependence(SYCLUniqueStableNameExpr *E);
ExprDependence computeDependence(UnresolvedSYCLKernelLaunchExpr *E);
ExprDependence computeDependence(PredefinedExpr *E);
ExprDependence computeDependence(CallExpr *E, ArrayRef<Expr *> PreArgs);
ExprDependence computeDependence(OffsetOfExpr *E);
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2999,6 +2999,7 @@ DEF_TRAVERSE_STMT(ParenListExpr, {})
DEF_TRAVERSE_STMT(SYCLUniqueStableNameExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
})
DEF_TRAVERSE_STMT(UnresolvedSYCLKernelLaunchExpr, {})
DEF_TRAVERSE_STMT(OpenACCAsteriskSizeExpr, {})
DEF_TRAVERSE_STMT(PredefinedExpr, {})
DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
Expand Down
53 changes: 53 additions & 0 deletions clang/include/clang/AST/StmtSYCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,59 @@ class SYCLKernelCallStmt : public Stmt {
}
};

// UnresolvedSYCLKernelLaunchExpr a call to the kernel launch function for a
// kernel that has not been instantiated yet. This Expr should be transformed to
// a CallExpr once the kernel and its name is known.
class UnresolvedSYCLKernelLaunchExpr : public Expr {
friend class ASTStmtReader;
QualType KernelNameType;
SourceLocation Loc;
// This is either UnresolvedLookupExpr or UnresolvedMemberExpr.
Expr *IdExpr = nullptr;
UnresolvedSYCLKernelLaunchExpr(SourceLocation L, QualType ExprTy,
QualType KNT, Expr *_IdExpr)
: Expr(UnresolvedSYCLKernelLaunchExprClass, ExprTy, VK_PRValue,
OK_Ordinary),
KernelNameType(KNT), Loc(L), IdExpr(_IdExpr) {
setDependence(computeDependence(this));
}

void setKernelNameType(QualType T) { KernelNameType = T; }
void setLocation(SourceLocation L) { Loc = L; }
void setIdExpr(Expr *Id) { IdExpr = Id; }

public:
static UnresolvedSYCLKernelLaunchExpr *Create(const ASTContext &C,
QualType ExprTy, QualType KNT,
SourceLocation Loc,
Expr *IdExpr) {
return new (C) UnresolvedSYCLKernelLaunchExpr(Loc, ExprTy, KNT, IdExpr);
}

static UnresolvedSYCLKernelLaunchExpr *CreateEmpty(const ASTContext &C) {
return new (C)
UnresolvedSYCLKernelLaunchExpr({}, C.VoidTy, C.VoidTy, nullptr);
}

QualType getKernelNameType() const { return KernelNameType; }
Expr *getIdExpr() const { return IdExpr; }
SourceLocation getLocation() const { return Loc; }

SourceLocation getBeginLoc() const { return Loc; }
SourceLocation getEndLoc() const { return Loc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnresolvedSYCLKernelLaunchExprClass;
}
// Iterators
child_range children() {
return child_range(child_iterator(), child_iterator());
}

const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

} // end namespace clang

#endif // LLVM_CLANG_AST_STMTSYCL_H
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -13015,6 +13015,15 @@ def err_sycl_entry_point_return_type : Error<
def err_sycl_entry_point_deduced_return_type : Error<
"the %0 attribute only applies to functions with a non-deduced 'void' return"
" type">;
def err_sycl_host_no_launch_function : Error<
"unable to find suitable 'sycl_enqueue_kernel_launch' function for host code "
"synthesis">;
def warn_sycl_device_no_host_launch_function : Warning<
"unable to find suitable 'sycl_enqueue_kernel_launch' function for host code "
"synthesis">,
InGroup<DiagGroup<"sycl-host-launcher">>;
def note_sycl_host_launch_function : Note<
"define 'sycl_enqueue_kernel_launch' function template to fix this problem">;

def warn_cuda_maxclusterrank_sm_90 : Warning<
"maxclusterrank requires sm_90 or higher, CUDA arch provided: %0, ignoring "
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/StmtNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def CoreturnStmt : StmtNode<Stmt>;
def Expr : StmtNode<ValueStmt, 1>;
def PredefinedExpr : StmtNode<Expr>;
def SYCLUniqueStableNameExpr : StmtNode<Expr>;
def UnresolvedSYCLKernelLaunchExpr : StmtNode<Expr>;
def DeclRefExpr : StmtNode<Expr>;
def IntegerLiteral : StmtNode<Expr>;
def FixedPointLiteral : StmtNode<Expr>;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Sema/ScopeInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ class FunctionScopeInfo {
/// The set of GNU address of label extension "&&label".
llvm::SmallVector<AddrLabelExpr *, 4> AddrLabels;

CompoundStmt *SYCLKernelLaunchStmt = nullptr;

public:
/// Represents a simple identification of a weak object.
///
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Sema/SemaSYCL.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ class SemaSYCL : public SemaBase {

void CheckSYCLExternalFunctionDecl(FunctionDecl *FD);
void CheckSYCLEntryPointFunctionDecl(FunctionDecl *FD);
StmtResult BuildSYCLKernelCallStmt(FunctionDecl *FD, CompoundStmt *Body);
StmtResult BuildSYCLKernelCallStmt(FunctionDecl *FD, CompoundStmt *Body,
CompoundStmt *LaunchStmt);
CompoundStmt *BuildSYCLKernelLaunchStmt(FunctionDecl *FD, QualType KNT);
ExprResult createSYCLKernelLaunchCall(const SYCLKernelInfo *SKI, Expr *IdExpr,
SourceLocation Loc);
};

} // namespace clang
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -2040,6 +2040,9 @@ enum StmtCode {
// SYCLUniqueStableNameExpr
EXPR_SYCL_UNIQUE_STABLE_NAME,

// UnresolvedSYCLKernelName
EXPR_UNRESOLVED_SYCL_KERNEL_LAUNCH,

// OpenACC Constructs/Exprs
STMT_OPENACC_COMPUTE_CONSTRUCT,
STMT_OPENACC_LOOP_CONSTRUCT,
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/ComputeDependence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/StmtSYCL.h"
#include "clang/Basic/ExceptionSpecificationType.h"
#include "llvm/ADT/ArrayRef.h"

Expand Down Expand Up @@ -634,6 +635,10 @@ ExprDependence clang::computeDependence(SYCLUniqueStableNameExpr *E) {
E->getTypeSourceInfo()->getType()->getDependence());
}

ExprDependence clang::computeDependence(UnresolvedSYCLKernelLaunchExpr *E) {
return toExprDependenceAsWritten(E->getKernelNameType()->getDependence());
}

ExprDependence clang::computeDependence(PredefinedExpr *E) {
return toExprDependenceForImpliedType(E->getType()->getDependence());
}
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3697,6 +3697,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
case PackIndexingExprClass:
case HLSLOutArgExprClass:
case OpenACCAsteriskSizeExprClass:
case UnresolvedSYCLKernelLaunchExprClass:
// These never have a side-effect.
return false;

Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17760,6 +17760,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case Expr::DependentCoawaitExprClass:
case Expr::CoyieldExprClass:
case Expr::SYCLUniqueStableNameExprClass:
case Expr::UnresolvedSYCLKernelLaunchExprClass:
case Expr::CXXParenListInitExprClass:
case Expr::HLSLOutArgExprClass:
return ICEDiag(IK_NotICE, E->getBeginLoc());
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5019,6 +5019,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
case Expr::AtomicExprClass:
case Expr::SourceLocExprClass:
case Expr::EmbedExprClass:
case Expr::UnresolvedSYCLKernelLaunchExprClass:
case Expr::BuiltinBitCastExprClass: {
NotPrimaryExpr();
if (!NullOut) {
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/AST/StmtPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,13 @@ void StmtPrinter::VisitSYCLUniqueStableNameExpr(
OS << ")";
}

void StmtPrinter::VisitUnresolvedSYCLKernelLaunchExpr(
UnresolvedSYCLKernelLaunchExpr *Node) {
OS << "sycl_kernel_name(";
Node->getKernelNameType().print(OS, Policy);
OS << ")";
}

void StmtPrinter::VisitPredefinedExpr(PredefinedExpr *Node) {
OS << PredefinedExpr::getIdentKindName(Node->getIdentKind());
}
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/StmtProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,11 @@ void StmtProfiler::VisitSYCLUniqueStableNameExpr(
VisitType(S->getTypeSourceInfo()->getType());
}

void StmtProfiler::VisitUnresolvedSYCLKernelLaunchExpr(
const UnresolvedSYCLKernelLaunchExpr *S) {
VisitExpr(S);
}

void StmtProfiler::VisitPredefinedExpr(const PredefinedExpr *S) {
VisitExpr(S);
ID.AddInteger(llvm::to_underlying(S->getIdentKind()));
Expand Down
26 changes: 22 additions & 4 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15754,7 +15754,6 @@ Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D,
if (!Bases.empty())
OpenMP().ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Dcl,
Bases);

return Dcl;
}

Expand Down Expand Up @@ -16167,6 +16166,20 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,

maybeAddDeclWithEffects(FD);

if (FD && !FD->isInvalidDecl() &&
FD->hasAttr<SYCLKernelEntryPointAttr>() && FnBodyScope) {
// Building KernelLaunchStmt requires performing an unqualified lookup which
// can only be done correctly while the stack of parsing scopes is alive, so
// we do it here when we start parsing function body even if it is a
// templated function.
const auto *SKEPAttr = FD->getAttr<SYCLKernelEntryPointAttr>();
if (!SKEPAttr->isInvalidAttr()) {
CompoundStmt *LaunchStmt =
SYCL().BuildSYCLKernelLaunchStmt(FD, SKEPAttr->getKernelName());
getCurFunction()->SYCLKernelLaunchStmt = LaunchStmt;
}
}

return D;
}

Expand Down Expand Up @@ -16368,9 +16381,14 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation,
SKEPAttr->setInvalidAttr();
}

if (Body && !FD->isTemplated() && !SKEPAttr->isInvalidAttr()) {
StmtResult SR =
SYCL().BuildSYCLKernelCallStmt(FD, cast<CompoundStmt>(Body));
auto *BodyCompound = dyn_cast_or_null<CompoundStmt>(Body);
// If Body is not a compound, that was a templated function and we don't
// need to build SYCLKernelCallStmt for it since it was already created by
// template instantiator.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little nervous about relying on a check for CompountStmt specifically here to determine what to build. I think there are three cases to consider:

  1. A function template or templated function for which an UnresolvedSYCLKernelEntryPointStmt is needed.
  2. An instantiated function template for which a SYCLKernelCallStmt was already instantiated.
  3. An explicit function template specialization or a non-template function for which a SYCLKernelCallStmt is needed.

I think these can be differentiated as follows:

  1. if FD->isTemplated() is true.
  2. otherwise, if FD->getTemplateSpecializationInfo() is non-null and isTemplateInstantiation(FD->getTemplateSpecializationKind())` is true.
  3. everything else.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated. FD->getTemplateSpecializationInfo() && isTemplateInstantiation(FD->getTemplateSpecializationKind()) seems to be breaking some tests. I used FD->isTemplateInstantiation() to detect the case instead.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I added the FD->getTemplateSpecializationInfo() condition because I wasn't sure what FD->getTemplateSpecializationKind() would return for a non-template function. But if it works as expected, then great.

There is a comment in the FunctionDecl::isTemplateInstantiation() definition that I don't really know what to make of. My best guess is that it relates to a possible ambiguous classification of an instantiated dependent explicit specialization. It could also be that the FIXME comment is old/stale; I didn't dig into it. The isTemplateInstantiation() name certainly suggests it is what we want here.

bool FunctionDecl::isTemplateInstantiation() const {
  // FIXME: Remove this, it's not clear what it means. (Which template
  // specialization kind?)
  return clang::isTemplateInstantiation(getTemplateSpecializationKind());
}

if (BodyCompound && !SKEPAttr->isInvalidAttr()) {
StmtResult SR = SYCL().BuildSYCLKernelCallStmt(
FD->isTemplated() ? nullptr : FD, BodyCompound,
getCurFunction()->SYCLKernelLaunchStmt);
if (SR.isInvalid())
return nullptr;
Body = SR.get();
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaExceptionSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
case Expr::UnaryExprOrTypeTraitExprClass:
case Expr::UnresolvedLookupExprClass:
case Expr::UnresolvedMemberExprClass:
case Expr::UnresolvedSYCLKernelLaunchExprClass:
// FIXME: Many of the above can throw.
return CT_Cannot;

Expand Down
Loading