Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 32 additions & 23 deletions clang/include/clang/AST/StmtOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -956,30 +956,46 @@ class OMPLoopBasedDirective : public OMPExecutableDirective {
}
};

/// Common class of data shared between
/// OMPCanonicalLoopNestTransformationDirective and transformations over
/// canonical loop sequences.
class OMPLoopTransformationDirective {
/// Number of (top-level) generated loops.
/// This value is 1 for most transformations as they only map one loop nest
/// into another.
/// Some loop transformations (like a non-partial 'unroll') may not generate
/// a loop nest, so this would be 0.
/// Some loop transformations (like 'fuse' with looprange and 'split') may
/// generate more than one loop nest, so the value would be >= 1.
unsigned NumGeneratedTopLevelLoops = 1;

protected:
void setNumGeneratedTopLevelLoops(unsigned N) {
NumGeneratedTopLevelLoops = N;
}

public:
unsigned getNumGeneratedTopLevelLoops() const {
return NumGeneratedTopLevelLoops;
}
};

/// The base class for all transformation directives of canonical loop nests.
class OMPCanonicalLoopNestTransformationDirective
: public OMPLoopBasedDirective {
: public OMPLoopBasedDirective,
public OMPLoopTransformationDirective {
friend class ASTStmtReader;

/// Number of loops generated by this loop transformation.
unsigned NumGeneratedLoops = 0;

protected:
explicit OMPCanonicalLoopNestTransformationDirective(
StmtClass SC, OpenMPDirectiveKind Kind, SourceLocation StartLoc,
SourceLocation EndLoc, unsigned NumAssociatedLoops)
: OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}

/// Set the number of loops generated by this loop transformation.
void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }

public:
/// Return the number of associated (consumed) loops.
unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }

/// Return the number of loops generated by this loop transformation.
unsigned getNumGeneratedLoops() const { return NumGeneratedLoops; }

/// Get the de-sugared statements after the loop transformation.
///
/// Might be nullptr if either the directive generates no loops and is handled
Expand Down Expand Up @@ -5560,9 +5576,7 @@ class OMPTileDirective final
unsigned NumLoops)
: OMPCanonicalLoopNestTransformationDirective(
OMPTileDirectiveClass, llvm::omp::OMPD_tile, StartLoc, EndLoc,
NumLoops) {
setNumGeneratedLoops(2 * NumLoops);
}
NumLoops) {}

void setPreInits(Stmt *PreInits) {
Data->getChildren()[PreInitsOffset] = PreInits;
Expand Down Expand Up @@ -5638,9 +5652,7 @@ class OMPStripeDirective final
unsigned NumLoops)
: OMPCanonicalLoopNestTransformationDirective(
OMPStripeDirectiveClass, llvm::omp::OMPD_stripe, StartLoc, EndLoc,
NumLoops) {
setNumGeneratedLoops(2 * NumLoops);
}
NumLoops) {}

void setPreInits(Stmt *PreInits) {
Data->getChildren()[PreInitsOffset] = PreInits;
Expand Down Expand Up @@ -5744,7 +5756,8 @@ class OMPUnrollDirective final
static OMPUnrollDirective *
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits);
unsigned NumGeneratedTopLevelLoops, Stmt *TransformedStmt,
Stmt *PreInits);

/// Build an empty '#pragma omp unroll' AST node for deserialization.
///
Expand Down Expand Up @@ -5794,9 +5807,7 @@ class OMPReverseDirective final
unsigned NumLoops)
: OMPCanonicalLoopNestTransformationDirective(
OMPReverseDirectiveClass, llvm::omp::OMPD_reverse, StartLoc, EndLoc,
NumLoops) {
setNumGeneratedLoops(NumLoops);
}
NumLoops) {}

void setPreInits(Stmt *PreInits) {
Data->getChildren()[PreInitsOffset] = PreInits;
Expand Down Expand Up @@ -5867,9 +5878,7 @@ class OMPInterchangeDirective final
SourceLocation EndLoc, unsigned NumLoops)
: OMPCanonicalLoopNestTransformationDirective(
OMPInterchangeDirectiveClass, llvm::omp::OMPD_interchange, StartLoc,
EndLoc, NumLoops) {
setNumGeneratedLoops(NumLoops);
}
EndLoc, NumLoops) {}

void setPreInits(Stmt *PreInits) {
Data->getChildren()[PreInitsOffset] = PreInits;
Expand Down
21 changes: 11 additions & 10 deletions clang/lib/AST/StmtOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,14 @@ bool OMPLoopBasedDirective::doForAllLoops(

Stmt *TransformedStmt = Dir->getTransformedStmt();
if (!TransformedStmt) {
unsigned NumGeneratedLoops = Dir->getNumGeneratedLoops();
if (NumGeneratedLoops == 0) {
unsigned NumGeneratedTopLevelLoops =
Dir->getNumGeneratedTopLevelLoops();
if (NumGeneratedTopLevelLoops == 0) {
// May happen if the loop transformation does not result in a
// generated loop (such as full unrolling).
break;
}
if (NumGeneratedLoops > 0) {
if (NumGeneratedTopLevelLoops > 0) {
// The loop transformation construct has generated loops, but these
// may not have been generated yet due to being in a dependent
// context.
Expand Down Expand Up @@ -447,16 +448,16 @@ OMPStripeDirective *OMPStripeDirective::CreateEmpty(const ASTContext &C,
SourceLocation(), SourceLocation(), NumLoops);
}

OMPUnrollDirective *
OMPUnrollDirective::Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt, unsigned NumGeneratedLoops,
Stmt *TransformedStmt, Stmt *PreInits) {
assert(NumGeneratedLoops <= 1 && "Unrolling generates at most one loop");
OMPUnrollDirective *OMPUnrollDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
unsigned NumGeneratedTopLevelLoops, Stmt *TransformedStmt, Stmt *PreInits) {
assert(NumGeneratedTopLevelLoops <= 1 &&
"Unrolling generates at most one loop");

auto *Dir = createDirective<OMPUnrollDirective>(
C, Clauses, AssociatedStmt, TransformedStmtOffset + 1, StartLoc, EndLoc);
Dir->setNumGeneratedLoops(NumGeneratedLoops);
Dir->setNumGeneratedTopLevelLoops(NumGeneratedTopLevelLoops);
Dir->setTransformedStmt(TransformedStmt);
Dir->setPreInits(PreInits);
return Dir;
Expand Down
12 changes: 7 additions & 5 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14919,12 +14919,13 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
Body, OriginalInits))
return StmtError();

unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
unsigned NumGeneratedTopLevelLoops = PartialClause ? 1 : 0;

// Delay unrolling to when template is completely instantiated.
if (SemaRef.CurContext->isDependentContext())
return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
NumGeneratedLoops, nullptr, nullptr);
NumGeneratedTopLevelLoops, nullptr,
nullptr);

assert(LoopHelpers.size() == NumLoops &&
"Expecting a single-dimensional loop iteration space");
Expand All @@ -14947,9 +14948,10 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
// The generated loop may only be passed to other loop-associated directive
// when a partial clause is specified. Without the requirement it is
// sufficient to generate loop unroll metadata at code-generation.
if (NumGeneratedLoops == 0)
if (NumGeneratedTopLevelLoops == 0)
return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
NumGeneratedLoops, nullptr, nullptr);
NumGeneratedTopLevelLoops, nullptr,
nullptr);

// Otherwise, we need to provide a de-sugared/transformed AST that can be
// associated with another loop directive.
Expand Down Expand Up @@ -15164,7 +15166,7 @@ StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());

return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
NumGeneratedLoops, OuterFor,
NumGeneratedTopLevelLoops, OuterFor,
buildPreInits(Context, PreInits));
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Serialization/ASTReaderStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2450,7 +2450,7 @@ void ASTStmtReader::VisitOMPSimdDirective(OMPSimdDirective *D) {
void ASTStmtReader::VisitOMPCanonicalLoopNestTransformationDirective(
OMPCanonicalLoopNestTransformationDirective *D) {
VisitOMPLoopBasedDirective(D);
D->setNumGeneratedLoops(Record.readUInt32());
D->setNumGeneratedTopLevelLoops(Record.readUInt32());
}

void ASTStmtReader::VisitOMPTileDirective(OMPTileDirective *D) {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Serialization/ASTWriterStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2459,7 +2459,7 @@ void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
void ASTStmtWriter::VisitOMPCanonicalLoopNestTransformationDirective(
OMPCanonicalLoopNestTransformationDirective *D) {
VisitOMPLoopBasedDirective(D);
Record.writeUInt32(D->getNumGeneratedLoops());
Record.writeUInt32(D->getNumGeneratedTopLevelLoops());
}

void ASTStmtWriter::VisitOMPTileDirective(OMPTileDirective *D) {
Expand Down