Skip to content

Commit 33119f7

Browse files
committed
Refactored preinits handling and improved coverage
1 parent c1e5fc3 commit 33119f7

File tree

10 files changed

+1862
-1023
lines changed

10 files changed

+1862
-1023
lines changed

clang/docs/OpenMPSupport.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ implementation.
376376
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
377377
| loop stripe transformation | :good:`done` | https://github.com/llvm/llvm-project/pull/119891 |
378378
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
379-
| loop fuse transformation | :good:`done` | :none:`unclaimed` | |
379+
| loop fuse transformation | :good:`prototyped` | :none:`unclaimed` | |
380380
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+
381381
| work distribute construct | :none:`unclaimed` | :none:`unclaimed` | |
382382
+-------------------------------------------------------------+---------------------------+---------------------------+--------------------------------------------------------------------------+

clang/include/clang/AST/StmtOpenMP.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,8 +1005,7 @@ class OMPLoopTransformationDirective : public OMPLoopBasedDirective {
10051005
Stmt::StmtClass C = T->getStmtClass();
10061006
return C == OMPTileDirectiveClass || C == OMPUnrollDirectiveClass ||
10071007
C == OMPReverseDirectiveClass || C == OMPInterchangeDirectiveClass ||
1008-
C == OMPStripeDirectiveClass ||
1009-
C == OMPFuseDirectiveClass;
1008+
C == OMPStripeDirectiveClass || C == OMPFuseDirectiveClass;
10101009
}
10111010
};
10121011

@@ -5653,6 +5652,8 @@ class OMPStripeDirective final : public OMPLoopTransformationDirective {
56535652
llvm::omp::OMPD_stripe, StartLoc, EndLoc,
56545653
NumLoops) {
56555654
setNumGeneratedLoops(2 * NumLoops);
5655+
// Similar to Tile, it only generates a single top level loop nest
5656+
setNumGeneratedLoopNests(1);
56565657
}
56575658

56585659
void setPreInits(Stmt *PreInits) {

clang/include/clang/Sema/SemaOpenMP.h

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,16 +1493,96 @@ class SemaOpenMP : public SemaBase {
14931493
SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
14941494
Stmt *&Body, SmallVectorImpl<SmallVector<Stmt *, 0>> &OriginalInits);
14951495

1496-
/// Analyzes and checks a loop sequence for use by a loop transformation
1496+
/// @brief Categories of loops encountered during semantic OpenMP loop
1497+
/// analysis
1498+
///
1499+
/// This enumeration identifies the structural category of a loop or sequence
1500+
/// of loops analyzed in the context of OpenMP transformations and directives.
1501+
/// This categorization helps differentiate between original source loops
1502+
/// and the structures resulting from applying OpenMP loop transformations.
1503+
enum class OMPLoopCategory {
1504+
1505+
/// @var OMPLoopCategory::RegularLoop
1506+
/// Represents a standard canonical loop nest found in the
1507+
/// original source code or an intact loop after transformations
1508+
/// (i.e Post/Pre loops of a loopranged fusion)
1509+
RegularLoop,
1510+
1511+
/// @var OMPLoopCategory::TransformSingleLoop
1512+
/// Represents the resulting loop structure when an OpenMP loop
1513+
// transformation, generates a single, top-level loop
1514+
TransformSingleLoop,
1515+
1516+
/// @var OMPLoopCategory::TransformLoopSequence
1517+
/// Represents the resulting loop structure when an OpenMP loop
1518+
/// transformation
1519+
/// generates a sequence of two or more canonical loop nests
1520+
TransformLoopSequence
1521+
};
1522+
1523+
/// The main recursive process of `checkTransformableLoopSequence` that
1524+
/// performs grammatical parsing of a canonical loop sequence. It extracts
1525+
/// key information, such as the number of top-level loops, loop statements,
1526+
/// helper expressions, and other relevant loop-related data, all in a single
1527+
/// execution to avoid redundant traversals. This analysis flattens inner
1528+
/// Loop Sequences
1529+
///
1530+
/// \param LoopSeqStmt The AST of the original statement.
1531+
/// \param LoopSeqSize [out] Number of top level canonical loops.
1532+
/// \param NumLoops [out] Number of total canonical loops (nested too).
1533+
/// \param LoopHelpers [out] The multiple loop analyses results.
1534+
/// \param ForStmts [out] The multiple Stmt of each For loop.
1535+
/// \param OriginalInits [out] The raw original initialization statements
1536+
/// of each belonging to a loop of the loop sequence
1537+
/// \param TransformPreInits [out] The multiple collection of statements and
1538+
/// declarations that must have been executed/declared
1539+
/// before entering the loop (each belonging to a
1540+
/// particular loop transformation, nullptr otherwise)
1541+
/// \param LoopSequencePreInits [out] Additional general collection of loop
1542+
/// transformation related statements and declarations
1543+
/// not bounded to a particular loop that must be
1544+
/// executed before entering the loop transformation
1545+
/// \param LoopCategories [out] A sequence of OMPLoopCategory values,
1546+
/// one for each loop or loop transformation node
1547+
/// successfully analyzed.
1548+
/// \param Context
1549+
/// \param Kind The loop transformation directive kind.
1550+
/// \return Whether the original statement is both syntactically and
1551+
/// semantically correct according to OpenMP 6.0 canonical loop
1552+
/// sequence definition.
1553+
bool analyzeLoopSequence(
1554+
Stmt *LoopSeqStmt, unsigned &LoopSeqSize, unsigned &NumLoops,
1555+
SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
1556+
SmallVectorImpl<Stmt *> &ForStmts,
1557+
SmallVectorImpl<SmallVector<Stmt *, 0>> &OriginalInits,
1558+
SmallVectorImpl<SmallVector<Stmt *, 0>> &TransformsPreInits,
1559+
SmallVectorImpl<SmallVector<Stmt *, 0>> &LoopSequencePreInits,
1560+
SmallVectorImpl<OMPLoopCategory> &LoopCategories, ASTContext &Context,
1561+
OpenMPDirectiveKind Kind);
1562+
1563+
/// Validates and checks whether a loop sequence can be transformed according
1564+
/// to the given directive, providing necessary setup and initialization
1565+
/// (Driver function) before recursion using `analyzeLoopSequence`.
14971566
///
14981567
/// \param Kind The loop transformation directive kind.
1499-
/// \param NumLoops [out] Number of total canonical loops
1500-
/// \param LoopSeqSize [out] Number of top level canonical loops
1568+
/// \param AStmt The AST of the original statement
1569+
/// \param LoopSeqSize [out] Number of top level canonical loops.
1570+
/// \param NumLoops [out] Number of total canonical loops (nested too)
15011571
/// \param LoopHelpers [out] The multiple loop analyses results.
1502-
/// \param LoopStmts [out] The multiple Stmt of each For loop.
1503-
/// \param OriginalInits [out] The multiple collection of statements and
1572+
/// \param ForStmts [out] The multiple Stmt of each For loop.
1573+
/// \param OriginalInits [out] The raw original initialization statements
1574+
/// of each belonging to a loop of the loop sequence
1575+
/// \param TransformsPreInits [out] The multiple collection of statements and
15041576
/// declarations that must have been executed/declared
1505-
/// before entering the loop.
1577+
/// before entering the loop (each belonging to a
1578+
/// particular loop transformation, nullptr otherwise)
1579+
/// \param LoopSequencePreInits [out] Additional general collection of loop
1580+
/// transformation related statements and declarations
1581+
/// not bounded to a particular loop that must be
1582+
/// executed before entering the loop transformation
1583+
/// \param LoopCategories [out] A sequence of OMPLoopCategory values,
1584+
/// one for each loop or loop transformation node
1585+
/// successfully analyzed.
15061586
/// \param Context
15071587
/// \return Whether there was an absence of errors or not
15081588
bool checkTransformableLoopSequence(
@@ -1511,7 +1591,9 @@ class SemaOpenMP : public SemaBase {
15111591
SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
15121592
SmallVectorImpl<Stmt *> &ForStmts,
15131593
SmallVectorImpl<SmallVector<Stmt *, 0>> &OriginalInits,
1514-
ASTContext &Context);
1594+
SmallVectorImpl<SmallVector<Stmt *, 0>> &TransformsPreInits,
1595+
SmallVectorImpl<SmallVector<Stmt *, 0>> &LoopSequencePreInits,
1596+
SmallVectorImpl<OMPLoopCategory> &LoopCategories, ASTContext &Context);
15151597

15161598
/// Helper to keep information about the current `omp begin/end declare
15171599
/// variant` nesting.

clang/lib/AST/StmtOpenMP.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ OMPUnrollDirective::Create(const ASTContext &C, SourceLocation StartLoc,
457457
C, Clauses, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc);
458458
Dir->setNumGeneratedLoops(NumGeneratedLoops);
459459
// The number of generated loops and loop nests during unroll matches
460+
// given that unroll only generates top level canonical loop nests
461+
// so each generated loop is a top level canonical loop nest
460462
Dir->setNumGeneratedLoopNests(NumGeneratedLoops);
461463
Dir->setTransformedStmt(TransformedStmt);
462464
Dir->setPreInits(PreInits);
@@ -517,6 +519,17 @@ OMPFuseDirective *OMPFuseDirective::Create(
517519
NumLoops);
518520
Dir->setTransformedStmt(TransformedStmt);
519521
Dir->setPreInits(PreInits);
522+
// The number of top level canonical nests could
523+
// not match the total number of generated loops
524+
// Example:
525+
// Before fusion:
526+
// for (int i = 0; i < N; ++i)
527+
// for (int j = 0; j < M; ++j)
528+
// A[i][j] = i + j;
529+
//
530+
// for (int k = 0; k < P; ++k)
531+
// B[k] = k * 2;
532+
// Here, NumLoopNests = 2, but NumLoops = 3.
520533
Dir->setNumGeneratedLoopNests(NumLoopNests);
521534
Dir->setNumGeneratedLoops(NumLoops);
522535
return Dir;

clang/lib/Basic/OpenMPKinds.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,8 @@ bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {
704704

705705
bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind) {
706706
return DKind == OMPD_tile || DKind == OMPD_unroll || DKind == OMPD_reverse ||
707-
DKind == OMPD_interchange || DKind == OMPD_stripe || DKind == OMPD_fuse;
707+
DKind == OMPD_interchange || DKind == OMPD_stripe ||
708+
DKind == OMPD_fuse;
708709
}
709710

710711
bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) {

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3242,6 +3242,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
32423242

32433243
// No other cases for now.
32443244
} else {
3245+
llvm::dbgs() << "THE DAMN DECLREFEXPR HASN'T BEEN ENTERED IN LOCALDECLMAP\n";
3246+
VD->dumpColor();
32453247
llvm_unreachable("DeclRefExpr for Decl not entered in LocalDeclMap?");
32463248
}
32473249

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5414,6 +5414,10 @@ class CodeGenFunction : public CodeGenTypeCache {
54145414

54155415
/// Set the address of a local variable.
54165416
void setAddrOfLocalVar(const VarDecl *VD, Address Addr) {
5417+
if (LocalDeclMap.count(VD)) {
5418+
llvm::errs() << "Warning: VarDecl already exists in map: ";
5419+
VD->dumpColor();
5420+
}
54175421
assert(!LocalDeclMap.count(VD) && "Decl already exists in LocalDeclMap!");
54185422
LocalDeclMap.insert({VD, Addr});
54195423
}

0 commit comments

Comments
 (0)