@@ -791,18 +791,23 @@ static void VisitField(CXXRecordDecl *Owner, RangeTy &&Item, QualType ItemTy,
791
791
else if (ItemTy->isStructureOrClassType ())
792
792
VisitAccessorWrapper (Owner, Item, ItemTy->getAsCXXRecordDecl (),
793
793
handlers...);
794
- #if 0
795
- // FIXME Enable this when structs are replaced by their fields
794
+ // FIXME Enable this when structs are replaced by their fields
795
+ #define STRUCTS_DECOMPOSED 0
796
+ #if STRUCTS_DECOMPOSED
796
797
else if (ItemTy->isArrayType ())
797
798
VisitArrayElements (Item, ItemTy, handlers...);
798
- #endif
799
+ else if (ItemTy->isScalarType ())
800
+ KF_FOR_EACH (handleScalarType, Item, ItemTy);
801
+ }
802
+ #else
799
803
}
800
804
801
805
template <typename RangeTy, typename ... Handlers>
802
806
static void VisitScalarField (CXXRecordDecl *Owner, RangeTy &&Item,
803
807
QualType ItemTy, Handlers &... handlers) {
804
808
KF_FOR_EACH (handleScalarType, Item, ItemTy);
805
809
}
810
+ #endif
806
811
807
812
template <typename RangeTy, typename ... Handlers>
808
813
static void VisitArrayElements (RangeTy Item, QualType FieldTy,
@@ -812,13 +817,18 @@ static void VisitArrayElements(RangeTy Item, QualType FieldTy,
812
817
int64_t ElemCount = CAT->getSize ().getSExtValue ();
813
818
std::initializer_list<int >{(handlers.enterArray (), 0 )...};
814
819
for (int64_t Count = 0 ; Count < ElemCount; Count++) {
820
+ #if STRUCTS_DECOMPOSED
821
+ VisitField (nullptr , Item, ET, handlers...);
822
+ #else
815
823
if (ET->isScalarType ())
816
824
VisitScalarField (nullptr , Item, ET, handlers...);
817
825
else
818
826
VisitField (nullptr , Item, ET, handlers...);
827
+ #endif
819
828
(void )std::initializer_list<int >{(handlers.nextElement (ET), 0 )...};
820
829
}
821
- (void )std::initializer_list<int >{(handlers.leaveArray (ET, ElemCount), 0 )...};
830
+ (void )std::initializer_list<int >{
831
+ (handlers.leaveArray (Item, ET, ElemCount), 0 )...};
822
832
}
823
833
824
834
template <typename RangeTy, typename ... Handlers>
@@ -932,20 +942,31 @@ template <typename Derived> class SyclKernelFieldHandler {
932
942
// class/field graph. Int Headers use this to calculate offset, most others
933
943
// don't have a need for these.
934
944
935
- virtual void enterStruct (const CXXRecordDecl *, FieldDecl *) {}
936
- virtual void leaveStruct (const CXXRecordDecl *, FieldDecl *) {}
937
- virtual void enterStruct (const CXXRecordDecl *, const CXXBaseSpecifier &) {}
938
- virtual void leaveStruct (const CXXRecordDecl *, const CXXBaseSpecifier &) {}
945
+ virtual bool enterStruct (const CXXRecordDecl *, FieldDecl *) { return true ; }
946
+ virtual bool leaveStruct (const CXXRecordDecl *, FieldDecl *) { return true ; }
947
+ virtual bool enterStruct (const CXXRecordDecl *, const CXXBaseSpecifier &) {
948
+ return true ;
949
+ }
950
+ virtual bool leaveStruct (const CXXRecordDecl *, const CXXBaseSpecifier &) {
951
+ return true ;
952
+ }
939
953
940
954
// The following are used for stepping through array elements.
941
955
942
- virtual void enterField (const CXXRecordDecl *, const CXXBaseSpecifier &) {}
943
- virtual void leaveField (const CXXRecordDecl *, const CXXBaseSpecifier &) {}
944
- virtual void enterField (const CXXRecordDecl *, FieldDecl *) {}
945
- virtual void leaveField (const CXXRecordDecl *, FieldDecl *) {}
946
- virtual void enterArray () {}
947
- virtual void nextElement (QualType) {}
948
- virtual void leaveArray (QualType, int64_t ) {}
956
+ virtual bool enterField (const CXXRecordDecl *, const CXXBaseSpecifier &) {
957
+ return true ;
958
+ }
959
+ virtual bool leaveField (const CXXRecordDecl *, const CXXBaseSpecifier &) {
960
+ return true ;
961
+ }
962
+ virtual bool enterField (const CXXRecordDecl *, FieldDecl *) { return true ; }
963
+ virtual bool leaveField (const CXXRecordDecl *, FieldDecl *) { return true ; }
964
+ virtual bool enterArray () { return true ; }
965
+ virtual bool nextElement (QualType) { return true ; }
966
+ virtual bool leaveArray (const CXXBaseSpecifier &, QualType, int64_t ) {
967
+ return true ;
968
+ }
969
+ virtual bool leaveArray (FieldDecl *, QualType, int64_t ) { return true ; }
949
970
};
950
971
951
972
// A type to check the validity of all of the argument types.
@@ -1242,6 +1263,7 @@ class SyclKernelBodyCreator
1242
1263
InitializedEntity VarEntity;
1243
1264
CXXRecordDecl *KernelObj;
1244
1265
llvm::SmallVector<Expr *, 16 > MemberExprBases;
1266
+ uint64_t ArrayIndex;
1245
1267
FunctionDecl *KernelCallerFunc;
1246
1268
1247
1269
// Using the statements/init expressions that we've created, this generates
@@ -1340,30 +1362,27 @@ class SyclKernelBodyCreator
1340
1362
InitExprs.push_back (MemberInit.get ());
1341
1363
}
1342
1364
1343
- void createExprForScalarElement (FieldDecl *FD, QualType FieldTy ) {
1365
+ void createExprForScalarElement (FieldDecl *FD) {
1344
1366
InitializedEntity ArrayEntity =
1345
1367
InitializedEntity::InitializeMember (FD, &VarEntity);
1346
1368
InitializationKind InitKind =
1347
1369
InitializationKind::CreateCopy (SourceLocation (), SourceLocation ());
1348
1370
Expr *DRE = createInitExpr (FD);
1349
- Expr *Idx = dyn_cast<ArraySubscriptExpr>(MemberExprBases.back ())->getIdx ();
1350
- llvm::APSInt Result;
1351
- SemaRef.VerifyIntegerConstantExpression (Idx, &Result);
1352
- uint64_t IntIdx = Result.getZExtValue ();
1353
1371
InitializedEntity Entity = InitializedEntity::InitializeElement (
1354
- SemaRef.getASTContext (), IntIdx, ArrayEntity);
1372
+ SemaRef.getASTContext (), ArrayIndex, ArrayEntity);
1373
+ ArrayIndex++;
1355
1374
InitializationSequence InitSeq (SemaRef, Entity, InitKind, DRE);
1356
1375
ExprResult MemberInit = InitSeq.Perform (SemaRef, Entity, InitKind, DRE);
1376
+ InitExprs.push_back (MemberInit.get ());
1377
+ }
1378
+
1379
+ void addArrayInit (FieldDecl *FD, int64_t Count) {
1357
1380
llvm::SmallVector<Expr *, 16 > ArrayInitExprs;
1358
- if (IntIdx > 0 ) {
1359
- // Continue with the current InitList
1360
- InitListExpr *ILE = cast<InitListExpr>(InitExprs.back ());
1381
+ for (int64_t I = 0 ; I < Count; I++) {
1382
+ ArrayInitExprs.push_back (InitExprs.back ());
1361
1383
InitExprs.pop_back ();
1362
- llvm::ArrayRef<Expr *> L = ILE->inits ();
1363
- for (size_t I = 0 ; I < L.size (); I++)
1364
- ArrayInitExprs.push_back (L[I]);
1365
1384
}
1366
- ArrayInitExprs.push_back (MemberInit. get ());
1385
+ std::reverse ( ArrayInitExprs.begin (), ArrayInitExprs. end ());
1367
1386
Expr *ILE = new (SemaRef.getASTContext ())
1368
1387
InitListExpr (SemaRef.getASTContext (), SourceLocation (), ArrayInitExprs,
1369
1388
SourceLocation ());
@@ -1421,8 +1440,10 @@ class SyclKernelBodyCreator
1421
1440
1422
1441
bool handleSpecialType (FieldDecl *FD, QualType Ty) {
1423
1442
const auto *RecordDecl = Ty->getAsCXXRecordDecl ();
1424
- // Perform initialization only if it is field of kernel object
1425
- if (MemberExprBases.size () == 2 ) {
1443
+ ArraySubscriptExpr *ArrayRef =
1444
+ dyn_cast<ArraySubscriptExpr>(MemberExprBases.back ());
1445
+ // Perform initialization only if decomposed from array
1446
+ if (ArrayRef || MemberExprBases.size () == 2 ) {
1426
1447
InitializedEntity Entity =
1427
1448
InitializedEntity::InitializeMember (FD, &VarEntity);
1428
1449
// Initialize with the default constructor.
@@ -1507,31 +1528,37 @@ class SyclKernelBodyCreator
1507
1528
1508
1529
bool handleScalarType (FieldDecl *FD, QualType FieldTy) final {
1509
1530
if (dyn_cast<ArraySubscriptExpr>(MemberExprBases.back ()))
1510
- createExprForScalarElement (FD, FieldTy );
1531
+ createExprForScalarElement (FD);
1511
1532
else
1512
1533
createExprForStructOrScalar (FD);
1513
1534
return true ;
1514
1535
}
1515
1536
1516
- void enterField (const CXXRecordDecl *RD, FieldDecl *FD) final {
1537
+ bool enterField (const CXXRecordDecl *RD, FieldDecl *FD) final {
1517
1538
if (!FD->getType ()->isReferenceType ())
1518
1539
MemberExprBases.push_back (BuildMemberExpr (MemberExprBases.back (), FD));
1540
+ return true ;
1519
1541
}
1520
1542
1521
- void leaveField (const CXXRecordDecl *, FieldDecl *FD) final {
1543
+ bool leaveField (const CXXRecordDecl *, FieldDecl *FD) final {
1522
1544
if (!FD->getType ()->isReferenceType ())
1523
1545
MemberExprBases.pop_back ();
1546
+ return true ;
1524
1547
}
1525
1548
1526
- void enterArray () final {
1549
+ bool enterArray () final {
1527
1550
Expr *ArrayBase = MemberExprBases.back ();
1528
1551
ExprResult IndexExpr = SemaRef.ActOnIntegerConstant (SourceLocation (), 0 );
1529
1552
ExprResult ElementBase = SemaRef.CreateBuiltinArraySubscriptExpr (
1530
1553
ArrayBase, SourceLocation (), IndexExpr.get (), SourceLocation ());
1531
1554
MemberExprBases.push_back (ElementBase.get ());
1555
+ ArrayIndex = 0 ;
1556
+ return true ;
1532
1557
}
1533
1558
1534
- void nextElement (QualType) final {
1559
+ bool nextElement (QualType ET) final {
1560
+ if (ET->isScalarType ())
1561
+ return true ;
1535
1562
ArraySubscriptExpr *LastArrayRef =
1536
1563
dyn_cast<ArraySubscriptExpr>(MemberExprBases.back ());
1537
1564
MemberExprBases.pop_back ();
@@ -1544,14 +1571,20 @@ class SyclKernelBodyCreator
1544
1571
ExprResult ElementBase = SemaRef.CreateBuiltinArraySubscriptExpr (
1545
1572
ArrayBase, SourceLocation (), IndexExpr.get (), SourceLocation ());
1546
1573
MemberExprBases.push_back (ElementBase.get ());
1574
+ return true ;
1547
1575
}
1548
1576
1549
- void leaveArray (QualType, int64_t ) final { MemberExprBases.pop_back (); }
1577
+ bool leaveArray (FieldDecl *FD, QualType, int64_t Count) final {
1578
+ addArrayInit (FD, Count);
1579
+ MemberExprBases.pop_back ();
1580
+ return true ;
1581
+ }
1550
1582
1551
1583
using SyclKernelFieldHandler::enterArray;
1552
1584
using SyclKernelFieldHandler::enterField;
1553
1585
using SyclKernelFieldHandler::handleScalarType;
1554
1586
using SyclKernelFieldHandler::handleSyclSamplerType;
1587
+ using SyclKernelFieldHandler::leaveArray;
1555
1588
using SyclKernelFieldHandler::leaveField;
1556
1589
};
1557
1590
@@ -1670,43 +1703,50 @@ class SyclKernelIntHeaderCreator
1670
1703
return true ;
1671
1704
}
1672
1705
1673
- void enterField (const CXXRecordDecl *RD, FieldDecl *FD) final {
1706
+ bool enterField (const CXXRecordDecl *RD, FieldDecl *FD) final {
1674
1707
CurOffset += SemaRef.getASTContext ().getFieldOffset (FD) / 8 ;
1708
+ return true ;
1675
1709
}
1676
1710
1677
- void leaveField (const CXXRecordDecl *, FieldDecl *FD) final {
1711
+ bool leaveField (const CXXRecordDecl *, FieldDecl *FD) final {
1678
1712
CurOffset -= SemaRef.getASTContext ().getFieldOffset (FD) / 8 ;
1713
+ return true ;
1679
1714
}
1680
1715
1681
- void enterField (const CXXRecordDecl *RD, const CXXBaseSpecifier &BS) final {
1716
+ bool enterField (const CXXRecordDecl *RD, const CXXBaseSpecifier &BS) final {
1682
1717
const ASTRecordLayout &Layout =
1683
1718
SemaRef.getASTContext ().getASTRecordLayout (RD);
1684
1719
CurOffset += Layout.getBaseClassOffset (BS.getType ()->getAsCXXRecordDecl ())
1685
1720
.getQuantity ();
1721
+ return true ;
1686
1722
}
1687
1723
1688
- void leaveField (const CXXRecordDecl *RD, const CXXBaseSpecifier &BS) final {
1724
+ bool leaveField (const CXXRecordDecl *RD, const CXXBaseSpecifier &BS) final {
1689
1725
const ASTRecordLayout &Layout =
1690
1726
SemaRef.getASTContext ().getASTRecordLayout (RD);
1691
1727
CurOffset -= Layout.getBaseClassOffset (BS.getType ()->getAsCXXRecordDecl ())
1692
1728
.getQuantity ();
1729
+ return true ;
1693
1730
}
1694
1731
1695
- void nextElement (QualType ET) final {
1732
+ bool nextElement (QualType ET) final {
1696
1733
CurOffset += SemaRef.getASTContext ().getTypeSizeInChars (ET).getQuantity ();
1734
+ return true ;
1697
1735
}
1698
1736
1699
- void leaveArray (QualType ET, int64_t Count) final {
1737
+ bool leaveArray (FieldDecl *, QualType ET, int64_t Count) final {
1700
1738
int64_t ArraySize =
1701
1739
SemaRef.getASTContext ().getTypeSizeInChars (ET).getQuantity ();
1702
1740
if (!ET->isArrayType ()) {
1703
1741
ArraySize *= Count;
1704
1742
}
1705
1743
CurOffset -= ArraySize;
1744
+ return true ;
1706
1745
}
1707
1746
1708
1747
using SyclKernelFieldHandler::handleScalarType;
1709
1748
using SyclKernelFieldHandler::handleSyclSamplerType;
1749
+ using SyclKernelFieldHandler::leaveArray;
1710
1750
};
1711
1751
} // namespace
1712
1752
0 commit comments