@@ -876,11 +876,12 @@ class KernelObjVisitor {
876
876
877
877
assert (ElemCount > 0 && " SYCL prohibits 0 sized arrays" );
878
878
VisitFirstElement (nullptr , FD, ET, handlers...);
879
- (void )std::initializer_list<int >{(handlers.nextElement (ET), 0 )...};
879
+ (void )std::initializer_list<int >{(handlers.nextElement (ET, 1 ), 0 )...};
880
880
881
881
for (int64_t Count = 1 ; Count < ElemCount; Count++) {
882
882
VisitNthElement (nullptr , FD, ET, handlers...);
883
- (void )std::initializer_list<int >{(handlers.nextElement (ET), 0 )...};
883
+ (void )std::initializer_list<int >{
884
+ (handlers.nextElement (ET, Count + 1 ), 0 )...};
884
885
}
885
886
886
887
(void )std::initializer_list<int >{
@@ -1085,7 +1086,7 @@ class SyclKernelFieldHandlerBase {
1085
1086
virtual bool enterField (const CXXRecordDecl *, FieldDecl *) { return true ; }
1086
1087
virtual bool leaveField (const CXXRecordDecl *, FieldDecl *) { return true ; }
1087
1088
virtual bool enterArray () { return true ; }
1088
- virtual bool nextElement (QualType) { return true ; }
1089
+ virtual bool nextElement (QualType, uint64_t ) { return true ; }
1089
1090
virtual bool leaveArray (FieldDecl *, QualType, int64_t ) { return true ; }
1090
1091
1091
1092
virtual ~SyclKernelFieldHandlerBase () = default ;
@@ -1665,7 +1666,6 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
1665
1666
InitializedEntity VarEntity;
1666
1667
const CXXRecordDecl *KernelObj;
1667
1668
llvm::SmallVector<Expr *, 16 > MemberExprBases;
1668
- uint64_t ArrayIndex;
1669
1669
FunctionDecl *KernelCallerFunc;
1670
1670
1671
1671
// Using the statements/init expressions that we've created, this generates
@@ -1778,17 +1778,62 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
1778
1778
InitExprs.push_back (MemberInit.get ());
1779
1779
}
1780
1780
1781
+ int getDims () {
1782
+ int Dims = 0 ;
1783
+ for (int i = MemberExprBases.size () - 1 ; i >= 0 ; --i) {
1784
+ if (!isa<ArraySubscriptExpr>(MemberExprBases[i]))
1785
+ break ;
1786
+ ++Dims;
1787
+ }
1788
+ return Dims;
1789
+ }
1790
+
1791
+ int64_t getArrayIndex (int Idx) {
1792
+ ArraySubscriptExpr *LastArrayRef =
1793
+ cast<ArraySubscriptExpr>(MemberExprBases[Idx]);
1794
+ Expr *LastIdx = LastArrayRef->getIdx ();
1795
+ llvm::APSInt Result;
1796
+ SemaRef.VerifyIntegerConstantExpression (LastIdx, &Result);
1797
+ return Result.getExtValue ();
1798
+ }
1799
+
1781
1800
void createExprForScalarElement (FieldDecl *FD) {
1782
- InitializedEntity ArrayEntity =
1801
+ llvm::SmallVector<InitializedEntity, 4 > InitEntities;
1802
+
1803
+ // For multi-dimensional arrays, an initialized entity needs to be
1804
+ // generated for each 'dimension'. For example, the initialized entity
1805
+ // for s.array[x][y][z] is constructed using initialized entities for
1806
+ // s.array[x][y], s.array[x] and s.array. InitEntities is used to maintain
1807
+ // this.
1808
+ InitializedEntity Entity =
1783
1809
InitializedEntity::InitializeMember (FD, &VarEntity);
1810
+ InitEntities.push_back (Entity);
1811
+
1812
+ // Calculate dimension using ArraySubscriptExpressions in MemberExprBases.
1813
+ // Each dimension has an ArraySubscriptExpression (maintains index)
1814
+ // in MemberExprBases. For example, if we are currently handling element
1815
+ // a[0][0][1], the top of stack entries are ArraySubscriptExpressions for
1816
+ // indices 0,0 and 1, with 1 on top.
1817
+ int Dims = getDims ();
1818
+
1819
+ // MemberExprBasesIdx is used to get the index of each dimension, in correct
1820
+ // order, from MemberExprBases. For example for a[0][0][1], getArrayIndex
1821
+ // will return 0, 0 and then 1.
1822
+ int MemberExprBasesIdx = MemberExprBases.size () - Dims;
1823
+ for (int I = 0 ; I < Dims; ++I) {
1824
+ InitializedEntity NewEntity = InitializedEntity::InitializeElement (
1825
+ SemaRef.getASTContext (), getArrayIndex (MemberExprBasesIdx),
1826
+ InitEntities.back ());
1827
+ InitEntities.push_back (NewEntity);
1828
+ ++MemberExprBasesIdx;
1829
+ }
1830
+
1784
1831
InitializationKind InitKind =
1785
1832
InitializationKind::CreateCopy (SourceLocation (), SourceLocation ());
1786
1833
Expr *DRE = createInitExpr (FD);
1787
- InitializedEntity Entity = InitializedEntity::InitializeElement (
1788
- SemaRef.getASTContext (), ArrayIndex, ArrayEntity);
1789
- ArrayIndex++;
1790
- InitializationSequence InitSeq (SemaRef, Entity, InitKind, DRE);
1791
- ExprResult MemberInit = InitSeq.Perform (SemaRef, Entity, InitKind, DRE);
1834
+ InitializationSequence InitSeq (SemaRef, InitEntities.back (), InitKind, DRE);
1835
+ ExprResult MemberInit =
1836
+ InitSeq.Perform (SemaRef, InitEntities.back (), InitKind, DRE);
1792
1837
InitExprs.push_back (MemberInit.get ());
1793
1838
}
1794
1839
@@ -1802,7 +1847,22 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
1802
1847
Expr *ILE = new (SemaRef.getASTContext ())
1803
1848
InitListExpr (SemaRef.getASTContext (), SourceLocation (), ArrayInitExprs,
1804
1849
SourceLocation ());
1805
- ILE->setType (FD->getType ());
1850
+
1851
+ // We need to find the type of the element for which we are generating the
1852
+ // InitListExpr. For example, for a multi-dimensional array say a[2][3][2],
1853
+ // the types for InitListExpr of the array and its 'sub-arrays' are -
1854
+ // int [2][3][2], int [3][2] and int [2]. This loop is used to obtain this
1855
+ // information from MemberExprBases. MemberExprBases holds
1856
+ // ArraySubscriptExprs and the top of stack shows how far we have descended
1857
+ // down the array. getDims() calculates this depth.
1858
+ QualType ILEType = FD->getType ();
1859
+ for (int I = getDims (); I > 1 ; I--) {
1860
+ const ConstantArrayType *CAT =
1861
+ SemaRef.getASTContext ().getAsConstantArrayType (ILEType);
1862
+ assert (CAT && " Should only be called on constant-size array." );
1863
+ ILEType = CAT->getElementType ();
1864
+ }
1865
+ ILE->setType (ILEType);
1806
1866
InitExprs.push_back (ILE);
1807
1867
}
1808
1868
@@ -2063,20 +2123,18 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
2063
2123
ExprResult ElementBase = SemaRef.CreateBuiltinArraySubscriptExpr (
2064
2124
ArrayBase, SourceLocation (), IndexExpr.get (), SourceLocation ());
2065
2125
MemberExprBases.push_back (ElementBase.get ());
2066
- ArrayIndex = 0 ;
2067
2126
return true ;
2068
2127
}
2069
2128
2070
- bool nextElement (QualType ET) final {
2071
- ArraySubscriptExpr *LastArrayRef =
2072
- cast<ArraySubscriptExpr>(MemberExprBases.back ());
2129
+ bool nextElement (QualType ET, uint64_t ) final {
2130
+ // Top of MemberExprBases holds ArraySubscriptExpression of element
2131
+ // we just handled, or the Array base for the dimension we are
2132
+ // currently visiting.
2133
+ int64_t nextIndex = getArrayIndex (MemberExprBases.size () - 1 ) + 1 ;
2073
2134
MemberExprBases.pop_back ();
2074
- Expr *LastIdx = LastArrayRef->getIdx ();
2075
- llvm::APSInt Result;
2076
- SemaRef.VerifyIntegerConstantExpression (LastIdx, &Result);
2077
2135
Expr *ArrayBase = MemberExprBases.back ();
2078
- ExprResult IndexExpr = SemaRef. ActOnIntegerConstant (
2079
- SourceLocation (), Result. getExtValue () + 1 );
2136
+ ExprResult IndexExpr =
2137
+ SemaRef. ActOnIntegerConstant ( SourceLocation (), nextIndex );
2080
2138
ExprResult ElementBase = SemaRef.CreateBuiltinArraySubscriptExpr (
2081
2139
ArrayBase, SourceLocation (), IndexExpr.get (), SourceLocation ());
2082
2140
MemberExprBases.push_back (ElementBase.get ());
@@ -2101,6 +2159,7 @@ class SyclKernelBodyCreator : public SyclKernelFieldHandler {
2101
2159
class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
2102
2160
SYCLIntegrationHeader &Header;
2103
2161
int64_t CurOffset = 0 ;
2162
+ llvm::SmallVector<size_t , 16 > ArrayBaseOffsets;
2104
2163
int StructDepth = 0 ;
2105
2164
2106
2165
// A series of functions to calculate the change in offset based on the type.
@@ -2248,18 +2307,20 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
2248
2307
return true ;
2249
2308
}
2250
2309
2251
- bool nextElement (QualType ET ) final {
2252
- CurOffset += SemaRef. getASTContext (). getTypeSizeInChars (ET). getQuantity ( );
2310
+ bool enterArray ( ) final {
2311
+ ArrayBaseOffsets. push_back (CurOffset );
2253
2312
return true ;
2254
2313
}
2255
2314
2256
- bool leaveArray (FieldDecl *, QualType ET, int64_t Count) final {
2257
- int64_t ArraySize =
2258
- SemaRef.getASTContext ().getTypeSizeInChars (ET).getQuantity ();
2259
- if (!ET->isArrayType ()) {
2260
- ArraySize *= Count;
2261
- }
2262
- CurOffset -= ArraySize;
2315
+ bool nextElement (QualType ET, uint64_t Index) final {
2316
+ int64_t Size = SemaRef.getASTContext ().getTypeSizeInChars (ET).getQuantity ();
2317
+ CurOffset = ArrayBaseOffsets.back () + Size * (Index);
2318
+ return true ;
2319
+ }
2320
+
2321
+ bool leaveArray (FieldDecl *, QualType ET, int64_t ) final {
2322
+ CurOffset = ArrayBaseOffsets.back ();
2323
+ ArrayBaseOffsets.pop_back ();
2263
2324
return true ;
2264
2325
}
2265
2326
using SyclKernelFieldHandler::enterStruct;
0 commit comments