15#ifndef LLVM_FRONTEND_OPENMP_CONSTRUCTCOMPOSITIONT_H
16#define LLVM_FRONTEND_OPENMP_CONSTRUCTCOMPOSITIONT_H
28#include <unordered_map>
29#include <unordered_set>
36 using TypeTy =
typename ClauseTy::TypeTy;
37 using IdTy =
typename ClauseTy::IdTy;
38 using ExprTy =
typename ClauseTy::ExprTy;
57 ClauseTy makeClause(llvm::omp::Clause clauseId, S &&specific) {
58 return typename ClauseTy::BaseT{clauseId, std::move(specific)};
62 makeCompound(
llvm::ArrayRef<DirectiveWithClauses<ClauseTy>> parts);
64 Presence checkPresence(llvm::omp::Clause clauseId);
72 void mergeReduction();
79 std::unordered_map<llvm::omp::Clause, llvm::BitVector> clausePresence;
81 std::unordered_map<llvm::omp::Clause, ClauseSet> clauseSets;
87 : version(version), leafs(leafs) {
115 for (
const auto &clause : leaf.clauses) {
117 auto &pset = clausePresence[clause.id];
118 if (pset.size() < leafs.size())
119 pset.resize(leafs.size());
124 cset.push_back(clause);
133 for (
auto &[
id,
clauses] : clauseSets) {
136 case llvm::omp::Clause::OMPC_if:
137 case llvm::omp::Clause::OMPC_reduction:
138 case llvm::omp::Clause::OMPC_shared:
139 case llvm::omp::Clause::OMPC_private:
140 case llvm::omp::Clause::OMPC_firstprivate:
141 case llvm::omp::Clause::OMPC_lastprivate:
155 [](
auto &&dwc) {
return dwc.id; });
161auto ConstructCompositionT<C>::checkPresence(llvm::omp::Clause clauseId)
163 auto found = clausePresence.find(clauseId);
164 if (found == clausePresence.end())
165 return Presence::None;
167 bool OnAll =
true, OnNone =
true;
169 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, clauseId, version))
172 if (found->second.test(index))
179 return Presence::None;
181 return Presence::All;
182 return Presence::Some;
185template <
typename C>
void ConstructCompositionT<C>::mergeIf() {
191 Presence presence = checkPresence(llvm::omp::Clause::OMPC_if);
192 if (presence == Presence::None)
195 const ClauseTy &some = *clauseSets[llvm::omp::Clause::OMPC_if].begin();
196 const auto &someIf = std::get<IfTy>(some.u);
198 if (presence == Presence::All) {
200 merged.clauses.emplace_back(
201 makeClause(llvm::omp::Clause::OMPC_if,
203 std::get<typename IfTy::IfExpression>(
208 int Idx = clausePresence[llvm::omp::Clause::OMPC_if].find_first();
210 merged.clauses.emplace_back(
211 makeClause(llvm::omp::Clause::OMPC_if,
213 std::get<typename IfTy::IfExpression>(
218template <
typename C>
void ConstructCompositionT<C>::mergeReduction() {
219 Presence presence = checkPresence(llvm::omp::Clause::OMPC_reduction);
220 if (presence == Presence::None)
224 using ModifierTy =
typename ReductionTy::ReductionModifier;
225 using IdentifiersTy =
typename ReductionTy::ReductionIdentifiers;
226 using ListTy =
typename ReductionTy::List;
234 auto equal = [](
const ClauseTy &red1,
const ClauseTy &red2) {
236 const auto r1 = std::get<ReductionTy>(red1.u);
237 const auto r2 = std::get<ReductionTy>(red2.u);
239 if (std::get<IdentifiersTy>(
r1.t) != std::get<IdentifiersTy>(
r2.t))
241 if (std::get<ListTy>(
r1.t) != std::get<ListTy>(
r2.t))
247 const ReductionTy &red = std::get<ReductionTy>(clause.u);
248 return std::get<std::optional<ModifierTy>>(red.t);
251 const ClauseSet &
reductions = clauseSets[llvm::omp::Clause::OMPC_reduction];
252 std::unordered_set<const ClauseTy *> visited;
254 typename ClauseSet::const_iterator first;
258 if (visited.count(&*first))
260 visited.insert(&*first);
264 std::optional<ModifierTy> modifier =
getModifier(*first);
268 for (
auto iter = std::next(first); iter !=
reductions.end(); ++iter) {
269 if (!
equal(*first, *iter))
271 visited.insert(&*iter);
272 if (!modifier || *modifier == ModifierTy::Default)
276 const auto &firstRed = std::get<ReductionTy>(first->u);
277 merged.clauses.emplace_back(makeClause(
278 llvm::omp::Clause::OMPC_reduction,
281 std::get<IdentifiersTy>(firstRed.t),
282 std::get<ListTy>(firstRed.t)}}));
286template <
typename C>
void ConstructCompositionT<C>::mergeDSA() {
294 FirstPrivate = 1 << 2,
295 LastPrivate = 1 << 3,
296 LastPrivateConditional = 1 << 4,
302 auto getDsa = [&](
const ObjectTy &object) -> std::pair<ObjectTy, int> & {
303 auto found =
llvm::find_if(objectDsa, [&](std::pair<ObjectTy, int> &p) {
304 return p.first.id() ==
object.
id();
306 if (found != objectDsa.
end())
317 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_shared]) {
318 for (
auto &
object : std::get<SharedTy>(clause.u).v)
319 getDsa(
object).second |= DSA::Shared;
322 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_private]) {
323 for (
auto &
object : std::get<PrivateTy>(clause.u).v)
324 getDsa(
object).second |= DSA::Private;
327 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_firstprivate]) {
328 for (
auto &
object : std::get<FirstprivateTy>(clause.u).v)
329 getDsa(
object).second |= DSA::FirstPrivate;
332 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_lastprivate]) {
333 using ModifierTy =
typename LastprivateTy::LastprivateModifier;
334 using ListTy =
typename LastprivateTy::List;
335 const auto &lastp = std::get<LastprivateTy>(clause.u);
336 for (
auto &
object : std::get<ListTy>(lastp.t)) {
337 auto &mod = std::get<std::optional<ModifierTy>>(lastp.t);
338 if (mod && *mod == ModifierTy::Conditional) {
339 getDsa(
object).second |= DSA::LastPrivateConditional;
341 getDsa(
object).second |= DSA::LastPrivate;
347 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_in_reduction]) {
349 using ListTy =
typename InReductionTy::List;
350 for (
auto &
object : std::get<ListTy>(std::get<InReductionTy>(clause.u).t))
351 getDsa(
object).second &= ~DSA::Shared;
353 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_linear]) {
355 using ListTy =
typename LinearTy::List;
356 for (
auto &
object : std::get<ListTy>(std::get<LinearTy>(clause.u).t))
357 getDsa(
object).second &= ~DSA::Shared;
359 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_reduction]) {
361 using ListTy =
typename ReductionTy::List;
362 for (
auto &
object : std::get<ListTy>(std::get<ReductionTy>(clause.u).t))
363 getDsa(
object).second &= ~DSA::Shared;
365 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_task_reduction]) {
367 using ListTy =
typename TaskReductionTy::List;
368 for (
auto &
object : std::get<ListTy>(std::get<TaskReductionTy>(clause.u).t))
369 getDsa(
object).second &= ~DSA::Shared;
373 for (
auto &[
object, dsa] : objectDsa) {
375 (DSA::FirstPrivate | DSA::LastPrivate | DSA::LastPrivateConditional)) {
376 if (dsa & DSA::FirstPrivate)
378 if (dsa & DSA::LastPrivateConditional)
380 else if (dsa & DSA::LastPrivate)
382 }
else if (dsa & DSA::Private) {
384 }
else if (dsa & DSA::Shared) {
390 if (!privateObj.
empty()) {
391 merged.clauses.emplace_back(
392 makeClause(llvm::omp::Clause::OMPC_private,
393 PrivateTy{std::move(privateObj)}));
395 if (!sharedObj.
empty()) {
396 merged.clauses.emplace_back(
397 makeClause(llvm::omp::Clause::OMPC_shared,
398 SharedTy{std::move(sharedObj)}));
400 if (!firstpObj.
empty()) {
401 merged.clauses.emplace_back(
402 makeClause(llvm::omp::Clause::OMPC_firstprivate,
403 FirstprivateTy{std::move(firstpObj)}));
405 if (!lastpObj.
empty()) {
406 merged.clauses.emplace_back(
407 makeClause(llvm::omp::Clause::OMPC_lastprivate,
408 LastprivateTy{{std::nullopt,
409 std::move(lastpObj)}}));
411 if (!lastpcObj.
empty()) {
412 auto conditional = LastprivateTy::LastprivateModifier::Conditional;
413 merged.clauses.emplace_back(
414 makeClause(llvm::omp::Clause::OMPC_lastprivate,
415 LastprivateTy{{conditional,
416 std::move(lastpcObj)}}));
This file implements the BitVector class.
static CSKYCP::CSKYCPModifier getModifier(unsigned Flags)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, int I, uint32_t *Buf)
static void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, int I, uint32_t *Buf)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
Directive getCompoundConstruct(ArrayRef< Directive > Parts)
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are are tuples (A,...
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
typename ClauseTy::IdTy IdTy
typename ClauseTy::ExprTy ExprTy
typename ClauseTy::TypeTy TypeTy
ConstructCompositionT(uint32_t version, llvm::ArrayRef< DirectiveWithClauses< ClauseTy > > leafs)
DirectiveWithClauses< ClauseTy > merged
tomp::type::ListT< ClauseType > clauses