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;
84template <
typename ClauseTy>
91 : version(version), leafs(leafs) {
119 for (
const auto &clause : leaf.clauses) {
121 auto &pset = clausePresence[clause.id];
122 if (pset.size() < leafs.size())
123 pset.resize(leafs.size());
128 cset.push_back(clause);
137 for (
auto &[
id,
clauses] : clauseSets) {
140 case llvm::omp::Clause::OMPC_if:
141 case llvm::omp::Clause::OMPC_reduction:
142 case llvm::omp::Clause::OMPC_shared:
143 case llvm::omp::Clause::OMPC_private:
144 case llvm::omp::Clause::OMPC_firstprivate:
145 case llvm::omp::Clause::OMPC_lastprivate:
159 [](
auto &&dwc) {
return dwc.id; });
165auto ConstructCompositionT<C>::checkPresence(llvm::omp::Clause clauseId)
167 auto found = clausePresence.find(clauseId);
168 if (found == clausePresence.end())
169 return Presence::None;
171 bool OnAll =
true, OnNone =
true;
173 if (!llvm::omp::isAllowedClauseForDirective(leaf.id, clauseId, version))
176 if (found->second.test(index))
183 return Presence::None;
185 return Presence::All;
186 return Presence::Some;
189template <
typename C>
void ConstructCompositionT<C>::mergeIf() {
195 Presence presence = checkPresence(llvm::omp::Clause::OMPC_if);
196 if (presence == Presence::None)
199 const ClauseTy &some = *clauseSets[llvm::omp::Clause::OMPC_if].begin();
200 const auto &someIf = std::get<IfTy>(some.u);
202 if (presence == Presence::All) {
204 merged.clauses.emplace_back(
205 makeClause(llvm::omp::Clause::OMPC_if,
207 std::get<typename IfTy::IfExpression>(
212 int Idx = clausePresence[llvm::omp::Clause::OMPC_if].find_first();
214 merged.clauses.emplace_back(
215 makeClause(llvm::omp::Clause::OMPC_if,
217 std::get<typename IfTy::IfExpression>(
222template <
typename C>
void ConstructCompositionT<C>::mergeReduction() {
223 Presence presence = checkPresence(llvm::omp::Clause::OMPC_reduction);
224 if (presence == Presence::None)
228 using ModifierTy =
typename ReductionTy::ReductionModifier;
229 using IdentifiersTy =
typename ReductionTy::ReductionIdentifiers;
230 using ListTy =
typename ReductionTy::List;
238 auto equal = [](
const ClauseTy &red1,
const ClauseTy &red2) {
240 const auto r1 = std::get<ReductionTy>(red1.u);
241 const auto r2 = std::get<ReductionTy>(red2.u);
243 if (std::get<IdentifiersTy>(
r1.t) != std::get<IdentifiersTy>(
r2.t))
245 if (std::get<ListTy>(
r1.t) != std::get<ListTy>(
r2.t))
251 const ReductionTy &red = std::get<ReductionTy>(clause.u);
252 return std::get<std::optional<ModifierTy>>(red.t);
255 const ClauseSet &
reductions = clauseSets[llvm::omp::Clause::OMPC_reduction];
256 std::unordered_set<const ClauseTy *> visited;
258 typename ClauseSet::const_iterator first;
262 if (visited.count(&*first))
264 visited.insert(&*first);
268 std::optional<ModifierTy> modifier =
getModifier(*first);
272 for (
auto iter = std::next(first); iter !=
reductions.end(); ++iter) {
273 if (!
equal(*first, *iter))
275 visited.insert(&*iter);
276 if (!modifier || *modifier == ModifierTy::Default)
280 const auto &firstRed = std::get<ReductionTy>(first->u);
281 merged.clauses.emplace_back(makeClause(
282 llvm::omp::Clause::OMPC_reduction,
285 std::get<IdentifiersTy>(firstRed.t),
286 std::get<ListTy>(firstRed.t)}}));
290template <
typename C>
void ConstructCompositionT<C>::mergeDSA() {
298 FirstPrivate = 1 << 2,
299 LastPrivate = 1 << 3,
300 LastPrivateConditional = 1 << 4,
306 auto getDsa = [&](
const ObjectTy &object) -> std::pair<ObjectTy, int> & {
307 auto found =
llvm::find_if(objectDsa, [&](std::pair<ObjectTy, int> &p) {
308 return p.first.id() ==
object.
id();
310 if (found != objectDsa.
end())
321 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_shared]) {
322 for (
auto &
object : std::get<SharedTy>(clause.u).v)
323 getDsa(
object).second |= DSA::Shared;
326 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_private]) {
327 for (
auto &
object : std::get<PrivateTy>(clause.u).v)
328 getDsa(
object).second |= DSA::Private;
331 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_firstprivate]) {
332 for (
auto &
object : std::get<FirstprivateTy>(clause.u).v)
333 getDsa(
object).second |= DSA::FirstPrivate;
336 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_lastprivate]) {
337 using ModifierTy =
typename LastprivateTy::LastprivateModifier;
338 using ListTy =
typename LastprivateTy::List;
339 const auto &lastp = std::get<LastprivateTy>(clause.u);
340 for (
auto &
object : std::get<ListTy>(lastp.t)) {
341 auto &
mod = std::get<std::optional<ModifierTy>>(lastp.t);
342 if (mod && *mod == ModifierTy::Conditional) {
343 getDsa(
object).second |= DSA::LastPrivateConditional;
345 getDsa(
object).second |= DSA::LastPrivate;
351 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_in_reduction]) {
353 using ListTy =
typename InReductionTy::List;
354 for (
auto &
object : std::get<ListTy>(std::get<InReductionTy>(clause.u).t))
355 getDsa(
object).second &= ~DSA::Shared;
357 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_linear]) {
359 using ListTy =
typename LinearTy::List;
360 for (
auto &
object : std::get<ListTy>(std::get<LinearTy>(clause.u).t))
361 getDsa(
object).second &= ~DSA::Shared;
363 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_reduction]) {
365 using ListTy =
typename ReductionTy::List;
366 for (
auto &
object : std::get<ListTy>(std::get<ReductionTy>(clause.u).t))
367 getDsa(
object).second &= ~DSA::Shared;
369 for (
auto &clause : clauseSets[llvm::omp::Clause::OMPC_task_reduction]) {
371 using ListTy =
typename TaskReductionTy::List;
372 for (
auto &
object : std::get<ListTy>(std::get<TaskReductionTy>(clause.u).t))
373 getDsa(
object).second &= ~DSA::Shared;
377 for (
auto &[
object, dsa] : objectDsa) {
379 (DSA::FirstPrivate | DSA::LastPrivate | DSA::LastPrivateConditional)) {
380 if (dsa & DSA::FirstPrivate)
382 if (dsa & DSA::LastPrivateConditional)
384 else if (dsa & DSA::LastPrivate)
386 }
else if (dsa & DSA::Private) {
388 }
else if (dsa & DSA::Shared) {
394 if (!privateObj.
empty()) {
395 merged.clauses.emplace_back(
396 makeClause(llvm::omp::Clause::OMPC_private,
397 PrivateTy{std::move(privateObj)}));
399 if (!sharedObj.
empty()) {
400 merged.clauses.emplace_back(
401 makeClause(llvm::omp::Clause::OMPC_shared,
402 SharedTy{std::move(sharedObj)}));
404 if (!firstpObj.
empty()) {
405 merged.clauses.emplace_back(
406 makeClause(llvm::omp::Clause::OMPC_firstprivate,
407 FirstprivateTy{std::move(firstpObj)}));
409 if (!lastpObj.
empty()) {
410 merged.clauses.emplace_back(
411 makeClause(llvm::omp::Clause::OMPC_lastprivate,
412 LastprivateTy{{std::nullopt,
413 std::move(lastpObj)}}));
415 if (!lastpcObj.
empty()) {
416 auto conditional = LastprivateTy::LastprivateModifier::Conditional;
417 merged.clauses.emplace_back(
418 makeClause(llvm::omp::Clause::OMPC_lastprivate,
419 LastprivateTy{{conditional,
420 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)
LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt mod(const DynamicAPInt &LHS, const DynamicAPInt &RHS)
is always non-negative.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
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