Skip to content

Commit bb48b0f

Browse files
Fixes ArrayIndex calculation. This information is now extracted
from MemberExprBases. Also fixes a mistake with offset calculation for integration headers generated. Adds lit tests. Patch by: Rajiv Deodhar and Elizabeth Andrews Signed-off-by: Elizabeth Andrews <[email protected]>
1 parent 494c1fb commit bb48b0f

File tree

3 files changed

+94
-37
lines changed

3 files changed

+94
-37
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ class KernelObjVisitor {
851851
std::initializer_list<int>{(handlers.enterArray(), 0)...};
852852
for (int64_t Count = 0; Count < ElemCount; Count++) {
853853
VisitElement(nullptr, FD, ET, handlers...);
854-
(void)std::initializer_list<int>{(handlers.nextElement(ET), 0)...};
854+
(void)std::initializer_list<int>{(handlers.nextElement(ET, Count), 0)...};
855855
}
856856
(void)std::initializer_list<int>{
857857
(handlers.leaveArray(FD, ET, ElemCount), 0)...};
@@ -1108,7 +1108,7 @@ class SyclKernelFieldHandler {
11081108
virtual bool enterField(const CXXRecordDecl *, FieldDecl *) { return true; }
11091109
virtual bool leaveField(const CXXRecordDecl *, FieldDecl *) { return true; }
11101110
virtual bool enterArray() { return true; }
1111-
virtual bool nextElement(QualType) { return true; }
1111+
virtual bool nextElement(QualType, int64_t) { return true; }
11121112
virtual bool leaveArray(FieldDecl *, QualType, int64_t) { return true; }
11131113

11141114
virtual ~SyclKernelFieldHandler() = default;
@@ -1626,7 +1626,6 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
16261626
InitializedEntity VarEntity;
16271627
const CXXRecordDecl *KernelObj;
16281628
llvm::SmallVector<Expr *, 16> MemberExprBases;
1629-
uint64_t ArrayIndex;
16301629
FunctionDecl *KernelCallerFunc;
16311630

16321631
// Using the statements/init expressions that we've created, this generates
@@ -1761,27 +1760,29 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
17611760
void createExprForScalarElement(FieldDecl *FD) {
17621761
llvm::SmallVector<InitializedEntity, 4> InitEntities;
17631762

1764-
InitializedEntity MemberEntity =
1765-
InitializedEntity::InitializeMember(FD, &VarEntity);
1766-
InitializedEntity Entity = InitializedEntity::InitializeElement(
1767-
SemaRef.getASTContext(), ArrayIndex, MemberEntity);
1768-
InitEntities.push_back(Entity);
17691763
// For multi-dimensional arrays, an initialized entity needs to be
17701764
// generated for each 'dimension'. For example, the initialized entity
17711765
// for s.array[x][y][z] is constructed using initialized entities for
17721766
// s.array[x][y], s.array[x] and s.array. InitEntities is used to maintain
1773-
// this. MemberExprBases is used to get the array index for 'current
1774-
// dimension'.
1775-
for (int i = MemberExprBases.size() - 2; i >= 0; --i) {
1776-
if (!isa<ArraySubscriptExpr>(MemberExprBases[i]))
1777-
break;
1767+
// this.
1768+
InitializedEntity Entity =
1769+
InitializedEntity::InitializeMember(FD, &VarEntity);
1770+
InitEntities.push_back(Entity);
1771+
1772+
// Calculate dimension using ArraySubscriptExpressions in MemberExprBases.
1773+
// Each dimension has an ArraySubscriptExpression (maintains index)
1774+
// in MemberExprBases. For example, if we are currently handling element
1775+
// a[0][0][1], the top of stack entries are ArraySubscriptExpressions for
1776+
// indices 0,0 and 1, with 1 on top.
1777+
int Dims = getDims();
1778+
int NIndex = MemberExprBases.size() - 1 - (Dims - 1);
1779+
for (int i = 0; i < Dims; ++i) {
17781780
InitializedEntity NewEntity = InitializedEntity::InitializeElement(
1779-
SemaRef.getASTContext(), getArrayIndex(i), InitEntities.back());
1781+
SemaRef.getASTContext(), getArrayIndex(NIndex), InitEntities.back());
17801782
InitEntities.push_back(NewEntity);
1783+
++NIndex;
17811784
}
17821785

1783-
ArrayIndex++;
1784-
17851786
InitializationKind InitKind =
17861787
InitializationKind::CreateCopy(SourceLocation(), SourceLocation());
17871788
Expr *DRE = createInitExpr(FD);
@@ -2067,14 +2068,14 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
20672068
ExprResult ElementBase = SemaRef.CreateBuiltinArraySubscriptExpr(
20682069
ArrayBase, SourceLocation(), IndexExpr.get(), SourceLocation());
20692070
MemberExprBases.push_back(ElementBase.get());
2070-
ArrayIndex = 0;
20712071
return true;
20722072
}
20732073

2074-
bool nextElement(QualType ET) final {
2074+
bool nextElement(QualType ET, int64_t) final {
20752075
// Top of MemberExprBases holds ArraySubscriptExpression of element
2076-
// we just finished processing.
2077-
int64_t nextIndex = getArrayIndex((MemberExprBases.size() - 1)) + 1;
2076+
// we just handled, or the Array base for the dimension we are
2077+
// currently visiting.
2078+
int64_t nextIndex = getArrayIndex(MemberExprBases.size() - 1) + 1;
20782079
MemberExprBases.pop_back();
20792080
Expr *ArrayBase = MemberExprBases.back();
20802081
ExprResult IndexExpr =
@@ -2103,6 +2104,7 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
21032104
class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
21042105
SYCLIntegrationHeader &Header;
21052106
int64_t CurOffset = 0;
2107+
llvm::SmallVector<size_t, 16> ArrayBases;
21062108
int StructDepth = 0;
21072109

21082110
void addParam(const FieldDecl *FD, QualType ArgTy,
@@ -2249,18 +2251,20 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
22492251
return true;
22502252
}
22512253

2252-
bool nextElement(QualType ET) final {
2253-
CurOffset += SemaRef.getASTContext().getTypeSizeInChars(ET).getQuantity();
2254+
bool enterArray() final {
2255+
ArrayBases.push_back(CurOffset);
22542256
return true;
22552257
}
22562258

2257-
bool leaveArray(FieldDecl *, QualType ET, int64_t Count) final {
2258-
int64_t ArraySize =
2259-
SemaRef.getASTContext().getTypeSizeInChars(ET).getQuantity();
2260-
if (!ET->isArrayType()) {
2261-
ArraySize *= Count;
2262-
}
2263-
CurOffset -= ArraySize;
2259+
bool nextElement(QualType ET, int64_t Index) final {
2260+
int64_t Size = SemaRef.getASTContext().getTypeSizeInChars(ET).getQuantity();
2261+
CurOffset = ArrayBases.back() + Size * (Index + 1);
2262+
return true;
2263+
}
2264+
2265+
bool leaveArray(FieldDecl *, QualType ET, int64_t) final {
2266+
CurOffset = ArrayBases.back();
2267+
ArrayBases.pop_back();
22642268
return true;
22652269
}
22662270
using SyclKernelFieldHandler::enterStruct;

clang/test/CodeGenSYCL/kernel-param-pod-array-ih.cpp

100755100644
Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313

1414
// CHECK: static constexpr
1515
// CHECK-NEXT: const char* const kernel_names[] = {
16-
// CHECK-NEXT: "_ZTSZ4mainE8kernel_B"
16+
// CHECK-NEXT: "_ZTSZ4mainE8kernel_B",
17+
// CHECK-NEXT: "_ZTSZ4mainE8kernel_C",
18+
// CHECK-NEXT: "_ZTSZ4mainE8kernel_D"
1719
// CHECK-NEXT: };
1820

1921
// CHECK: static constexpr
@@ -25,14 +27,40 @@
2527
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 12 },
2628
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 16 },
2729
// CHECK-EMPTY:
30+
// CHECK-NEXT: //--- _ZTSZ4mainE8kernel_C
31+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 },
32+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 4 },
33+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 8 },
34+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 12 },
35+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 16 },
36+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 20 },
37+
// CHECK-EMPTY:
38+
// CHECK-NEXT: //--- _ZTSZ4mainE8kernel_D
39+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 0 },
40+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 4 },
41+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 8 },
42+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 12 },
43+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 16 },
44+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 20 },
45+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 24 },
46+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 28 },
47+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 32 },
48+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 36 },
49+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 40 },
50+
// CHECK-NEXT: { kernel_param_kind_t::kind_std_layout, 4, 44 },
51+
// CHECK-EMPTY:
2852
// CHECK-NEXT: };
2953

3054
// CHECK: static constexpr
3155
// CHECK-NEXT: const unsigned kernel_signature_start[] = {
32-
// CHECK-NEXT: 0 // _ZTSZ4mainE8kernel_B
56+
// CHECK-NEXT: 0, // _ZTSZ4mainE8kernel_B
57+
// CHECK-NEXT: 6, // _ZTSZ4mainE8kernel_C
58+
// CHECK-NEXT: 13 // _ZTSZ4mainE8kernel_D
3359
// CHECK-NEXT: };
3460

3561
// CHECK: template <> struct KernelInfo<class kernel_B> {
62+
// CHECK: template <> struct KernelInfo<class kernel_C> {
63+
// CHECK: template <> struct KernelInfo<class kernel_D> {
3664

3765
#include <sycl.hpp>
3866

@@ -46,9 +74,21 @@ __attribute__((sycl_kernel)) void a_kernel(Func kernelFunc) {
4674
int main() {
4775

4876
int a[5];
77+
int b[2][3];
78+
int c[2][3][2];
4979

5080
a_kernel<class kernel_B>(
5181
[=]() {
5282
int local = a[3];
5383
});
84+
85+
a_kernel<class kernel_C>(
86+
[=]() {
87+
int local = b[0][1];
88+
});
89+
90+
a_kernel<class kernel_D>(
91+
[=]() {
92+
int local = c[0][1][1];
93+
});
5494
}

sycl/test/array_param/array-kernel-param-run.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
using namespace cl::sycl;
1313

14-
constexpr size_t c_num_items = 100;
14+
constexpr size_t c_num_items = 4;
1515
range<1> num_items{c_num_items}; // range<1>(num_items)
1616

1717
// Change if tests are added/removed
@@ -48,20 +48,33 @@ void init(T &A, int value, int increment) {
4848
}
4949

5050
bool test_one_array(queue &myQueue) {
51-
int input1[c_num_items];
51+
int input1[c_num_items][c_num_items];
52+
int input2[c_num_items][c_num_items][c_num_items];
5253
int output[c_num_items];
5354
int ref[c_num_items];
54-
init(input1, 1, 1);
55-
init(output, 51, 1);
56-
init(ref, 2, 1);
55+
int value1 = 0;
56+
int value2 = 0;
57+
int increment = 1;
58+
for (int i = 0; i < c_num_items; i++) {
59+
for (int j = 0; j < c_num_items; j++) {
60+
for (int k = 0; k < c_num_items; k++) {
61+
input2[i][j][k] = value1;
62+
value1 += increment;
63+
}
64+
input1[i][j] = value2;
65+
value2 += increment;
66+
}
67+
}
68+
init(output, 511, 1);
69+
init(ref, 37, 2);
5770

5871
auto out_buffer = buffer<int, 1>(&output[0], num_items);
5972

6073
myQueue.submit([&](handler &cgh) {
6174
auto output_accessor = out_buffer.get_access<access::mode::write>(cgh);
6275

6376
cgh.parallel_for<class one_array>(num_items, [=](cl::sycl::id<1> index) {
64-
output_accessor[index] = input1[index] + 1;
77+
output_accessor[index] = input1[0][index] + input2[2][1][index] + 1;
6578
});
6679
});
6780
const auto HostAccessor =

0 commit comments

Comments
 (0)