llvm/llvm/include/llvm/Frontend/OpenMP/ConstructDecompositionT.h

//===- ConstructDecompositionT.h -- Decomposing compound constructs -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Given a compound construct with a set of clauses, generate the list of
// constituent leaf constructs, each with a list of clauses that apply to it.
//
// Note: Clauses that are not originally present, but that are implied by the
// OpenMP spec are materialized, and are present in the output.
//
// Note: Composite constructs will also be broken up into leaf constructs.
// If composite constructs require processing as a whole, the lists of clauses
// for each leaf constituent should be merged.
//===----------------------------------------------------------------------===//
#ifndef LLVM_FRONTEND_OPENMP_CONSTRUCTDECOMPOSITIONT_H
#define LLVM_FRONTEND_OPENMP_CONSTRUCTDECOMPOSITIONT_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Frontend/OpenMP/ClauseT.h"
#include "llvm/Frontend/OpenMP/OMP.h"

#include <iterator>
#include <list>
#include <optional>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <variant>

static inline llvm::ArrayRef<llvm::omp::Directive> getWorksharing() {}

static inline llvm::ArrayRef<llvm::omp::Directive> getWorksharingLoop() {}

namespace detail {
template <typename Container, typename Predicate>
typename std::remove_reference_t<Container>::iterator
find_unique(Container &&container, Predicate &&pred) {}
} // namespace detail

namespace tomp {

// ClauseType - Either instance of ClauseT, or a type derived from ClauseT.
//
// This is the clause representation in the code using this infrastructure.
//
// HelperType - A class that implements two member functions:
//
//   // Return the base object of the given object, if any.
//   std::optional<Object> getBaseObject(const Object &object) const
//   // Return the iteration variable of the outermost loop associated
//   // with the construct being worked on, if any.
//   std::optional<Object> getLoopIterVar() const
template <typename ClauseType, typename HelperType>
struct ConstructDecompositionT {};

// Deduction guide
template <typename ClauseType, typename HelperType>
ConstructDecompositionT(uint32_t, HelperType &, llvm::omp::Directive,
                        llvm::ArrayRef<ClauseType>)
    -> ConstructDecompositionT<ClauseType, HelperType>;

template <typename C, typename H>
void ConstructDecompositionT<C, H>::addClauseSymsToMap(const ObjectTy &object,
                                                       const ClauseTy *node) {}

template <typename C, typename H>
void ConstructDecompositionT<C, H>::addClauseSymsToMap(
    const tomp::ObjectListT<IdTy, ExprTy> &objects, const ClauseTy *node) {}

template <typename C, typename H>
void ConstructDecompositionT<C, H>::addClauseSymsToMap(const TypeTy &item,
                                                       const ClauseTy *node) {}

template <typename C, typename H>
void ConstructDecompositionT<C, H>::addClauseSymsToMap(const ExprTy &item,
                                                       const ClauseTy *node) {}

template <typename C, typename H>
void ConstructDecompositionT<C, H>::addClauseSymsToMap(
    const tomp::clause::MapT<TypeTy, IdTy, ExprTy> &item,
    const ClauseTy *node) {}

template <typename C, typename H>
template <typename U>
void ConstructDecompositionT<C, H>::addClauseSymsToMap(
    const std::optional<U> &item, const ClauseTy *node) {}

template <typename C, typename H>
template <typename U>
void ConstructDecompositionT<C, H>::addClauseSymsToMap(
    const tomp::ListT<U> &item, const ClauseTy *node) {}

template <typename C, typename H>
template <typename... U, size_t... Is>
void ConstructDecompositionT<C, H>::addClauseSymsToMap(
    const std::tuple<U...> &item, const ClauseTy *node,
    std::index_sequence<Is...>) {}

template <typename C, typename H>
template <typename U>
std::enable_if_t<std::is_enum_v<llvm::remove_cvref_t<U>>, void>
ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
                                                  const ClauseTy *node) {}

template <typename C, typename H>
template <typename U>
std::enable_if_t<llvm::remove_cvref_t<U>::EmptyTrait::value, void>
ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
                                                  const ClauseTy *node) {}

template <typename C, typename H>
template <typename U>
std::enable_if_t<llvm::remove_cvref_t<U>::IncompleteTrait::value, void>
ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
                                                  const ClauseTy *node) {}

template <typename C, typename H>
template <typename U>
std::enable_if_t<llvm::remove_cvref_t<U>::WrapperTrait::value, void>
ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
                                                  const ClauseTy *node) {}

template <typename C, typename H>
template <typename U>
std::enable_if_t<llvm::remove_cvref_t<U>::TupleTrait::value, void>
ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
                                                  const ClauseTy *node) {}

template <typename C, typename H>
template <typename U>
std::enable_if_t<llvm::remove_cvref_t<U>::UnionTrait::value, void>
ConstructDecompositionT<C, H>::addClauseSymsToMap(U &&item,
                                                  const ClauseTy *node) {}

// Apply a clause to the only directive that allows it. If there are no
// directives that allow it, or if there is more that one, do not apply
// anything and return false, otherwise return true.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyToUnique(const ClauseTy *node) {}

// Apply a clause to the first directive in given range that allows it.
// If such a directive does not exist, return false, otherwise return true.
template <typename C, typename H>
template <typename Iterator>
bool ConstructDecompositionT<C, H>::applyToFirst(
    const ClauseTy *node, llvm::iterator_range<Iterator> range) {}

// Apply a clause to the innermost directive that allows it. If such a
// directive does not exist, return false, otherwise return true.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyToInnermost(const ClauseTy *node) {}

// Apply a clause to the outermost directive that allows it. If such a
// directive does not exist, return false, otherwise return true.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyToOutermost(const ClauseTy *node) {}

template <typename C, typename H>
template <typename Predicate>
bool ConstructDecompositionT<C, H>::applyIf(const ClauseTy *node,
                                            Predicate shouldApply) {}

template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyToAll(const ClauseTy *node) {}

template <typename C, typename H>
template <typename Specific>
bool ConstructDecompositionT<C, H>::applyClause(Specific &&specific,
                                                const ClauseTy *node) {}

// COLLAPSE
// [5.2:93:20-21]
// Directives: distribute, do, for, loop, simd, taskloop
//
// [5.2:339:35]
// (35) The collapse clause is applied once to the combined or composite
// construct.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::CollapseT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// PRIVATE
// [5.2:111:5-7]
// Directives: distribute, do, for, loop, parallel, scope, sections, simd,
// single, target, task, taskloop, teams
//
// [5.2:340:1-2]
// (1) The effect of the 1 private clause is as if it is applied only to the
// innermost leaf construct that permits it.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::PrivateT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// FIRSTPRIVATE
// [5.2:112:5-7]
// Directives: distribute, do, for, parallel, scope, sections, single, target,
// task, taskloop, teams
//
// [5.2:340:3-20]
// (3) The effect of the firstprivate clause is as if it is applied to one or
// more leaf constructs as follows:
//  (5) To the distribute construct if it is among the constituent constructs;
//  (6) To the teams construct if it is among the constituent constructs and the
//      distribute construct is not;
//  (8) To a worksharing construct that accepts the clause if one is among the
//      constituent constructs;
//  (9) To the taskloop construct if it is among the constituent constructs;
// (10) To the parallel construct if it is among the constituent constructs and
//      neither a taskloop construct nor a worksharing construct that accepts
//      the clause is among them;
// (12) To the target construct if it is among the constituent constructs and
//      the same list item neither appears in a lastprivate clause nor is the
//      base variable or base pointer of a list item that appears in a map
//      clause.
//
// (15) If the parallel construct is among the constituent constructs and the
// effect is not as if the firstprivate clause is applied to it by the above
// rules, then the effect is as if the shared clause with the same list item is
// applied to the parallel construct.
// (17) If the teams construct is among the constituent constructs and the
// effect is not as if the firstprivate clause is applied to it by the above
// rules, then the effect is as if the shared clause with the same list item is
// applied to the teams construct.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::FirstprivateT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// LASTPRIVATE
// [5.2:115:7-8]
// Directives: distribute, do, for, loop, sections, simd, taskloop
//
// [5.2:340:21-30]
// (21) The effect of the lastprivate clause is as if it is applied to all leaf
// constructs that permit the clause.
// (22) If the parallel construct is among the constituent constructs and the
// list item is not also specified in the firstprivate clause, then the effect
// of the lastprivate clause is as if the shared clause with the same list item
// is applied to the parallel construct.
// (24) If the teams construct is among the constituent constructs and the list
// item is not also specified in the firstprivate clause, then the effect of the
// lastprivate clause is as if the shared clause with the same list item is
// applied to the teams construct.
// (27) If the target construct is among the constituent constructs and the list
// item is not the base variable or base pointer of a list item that appears in
// a map clause, the effect of the lastprivate clause is as if the same list
// item appears in a map clause with a map-type of tofrom.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::LastprivateT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// SHARED
// [5.2:110:5-6]
// Directives: parallel, task, taskloop, teams
//
// [5.2:340:31-32]
// (31) The effect of the shared, default, thread_limit, or order clause is as
// if it is applied to all leaf constructs that permit the clause.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::SharedT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// DEFAULT
// [5.2:109:5-6]
// Directives: parallel, task, taskloop, teams
//
// [5.2:340:31-32]
// (31) The effect of the shared, default, thread_limit, or order clause is as
// if it is applied to all leaf constructs that permit the clause.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::DefaultT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// THREAD_LIMIT
// [5.2:277:14-15]
// Directives: target, teams
//
// [5.2:340:31-32]
// (31) The effect of the shared, default, thread_limit, or order clause is as
// if it is applied to all leaf constructs that permit the clause.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::ThreadLimitT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// ORDER
// [5.2:234:3-4]
// Directives: distribute, do, for, loop, simd
//
// [5.2:340:31-32]
// (31) The effect of the shared, default, thread_limit, or order clause is as
// if it is applied to all leaf constructs that permit the clause.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::OrderT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// ALLOCATE
// [5.2:178:7-9]
// Directives: allocators, distribute, do, for, parallel, scope, sections,
// single, target, task, taskgroup, taskloop, teams
//
// [5.2:340:33-35]
// (33) The effect of the allocate clause is as if it is applied to all leaf
// constructs that permit the clause and to which a data-sharing attribute
// clause that may create a private copy of the same list item is applied.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::AllocateT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// REDUCTION
// [5.2:134:17-18]
// Directives: do, for, loop, parallel, scope, sections, simd, taskloop, teams
//
// [5.2:340:36-37], [5.2:341:1-13]
// (36) The effect of the reduction clause is as if it is applied to all leaf
// constructs that permit the clause, except for the following constructs:
//  (1) The parallel construct, when combined with the sections,
//      worksharing-loop, loop, or taskloop construct; and
//  (3) The teams construct, when combined with the loop construct.
// (4) For the parallel and teams constructs above, the effect of the reduction
// clause instead is as if each list item or, for any list item that is an array
// item, its corresponding base array or base pointer appears in a shared clause
// for the construct.
// (6) If the task reduction-modifier is specified, the effect is as if it only
// modifies the behavior of the reduction clause on the innermost leaf construct
// that accepts the modifier (see Section 5.5.8).
// (8) If the inscan reduction-modifier is specified, the effect is as if it
// modifies the behavior of the reduction clause on all constructs of the
// combined construct to which the clause is applied and that accept the
// modifier.
// (10) If a list item in a reduction clause on a combined target construct does
// not have the same base variable or base pointer as a list item in a map
// clause on the construct, then the effect is as if the list item in the
// reduction clause appears as a list item in a map clause with a map-type of
// tofrom.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::ReductionT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// IF
// [5.2:72:7-9]
// Directives: cancel, parallel, simd, target, target data, target enter data,
// target exit data, target update, task, taskloop
//
// [5.2:72:15-18]
// (15) For combined or composite constructs, the if clause only applies to the
// semantics of the construct named in the directive-name-modifier.
// (16) For a combined or composite construct, if no directive-name-modifier is
// specified then the if clause applies to all constituent constructs to which
// an if clause can apply.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::IfT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// LINEAR
// [5.2:118:1-2]
// Directives: declare simd, do, for, simd
//
// [5.2:341:15-22]
// (15.1) The effect of the linear clause is as if it is applied to the
// innermost leaf construct.
// (15.2) Additionally, if the list item is not the iteration variable of a simd
// or worksharing-loop SIMD construct, the effect on the outer leaf constructs
// is as if the list item was specified in firstprivate and lastprivate clauses
// on the combined or composite construct, with the rules specified above
// applied.
// (19) If a list item of the linear clause is the iteration variable of a simd
// or worksharing-loop SIMD construct and it is not declared in the construct,
// the effect on the outer leaf constructs is as if the list item was specified
// in a lastprivate clause on the combined or composite construct with the rules
// specified above applied.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::LinearT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

// NOWAIT
// [5.2:308:11-13]
// Directives: dispatch, do, for, interop, scope, sections, single, target,
// target enter data, target exit data, target update, taskwait, workshare
//
// [5.2:341:23]
// (23) The effect of the nowait clause is as if it is applied to the outermost
// leaf construct that permits it.
template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::NowaitT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

template <typename C, typename H>
bool ConstructDecompositionT<C, H>::applyClause(
    const tomp::clause::OmpxAttributeT<TypeTy, IdTy, ExprTy> &clause,
    const ClauseTy *node) {}

template <typename C, typename H> bool ConstructDecompositionT<C, H>::split() {}

} // namespace tomp

#endif // LLVM_FRONTEND_OPENMP_CONSTRUCTDECOMPOSITIONT_H