================
@@ -213,6 +202,409 @@ class HostEvalInfo {
   llvm::SmallVector<const semantics::Symbol *> iv;
   bool loopNestApplied = false, parallelApplied = false;
 };
+
+/// A base class to help iterate over OpenMP constructs based on an expected
+/// sequence.
+///
+/// The main entry point process() will call processDirective() for the
+/// OpenMP directive associated to the initial given evaluation based on 
whether
+/// it is part of the initialDirsToProcess() set. A nested OpenMP evaluation
+/// might optionally be also visited by the pattern if it meets all of the
+/// following conditions:
+///   - It is the only nested evaluation, apart from an optional END statement
+///     associated to the same directive.
+///   - The OpenMP directive is part of the directive set returned by the
+///     `processDirective` call for the parent.
+///
+/// Subclasses define the expected pattern by implementing the
+/// initialDirsToProcess() and processDirective() methods, and users are
+/// expected to use process() to trigger the complete pattern visit.
+class OpenMPPatternProcessor {
+public:
+  OpenMPPatternProcessor(semantics::SemanticsContext &semaCtx)
+      : semaCtx{semaCtx} {}
+  virtual ~OpenMPPatternProcessor() = default;
+
+  /// Run the pattern from the given evaluation.
+  void process(lower::pft::Evaluation &eval) {
+    dirsToProcess = initialDirsToProcess();
+    processEval(eval);
+  }
+
+protected:
+  /// Returns the set of directives of interest at the beginning of the 
pattern.
+  virtual OmpDirectiveSet initialDirsToProcess() const = 0;
+
+  /// Processes a single directive and, based on it, returns the set of other
+  /// directives of interest that would be part of the pattern if nested inside
+  /// of it.
+  virtual OmpDirectiveSet processDirective(lower::pft::Evaluation &eval,
+                                           llvm::omp::Directive dir) = 0;
+
+  /// Obtain the list of clauses of the given OpenMP block or loop construct
+  /// evaluation. If it's not an OpenMP construct, no modifications are made to
+  /// the \c clauses output argument.
+  void extractClauses(lower::pft::Evaluation &eval, List<Clause> &clauses) {
+    const auto *ompEval{eval.getIf<parser::OpenMPConstruct>()};
+    if (!ompEval)
+      return;
+
+    const parser::OmpClauseList *beginClauseList{nullptr};
+    const parser::OmpClauseList *endClauseList{nullptr};
+    common::visit(
+        [&](const auto &construct) {
+          using Type = llvm::remove_cvref_t<decltype(construct)>;
+          if constexpr (std::is_same_v<Type, parser::OmpBlockConstruct> ||
+                        std::is_same_v<Type, parser::OpenMPLoopConstruct>) {
+            beginClauseList = &construct.BeginDir().Clauses();
+            if (auto &endSpec{construct.EndDir()})
+              endClauseList = &endSpec->Clauses();
+          }
+        },
+        ompEval->u);
----------------
Meinersbur wrote:

[not a change request] Could be a generalizable pattern pattern:
```suggestion
common::visit_any_of<parser::OmpBlockConstruct, 
parser::OpenMPLoopConstruct>(ompEval,[&](auto &construct) {
            beginClauseList = &construct.BeginDir().Clauses();
            if (auto &endSpec{construct.EndDir()})
              endClauseList = &endSpec->Clauses();
});
```


https://github.com/llvm/llvm-project/pull/186166
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to