Skip to content

Commit 1c05467

Browse files
committed
Refactored preinits handling and improved coverage
1 parent c76888b commit 1c05467

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
@@ -1494,16 +1494,96 @@ class SemaOpenMP : public SemaBase {
14941494
SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
14951495
Stmt *&Body, SmallVectorImpl<SmallVector<Stmt *, 0>> &OriginalInits);
14961496

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

15171599
/// Helper to keep information about the current `omp begin/end declare
15181600
/// 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);
@@ -520,6 +522,17 @@ OMPFuseDirective *OMPFuseDirective::Create(
520522
NumLoops);
521523
Dir->setTransformedStmt(TransformedStmt);
522524
Dir->setPreInits(PreInits);
525+
// The number of top level canonical nests could
526+
// not match the total number of generated loops
527+
// Example:
528+
// Before fusion:
529+
// for (int i = 0; i < N; ++i)
530+
// for (int j = 0; j < M; ++j)
531+
// A[i][j] = i + j;
532+
//
533+
// for (int k = 0; k < P; ++k)
534+
// B[k] = k * 2;
535+
// Here, NumLoopNests = 2, but NumLoops = 3.
523536
Dir->setNumGeneratedLoopNests(NumLoopNests);
524537
Dir->setNumGeneratedLoops(NumLoops);
525538
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
@@ -3257,6 +3257,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
32573257

32583258
// No other cases for now.
32593259
} else {
3260+
llvm::dbgs() << "THE DAMN DECLREFEXPR HASN'T BEEN ENTERED IN LOCALDECLMAP\n";
3261+
VD->dumpColor();
32603262
llvm_unreachable("DeclRefExpr for Decl not entered in LocalDeclMap?");
32613263
}
32623264

clang/lib/CodeGen/CodeGenFunction.h

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

53645364
/// Set the address of a local variable.
53655365
void setAddrOfLocalVar(const VarDecl *VD, Address Addr) {
5366+
if (LocalDeclMap.count(VD)) {
5367+
llvm::errs() << "Warning: VarDecl already exists in map: ";
5368+
VD->dumpColor();
5369+
}
53665370
assert(!LocalDeclMap.count(VD) && "Decl already exists in LocalDeclMap!");
53675371
LocalDeclMap.insert({VD, Addr});
53685372
}

0 commit comments

Comments
 (0)