aboutsummaryrefslogtreecommitdiff
path: root/clang/include
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang-c/Index.h4
-rw-r--r--clang/include/clang/AST/OpenMPClause.h74
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h11
-rw-r--r--clang/include/clang/AST/StmtOpenMP.h196
-rw-r--r--clang/include/clang/Basic/AMDGPUTypes.def1
-rw-r--r--clang/include/clang/Basic/Builtins.def1
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td18
-rw-r--r--clang/include/clang/Basic/OpenMPKinds.h7
-rw-r--r--clang/include/clang/Basic/StmtNodes.td4
-rw-r--r--clang/include/clang/CIR/MissingFeatures.h2
-rw-r--r--clang/include/clang/Parse/Parser.h3
-rw-r--r--clang/include/clang/Sema/Sema.h4
-rw-r--r--clang/include/clang/Sema/SemaOpenMP.h89
-rw-r--r--clang/include/clang/Serialization/ASTBitCodes.h1
14 files changed, 396 insertions, 19 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index be038d9..f13d9c9 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2162,6 +2162,10 @@ enum CXCursorKind {
*/
CXCursor_OMPStripeDirective = 310,
+ /** OpenMP fuse directive
+ */
+ CXCursor_OMPFuseDirective = 311,
+
/** OpenACC Compute Construct.
*/
CXCursor_OpenACCComputeConstruct = 320,
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 42b4268..68d220a 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -1149,6 +1149,80 @@ public:
static OMPFullClause *CreateEmpty(const ASTContext &C);
};
+/// This class represents the 'looprange' clause in the
+/// '#pragma omp fuse' directive
+///
+/// \code {c}
+/// #pragma omp fuse looprange(1,2)
+/// {
+/// for(int i = 0; i < 64; ++i)
+/// for(int j = 0; j < 256; j+=2)
+/// for(int k = 127; k >= 0; --k)
+/// \endcode
+class OMPLoopRangeClause final : public OMPClause {
+ friend class OMPClauseReader;
+ /// Location of '('
+ SourceLocation LParenLoc;
+
+ /// Location of first and count expressions
+ SourceLocation FirstLoc, CountLoc;
+
+ /// Number of looprange arguments (always 2: first, count)
+ enum { FirstExpr, CountExpr, NumArgs };
+ Stmt *Args[NumArgs] = {nullptr, nullptr};
+
+ /// Set looprange 'first' expression
+ void setFirst(Expr *E) { Args[FirstExpr] = E; }
+
+ /// Set looprange 'count' expression
+ void setCount(Expr *E) { Args[CountExpr] = E; }
+
+ /// Build an empty clause for deserialization.
+ explicit OMPLoopRangeClause()
+ : OMPClause(llvm::omp::OMPC_looprange, {}, {}) {}
+
+public:
+ /// Build a 'looprange' clause AST node.
+ static OMPLoopRangeClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation FirstLoc, SourceLocation CountLoc,
+ SourceLocation EndLoc, Expr *First, Expr *Count);
+
+ /// Build an empty 'looprange' clause node.
+ static OMPLoopRangeClause *CreateEmpty(const ASTContext &C);
+
+ // Location getters/setters
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+ SourceLocation getFirstLoc() const { return FirstLoc; }
+ SourceLocation getCountLoc() const { return CountLoc; }
+
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ void setFirstLoc(SourceLocation Loc) { FirstLoc = Loc; }
+ void setCountLoc(SourceLocation Loc) { CountLoc = Loc; }
+
+ /// Get looprange 'first' expression
+ Expr *getFirst() const { return cast_or_null<Expr>(Args[FirstExpr]); }
+
+ /// Get looprange 'count' expression
+ Expr *getCount() const { return cast_or_null<Expr>(Args[CountExpr]); }
+
+ child_range children() { return child_range(Args, Args + NumArgs); }
+ const_child_range children() const {
+ return const_child_range(Args, Args + NumArgs);
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_looprange;
+ }
+};
+
/// Representation of the 'partial' clause of the '#pragma omp unroll'
/// directive.
///
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index af1a073..7a2881f 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3177,6 +3177,9 @@ DEF_TRAVERSE_STMT(OMPUnrollDirective,
DEF_TRAVERSE_STMT(OMPReverseDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
+DEF_TRAVERSE_STMT(OMPFuseDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
DEF_TRAVERSE_STMT(OMPInterchangeDirective,
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
@@ -3495,6 +3498,14 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFullClause(OMPFullClause *C) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLoopRangeClause(
+ OMPLoopRangeClause *C) {
+ TRY_TO(TraverseStmt(C->getFirst()));
+ TRY_TO(TraverseStmt(C->getCount()));
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPPartialClause(OMPPartialClause *C) {
TRY_TO(TraverseStmt(C->getFactor()));
return true;
diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h
index d9f87f1..bc6aeaa8 100644
--- a/clang/include/clang/AST/StmtOpenMP.h
+++ b/clang/include/clang/AST/StmtOpenMP.h
@@ -21,6 +21,7 @@
#include "clang/AST/StmtCXX.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/Casting.h"
namespace clang {
@@ -677,6 +678,10 @@ public:
}
};
+// Forward declaration of a generic loop transformation. Used in the declaration
+// of OMPLoopBasedDirective.
+class OMPLoopTransformationDirective;
+
/// The base class for all loop-based directives, including loop transformation
/// directives.
class OMPLoopBasedDirective : public OMPExecutableDirective {
@@ -889,24 +894,23 @@ public:
/// Calls the specified callback function for all the loops in \p CurStmt,
/// from the outermost to the innermost.
- static bool doForAllLoops(
- Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
- llvm::function_ref<bool(unsigned, Stmt *)> Callback,
- llvm::function_ref<void(OMPCanonicalLoopNestTransformationDirective *)>
- OnTransformationCallback);
+ static bool
+ doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
+ unsigned NumLoops,
+ llvm::function_ref<bool(unsigned, Stmt *)> Callback,
+ llvm::function_ref<void(OMPLoopTransformationDirective *)>
+ OnTransformationCallback);
static bool
doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
unsigned NumLoops,
llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
- llvm::function_ref<
- void(const OMPCanonicalLoopNestTransformationDirective *)>
+ llvm::function_ref<void(const OMPLoopTransformationDirective *)>
OnTransformationCallback) {
auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
return Callback(Cnt, CurStmt);
};
auto &&NewTransformCb =
- [OnTransformationCallback](
- OMPCanonicalLoopNestTransformationDirective *A) {
+ [OnTransformationCallback](OMPLoopTransformationDirective *A) {
OnTransformationCallback(A);
};
return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
@@ -919,7 +923,7 @@ public:
doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
unsigned NumLoops,
llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
- auto &&TransformCb = [](OMPCanonicalLoopNestTransformationDirective *) {};
+ auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
TransformCb);
}
@@ -957,9 +961,11 @@ public:
};
/// Common class of data shared between
-/// OMPCanonicalLoopNestTransformationDirective and transformations over
-/// canonical loop sequences.
+/// OMPCanonicalLoopNestTransformationDirective and
+/// OMPCanonicalLoopSequenceTransformationDirective
class OMPLoopTransformationDirective {
+ friend class ASTStmtReader;
+
/// Number of (top-level) generated loops.
/// This value is 1 for most transformations as they only map one loop nest
/// into another.
@@ -969,15 +975,39 @@ class OMPLoopTransformationDirective {
/// generate more than one loop nest, so the value would be >= 1.
unsigned NumGeneratedTopLevelLoops = 1;
+ /// We need this because we cannot easily make OMPLoopTransformationDirective
+ /// a proper Stmt.
+ Stmt *S = nullptr;
+
protected:
void setNumGeneratedTopLevelLoops(unsigned N) {
NumGeneratedTopLevelLoops = N;
}
+ explicit OMPLoopTransformationDirective(Stmt *S) : S(S) {}
+
public:
unsigned getNumGeneratedTopLevelLoops() const {
return NumGeneratedTopLevelLoops;
}
+
+ /// Returns the specific directive related to this loop transformation.
+ Stmt *getDirective() const { return S; }
+
+ /// Get the de-sugared statements after the loop transformation.
+ ///
+ /// Might be nullptr if either the directive generates no loops and is handled
+ /// directly in CodeGen, or resolving a template-dependence context is
+ /// required.
+ Stmt *getTransformedStmt() const;
+
+ /// Return preinits statement.
+ Stmt *getPreInits() const;
+
+ static bool classof(const Stmt *T) {
+ return isa<OMPCanonicalLoopNestTransformationDirective,
+ OMPCanonicalLoopSequenceTransformationDirective>(T);
+ }
};
/// The base class for all transformation directives of canonical loop nests.
@@ -990,7 +1020,8 @@ protected:
explicit OMPCanonicalLoopNestTransformationDirective(
StmtClass SC, OpenMPDirectiveKind Kind, SourceLocation StartLoc,
SourceLocation EndLoc, unsigned NumAssociatedLoops)
- : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
+ : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops),
+ OMPLoopTransformationDirective(this) {}
public:
/// Return the number of associated (consumed) loops.
@@ -5928,6 +5959,112 @@ public:
}
};
+/// The base class for all transformation directives of canonical loop
+/// sequences (currently only 'fuse')
+class OMPCanonicalLoopSequenceTransformationDirective
+ : public OMPExecutableDirective,
+ public OMPLoopTransformationDirective {
+ friend class ASTStmtReader;
+
+protected:
+ explicit OMPCanonicalLoopSequenceTransformationDirective(
+ StmtClass SC, OpenMPDirectiveKind Kind, SourceLocation StartLoc,
+ SourceLocation EndLoc)
+ : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
+ OMPLoopTransformationDirective(this) {}
+
+public:
+ /// Get the de-sugared statements after the loop transformation.
+ ///
+ /// Might be nullptr if either the directive generates no loops and is handled
+ /// directly in CodeGen, or resolving a template-dependence context is
+ /// required.
+ Stmt *getTransformedStmt() const;
+
+ /// Return preinits statement.
+ Stmt *getPreInits() const;
+
+ static bool classof(const Stmt *T) {
+ Stmt::StmtClass C = T->getStmtClass();
+ return C == OMPFuseDirectiveClass;
+ }
+};
+
+/// Represents the '#pragma omp fuse' loop transformation directive
+///
+/// \code{c}
+/// #pragma omp fuse
+/// {
+/// for(int i = 0; i < m1; ++i) {...}
+/// for(int j = 0; j < m2; ++j) {...}
+/// ...
+/// }
+/// \endcode
+class OMPFuseDirective final
+ : public OMPCanonicalLoopSequenceTransformationDirective {
+ friend class ASTStmtReader;
+ friend class OMPExecutableDirective;
+
+ // Offsets of child members.
+ enum {
+ PreInitsOffset = 0,
+ TransformedStmtOffset,
+ };
+
+ explicit OMPFuseDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPCanonicalLoopSequenceTransformationDirective(
+ OMPFuseDirectiveClass, llvm::omp::OMPD_fuse, StartLoc, EndLoc) {}
+
+ void setPreInits(Stmt *PreInits) {
+ Data->getChildren()[PreInitsOffset] = PreInits;
+ }
+
+ void setTransformedStmt(Stmt *S) {
+ Data->getChildren()[TransformedStmtOffset] = S;
+ }
+
+public:
+ /// Create a new AST node representation for #pragma omp fuse'
+ ///
+ /// \param C Context of the AST
+ /// \param StartLoc Location of the introducer (e.g the 'omp' token)
+ /// \param EndLoc Location of the directive's end (e.g the tok::eod)
+ /// \param Clauses The directive's clauses
+ /// \param NumLoops Total number of loops in the canonical loop sequence.
+ /// \param NumGeneratedTopLevelLoops Number of top-level generated loops.
+ // Typically 1 but looprange clause can
+ // change this.
+ /// \param AssociatedStmt The outermost associated loop
+ /// \param TransformedStmt The loop nest after fusion, or nullptr in
+ /// dependent
+ /// \param PreInits Helper preinits statements for the loop nest
+ static OMPFuseDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, unsigned NumGeneratedTopLevelLoops,
+ Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits);
+
+ /// Build an empty '#pragma omp fuse' AST node for deserialization
+ ///
+ /// \param C Context of the AST
+ /// \param NumClauses Number of clauses to allocate
+ /// \param NumLoops Number of top level loops to allocate
+ static OMPFuseDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses);
+
+ /// Gets the associated loops after the transformation. This is the de-sugared
+ /// replacement or nulltpr in dependent contexts.
+ Stmt *getTransformedStmt() const {
+ return Data->getChildren()[TransformedStmtOffset];
+ }
+
+ /// Return preinits statement.
+ Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OMPFuseDirectiveClass;
+ }
+};
+
/// This represents '#pragma omp scan' directive.
///
/// \code
@@ -6596,4 +6733,37 @@ public:
} // end namespace clang
+namespace llvm {
+// Allow a Stmt* be casted correctly to an OMPLoopTransformationDirective*.
+// The default routines would just use a C-style cast which won't work well
+// for the multiple inheritance here. We have to use a static cast from the
+// corresponding subclass.
+template <>
+struct CastInfo<clang::OMPLoopTransformationDirective, clang::Stmt *>
+ : public NullableValueCastFailed<clang::OMPLoopTransformationDirective *>,
+ public DefaultDoCastIfPossible<
+ clang::OMPLoopTransformationDirective *, clang::Stmt *,
+ CastInfo<clang::OMPLoopTransformationDirective, clang::Stmt *>> {
+ static bool isPossible(const clang::Stmt *T) {
+ return clang::OMPLoopTransformationDirective::classof(T);
+ }
+
+ static clang::OMPLoopTransformationDirective *doCast(clang::Stmt *T) {
+ if (auto *D =
+ dyn_cast<clang::OMPCanonicalLoopNestTransformationDirective>(T))
+ return static_cast<clang::OMPLoopTransformationDirective *>(D);
+ if (auto *D =
+ dyn_cast<clang::OMPCanonicalLoopSequenceTransformationDirective>(T))
+ return static_cast<clang::OMPLoopTransformationDirective *>(D);
+ llvm_unreachable("unexpected type");
+ }
+};
+template <>
+struct CastInfo<clang::OMPLoopTransformationDirective, const clang::Stmt *>
+ : public ConstStrippingForwardingCast<
+ clang::OMPLoopTransformationDirective, const clang::Stmt *,
+ CastInfo<clang::OMPLoopTransformationDirective, clang::Stmt *>> {};
+
+} // namespace llvm
+
#endif
diff --git a/clang/include/clang/Basic/AMDGPUTypes.def b/clang/include/clang/Basic/AMDGPUTypes.def
index d3dff446..089a72b 100644
--- a/clang/include/clang/Basic/AMDGPUTypes.def
+++ b/clang/include/clang/Basic/AMDGPUTypes.def
@@ -21,6 +21,7 @@
#endif
AMDGPU_OPAQUE_PTR_TYPE("__amdgpu_buffer_rsrc_t", AMDGPUBufferRsrc, AMDGPUBufferRsrcTy, 128, 128, 8)
+AMDGPU_OPAQUE_PTR_TYPE("__amdgpu_texture_t", AMDGPUTexture, AMDGPUTextureTy, 256, 256, 0)
AMDGPU_NAMED_BARRIER_TYPE("__amdgpu_named_workgroup_barrier_t", AMDGPUNamedWorkgroupBarrier, AMDGPUNamedWorkgroupBarrierTy, 128, 32, 0)
diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index 9aad00b..b856ad1 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -34,6 +34,7 @@
// Q -> target builtin type, followed by a character to distinguish the builtin type
// Qa -> AArch64 svcount_t builtin type.
// Qb -> AMDGPU __amdgpu_buffer_rsrc_t builtin type.
+// Qt -> AMDGPU __amdgpu_texture_t builtin type.
// E -> ext_vector, followed by the number of elements and the base type.
// X -> _Complex, followed by the base type.
// Y -> ptrdiff_t
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dc4c6d3..b157cbb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5770,8 +5770,10 @@ def err_template_recursion_depth_exceeded : Error<
def err_constraint_depends_on_self
: Error<"satisfaction of constraint %0 depends on itself">,
NoSFINAE;
-def note_template_recursion_depth : Note<
- "use -ftemplate-depth=N to increase recursive template instantiation depth">;
+def note_template_recursion_depth
+ : Note<"use -ftemplate-depth=N to increase recursive template "
+ "instantiation depth">,
+ NoSFINAE;
def err_template_instantiate_within_definition : Error<
"%select{implicit|explicit}0 instantiation of template %1 within its"
@@ -11761,6 +11763,18 @@ def note_omp_implicit_dsa : Note<
"implicitly determined as %0">;
def err_omp_loop_var_dsa : Error<
"loop iteration variable in the associated loop of 'omp %1' directive may not be %0, predetermined as %2">;
+def err_omp_not_a_loop_sequence
+ : Error<"statement after '#pragma omp %0' must be a loop sequence "
+ "containing canonical loops or loop-generating constructs">;
+def err_omp_empty_loop_sequence
+ : Error<"loop sequence after '#pragma omp %0' must contain at least 1 "
+ "canonical loop or loop-generating construct">;
+def err_omp_invalid_looprange
+ : Error<"looprange clause selects loops from %1 to %2 but this exceeds the "
+ "number of loops (%3) in the loop sequence">;
+def warn_omp_redundant_fusion : Warning<"looprange clause selects a single "
+ "loop, resulting in redundant fusion">,
+ InGroup<OpenMPClauses>;
def err_omp_not_for : Error<
"%select{statement after '#pragma omp %1' must be a for loop|"
"expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">;
diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h
index 4c988e0..ed89a31 100644
--- a/clang/include/clang/Basic/OpenMPKinds.h
+++ b/clang/include/clang/Basic/OpenMPKinds.h
@@ -391,6 +391,13 @@ bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind);
bool isOpenMPCanonicalLoopNestTransformationDirective(
OpenMPDirectiveKind DKind);
+/// Checks if the specified directive is a loop transformation directive that
+/// applies to a canonical loop sequence.
+/// \param DKind Specified directive.
+/// \return True iff the directive is a loop transformation.
+bool isOpenMPCanonicalLoopSequenceTransformationDirective(
+ OpenMPDirectiveKind DKind);
+
/// Checks if the specified directive is a loop transformation directive.
/// \param DKind Specified directive.
/// \return True iff the directive is a loop transformation.
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index dd1a244..bf3686b 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -238,6 +238,10 @@ def OMPUnrollDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>;
def OMPReverseDirective : StmtNode<OMPCanonicalLoopNestTransformationDirective>;
def OMPInterchangeDirective
: StmtNode<OMPCanonicalLoopNestTransformationDirective>;
+def OMPCanonicalLoopSequenceTransformationDirective
+ : StmtNode<OMPExecutableDirective, 1>;
+def OMPFuseDirective
+ : StmtNode<OMPCanonicalLoopSequenceTransformationDirective>;
def OMPForDirective : StmtNode<OMPLoopDirective>;
def OMPForSimdDirective : StmtNode<OMPLoopDirective>;
def OMPSectionsDirective : StmtNode<OMPExecutableDirective>;
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 0fac1b2..7e59989 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -208,6 +208,7 @@ struct MissingFeatures {
static bool dataLayoutTypeAllocSize() { return false; }
static bool dataLayoutTypeStoreSize() { return false; }
static bool deferredCXXGlobalInit() { return false; }
+ static bool deleteArray() { return false; }
static bool devirtualizeMemberFunction() { return false; }
static bool ehCleanupFlags() { return false; }
static bool ehCleanupScope() { return false; }
@@ -219,6 +220,7 @@ struct MissingFeatures {
static bool emitCondLikelihoodViaExpectIntrinsic() { return false; }
static bool emitLifetimeMarkers() { return false; }
static bool emitLValueAlignmentAssumption() { return false; }
+ static bool emitNullCheckForDeleteCalls() { return false; }
static bool emitNullabilityCheck() { return false; }
static bool emitTypeCheck() { return false; }
static bool emitTypeMetadataCodeForVCall() { return false; }
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 30edd30..e301cf1 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -6767,6 +6767,9 @@ private:
OpenMPClauseKind Kind,
bool ParseOnly);
+ /// Parses the 'looprange' clause of a '#pragma omp fuse' directive.
+ OMPClause *ParseOpenMPLoopRangeClause();
+
/// Parses the 'sizes' clause of a '#pragma omp tile' directive.
OMPClause *ParseOpenMPSizesClause();
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 2bd6be2..f53aafd 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13335,8 +13335,6 @@ public:
Sema &SemaRef;
bool Invalid;
bool AlreadyInstantiating;
- bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
- SourceRange InstantiationRange);
InstantiatingTemplate(Sema &SemaRef,
CodeSynthesisContext::SynthesisKind Kind,
@@ -13529,7 +13527,7 @@ public:
~ArgPackSubstIndexRAII() { Self.ArgPackSubstIndex = OldSubstIndex; }
};
- void pushCodeSynthesisContext(CodeSynthesisContext Ctx);
+ bool pushCodeSynthesisContext(CodeSynthesisContext Ctx);
void popCodeSynthesisContext();
void PrintContextStack(InstantiationContextDiagFuncRef DiagFunc) {
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index c0fd7a6..daf58b1 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -463,6 +463,13 @@ public:
Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc);
+
+ /// Called on well-formed '#pragma omp fuse' after parsing of its
+ /// clauses and the associated statement.
+ StmtResult ActOnOpenMPFuseDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc);
+
/// Called on well-formed '\#pragma omp for' after parsing
/// of the associated statement.
StmtResult
@@ -921,6 +928,12 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
+
+ /// Called on well-form 'looprange' clause after parsing its arguments.
+ OMPClause *
+ ActOnOpenMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation FirstLoc,
+ SourceLocation CountLoc, SourceLocation EndLoc);
/// Called on well-formed 'ordered' clause.
OMPClause *
ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc,
@@ -1485,7 +1498,81 @@ private:
bool checkTransformableLoopNest(
OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
- Stmt *&Body, SmallVectorImpl<SmallVector<Stmt *, 0>> &OriginalInits);
+ Stmt *&Body, SmallVectorImpl<SmallVector<Stmt *>> &OriginalInits);
+
+ /// Holds the result of the analysis of a (possibly canonical) loop.
+ struct LoopAnalysis {
+ /// The analyzed loop or loop transformation.
+ Stmt *AStmt = nullptr;
+ /// Loop analyses results.
+ OMPLoopBasedDirective::HelperExprs HelperExprs;
+ /// The for-statement of the loop. TheForStmt equals AStmt only when the
+ /// latter is a canonical loop (i.e. not a loop transformation).
+ Stmt *TheForStmt = nullptr;
+ /// Initialization statements before transformations.
+ SmallVector<Stmt *> OriginalInits;
+ /// Initialization statements required after transformation of this loop.
+ SmallVector<Stmt *> TransformsPreInits;
+
+ explicit LoopAnalysis(Stmt *S) : AStmt(S) {}
+
+ bool isRegularLoop() const { return isRegularLoop(AStmt); }
+ bool isLoopTransformation() const { return isLoopTransformation(AStmt); }
+
+ // Convenience functions used when building LoopSequenceAnalysis.
+ static bool isRegularLoop(Stmt *S) {
+ return isa<ForStmt, CXXForRangeStmt>(S);
+ }
+ static bool isLoopTransformation(Stmt *S) {
+ return isa<OMPLoopTransformationDirective>(S);
+ }
+ };
+
+ /// Holds the result of the analysis of a (possibly canonical) loop sequence.
+ struct LoopSequenceAnalysis {
+ /// Number of top level canonical loops.
+ unsigned LoopSeqSize = 0;
+ /// For each loop results of the analysis.
+ SmallVector<LoopAnalysis, 2> Loops;
+ /// Additional code required before entering the transformed loop sequence.
+ SmallVector<Stmt *> LoopSequencePreInits;
+
+ // Convenience function used when building the LoopSequenceAnalysis.
+ static bool isLoopSequenceDerivation(Stmt *S) {
+ return LoopAnalysis::isRegularLoop(S) ||
+ LoopAnalysis::isLoopTransformation(S);
+ }
+ };
+
+ /// The main recursive process of `checkTransformableLoopSequence` that
+ /// performs grammatical parsing of a canonical loop sequence. It extracts
+ /// key information, such as the number of top-level loops, loop statements,
+ /// helper expressions, and other relevant loop-related data, all in a single
+ /// execution to avoid redundant traversals. This analysis flattens inner
+ /// Loop Sequences
+ ///
+ /// \param LoopSeqStmt The AST of the original statement.
+ /// \param SeqAnalysis [out] Result of the analysis of \p LoopSeqStmt
+ /// \param Context
+ /// \param Kind The loop transformation directive kind.
+ /// \return Whether the original statement is both syntactically and
+ /// semantically correct according to OpenMP 6.0 canonical loop
+ /// sequence definition.
+ bool analyzeLoopSequence(Stmt *LoopSeqStmt, LoopSequenceAnalysis &SeqAnalysis,
+ ASTContext &Context, OpenMPDirectiveKind Kind);
+
+ /// Validates and checks whether a loop sequence can be transformed according
+ /// to the given directive, providing necessary setup and initialization
+ /// (Driver function) before recursion using `analyzeLoopSequence`.
+ ///
+ /// \param Kind The loop transformation directive kind.
+ /// \param AStmt The AST of the original statement
+ /// \param SeqAnalysis [out] Result of the analysis of \p LoopSeqStmt
+ /// \param Context
+ /// \return Whether there was an absence of errors or not
+ bool checkTransformableLoopSequence(OpenMPDirectiveKind Kind, Stmt *AStmt,
+ LoopSequenceAnalysis &SeqAnalysis,
+ ASTContext &Context);
/// Helper to keep information about the current `omp begin/end declare
/// variant` nesting.
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 441047d..99864c7 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1951,6 +1951,7 @@ enum StmtCode {
STMT_OMP_UNROLL_DIRECTIVE,
STMT_OMP_REVERSE_DIRECTIVE,
STMT_OMP_INTERCHANGE_DIRECTIVE,
+ STMT_OMP_FUSE_DIRECTIVE,
STMT_OMP_FOR_DIRECTIVE,
STMT_OMP_FOR_SIMD_DIRECTIVE,
STMT_OMP_SECTIONS_DIRECTIVE,