-
Notifications
You must be signed in to change notification settings - Fork 768
[SYCL] defer kernel diagnostics #181
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,18 +38,6 @@ enum target { | |
image_array | ||
}; | ||
|
||
enum RestrictKind { | ||
KernelGlobalVariable, | ||
KernelRTTI, | ||
KernelNonConstStaticDataVariable, | ||
KernelCallVirtualFunction, | ||
KernelCallRecursiveFunction, | ||
KernelCallFunctionPointer, | ||
KernelAllocateStorage, | ||
KernelUseExceptions, | ||
KernelUseAssembly | ||
}; | ||
|
||
using ParamDesc = std::tuple<QualType, IdentifierInfo *, TypeSourceInfo *>; | ||
|
||
/// Various utilities. | ||
|
@@ -95,16 +83,16 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
// definitions. | ||
if (RecursiveSet.count(Callee)) { | ||
SemaRef.Diag(e->getExprLoc(), diag::err_sycl_restrict) | ||
<< KernelCallRecursiveFunction; | ||
<< Sema::KernelCallRecursiveFunction; | ||
SemaRef.Diag(Callee->getSourceRange().getBegin(), | ||
diag::note_sycl_recursive_function_declared_here) | ||
<< KernelCallRecursiveFunction; | ||
<< Sema::KernelCallRecursiveFunction; | ||
} | ||
|
||
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Callee)) | ||
if (Method->isVirtual()) | ||
SemaRef.Diag(e->getExprLoc(), diag::err_sycl_restrict) | ||
<< KernelCallVirtualFunction; | ||
<< Sema::KernelCallVirtualFunction; | ||
|
||
CheckSYCLType(Callee->getReturnType(), Callee->getSourceRange()); | ||
|
||
|
@@ -116,7 +104,7 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
} | ||
} else if (!SemaRef.getLangOpts().SYCLAllowFuncPtr) | ||
SemaRef.Diag(e->getExprLoc(), diag::err_sycl_restrict) | ||
<< KernelCallFunctionPointer; | ||
<< Sema::KernelCallFunctionPointer; | ||
return true; | ||
} | ||
|
||
|
@@ -144,12 +132,12 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
} | ||
|
||
bool VisitCXXTypeidExpr(CXXTypeidExpr *E) { | ||
SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) << KernelRTTI; | ||
SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) << Sema::KernelRTTI; | ||
return true; | ||
} | ||
|
||
bool VisitCXXDynamicCastExpr(const CXXDynamicCastExpr *E) { | ||
SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) << KernelRTTI; | ||
SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) << Sema::KernelRTTI; | ||
return true; | ||
} | ||
|
||
|
@@ -178,7 +166,7 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
bool IsConst = VD->getType().getNonReferenceType().isConstQualified(); | ||
if (!IsConst && VD->isStaticDataMember()) | ||
SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) | ||
<< KernelNonConstStaticDataVariable; | ||
<< Sema::KernelNonConstStaticDataVariable; | ||
} | ||
return true; | ||
} | ||
|
@@ -189,11 +177,11 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
bool IsConst = VD->getType().getNonReferenceType().isConstQualified(); | ||
if (!IsConst && VD->isStaticDataMember()) | ||
SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) | ||
<< KernelNonConstStaticDataVariable; | ||
<< Sema::KernelNonConstStaticDataVariable; | ||
else if (!IsConst && VD->hasGlobalStorage() && !VD->isStaticLocal() && | ||
!VD->isStaticDataMember() && !isa<ParmVarDecl>(VD)) | ||
SemaRef.Diag(E->getLocation(), diag::err_sycl_restrict) | ||
<< KernelGlobalVariable; | ||
<< Sema::KernelGlobalVariable; | ||
if (!VD->isLocalVarDeclOrParm() && VD->hasGlobalStorage()) { | ||
VD->addAttr(SYCLDeviceAttr::CreateImplicit(SemaRef.Context)); | ||
SemaRef.addSyclDeviceDecl(VD); | ||
|
@@ -213,7 +201,7 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
if (FunctionDecl *FD = E->getOperatorNew()) { | ||
if (FD->isReplaceableGlobalAllocationFunction()) { | ||
SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) | ||
<< KernelAllocateStorage; | ||
<< Sema::KernelAllocateStorage; | ||
} else if (FunctionDecl *Def = FD->getDefinition()) { | ||
if (!Def->hasAttr<SYCLDeviceAttr>()) { | ||
Def->addAttr(SYCLDeviceAttr::CreateImplicit(SemaRef.Context)); | ||
|
@@ -223,40 +211,16 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
} | ||
return true; | ||
} | ||
|
||
bool VisitCXXThrowExpr(CXXThrowExpr *E) { | ||
SemaRef.Diag(E->getExprLoc(), diag::err_sycl_restrict) | ||
<< KernelUseExceptions; | ||
return true; | ||
} | ||
|
||
bool VisitCXXCatchStmt(CXXCatchStmt *S) { | ||
SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) | ||
<< KernelUseExceptions; | ||
return true; | ||
} | ||
|
||
bool VisitCXXTryStmt(CXXTryStmt *S) { | ||
SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) | ||
<< KernelUseExceptions; | ||
return true; | ||
} | ||
|
||
bool VisitSEHTryStmt(SEHTryStmt *S) { | ||
SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) | ||
<< KernelUseExceptions; | ||
return true; | ||
} | ||
|
||
|
||
bool VisitGCCAsmStmt(GCCAsmStmt *S) { | ||
SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) | ||
<< KernelUseAssembly; | ||
<< Sema::KernelUseAssembly; | ||
return true; | ||
} | ||
|
||
bool VisitMSAsmStmt(MSAsmStmt *S) { | ||
SemaRef.Diag(S->getBeginLoc(), diag::err_sycl_restrict) | ||
<< KernelUseAssembly; | ||
<< Sema::KernelUseAssembly; | ||
return true; | ||
} | ||
|
||
|
@@ -361,21 +325,31 @@ class MarkDeviceFunction : public RecursiveASTVisitor<MarkDeviceFunction> { | |
return true; | ||
|
||
if (CRD->isPolymorphic()) { | ||
SemaRef.Diag(CRD->getLocation(), diag::err_sycl_virtual_types); | ||
SemaRef.Diag(Loc.getBegin(), diag::note_sycl_used_here); | ||
// Exceptions aren't allowed in SYCL device code. | ||
if (SemaRef.getLangOpts().SYCLIsDevice) { | ||
SemaRef.SYCLDiagIfDeviceCode(CRD->getLocation(), | ||
diag::err_sycl_restrict) | ||
<< Sema::KernelHavePolymorphicClass; | ||
SemaRef.SYCLDiagIfDeviceCode(Loc.getBegin(), | ||
diag::note_sycl_used_here); | ||
} | ||
return false; | ||
} | ||
|
||
for (const auto &Field : CRD->fields()) { | ||
if (!CheckSYCLType(Field->getType(), Field->getSourceRange(), Visited)) { | ||
SemaRef.Diag(Loc.getBegin(), diag::note_sycl_used_here); | ||
if (SemaRef.getLangOpts().SYCLIsDevice) | ||
SemaRef.SYCLDiagIfDeviceCode(Loc.getBegin(), | ||
diag::note_sycl_used_here); | ||
return false; | ||
} | ||
} | ||
} else if (const auto *RD = Ty->getAsRecordDecl()) { | ||
for (const auto &Field : RD->fields()) { | ||
if (!CheckSYCLType(Field->getType(), Field->getSourceRange(), Visited)) { | ||
SemaRef.Diag(Loc.getBegin(), diag::note_sycl_used_here); | ||
if (SemaRef.getLangOpts().SYCLIsDevice) | ||
SemaRef.SYCLDiagIfDeviceCode(Loc.getBegin(), | ||
diag::note_sycl_used_here); | ||
return false; | ||
} | ||
} | ||
|
@@ -1036,6 +1010,54 @@ void Sema::MarkDevice(void) { | |
} | ||
} | ||
} | ||
// | ||
// Do we know that we will eventually codegen the given function? | ||
static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { | ||
if (!FD) | ||
return true; // Seen in LIT testing | ||
|
||
if (FD->hasAttr<SYCLDeviceAttr>() || | ||
FD->hasAttr<SYCLKernelAttr>()) | ||
return true; | ||
|
||
// Templates are emitted when they're instantiated. | ||
if (FD->isDependentContext()) | ||
return false; | ||
|
||
// Otherwise, the function is known-emitted if it's in our set of | ||
// known-emitted functions. | ||
return S.DeviceKnownEmittedFns.count(FD) > 0; | ||
} | ||
|
||
Sema::DeviceDiagBuilder Sema::SYCLDiagIfDeviceCode(SourceLocation Loc, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi Premanand, I need something like this function to avoid emitting an error for a function that has varargs and which is not part of DEVICE code. Q1: Would your fix help with this error: "variadic function cannot use spir_function calling convention" emitted from SemaType.cpp:7014 ? Q2: This MergeRequest was created almost 2 weeks ago. Is there some ETA for this fix approval/merge? |
||
unsigned DiagID) { | ||
assert(getLangOpts().SYCLIsDevice && | ||
"Should only be called during SYCL compilation"); | ||
DeviceDiagBuilder::Kind DiagKind = [this] { | ||
if (isKnownEmitted(*this, dyn_cast<FunctionDecl>(CurContext))) | ||
return DeviceDiagBuilder::K_ImmediateWithCallStack; | ||
return DeviceDiagBuilder::K_Deferred; | ||
}(); | ||
return DeviceDiagBuilder(DiagKind, Loc, DiagID, | ||
dyn_cast<FunctionDecl>(CurContext), *this); | ||
} | ||
|
||
bool Sema::CheckSYCLCall(SourceLocation Loc, FunctionDecl *Callee) { | ||
|
||
assert(Callee && "Callee may not be null."); | ||
FunctionDecl *Caller = getCurFunctionDecl(); | ||
|
||
// If the caller is known-emitted, mark the callee as known-emitted. | ||
// Otherwise, mark the call in our call graph so we can traverse it later. | ||
if (//!isOpenMPDeviceDelayedContext(*this) || | ||
(Caller && Caller->hasAttr<SYCLKernelAttr>()) || | ||
(Caller && Caller->hasAttr<SYCLDeviceAttr>()) || | ||
(Caller && isKnownEmitted(*this, Caller))) | ||
markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); | ||
else if (Caller) | ||
DeviceCallGraph[Caller].insert({Callee, Loc}); | ||
return true; | ||
} | ||
|
||
// ----------------------------------------------------------------------------- | ||
// Integration header functionality implementation | ||
|
Uh oh!
There was an error while loading. Please reload this page.