Skip to content

Commit d0d8a56

Browse files
NaghasansommerlukasAD2605maarquitos14callumfare
authored
Implement work_group_static / work_group_scratch_memory (#15061)
The patch partially implements `work_group_static` and update proposal. Implemented: - `work_group_static` to handle static allocation in kernel. - `get_dynamic_work_group_memory` to handle runtime allocation, but only on CUDA `work_group_static` is implemented by exposing `SYCLScope(WorkGroup)`, allowing the class to be decorated by the attribute and uses the same mechanism during lowering to place the variable in local memory. `get_dynamic_work_group_memory` uses a new builtin function, `__sycl_dynamicLocalMemoryPlaceholder `, which is lowered into referencing a 0 sized array GV when targeting NVPTX. The approach for SPIR will need to differ from this lowering. UR change oneapi-src/unified-runtime#1968, oneapi-src/unified-runtime#2403 --------- Signed-off-by: Lukas Sommer <[email protected]> Signed-off-by: Victor Lomuller <[email protected]> Co-authored-by: Lukas Sommer <[email protected]> Co-authored-by: Atharva Dubey <[email protected]> Co-authored-by: Marcos Maronas <[email protected]> Co-authored-by: Callum Fare <[email protected]> Co-authored-by: Martin Morrison-Grant <[email protected]>
1 parent 8a17167 commit d0d8a56

File tree

66 files changed

+1816
-388
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+1816
-388
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,12 +1682,12 @@ def SYCLIntelESimdVectorize : InheritableAttr {
16821682
}
16831683

16841684
def SYCLScope : Attr {
1685-
// No spelling, as this attribute can't be created in the source code.
1686-
let Spellings = [];
1685+
let Spellings = [CXX11<"__sycl_detail__", "wg_scope">];
16871686
let Args = [EnumArgument<"level", "Level", /*is_string=*/false,
16881687
["work_group", "work_item"],
1689-
["WorkGroup", "WorkItem"]>];
1690-
let Subjects = SubjectList<[Function, Var]>;
1688+
["WorkGroup", "WorkItem"],
1689+
/*optional=*/true>];
1690+
let Subjects = SubjectList<[Function, Var, CXXRecord]>;
16911691
let LangOpts = [SYCLIsDevice];
16921692

16931693
let AdditionalMembers = [{
@@ -1700,7 +1700,7 @@ def SYCLScope : Attr {
17001700
}
17011701
}];
17021702

1703-
let Documentation = [InternalOnly];
1703+
let Documentation = [SYCLWGScopeDocs];
17041704
}
17051705

17061706
def SYCLDeviceIndirectlyCallable : InheritableAttr {

clang/include/clang/Basic/AttrDocs.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4271,6 +4271,18 @@ function pointer for the specified function.
42714271
}];
42724272
}
42734273

4274+
def SYCLWGScopeDocs : Documentation {
4275+
let Category = DocCatFunction;
4276+
let Heading = "__sycl_detail__::wg_scope";
4277+
let Content = [{
4278+
This attribute can only be applied to records with a trivial default constructor and destructor.
4279+
Types with this attribute cannot be used for non-static data members.
4280+
It indicates that any block and namespace scope variable of a type holding this attribute
4281+
will be allocated in local memory. For variables allocated in block scope, they behave
4282+
as implicitly declared as static.
4283+
}];
4284+
}
4285+
42744286
def SYCLDeviceDocs : Documentation {
42754287
let Category = DocCatFunction;
42764288
let Heading = "sycl_device";

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12556,6 +12556,11 @@ def err_sycl_external_global : Error<
1255612556
def warn_sycl_kernel_too_big_args : Warning<
1255712557
"size of kernel arguments (%0 bytes) may exceed the supported maximum "
1255812558
"of %1 bytes on some devices">, InGroup<SyclStrict>, ShowInSystemHeader;
12559+
def err_sycl_wg_scope : Error<
12560+
"SYCL work group scope only applies to class with a trivial "
12561+
"%select{default constructor|destructor}0">;
12562+
def err_sycl_field_with_wg_scope : Error<
12563+
"non-static data member is of a type with a SYCL work group scope attribute applied to it">;
1255912564
def err_sycl_virtual_types : Error<
1256012565
"no class with a vtable can be used in a SYCL kernel or any code included in the kernel">;
1256112566
def note_sycl_recursive_function_declared_here: Note<"function implemented using recursion declared here">;

clang/include/clang/Sema/SemaSYCL.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ class SemaSYCL : public SemaBase {
267267

268268
void CheckSYCLKernelCall(FunctionDecl *CallerFunc,
269269
ArrayRef<const Expr *> Args);
270+
void CheckSYCLScopeAttr(CXXRecordDecl *Decl);
270271

271272
/// Creates a SemaDiagnosticBuilder that emits the diagnostic if the current
272273
/// context is "used as device code".
@@ -478,6 +479,7 @@ class SemaSYCL : public SemaBase {
478479
const ParsedAttr &AL);
479480
void handleSYCLIntelMaxWorkGroupsPerMultiprocessor(Decl *D,
480481
const ParsedAttr &AL);
482+
void handleSYCLScopeAttr(Decl *D, const ParsedAttr &AL);
481483

482484
void checkSYCLAddIRAttributesFunctionAttrConflicts(Decl *D);
483485

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,11 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
217217
if (D.getType().getAddressSpace() == LangAS::opencl_local)
218218
return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D);
219219

220-
if (D.getAttr<SYCLScopeAttr>() && D.getAttr<SYCLScopeAttr>()->isWorkGroup())
220+
SYCLScopeAttr *ScopeAttr = D.getAttr<SYCLScopeAttr>();
221+
if (!ScopeAttr)
222+
if (auto *RD = D.getType()->getAsCXXRecordDecl())
223+
ScopeAttr = RD->getAttr<SYCLScopeAttr>();
224+
if (ScopeAttr && ScopeAttr->isWorkGroup())
221225
return CGM.getSYCLRuntime().emitWorkGroupLocalVarDecl(*this, D);
222226

223227
assert(D.hasLocalStorage());

clang/lib/CodeGen/CGSYCLRuntime.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,10 @@ void CGSYCLRuntime::emitWorkGroupLocalVarDecl(CodeGenFunction &CGF,
9696
const VarDecl &D) {
9797
#ifndef NDEBUG
9898
SYCLScopeAttr *Scope = D.getAttr<SYCLScopeAttr>();
99-
assert(Scope && Scope->isWorkGroup() && "work group scope expected");
99+
if (!Scope)
100+
if (auto *RD = D.getType()->getAsCXXRecordDecl())
101+
Scope = RD->getAttr<SYCLScopeAttr>();
102+
assert((Scope && Scope->isWorkGroup()) && "work group scope expected");
100103
#endif // NDEBUG
101104
// generate global variable in the address space selected by the clang CodeGen
102105
// (should be local)

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5789,6 +5789,9 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
57895789

57905790
if (LangOpts.SYCLIsDevice && D) {
57915791
auto *Scope = D->getAttr<SYCLScopeAttr>();
5792+
if (!Scope)
5793+
if (auto *RD = D->getType()->getAsCXXRecordDecl())
5794+
Scope = RD->getAttr<SYCLScopeAttr>();
57925795
if (Scope && Scope->isWorkGroup())
57935796
return LangAS::sycl_local;
57945797
}

clang/lib/Sema/Sema.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1849,7 +1849,9 @@ class DeferredDiagnosticsEmitter
18491849
if (!S.SYCL().checkAllowedSYCLInitializer(VD) &&
18501850
!S.SYCL()
18511851
.isTypeDecoratedWithDeclAttribute<
1852-
SYCLGlobalVariableAllowedAttr>(VD->getType())) {
1852+
SYCLGlobalVariableAllowedAttr>(VD->getType()) &&
1853+
!S.SYCL().isTypeDecoratedWithDeclAttribute<SYCLScopeAttr>(
1854+
VD->getType())) {
18531855
S.Diag(Loc, diag::err_sycl_restrict)
18541856
<< SemaSYCL::KernelConstStaticVariable;
18551857
return;

clang/lib/Sema/SemaDecl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7876,6 +7876,8 @@ NamedDecl *Sema::ActOnVariableDeclarator(
78767876
// attribute.
78777877
if (SCSpec == DeclSpec::SCS_static && !R.isConstant(Context) &&
78787878
!SYCL().isTypeDecoratedWithDeclAttribute<SYCLGlobalVariableAllowedAttr>(
7879+
NewVD->getType()) &&
7880+
!SYCL().isTypeDecoratedWithDeclAttribute<SYCLScopeAttr>(
78797881
NewVD->getType()))
78807882
SYCL().DiagIfDeviceCode(D.getIdentifierLoc(), diag::err_sycl_restrict)
78817883
<< SemaSYCL::KernelNonConstStaticDataVariable;
@@ -18578,6 +18580,14 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
1857818580
InvalidDecl = true;
1857918581
}
1858018582

18583+
if (LangOpts.SYCLIsDevice) {
18584+
const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
18585+
if (RD && RD->hasAttr<SYCLScopeAttr>()) {
18586+
Diag(Loc, diag::err_sycl_field_with_wg_scope);
18587+
InvalidDecl = true;
18588+
}
18589+
}
18590+
1858118591
if (LangOpts.OpenCL) {
1858218592
// OpenCL v1.2 s6.9b,r & OpenCL v2.0 s6.12.5 - The following types cannot be
1858318593
// used as structure or union field: image, sampler, event or block types.

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6717,6 +6717,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
67176717
case ParsedAttr::AT_SYCLDevice:
67186718
S.SYCL().handleSYCLDeviceAttr(D, AL);
67196719
break;
6720+
case ParsedAttr::AT_SYCLScope:
6721+
S.SYCL().handleSYCLScopeAttr(D, AL);
6722+
break;
67206723
case ParsedAttr::AT_SYCLDeviceIndirectlyCallable:
67216724
S.SYCL().handleSYCLDeviceIndirectlyCallableAttr(D, AL);
67226725
break;

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7217,6 +7217,9 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
72177217
else if (Record->hasAttr<CUDADeviceBuiltinTextureTypeAttr>())
72187218
checkCUDADeviceBuiltinTextureClassTemplate(*this, Record);
72197219
}
7220+
if (getLangOpts().SYCLIsDevice && Record->hasAttr<SYCLScopeAttr>()) {
7221+
SYCL().CheckSYCLScopeAttr(Record);
7222+
}
72207223
}
72217224

72227225
/// Look up the special member function that would be called by a special

clang/lib/Sema/SemaExpr.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,15 +235,19 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
235235
VD->getStorageClass() == SC_Static &&
236236
!VD->hasAttr<SYCLGlobalVarAttr>() &&
237237
!SemaSYCL::isTypeDecoratedWithDeclAttribute<
238-
SYCLGlobalVariableAllowedAttr>(VD->getType()))
238+
SYCLGlobalVariableAllowedAttr>(VD->getType()) &&
239+
!SemaSYCL::isTypeDecoratedWithDeclAttribute<SYCLScopeAttr>(
240+
VD->getType()))
239241
SYCL().DiagIfDeviceCode(*Locs.begin(), diag::err_sycl_restrict)
240242
<< SemaSYCL::KernelNonConstStaticDataVariable;
241243
// Non-const globals are not allowed in SYCL except for ESIMD or with the
242244
// SYCLGlobalVar or SYCLGlobalVariableAllowed attribute.
243245
else if (IsRuntimeEvaluated && !IsEsimdPrivateGlobal && !IsConst &&
244246
VD->hasGlobalStorage() && !VD->hasAttr<SYCLGlobalVarAttr>() &&
245247
!SemaSYCL::isTypeDecoratedWithDeclAttribute<
246-
SYCLGlobalVariableAllowedAttr>(VD->getType()))
248+
SYCLGlobalVariableAllowedAttr>(VD->getType()) &&
249+
!SemaSYCL::isTypeDecoratedWithDeclAttribute<SYCLScopeAttr>(
250+
VD->getType()))
247251
SYCL().DiagIfDeviceCode(*Locs.begin(), diag::err_sycl_restrict)
248252
<< SemaSYCL::KernelGlobalVariable;
249253
// ESIMD globals cannot be used in a SYCL context.

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5210,6 +5210,28 @@ void SemaSYCL::CheckSYCLKernelCall(FunctionDecl *KernelFunc,
52105210
KernelFunc->setInvalidDecl();
52115211
}
52125212

5213+
void SemaSYCL::CheckSYCLScopeAttr(CXXRecordDecl *Decl) {
5214+
assert(Decl->hasAttr<SYCLScopeAttr>());
5215+
5216+
bool HasError = false;
5217+
5218+
if (Decl->isDependentContext())
5219+
return;
5220+
5221+
// We don't emit both diags at the time as note will only be emitted for the
5222+
// first, which is confusing. So we check both cases but only report one.
5223+
if (!Decl->hasTrivialDefaultConstructor()) {
5224+
Diag(Decl->getLocation(), diag::err_sycl_wg_scope) << 0;
5225+
HasError = true;
5226+
} else if (!Decl->hasTrivialDestructor()) {
5227+
Diag(Decl->getLocation(), diag::err_sycl_wg_scope) << 1;
5228+
HasError = true;
5229+
}
5230+
5231+
if (HasError)
5232+
Decl->dropAttr<SYCLScopeAttr>();
5233+
}
5234+
52135235
// For a wrapped parallel_for, copy attributes from original
52145236
// kernel to wrapped kernel.
52155237
void SemaSYCL::copySYCLKernelAttrs(CXXMethodDecl *CallOperator) {

clang/lib/Sema/SemaSYCLDeclAttr.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3109,6 +3109,21 @@ void SemaSYCL::handleSYCLRegisterNumAttr(Decl *D, const ParsedAttr &AL) {
31093109
D->addAttr(::new (Context) SYCLRegisterNumAttr(Context, AL, RegNo));
31103110
}
31113111

3112+
void SemaSYCL::handleSYCLScopeAttr(Decl *D, const ParsedAttr &AL) {
3113+
if (!AL.checkExactlyNumArgs(SemaRef, 0))
3114+
return;
3115+
if (auto *CRD = dyn_cast<CXXRecordDecl>(D);
3116+
!CRD || !(CRD->isClass() || CRD->isStruct())) {
3117+
SemaRef.Diag(AL.getRange().getBegin(),
3118+
diag::err_attribute_wrong_decl_type_str)
3119+
<< AL << AL.isRegularKeywordAttribute() << "classes";
3120+
return;
3121+
}
3122+
3123+
D->addAttr(SYCLScopeAttr::Create(SemaRef.getASTContext(),
3124+
SYCLScopeAttr::Level::WorkGroup, AL));
3125+
}
3126+
31123127
void SemaSYCL::checkSYCLAddIRAttributesFunctionAttrConflicts(Decl *D) {
31133128
const auto *AddIRFuncAttr = D->getAttr<SYCLAddIRAttributesFunctionAttr>();
31143129

clang/test/Misc/pragma-attribute-supported-attributes-list.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@
204204
// CHECK-NEXT: SYCLIntelUseStallEnableClusters (SubjectMatchRule_function)
205205
// CHECK-NEXT: SYCLKernelEntryPoint (SubjectMatchRule_function)
206206
// CHECK-NEXT: SYCLRegisterNum (SubjectMatchRule_variable_is_global)
207+
// CHECK-NEXT: SYCLScope (SubjectMatchRule_function, SubjectMatchRule_variable, SubjectMatchRule_record)
207208
// CHECK-NEXT: SYCLSimd (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
208209
// CHECK-NEXT: SYCLSpecialClass (SubjectMatchRule_record)
209210
// CHECK-NEXT: SYCLType (SubjectMatchRule_record, SubjectMatchRule_enum)

clang/test/SemaSYCL/sycl_wg_scope.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Verify the use of wg_scope is correctly diagnosed.
2+
// RUN: %clang_cc1 -fsycl-is-device -verify %s
3+
4+
class [[__sycl_detail__::wg_scope]] G1 {};
5+
class [[__sycl_detail__::wg_scope]] G2 {
6+
G2() = default;
7+
G2(int i) : i(i) {}
8+
int i;
9+
};
10+
11+
class [[__sycl_detail__::wg_scope]] G3 {
12+
~G3() = default;
13+
};
14+
15+
class [[__sycl_detail__::wg_scope]] B4 { // expected-error {{SYCL work group scope only applies to class with a trivial default constructor}}
16+
B4() {}
17+
};
18+
19+
class [[__sycl_detail__::wg_scope]] B5 { // expected-error {{SYCL work group scope only applies to class with a trivial destructor}}
20+
~B5() {}
21+
};
22+
23+
class [[__sycl_detail__::wg_scope]] B6 { // expected-error {{SYCL work group scope only applies to class with a trivial default constructor}}
24+
B6() {}
25+
~B6() {}
26+
};
27+
28+
template <typename T> class [[__sycl_detail__::wg_scope]] B7 { // #B7
29+
public:
30+
T obj;
31+
};
32+
33+
struct Valid {};
34+
struct InvalidCtor {
35+
InvalidCtor() {}
36+
};
37+
struct InvalidDtor {
38+
~InvalidDtor() {}
39+
};
40+
struct InvalidCDtor {
41+
InvalidCDtor() {}
42+
~InvalidCDtor() {}
43+
};
44+
45+
B7<Valid> b7;
46+
// expected-error@#B7 {{SYCL work group scope only applies to class with a trivial default constructor}}
47+
// expected-note@+1 {{in instantiation of template class 'B7<InvalidCtor>' requested here}}
48+
B7<InvalidCtor> b9;
49+
// expected-error@#B7 {{SYCL work group scope only applies to class with a trivial destructor}}
50+
// expected-note@+1 {{in instantiation of template class 'B7<InvalidDtor>' requested here}}
51+
B7<InvalidDtor> b10;
52+
// expected-error@#B7 {{SYCL work group scope only applies to class with a trivial default constructor}}
53+
// expected-note@+1 {{in instantiation of template class 'B7<InvalidCDtor>' requested here}}
54+
B7<InvalidCDtor> b11;
55+
56+
template <typename T> class [[__sycl_detail__::wg_scope]] B12 { // #B12
57+
public:
58+
B12() = default;
59+
~B12() = default;
60+
T obj;
61+
};
62+
63+
B12<Valid> b12;
64+
// expected-error@#B12 {{SYCL work group scope only applies to class with a trivial default constructor}}
65+
// expected-note@+1 {{in instantiation of template class 'B12<InvalidCtor>' requested here}}
66+
B12<InvalidCtor> b13;
67+
68+
class B14 {
69+
G1 field; // expected-error {{non-static data member is of a type with a SYCL work group scope attribute applied to it}}
70+
};
71+
72+
template <typename T> class B15 {
73+
T field; // #B15-field
74+
};
75+
76+
// expected-error@#B15-field {{non-static data member is of a type with a SYCL work group scope attribute applied to it}}
77+
// expected-note@+1 {{in instantiation of template class 'B15<G1>' requested here}}
78+
B15<G1> b15;
79+
80+
G1 g16;
81+
static G1 g17;
82+
83+
struct Wrap {
84+
static G1 g18;
85+
};
86+
87+
__attribute__((sycl_device)) void ref_func() {
88+
G1 g19;
89+
static G1 g20;
90+
91+
(void)g16;
92+
(void)g17;
93+
(void)Wrap::g18;
94+
}

llvm/include/llvm/SYCLLowerIR/LowerWGLocalMemory.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ class SYCLLowerWGLocalMemoryPass
4747
ModulePass *createSYCLLowerWGLocalMemoryLegacyPass();
4848
void initializeSYCLLowerWGLocalMemoryLegacyPass(PassRegistry &);
4949

50+
namespace sycl {
51+
std::vector<std::pair<StringRef, int>>
52+
getKernelNamesUsingImplicitLocalMem(const Module &M);
53+
}
54+
5055
} // namespace llvm
5156

5257
#endif // LLVM_SYCLLOWERIR_LOWERWGLOCALMEMORY_H

llvm/include/llvm/Support/PropertySetIO.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ class PropertySetRegistry {
210210
static constexpr char SYCL_DEVICE_REQUIREMENTS[] = "SYCL/device requirements";
211211
static constexpr char SYCL_HOST_PIPES[] = "SYCL/host pipes";
212212
static constexpr char SYCL_VIRTUAL_FUNCTIONS[] = "SYCL/virtual functions";
213+
static constexpr char SYCL_IMPLICIT_LOCAL_ARG[] = "SYCL/implicit local arg";
213214

214215
/// Function for bulk addition of an entire property set in the given
215216
/// \p Category .

llvm/lib/SYCLLowerIR/ComputeModuleRuntimeInfo.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "llvm/SYCLLowerIR/CompileTimePropertiesPass.h"
1717
#include "llvm/SYCLLowerIR/DeviceGlobals.h"
1818
#include "llvm/SYCLLowerIR/HostPipes.h"
19+
#include "llvm/SYCLLowerIR/LowerWGLocalMemory.h"
1920
#include "llvm/SYCLLowerIR/ModuleSplitter.h"
2021
#include "llvm/SYCLLowerIR/SYCLDeviceLibReqMask.h"
2122
#include "llvm/SYCLLowerIR/SYCLKernelParamOptInfo.h"
@@ -388,6 +389,13 @@ PropSetRegTy computeModuleProperties(const Module &M,
388389
for (const StringRef &FName : FuncNames)
389390
PropSet.add(PropSetRegTy::SYCL_ASSERT_USED, FName, true);
390391
}
392+
{
393+
std::vector<std::pair<StringRef, int>> ArgPos =
394+
getKernelNamesUsingImplicitLocalMem(M);
395+
for (const auto &FuncAndArgPos : ArgPos)
396+
PropSet.add(PropSetRegTy::SYCL_IMPLICIT_LOCAL_ARG, FuncAndArgPos.first,
397+
FuncAndArgPos.second);
398+
}
391399

392400
{
393401
if (isModuleUsingAsan(M))

0 commit comments

Comments
 (0)