forked from OSchip/llvm-project
2498 lines
89 KiB
C++
2498 lines
89 KiB
C++
//===- OpenMPClause.cpp - Classes for OpenMP clauses ----------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the subclesses of Stmt class declared in OpenMPClause.h
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/AST/OpenMPClause.h"
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/AST/Attr.h"
|
|
#include "clang/AST/Decl.h"
|
|
#include "clang/AST/DeclOpenMP.h"
|
|
#include "clang/Basic/LLVM.h"
|
|
#include "clang/Basic/OpenMPKinds.h"
|
|
#include "clang/Basic/TargetInfo.h"
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
|
#include "llvm/Support/Casting.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include <algorithm>
|
|
#include <cassert>
|
|
|
|
using namespace clang;
|
|
using namespace llvm;
|
|
using namespace omp;
|
|
|
|
OMPClause::child_range OMPClause::children() {
|
|
switch (getClauseKind()) {
|
|
default:
|
|
break;
|
|
#define GEN_CLANG_CLAUSE_CLASS
|
|
#define CLAUSE_CLASS(Enum, Str, Class) \
|
|
case Enum: \
|
|
return static_cast<Class *>(this)->children();
|
|
#include "llvm/Frontend/OpenMP/OMP.inc"
|
|
}
|
|
llvm_unreachable("unknown OMPClause");
|
|
}
|
|
|
|
OMPClause::child_range OMPClause::used_children() {
|
|
switch (getClauseKind()) {
|
|
#define GEN_CLANG_CLAUSE_CLASS
|
|
#define CLAUSE_CLASS(Enum, Str, Class) \
|
|
case Enum: \
|
|
return static_cast<Class *>(this)->used_children();
|
|
#define CLAUSE_NO_CLASS(Enum, Str) \
|
|
case Enum: \
|
|
break;
|
|
#include "llvm/Frontend/OpenMP/OMP.inc"
|
|
}
|
|
llvm_unreachable("unknown OMPClause");
|
|
}
|
|
|
|
OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) {
|
|
auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C));
|
|
return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
|
|
}
|
|
|
|
const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
|
|
switch (C->getClauseKind()) {
|
|
case OMPC_schedule:
|
|
return static_cast<const OMPScheduleClause *>(C);
|
|
case OMPC_dist_schedule:
|
|
return static_cast<const OMPDistScheduleClause *>(C);
|
|
case OMPC_firstprivate:
|
|
return static_cast<const OMPFirstprivateClause *>(C);
|
|
case OMPC_lastprivate:
|
|
return static_cast<const OMPLastprivateClause *>(C);
|
|
case OMPC_reduction:
|
|
return static_cast<const OMPReductionClause *>(C);
|
|
case OMPC_task_reduction:
|
|
return static_cast<const OMPTaskReductionClause *>(C);
|
|
case OMPC_in_reduction:
|
|
return static_cast<const OMPInReductionClause *>(C);
|
|
case OMPC_linear:
|
|
return static_cast<const OMPLinearClause *>(C);
|
|
case OMPC_if:
|
|
return static_cast<const OMPIfClause *>(C);
|
|
case OMPC_num_threads:
|
|
return static_cast<const OMPNumThreadsClause *>(C);
|
|
case OMPC_num_teams:
|
|
return static_cast<const OMPNumTeamsClause *>(C);
|
|
case OMPC_thread_limit:
|
|
return static_cast<const OMPThreadLimitClause *>(C);
|
|
case OMPC_device:
|
|
return static_cast<const OMPDeviceClause *>(C);
|
|
case OMPC_grainsize:
|
|
return static_cast<const OMPGrainsizeClause *>(C);
|
|
case OMPC_num_tasks:
|
|
return static_cast<const OMPNumTasksClause *>(C);
|
|
case OMPC_final:
|
|
return static_cast<const OMPFinalClause *>(C);
|
|
case OMPC_priority:
|
|
return static_cast<const OMPPriorityClause *>(C);
|
|
case OMPC_novariants:
|
|
return static_cast<const OMPNovariantsClause *>(C);
|
|
case OMPC_nocontext:
|
|
return static_cast<const OMPNocontextClause *>(C);
|
|
case OMPC_filter:
|
|
return static_cast<const OMPFilterClause *>(C);
|
|
case OMPC_default:
|
|
case OMPC_proc_bind:
|
|
case OMPC_safelen:
|
|
case OMPC_simdlen:
|
|
case OMPC_sizes:
|
|
case OMPC_allocator:
|
|
case OMPC_allocate:
|
|
case OMPC_collapse:
|
|
case OMPC_private:
|
|
case OMPC_shared:
|
|
case OMPC_aligned:
|
|
case OMPC_copyin:
|
|
case OMPC_copyprivate:
|
|
case OMPC_ordered:
|
|
case OMPC_nowait:
|
|
case OMPC_untied:
|
|
case OMPC_mergeable:
|
|
case OMPC_threadprivate:
|
|
case OMPC_flush:
|
|
case OMPC_depobj:
|
|
case OMPC_read:
|
|
case OMPC_write:
|
|
case OMPC_update:
|
|
case OMPC_capture:
|
|
case OMPC_seq_cst:
|
|
case OMPC_acq_rel:
|
|
case OMPC_acquire:
|
|
case OMPC_release:
|
|
case OMPC_relaxed:
|
|
case OMPC_depend:
|
|
case OMPC_threads:
|
|
case OMPC_simd:
|
|
case OMPC_map:
|
|
case OMPC_nogroup:
|
|
case OMPC_hint:
|
|
case OMPC_defaultmap:
|
|
case OMPC_unknown:
|
|
case OMPC_uniform:
|
|
case OMPC_to:
|
|
case OMPC_from:
|
|
case OMPC_use_device_ptr:
|
|
case OMPC_use_device_addr:
|
|
case OMPC_is_device_ptr:
|
|
case OMPC_unified_address:
|
|
case OMPC_unified_shared_memory:
|
|
case OMPC_reverse_offload:
|
|
case OMPC_dynamic_allocators:
|
|
case OMPC_atomic_default_mem_order:
|
|
case OMPC_device_type:
|
|
case OMPC_match:
|
|
case OMPC_nontemporal:
|
|
case OMPC_order:
|
|
case OMPC_destroy:
|
|
case OMPC_detach:
|
|
case OMPC_inclusive:
|
|
case OMPC_exclusive:
|
|
case OMPC_uses_allocators:
|
|
case OMPC_affinity:
|
|
case OMPC_when:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(OMPClause *C) {
|
|
auto *Res = OMPClauseWithPostUpdate::get(const_cast<const OMPClause *>(C));
|
|
return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;
|
|
}
|
|
|
|
const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) {
|
|
switch (C->getClauseKind()) {
|
|
case OMPC_lastprivate:
|
|
return static_cast<const OMPLastprivateClause *>(C);
|
|
case OMPC_reduction:
|
|
return static_cast<const OMPReductionClause *>(C);
|
|
case OMPC_task_reduction:
|
|
return static_cast<const OMPTaskReductionClause *>(C);
|
|
case OMPC_in_reduction:
|
|
return static_cast<const OMPInReductionClause *>(C);
|
|
case OMPC_linear:
|
|
return static_cast<const OMPLinearClause *>(C);
|
|
case OMPC_schedule:
|
|
case OMPC_dist_schedule:
|
|
case OMPC_firstprivate:
|
|
case OMPC_default:
|
|
case OMPC_proc_bind:
|
|
case OMPC_if:
|
|
case OMPC_final:
|
|
case OMPC_num_threads:
|
|
case OMPC_safelen:
|
|
case OMPC_simdlen:
|
|
case OMPC_sizes:
|
|
case OMPC_allocator:
|
|
case OMPC_allocate:
|
|
case OMPC_collapse:
|
|
case OMPC_private:
|
|
case OMPC_shared:
|
|
case OMPC_aligned:
|
|
case OMPC_copyin:
|
|
case OMPC_copyprivate:
|
|
case OMPC_ordered:
|
|
case OMPC_nowait:
|
|
case OMPC_untied:
|
|
case OMPC_mergeable:
|
|
case OMPC_threadprivate:
|
|
case OMPC_flush:
|
|
case OMPC_depobj:
|
|
case OMPC_read:
|
|
case OMPC_write:
|
|
case OMPC_update:
|
|
case OMPC_capture:
|
|
case OMPC_seq_cst:
|
|
case OMPC_acq_rel:
|
|
case OMPC_acquire:
|
|
case OMPC_release:
|
|
case OMPC_relaxed:
|
|
case OMPC_depend:
|
|
case OMPC_device:
|
|
case OMPC_threads:
|
|
case OMPC_simd:
|
|
case OMPC_map:
|
|
case OMPC_num_teams:
|
|
case OMPC_thread_limit:
|
|
case OMPC_priority:
|
|
case OMPC_grainsize:
|
|
case OMPC_nogroup:
|
|
case OMPC_num_tasks:
|
|
case OMPC_hint:
|
|
case OMPC_defaultmap:
|
|
case OMPC_unknown:
|
|
case OMPC_uniform:
|
|
case OMPC_to:
|
|
case OMPC_from:
|
|
case OMPC_use_device_ptr:
|
|
case OMPC_use_device_addr:
|
|
case OMPC_is_device_ptr:
|
|
case OMPC_unified_address:
|
|
case OMPC_unified_shared_memory:
|
|
case OMPC_reverse_offload:
|
|
case OMPC_dynamic_allocators:
|
|
case OMPC_atomic_default_mem_order:
|
|
case OMPC_device_type:
|
|
case OMPC_match:
|
|
case OMPC_nontemporal:
|
|
case OMPC_order:
|
|
case OMPC_destroy:
|
|
case OMPC_novariants:
|
|
case OMPC_nocontext:
|
|
case OMPC_detach:
|
|
case OMPC_inclusive:
|
|
case OMPC_exclusive:
|
|
case OMPC_uses_allocators:
|
|
case OMPC_affinity:
|
|
case OMPC_when:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
/// Gets the address of the original, non-captured, expression used in the
|
|
/// clause as the preinitializer.
|
|
static Stmt **getAddrOfExprAsWritten(Stmt *S) {
|
|
if (!S)
|
|
return nullptr;
|
|
if (auto *DS = dyn_cast<DeclStmt>(S)) {
|
|
assert(DS->isSingleDecl() && "Only single expression must be captured.");
|
|
if (auto *OED = dyn_cast<OMPCapturedExprDecl>(DS->getSingleDecl()))
|
|
return OED->getInitAddress();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
OMPClause::child_range OMPIfClause::used_children() {
|
|
if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
|
|
return child_range(C, C + 1);
|
|
return child_range(&Condition, &Condition + 1);
|
|
}
|
|
|
|
OMPClause::child_range OMPGrainsizeClause::used_children() {
|
|
if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
|
|
return child_range(C, C + 1);
|
|
return child_range(&Grainsize, &Grainsize + 1);
|
|
}
|
|
|
|
OMPClause::child_range OMPNumTasksClause::used_children() {
|
|
if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
|
|
return child_range(C, C + 1);
|
|
return child_range(&NumTasks, &NumTasks + 1);
|
|
}
|
|
|
|
OMPClause::child_range OMPFinalClause::used_children() {
|
|
if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
|
|
return child_range(C, C + 1);
|
|
return child_range(&Condition, &Condition + 1);
|
|
}
|
|
|
|
OMPClause::child_range OMPPriorityClause::used_children() {
|
|
if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
|
|
return child_range(C, C + 1);
|
|
return child_range(&Priority, &Priority + 1);
|
|
}
|
|
|
|
OMPClause::child_range OMPNovariantsClause::used_children() {
|
|
if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
|
|
return child_range(C, C + 1);
|
|
return child_range(&Condition, &Condition + 1);
|
|
}
|
|
|
|
OMPClause::child_range OMPNocontextClause::used_children() {
|
|
if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
|
|
return child_range(C, C + 1);
|
|
return child_range(&Condition, &Condition + 1);
|
|
}
|
|
|
|
OMPOrderedClause *OMPOrderedClause::Create(const ASTContext &C, Expr *Num,
|
|
unsigned NumLoops,
|
|
SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation EndLoc) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
|
|
auto *Clause =
|
|
new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc, LParenLoc, EndLoc);
|
|
for (unsigned I = 0; I < NumLoops; ++I) {
|
|
Clause->setLoopNumIterations(I, nullptr);
|
|
Clause->setLoopCounter(I, nullptr);
|
|
}
|
|
return Clause;
|
|
}
|
|
|
|
OMPOrderedClause *OMPOrderedClause::CreateEmpty(const ASTContext &C,
|
|
unsigned NumLoops) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
|
|
auto *Clause = new (Mem) OMPOrderedClause(NumLoops);
|
|
for (unsigned I = 0; I < NumLoops; ++I) {
|
|
Clause->setLoopNumIterations(I, nullptr);
|
|
Clause->setLoopCounter(I, nullptr);
|
|
}
|
|
return Clause;
|
|
}
|
|
|
|
void OMPOrderedClause::setLoopNumIterations(unsigned NumLoop,
|
|
Expr *NumIterations) {
|
|
assert(NumLoop < NumberOfLoops && "out of loops number.");
|
|
getTrailingObjects<Expr *>()[NumLoop] = NumIterations;
|
|
}
|
|
|
|
ArrayRef<Expr *> OMPOrderedClause::getLoopNumIterations() const {
|
|
return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumberOfLoops);
|
|
}
|
|
|
|
void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) {
|
|
assert(NumLoop < NumberOfLoops && "out of loops number.");
|
|
getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop] = Counter;
|
|
}
|
|
|
|
Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) {
|
|
assert(NumLoop < NumberOfLoops && "out of loops number.");
|
|
return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
|
|
}
|
|
|
|
const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const {
|
|
assert(NumLoop < NumberOfLoops && "out of loops number.");
|
|
return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
|
|
}
|
|
|
|
OMPUpdateClause *OMPUpdateClause::Create(const ASTContext &C,
|
|
SourceLocation StartLoc,
|
|
SourceLocation EndLoc) {
|
|
return new (C) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/false);
|
|
}
|
|
|
|
OMPUpdateClause *
|
|
OMPUpdateClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
|
SourceLocation LParenLoc, SourceLocation ArgumentLoc,
|
|
OpenMPDependClauseKind DK, SourceLocation EndLoc) {
|
|
void *Mem =
|
|
C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),
|
|
alignof(OMPUpdateClause));
|
|
auto *Clause =
|
|
new (Mem) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/true);
|
|
Clause->setLParenLoc(LParenLoc);
|
|
Clause->setArgumentLoc(ArgumentLoc);
|
|
Clause->setDependencyKind(DK);
|
|
return Clause;
|
|
}
|
|
|
|
OMPUpdateClause *OMPUpdateClause::CreateEmpty(const ASTContext &C,
|
|
bool IsExtended) {
|
|
if (!IsExtended)
|
|
return new (C) OMPUpdateClause(/*IsExtended=*/false);
|
|
void *Mem =
|
|
C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),
|
|
alignof(OMPUpdateClause));
|
|
auto *Clause = new (Mem) OMPUpdateClause(/*IsExtended=*/true);
|
|
Clause->IsExtended = true;
|
|
return Clause;
|
|
}
|
|
|
|
void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
|
|
assert(VL.size() == varlist_size() &&
|
|
"Number of private copies is not the same as the preallocated buffer");
|
|
std::copy(VL.begin(), VL.end(), varlist_end());
|
|
}
|
|
|
|
OMPPrivateClause *
|
|
OMPPrivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
|
SourceLocation LParenLoc, SourceLocation EndLoc,
|
|
ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
|
|
// Allocate space for private variables and initializer expressions.
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
|
|
OMPPrivateClause *Clause =
|
|
new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
Clause->setPrivateCopies(PrivateVL);
|
|
return Clause;
|
|
}
|
|
|
|
OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
|
|
return new (Mem) OMPPrivateClause(N);
|
|
}
|
|
|
|
void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
|
|
assert(VL.size() == varlist_size() &&
|
|
"Number of private copies is not the same as the preallocated buffer");
|
|
std::copy(VL.begin(), VL.end(), varlist_end());
|
|
}
|
|
|
|
void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
|
|
assert(VL.size() == varlist_size() &&
|
|
"Number of inits is not the same as the preallocated buffer");
|
|
std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
|
|
}
|
|
|
|
OMPFirstprivateClause *
|
|
OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
|
SourceLocation LParenLoc, SourceLocation EndLoc,
|
|
ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
|
|
ArrayRef<Expr *> InitVL, Stmt *PreInit) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * VL.size()));
|
|
OMPFirstprivateClause *Clause =
|
|
new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
Clause->setPrivateCopies(PrivateVL);
|
|
Clause->setInits(InitVL);
|
|
Clause->setPreInitStmt(PreInit);
|
|
return Clause;
|
|
}
|
|
|
|
OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * N));
|
|
return new (Mem) OMPFirstprivateClause(N);
|
|
}
|
|
|
|
void OMPLastprivateClause::setPrivateCopies(ArrayRef<Expr *> PrivateCopies) {
|
|
assert(PrivateCopies.size() == varlist_size() &&
|
|
"Number of private copies is not the same as the preallocated buffer");
|
|
std::copy(PrivateCopies.begin(), PrivateCopies.end(), varlist_end());
|
|
}
|
|
|
|
void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
|
|
assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
|
|
"not the same as the "
|
|
"preallocated buffer");
|
|
std::copy(SrcExprs.begin(), SrcExprs.end(), getPrivateCopies().end());
|
|
}
|
|
|
|
void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
|
|
assert(DstExprs.size() == varlist_size() && "Number of destination "
|
|
"expressions is not the same as "
|
|
"the preallocated buffer");
|
|
std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
|
|
}
|
|
|
|
void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
|
|
assert(AssignmentOps.size() == varlist_size() &&
|
|
"Number of assignment expressions is not the same as the preallocated "
|
|
"buffer");
|
|
std::copy(AssignmentOps.begin(), AssignmentOps.end(),
|
|
getDestinationExprs().end());
|
|
}
|
|
|
|
OMPLastprivateClause *OMPLastprivateClause::Create(
|
|
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
|
|
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
|
|
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
|
|
OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc,
|
|
SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
|
|
OMPLastprivateClause *Clause = new (Mem) OMPLastprivateClause(
|
|
StartLoc, LParenLoc, EndLoc, LPKind, LPKindLoc, ColonLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
Clause->setSourceExprs(SrcExprs);
|
|
Clause->setDestinationExprs(DstExprs);
|
|
Clause->setAssignmentOps(AssignmentOps);
|
|
Clause->setPreInitStmt(PreInit);
|
|
Clause->setPostUpdateExpr(PostUpdate);
|
|
return Clause;
|
|
}
|
|
|
|
OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
|
|
return new (Mem) OMPLastprivateClause(N);
|
|
}
|
|
|
|
OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
|
|
SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation EndLoc,
|
|
ArrayRef<Expr *> VL) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
|
|
OMPSharedClause *Clause =
|
|
new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
return Clause;
|
|
}
|
|
|
|
OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
|
|
return new (Mem) OMPSharedClause(N);
|
|
}
|
|
|
|
void OMPLinearClause::setPrivates(ArrayRef<Expr *> PL) {
|
|
assert(PL.size() == varlist_size() &&
|
|
"Number of privates is not the same as the preallocated buffer");
|
|
std::copy(PL.begin(), PL.end(), varlist_end());
|
|
}
|
|
|
|
void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {
|
|
assert(IL.size() == varlist_size() &&
|
|
"Number of inits is not the same as the preallocated buffer");
|
|
std::copy(IL.begin(), IL.end(), getPrivates().end());
|
|
}
|
|
|
|
void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {
|
|
assert(UL.size() == varlist_size() &&
|
|
"Number of updates is not the same as the preallocated buffer");
|
|
std::copy(UL.begin(), UL.end(), getInits().end());
|
|
}
|
|
|
|
void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {
|
|
assert(FL.size() == varlist_size() &&
|
|
"Number of final updates is not the same as the preallocated buffer");
|
|
std::copy(FL.begin(), FL.end(), getUpdates().end());
|
|
}
|
|
|
|
void OMPLinearClause::setUsedExprs(ArrayRef<Expr *> UE) {
|
|
assert(
|
|
UE.size() == varlist_size() + 1 &&
|
|
"Number of used expressions is not the same as the preallocated buffer");
|
|
std::copy(UE.begin(), UE.end(), getFinals().end() + 2);
|
|
}
|
|
|
|
OMPLinearClause *OMPLinearClause::Create(
|
|
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
|
|
OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
|
|
SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
|
|
ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
|
|
Stmt *PreInit, Expr *PostUpdate) {
|
|
// Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
|
|
// (Step and CalcStep), list of used expression + step.
|
|
void *Mem =
|
|
C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2 + VL.size() + 1));
|
|
OMPLinearClause *Clause = new (Mem) OMPLinearClause(
|
|
StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
Clause->setPrivates(PL);
|
|
Clause->setInits(IL);
|
|
// Fill update and final expressions with zeroes, they are provided later,
|
|
// after the directive construction.
|
|
std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
|
|
nullptr);
|
|
std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
|
|
nullptr);
|
|
std::fill(Clause->getUsedExprs().begin(), Clause->getUsedExprs().end(),
|
|
nullptr);
|
|
Clause->setStep(Step);
|
|
Clause->setCalcStep(CalcStep);
|
|
Clause->setPreInitStmt(PreInit);
|
|
Clause->setPostUpdateExpr(PostUpdate);
|
|
return Clause;
|
|
}
|
|
|
|
OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
|
|
unsigned NumVars) {
|
|
// Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
|
|
// (Step and CalcStep), list of used expression + step.
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * NumVars + 2 + NumVars +1));
|
|
return new (Mem) OMPLinearClause(NumVars);
|
|
}
|
|
|
|
OMPClause::child_range OMPLinearClause::used_children() {
|
|
// Range includes only non-nullptr elements.
|
|
return child_range(
|
|
reinterpret_cast<Stmt **>(getUsedExprs().begin()),
|
|
reinterpret_cast<Stmt **>(llvm::find(getUsedExprs(), nullptr)));
|
|
}
|
|
|
|
OMPAlignedClause *
|
|
OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
|
SourceLocation LParenLoc, SourceLocation ColonLoc,
|
|
SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
|
|
OMPAlignedClause *Clause = new (Mem)
|
|
OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
Clause->setAlignment(A);
|
|
return Clause;
|
|
}
|
|
|
|
OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
|
|
unsigned NumVars) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumVars + 1));
|
|
return new (Mem) OMPAlignedClause(NumVars);
|
|
}
|
|
|
|
void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
|
|
assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
|
|
"not the same as the "
|
|
"preallocated buffer");
|
|
std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
|
|
}
|
|
|
|
void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
|
|
assert(DstExprs.size() == varlist_size() && "Number of destination "
|
|
"expressions is not the same as "
|
|
"the preallocated buffer");
|
|
std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
|
|
}
|
|
|
|
void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
|
|
assert(AssignmentOps.size() == varlist_size() &&
|
|
"Number of assignment expressions is not the same as the preallocated "
|
|
"buffer");
|
|
std::copy(AssignmentOps.begin(), AssignmentOps.end(),
|
|
getDestinationExprs().end());
|
|
}
|
|
|
|
OMPCopyinClause *OMPCopyinClause::Create(
|
|
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
|
|
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
|
|
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
|
|
OMPCopyinClause *Clause =
|
|
new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
Clause->setSourceExprs(SrcExprs);
|
|
Clause->setDestinationExprs(DstExprs);
|
|
Clause->setAssignmentOps(AssignmentOps);
|
|
return Clause;
|
|
}
|
|
|
|
OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
|
|
return new (Mem) OMPCopyinClause(N);
|
|
}
|
|
|
|
void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
|
|
assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
|
|
"not the same as the "
|
|
"preallocated buffer");
|
|
std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
|
|
}
|
|
|
|
void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
|
|
assert(DstExprs.size() == varlist_size() && "Number of destination "
|
|
"expressions is not the same as "
|
|
"the preallocated buffer");
|
|
std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
|
|
}
|
|
|
|
void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
|
|
assert(AssignmentOps.size() == varlist_size() &&
|
|
"Number of assignment expressions is not the same as the preallocated "
|
|
"buffer");
|
|
std::copy(AssignmentOps.begin(), AssignmentOps.end(),
|
|
getDestinationExprs().end());
|
|
}
|
|
|
|
OMPCopyprivateClause *OMPCopyprivateClause::Create(
|
|
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
|
|
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
|
|
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
|
|
OMPCopyprivateClause *Clause =
|
|
new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
Clause->setSourceExprs(SrcExprs);
|
|
Clause->setDestinationExprs(DstExprs);
|
|
Clause->setAssignmentOps(AssignmentOps);
|
|
return Clause;
|
|
}
|
|
|
|
OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
|
|
return new (Mem) OMPCopyprivateClause(N);
|
|
}
|
|
|
|
void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
|
|
assert(Privates.size() == varlist_size() &&
|
|
"Number of private copies is not the same as the preallocated buffer");
|
|
std::copy(Privates.begin(), Privates.end(), varlist_end());
|
|
}
|
|
|
|
void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
|
|
assert(
|
|
LHSExprs.size() == varlist_size() &&
|
|
"Number of LHS expressions is not the same as the preallocated buffer");
|
|
std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
|
|
}
|
|
|
|
void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
|
|
assert(
|
|
RHSExprs.size() == varlist_size() &&
|
|
"Number of RHS expressions is not the same as the preallocated buffer");
|
|
std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
|
|
}
|
|
|
|
void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
|
|
assert(ReductionOps.size() == varlist_size() && "Number of reduction "
|
|
"expressions is not the same "
|
|
"as the preallocated buffer");
|
|
std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
|
|
}
|
|
|
|
void OMPReductionClause::setInscanCopyOps(ArrayRef<Expr *> Ops) {
|
|
assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
|
|
assert(Ops.size() == varlist_size() && "Number of copy "
|
|
"expressions is not the same "
|
|
"as the preallocated buffer");
|
|
llvm::copy(Ops, getReductionOps().end());
|
|
}
|
|
|
|
void OMPReductionClause::setInscanCopyArrayTemps(
|
|
ArrayRef<Expr *> CopyArrayTemps) {
|
|
assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
|
|
assert(CopyArrayTemps.size() == varlist_size() &&
|
|
"Number of copy temp expressions is not the same as the preallocated "
|
|
"buffer");
|
|
llvm::copy(CopyArrayTemps, getInscanCopyOps().end());
|
|
}
|
|
|
|
void OMPReductionClause::setInscanCopyArrayElems(
|
|
ArrayRef<Expr *> CopyArrayElems) {
|
|
assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
|
|
assert(CopyArrayElems.size() == varlist_size() &&
|
|
"Number of copy temp expressions is not the same as the preallocated "
|
|
"buffer");
|
|
llvm::copy(CopyArrayElems, getInscanCopyArrayTemps().end());
|
|
}
|
|
|
|
OMPReductionClause *OMPReductionClause::Create(
|
|
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
|
|
SourceLocation ModifierLoc, SourceLocation EndLoc, SourceLocation ColonLoc,
|
|
OpenMPReductionClauseModifier Modifier, ArrayRef<Expr *> VL,
|
|
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
|
|
ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
|
|
ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
|
|
ArrayRef<Expr *> CopyOps, ArrayRef<Expr *> CopyArrayTemps,
|
|
ArrayRef<Expr *> CopyArrayElems, Stmt *PreInit, Expr *PostUpdate) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(
|
|
(Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * VL.size()));
|
|
auto *Clause = new (Mem)
|
|
OMPReductionClause(StartLoc, LParenLoc, ModifierLoc, EndLoc, ColonLoc,
|
|
Modifier, VL.size(), QualifierLoc, NameInfo);
|
|
Clause->setVarRefs(VL);
|
|
Clause->setPrivates(Privates);
|
|
Clause->setLHSExprs(LHSExprs);
|
|
Clause->setRHSExprs(RHSExprs);
|
|
Clause->setReductionOps(ReductionOps);
|
|
Clause->setPreInitStmt(PreInit);
|
|
Clause->setPostUpdateExpr(PostUpdate);
|
|
if (Modifier == OMPC_REDUCTION_inscan) {
|
|
Clause->setInscanCopyOps(CopyOps);
|
|
Clause->setInscanCopyArrayTemps(CopyArrayTemps);
|
|
Clause->setInscanCopyArrayElems(CopyArrayElems);
|
|
} else {
|
|
assert(CopyOps.empty() &&
|
|
"copy operations are expected in inscan reductions only.");
|
|
assert(CopyArrayTemps.empty() &&
|
|
"copy array temps are expected in inscan reductions only.");
|
|
assert(CopyArrayElems.empty() &&
|
|
"copy array temps are expected in inscan reductions only.");
|
|
}
|
|
return Clause;
|
|
}
|
|
|
|
OMPReductionClause *
|
|
OMPReductionClause::CreateEmpty(const ASTContext &C, unsigned N,
|
|
OpenMPReductionClauseModifier Modifier) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(
|
|
(Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * N));
|
|
auto *Clause = new (Mem) OMPReductionClause(N);
|
|
Clause->setModifier(Modifier);
|
|
return Clause;
|
|
}
|
|
|
|
void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
|
|
assert(Privates.size() == varlist_size() &&
|
|
"Number of private copies is not the same as the preallocated buffer");
|
|
std::copy(Privates.begin(), Privates.end(), varlist_end());
|
|
}
|
|
|
|
void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
|
|
assert(
|
|
LHSExprs.size() == varlist_size() &&
|
|
"Number of LHS expressions is not the same as the preallocated buffer");
|
|
std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
|
|
}
|
|
|
|
void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
|
|
assert(
|
|
RHSExprs.size() == varlist_size() &&
|
|
"Number of RHS expressions is not the same as the preallocated buffer");
|
|
std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
|
|
}
|
|
|
|
void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
|
|
assert(ReductionOps.size() == varlist_size() && "Number of task reduction "
|
|
"expressions is not the same "
|
|
"as the preallocated buffer");
|
|
std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
|
|
}
|
|
|
|
OMPTaskReductionClause *OMPTaskReductionClause::Create(
|
|
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
|
|
SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
|
|
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
|
|
ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
|
|
ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
|
|
Expr *PostUpdate) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
|
|
OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause(
|
|
StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
|
|
Clause->setVarRefs(VL);
|
|
Clause->setPrivates(Privates);
|
|
Clause->setLHSExprs(LHSExprs);
|
|
Clause->setRHSExprs(RHSExprs);
|
|
Clause->setReductionOps(ReductionOps);
|
|
Clause->setPreInitStmt(PreInit);
|
|
Clause->setPostUpdateExpr(PostUpdate);
|
|
return Clause;
|
|
}
|
|
|
|
OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
|
|
return new (Mem) OMPTaskReductionClause(N);
|
|
}
|
|
|
|
void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
|
|
assert(Privates.size() == varlist_size() &&
|
|
"Number of private copies is not the same as the preallocated buffer");
|
|
std::copy(Privates.begin(), Privates.end(), varlist_end());
|
|
}
|
|
|
|
void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
|
|
assert(
|
|
LHSExprs.size() == varlist_size() &&
|
|
"Number of LHS expressions is not the same as the preallocated buffer");
|
|
std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
|
|
}
|
|
|
|
void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
|
|
assert(
|
|
RHSExprs.size() == varlist_size() &&
|
|
"Number of RHS expressions is not the same as the preallocated buffer");
|
|
std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
|
|
}
|
|
|
|
void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
|
|
assert(ReductionOps.size() == varlist_size() && "Number of in reduction "
|
|
"expressions is not the same "
|
|
"as the preallocated buffer");
|
|
std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
|
|
}
|
|
|
|
void OMPInReductionClause::setTaskgroupDescriptors(
|
|
ArrayRef<Expr *> TaskgroupDescriptors) {
|
|
assert(TaskgroupDescriptors.size() == varlist_size() &&
|
|
"Number of in reduction descriptors is not the same as the "
|
|
"preallocated buffer");
|
|
std::copy(TaskgroupDescriptors.begin(), TaskgroupDescriptors.end(),
|
|
getReductionOps().end());
|
|
}
|
|
|
|
OMPInReductionClause *OMPInReductionClause::Create(
|
|
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
|
|
SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
|
|
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
|
|
ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
|
|
ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
|
|
ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * VL.size()));
|
|
OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(
|
|
StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
|
|
Clause->setVarRefs(VL);
|
|
Clause->setPrivates(Privates);
|
|
Clause->setLHSExprs(LHSExprs);
|
|
Clause->setRHSExprs(RHSExprs);
|
|
Clause->setReductionOps(ReductionOps);
|
|
Clause->setTaskgroupDescriptors(TaskgroupDescriptors);
|
|
Clause->setPreInitStmt(PreInit);
|
|
Clause->setPostUpdateExpr(PostUpdate);
|
|
return Clause;
|
|
}
|
|
|
|
OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * N));
|
|
return new (Mem) OMPInReductionClause(N);
|
|
}
|
|
|
|
OMPSizesClause *OMPSizesClause::Create(const ASTContext &C,
|
|
SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation EndLoc,
|
|
ArrayRef<Expr *> Sizes) {
|
|
OMPSizesClause *Clause = CreateEmpty(C, Sizes.size());
|
|
Clause->setLocStart(StartLoc);
|
|
Clause->setLParenLoc(LParenLoc);
|
|
Clause->setLocEnd(EndLoc);
|
|
Clause->setSizesRefs(Sizes);
|
|
return Clause;
|
|
}
|
|
|
|
OMPSizesClause *OMPSizesClause::CreateEmpty(const ASTContext &C,
|
|
unsigned NumSizes) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumSizes));
|
|
return new (Mem) OMPSizesClause(NumSizes);
|
|
}
|
|
|
|
OMPFullClause *OMPFullClause::Create(const ASTContext &C,
|
|
SourceLocation StartLoc,
|
|
SourceLocation EndLoc) {
|
|
OMPFullClause *Clause = CreateEmpty(C);
|
|
Clause->setLocStart(StartLoc);
|
|
Clause->setLocEnd(EndLoc);
|
|
return Clause;
|
|
}
|
|
|
|
OMPFullClause *OMPFullClause::CreateEmpty(const ASTContext &C) {
|
|
return new (C) OMPFullClause();
|
|
}
|
|
|
|
OMPPartialClause *OMPPartialClause::Create(const ASTContext &C,
|
|
SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation EndLoc,
|
|
Expr *Factor) {
|
|
OMPPartialClause *Clause = CreateEmpty(C);
|
|
Clause->setLocStart(StartLoc);
|
|
Clause->setLParenLoc(LParenLoc);
|
|
Clause->setLocEnd(EndLoc);
|
|
Clause->setFactor(Factor);
|
|
return Clause;
|
|
}
|
|
|
|
OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {
|
|
return new (C) OMPPartialClause();
|
|
}
|
|
|
|
OMPAllocateClause *
|
|
OMPAllocateClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
|
SourceLocation LParenLoc, Expr *Allocator,
|
|
SourceLocation ColonLoc, SourceLocation EndLoc,
|
|
ArrayRef<Expr *> VL) {
|
|
// Allocate space for private variables and initializer expressions.
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
|
|
auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator,
|
|
ColonLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
return Clause;
|
|
}
|
|
|
|
OMPAllocateClause *OMPAllocateClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
|
|
return new (Mem) OMPAllocateClause(N);
|
|
}
|
|
|
|
OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
|
|
SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation EndLoc,
|
|
ArrayRef<Expr *> VL) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
|
|
OMPFlushClause *Clause =
|
|
new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
return Clause;
|
|
}
|
|
|
|
OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
|
|
return new (Mem) OMPFlushClause(N);
|
|
}
|
|
|
|
OMPDepobjClause *OMPDepobjClause::Create(const ASTContext &C,
|
|
SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation RParenLoc,
|
|
Expr *Depobj) {
|
|
auto *Clause = new (C) OMPDepobjClause(StartLoc, LParenLoc, RParenLoc);
|
|
Clause->setDepobj(Depobj);
|
|
return Clause;
|
|
}
|
|
|
|
OMPDepobjClause *OMPDepobjClause::CreateEmpty(const ASTContext &C) {
|
|
return new (C) OMPDepobjClause();
|
|
}
|
|
|
|
OMPDependClause *
|
|
OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
|
SourceLocation LParenLoc, SourceLocation EndLoc,
|
|
Expr *DepModifier, OpenMPDependClauseKind DepKind,
|
|
SourceLocation DepLoc, SourceLocation ColonLoc,
|
|
ArrayRef<Expr *> VL, unsigned NumLoops) {
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *>(VL.size() + /*depend-modifier*/ 1 + NumLoops),
|
|
alignof(OMPDependClause));
|
|
OMPDependClause *Clause = new (Mem)
|
|
OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
|
|
Clause->setVarRefs(VL);
|
|
Clause->setDependencyKind(DepKind);
|
|
Clause->setDependencyLoc(DepLoc);
|
|
Clause->setColonLoc(ColonLoc);
|
|
Clause->setModifier(DepModifier);
|
|
for (unsigned I = 0 ; I < NumLoops; ++I)
|
|
Clause->setLoopData(I, nullptr);
|
|
return Clause;
|
|
}
|
|
|
|
OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N,
|
|
unsigned NumLoops) {
|
|
void *Mem =
|
|
C.Allocate(totalSizeToAlloc<Expr *>(N + /*depend-modifier*/ 1 + NumLoops),
|
|
alignof(OMPDependClause));
|
|
return new (Mem) OMPDependClause(N, NumLoops);
|
|
}
|
|
|
|
void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
|
|
assert((getDependencyKind() == OMPC_DEPEND_sink ||
|
|
getDependencyKind() == OMPC_DEPEND_source) &&
|
|
NumLoop < NumLoops &&
|
|
"Expected sink or source depend + loop index must be less number of "
|
|
"loops.");
|
|
auto *It = std::next(getVarRefs().end(), NumLoop + 1);
|
|
*It = Cnt;
|
|
}
|
|
|
|
Expr *OMPDependClause::getLoopData(unsigned NumLoop) {
|
|
assert((getDependencyKind() == OMPC_DEPEND_sink ||
|
|
getDependencyKind() == OMPC_DEPEND_source) &&
|
|
NumLoop < NumLoops &&
|
|
"Expected sink or source depend + loop index must be less number of "
|
|
"loops.");
|
|
auto *It = std::next(getVarRefs().end(), NumLoop + 1);
|
|
return *It;
|
|
}
|
|
|
|
const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const {
|
|
assert((getDependencyKind() == OMPC_DEPEND_sink ||
|
|
getDependencyKind() == OMPC_DEPEND_source) &&
|
|
NumLoop < NumLoops &&
|
|
"Expected sink or source depend + loop index must be less number of "
|
|
"loops.");
|
|
const auto *It = std::next(getVarRefs().end(), NumLoop + 1);
|
|
return *It;
|
|
}
|
|
|
|
void OMPDependClause::setModifier(Expr *DepModifier) {
|
|
*getVarRefs().end() = DepModifier;
|
|
}
|
|
Expr *OMPDependClause::getModifier() { return *getVarRefs().end(); }
|
|
|
|
unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber(
|
|
MappableExprComponentListsRef ComponentLists) {
|
|
unsigned TotalNum = 0u;
|
|
for (auto &C : ComponentLists)
|
|
TotalNum += C.size();
|
|
return TotalNum;
|
|
}
|
|
|
|
unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
|
|
ArrayRef<const ValueDecl *> Declarations) {
|
|
unsigned TotalNum = 0u;
|
|
llvm::SmallPtrSet<const ValueDecl *, 8> Cache;
|
|
for (const ValueDecl *D : Declarations) {
|
|
const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
|
|
if (Cache.count(VD))
|
|
continue;
|
|
++TotalNum;
|
|
Cache.insert(VD);
|
|
}
|
|
return TotalNum;
|
|
}
|
|
|
|
OMPMapClause *OMPMapClause::Create(
|
|
const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
|
|
ArrayRef<ValueDecl *> Declarations,
|
|
MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
|
|
ArrayRef<OpenMPMapModifierKind> MapModifiers,
|
|
ArrayRef<SourceLocation> MapModifiersLoc,
|
|
NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
|
|
OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc) {
|
|
OMPMappableExprListSizeTy Sizes;
|
|
Sizes.NumVars = Vars.size();
|
|
Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
|
|
Sizes.NumComponentLists = ComponentLists.size();
|
|
Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
|
|
|
|
// We need to allocate:
|
|
// 2 x NumVars x Expr* - we have an original list expression and an associated
|
|
// user-defined mapper for each clause list entry.
|
|
// NumUniqueDeclarations x ValueDecl* - unique base declarations associated
|
|
// with each component list.
|
|
// (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
|
|
// number of lists for each unique declaration and the size of each component
|
|
// list.
|
|
// NumComponents x MappableComponent - the total of all the components in all
|
|
// the lists.
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
OMPMapClause *Clause = new (Mem)
|
|
OMPMapClause(MapModifiers, MapModifiersLoc, UDMQualifierLoc, MapperId,
|
|
Type, TypeIsImplicit, TypeLoc, Locs, Sizes);
|
|
|
|
Clause->setVarRefs(Vars);
|
|
Clause->setUDMapperRefs(UDMapperRefs);
|
|
Clause->setClauseInfo(Declarations, ComponentLists);
|
|
Clause->setMapType(Type);
|
|
Clause->setMapLoc(TypeLoc);
|
|
return Clause;
|
|
}
|
|
|
|
OMPMapClause *
|
|
OMPMapClause::CreateEmpty(const ASTContext &C,
|
|
const OMPMappableExprListSizeTy &Sizes) {
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
return new (Mem) OMPMapClause(Sizes);
|
|
}
|
|
|
|
OMPToClause *OMPToClause::Create(
|
|
const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
|
|
ArrayRef<ValueDecl *> Declarations,
|
|
MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
|
|
ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
|
|
ArrayRef<SourceLocation> MotionModifiersLoc,
|
|
NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
|
|
OMPMappableExprListSizeTy Sizes;
|
|
Sizes.NumVars = Vars.size();
|
|
Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
|
|
Sizes.NumComponentLists = ComponentLists.size();
|
|
Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
|
|
|
|
// We need to allocate:
|
|
// 2 x NumVars x Expr* - we have an original list expression and an associated
|
|
// user-defined mapper for each clause list entry.
|
|
// NumUniqueDeclarations x ValueDecl* - unique base declarations associated
|
|
// with each component list.
|
|
// (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
|
|
// number of lists for each unique declaration and the size of each component
|
|
// list.
|
|
// NumComponents x MappableComponent - the total of all the components in all
|
|
// the lists.
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
|
|
auto *Clause = new (Mem) OMPToClause(MotionModifiers, MotionModifiersLoc,
|
|
UDMQualifierLoc, MapperId, Locs, Sizes);
|
|
|
|
Clause->setVarRefs(Vars);
|
|
Clause->setUDMapperRefs(UDMapperRefs);
|
|
Clause->setClauseInfo(Declarations, ComponentLists);
|
|
return Clause;
|
|
}
|
|
|
|
OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C,
|
|
const OMPMappableExprListSizeTy &Sizes) {
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
return new (Mem) OMPToClause(Sizes);
|
|
}
|
|
|
|
OMPFromClause *OMPFromClause::Create(
|
|
const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
|
|
ArrayRef<ValueDecl *> Declarations,
|
|
MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
|
|
ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
|
|
ArrayRef<SourceLocation> MotionModifiersLoc,
|
|
NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
|
|
OMPMappableExprListSizeTy Sizes;
|
|
Sizes.NumVars = Vars.size();
|
|
Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
|
|
Sizes.NumComponentLists = ComponentLists.size();
|
|
Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
|
|
|
|
// We need to allocate:
|
|
// 2 x NumVars x Expr* - we have an original list expression and an associated
|
|
// user-defined mapper for each clause list entry.
|
|
// NumUniqueDeclarations x ValueDecl* - unique base declarations associated
|
|
// with each component list.
|
|
// (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
|
|
// number of lists for each unique declaration and the size of each component
|
|
// list.
|
|
// NumComponents x MappableComponent - the total of all the components in all
|
|
// the lists.
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
|
|
auto *Clause =
|
|
new (Mem) OMPFromClause(MotionModifiers, MotionModifiersLoc,
|
|
UDMQualifierLoc, MapperId, Locs, Sizes);
|
|
|
|
Clause->setVarRefs(Vars);
|
|
Clause->setUDMapperRefs(UDMapperRefs);
|
|
Clause->setClauseInfo(Declarations, ComponentLists);
|
|
return Clause;
|
|
}
|
|
|
|
OMPFromClause *
|
|
OMPFromClause::CreateEmpty(const ASTContext &C,
|
|
const OMPMappableExprListSizeTy &Sizes) {
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
return new (Mem) OMPFromClause(Sizes);
|
|
}
|
|
|
|
void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {
|
|
assert(VL.size() == varlist_size() &&
|
|
"Number of private copies is not the same as the preallocated buffer");
|
|
std::copy(VL.begin(), VL.end(), varlist_end());
|
|
}
|
|
|
|
void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
|
|
assert(VL.size() == varlist_size() &&
|
|
"Number of inits is not the same as the preallocated buffer");
|
|
std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
|
|
}
|
|
|
|
OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
|
|
const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
|
|
ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
|
|
ArrayRef<ValueDecl *> Declarations,
|
|
MappableExprComponentListsRef ComponentLists) {
|
|
OMPMappableExprListSizeTy Sizes;
|
|
Sizes.NumVars = Vars.size();
|
|
Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
|
|
Sizes.NumComponentLists = ComponentLists.size();
|
|
Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
|
|
|
|
// We need to allocate:
|
|
// NumVars x Expr* - we have an original list expression for each clause
|
|
// list entry.
|
|
// NumUniqueDeclarations x ValueDecl* - unique base declarations associated
|
|
// with each component list.
|
|
// (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
|
|
// number of lists for each unique declaration and the size of each component
|
|
// list.
|
|
// NumComponents x MappableComponent - the total of all the components in all
|
|
// the lists.
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
|
|
OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);
|
|
|
|
Clause->setVarRefs(Vars);
|
|
Clause->setPrivateCopies(PrivateVars);
|
|
Clause->setInits(Inits);
|
|
Clause->setClauseInfo(Declarations, ComponentLists);
|
|
return Clause;
|
|
}
|
|
|
|
OMPUseDevicePtrClause *
|
|
OMPUseDevicePtrClause::CreateEmpty(const ASTContext &C,
|
|
const OMPMappableExprListSizeTy &Sizes) {
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
return new (Mem) OMPUseDevicePtrClause(Sizes);
|
|
}
|
|
|
|
OMPUseDeviceAddrClause *
|
|
OMPUseDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
|
|
ArrayRef<Expr *> Vars,
|
|
ArrayRef<ValueDecl *> Declarations,
|
|
MappableExprComponentListsRef ComponentLists) {
|
|
OMPMappableExprListSizeTy Sizes;
|
|
Sizes.NumVars = Vars.size();
|
|
Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
|
|
Sizes.NumComponentLists = ComponentLists.size();
|
|
Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
|
|
|
|
// We need to allocate:
|
|
// 3 x NumVars x Expr* - we have an original list expression for each clause
|
|
// list entry and an equal number of private copies and inits.
|
|
// NumUniqueDeclarations x ValueDecl* - unique base declarations associated
|
|
// with each component list.
|
|
// (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
|
|
// number of lists for each unique declaration and the size of each component
|
|
// list.
|
|
// NumComponents x MappableComponent - the total of all the components in all
|
|
// the lists.
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
|
|
auto *Clause = new (Mem) OMPUseDeviceAddrClause(Locs, Sizes);
|
|
|
|
Clause->setVarRefs(Vars);
|
|
Clause->setClauseInfo(Declarations, ComponentLists);
|
|
return Clause;
|
|
}
|
|
|
|
OMPUseDeviceAddrClause *
|
|
OMPUseDeviceAddrClause::CreateEmpty(const ASTContext &C,
|
|
const OMPMappableExprListSizeTy &Sizes) {
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
return new (Mem) OMPUseDeviceAddrClause(Sizes);
|
|
}
|
|
|
|
OMPIsDevicePtrClause *
|
|
OMPIsDevicePtrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
|
|
ArrayRef<Expr *> Vars,
|
|
ArrayRef<ValueDecl *> Declarations,
|
|
MappableExprComponentListsRef ComponentLists) {
|
|
OMPMappableExprListSizeTy Sizes;
|
|
Sizes.NumVars = Vars.size();
|
|
Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
|
|
Sizes.NumComponentLists = ComponentLists.size();
|
|
Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
|
|
|
|
// We need to allocate:
|
|
// NumVars x Expr* - we have an original list expression for each clause list
|
|
// entry.
|
|
// NumUniqueDeclarations x ValueDecl* - unique base declarations associated
|
|
// with each component list.
|
|
// (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
|
|
// number of lists for each unique declaration and the size of each component
|
|
// list.
|
|
// NumComponents x MappableComponent - the total of all the components in all
|
|
// the lists.
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
|
|
OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(Locs, Sizes);
|
|
|
|
Clause->setVarRefs(Vars);
|
|
Clause->setClauseInfo(Declarations, ComponentLists);
|
|
return Clause;
|
|
}
|
|
|
|
OMPIsDevicePtrClause *
|
|
OMPIsDevicePtrClause::CreateEmpty(const ASTContext &C,
|
|
const OMPMappableExprListSizeTy &Sizes) {
|
|
void *Mem = C.Allocate(
|
|
totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
|
|
OMPClauseMappableExprCommon::MappableComponent>(
|
|
Sizes.NumVars, Sizes.NumUniqueDeclarations,
|
|
Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
|
|
Sizes.NumComponents));
|
|
return new (Mem) OMPIsDevicePtrClause(Sizes);
|
|
}
|
|
|
|
OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,
|
|
SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation EndLoc,
|
|
ArrayRef<Expr *> VL) {
|
|
// Allocate space for nontemporal variables + private references.
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
|
|
auto *Clause =
|
|
new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
return Clause;
|
|
}
|
|
|
|
OMPNontemporalClause *OMPNontemporalClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
|
|
return new (Mem) OMPNontemporalClause(N);
|
|
}
|
|
|
|
void OMPNontemporalClause::setPrivateRefs(ArrayRef<Expr *> VL) {
|
|
assert(VL.size() == varlist_size() && "Number of private references is not "
|
|
"the same as the preallocated buffer");
|
|
std::copy(VL.begin(), VL.end(), varlist_end());
|
|
}
|
|
|
|
OMPInclusiveClause *OMPInclusiveClause::Create(const ASTContext &C,
|
|
SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation EndLoc,
|
|
ArrayRef<Expr *> VL) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
|
|
auto *Clause =
|
|
new (Mem) OMPInclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
return Clause;
|
|
}
|
|
|
|
OMPInclusiveClause *OMPInclusiveClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
|
|
return new (Mem) OMPInclusiveClause(N);
|
|
}
|
|
|
|
OMPExclusiveClause *OMPExclusiveClause::Create(const ASTContext &C,
|
|
SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation EndLoc,
|
|
ArrayRef<Expr *> VL) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
|
|
auto *Clause =
|
|
new (Mem) OMPExclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
|
|
Clause->setVarRefs(VL);
|
|
return Clause;
|
|
}
|
|
|
|
OMPExclusiveClause *OMPExclusiveClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
|
|
return new (Mem) OMPExclusiveClause(N);
|
|
}
|
|
|
|
void OMPUsesAllocatorsClause::setAllocatorsData(
|
|
ArrayRef<OMPUsesAllocatorsClause::Data> Data) {
|
|
assert(Data.size() == NumOfAllocators &&
|
|
"Size of allocators data is not the same as the preallocated buffer.");
|
|
for (unsigned I = 0, E = Data.size(); I < E; ++I) {
|
|
const OMPUsesAllocatorsClause::Data &D = Data[I];
|
|
getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
|
|
static_cast<int>(ExprOffsets::Allocator)] =
|
|
D.Allocator;
|
|
getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
|
|
static_cast<int>(
|
|
ExprOffsets::AllocatorTraits)] =
|
|
D.AllocatorTraits;
|
|
getTrailingObjects<
|
|
SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
|
|
static_cast<int>(ParenLocsOffsets::LParen)] =
|
|
D.LParenLoc;
|
|
getTrailingObjects<
|
|
SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
|
|
static_cast<int>(ParenLocsOffsets::RParen)] =
|
|
D.RParenLoc;
|
|
}
|
|
}
|
|
|
|
OMPUsesAllocatorsClause::Data
|
|
OMPUsesAllocatorsClause::getAllocatorData(unsigned I) const {
|
|
OMPUsesAllocatorsClause::Data Data;
|
|
Data.Allocator =
|
|
getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
|
|
static_cast<int>(ExprOffsets::Allocator)];
|
|
Data.AllocatorTraits =
|
|
getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
|
|
static_cast<int>(
|
|
ExprOffsets::AllocatorTraits)];
|
|
Data.LParenLoc = getTrailingObjects<
|
|
SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
|
|
static_cast<int>(ParenLocsOffsets::LParen)];
|
|
Data.RParenLoc = getTrailingObjects<
|
|
SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
|
|
static_cast<int>(ParenLocsOffsets::RParen)];
|
|
return Data;
|
|
}
|
|
|
|
OMPUsesAllocatorsClause *
|
|
OMPUsesAllocatorsClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
|
SourceLocation LParenLoc, SourceLocation EndLoc,
|
|
ArrayRef<OMPUsesAllocatorsClause::Data> Data) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(
|
|
static_cast<int>(ExprOffsets::Total) * Data.size(),
|
|
static_cast<int>(ParenLocsOffsets::Total) * Data.size()));
|
|
auto *Clause = new (Mem)
|
|
OMPUsesAllocatorsClause(StartLoc, LParenLoc, EndLoc, Data.size());
|
|
Clause->setAllocatorsData(Data);
|
|
return Clause;
|
|
}
|
|
|
|
OMPUsesAllocatorsClause *
|
|
OMPUsesAllocatorsClause::CreateEmpty(const ASTContext &C, unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(
|
|
static_cast<int>(ExprOffsets::Total) * N,
|
|
static_cast<int>(ParenLocsOffsets::Total) * N));
|
|
return new (Mem) OMPUsesAllocatorsClause(N);
|
|
}
|
|
|
|
OMPAffinityClause *
|
|
OMPAffinityClause::Create(const ASTContext &C, SourceLocation StartLoc,
|
|
SourceLocation LParenLoc, SourceLocation ColonLoc,
|
|
SourceLocation EndLoc, Expr *Modifier,
|
|
ArrayRef<Expr *> Locators) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Locators.size() + 1));
|
|
auto *Clause = new (Mem)
|
|
OMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, Locators.size());
|
|
Clause->setModifier(Modifier);
|
|
Clause->setVarRefs(Locators);
|
|
return Clause;
|
|
}
|
|
|
|
OMPAffinityClause *OMPAffinityClause::CreateEmpty(const ASTContext &C,
|
|
unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + 1));
|
|
return new (Mem) OMPAffinityClause(N);
|
|
}
|
|
|
|
OMPInitClause *OMPInitClause::Create(const ASTContext &C, Expr *InteropVar,
|
|
ArrayRef<Expr *> PrefExprs, bool IsTarget,
|
|
bool IsTargetSync, SourceLocation StartLoc,
|
|
SourceLocation LParenLoc,
|
|
SourceLocation VarLoc,
|
|
SourceLocation EndLoc) {
|
|
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(PrefExprs.size() + 1));
|
|
auto *Clause =
|
|
new (Mem) OMPInitClause(IsTarget, IsTargetSync, StartLoc, LParenLoc,
|
|
VarLoc, EndLoc, PrefExprs.size() + 1);
|
|
Clause->setInteropVar(InteropVar);
|
|
llvm::copy(PrefExprs, Clause->getTrailingObjects<Expr *>() + 1);
|
|
return Clause;
|
|
}
|
|
|
|
OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C, unsigned N) {
|
|
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
|
|
return new (Mem) OMPInitClause(N);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// OpenMP clauses printing methods
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
|
|
OS << "if(";
|
|
if (Node->getNameModifier() != OMPD_unknown)
|
|
OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": ";
|
|
Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
|
|
OS << "final(";
|
|
Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
|
|
OS << "num_threads(";
|
|
Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
|
|
OS << "safelen(";
|
|
Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
|
|
OS << "simdlen(";
|
|
Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPSizesClause(OMPSizesClause *Node) {
|
|
OS << "sizes(";
|
|
bool First = true;
|
|
for (auto Size : Node->getSizesRefs()) {
|
|
if (!First)
|
|
OS << ", ";
|
|
Size->printPretty(OS, nullptr, Policy, 0);
|
|
First = false;
|
|
}
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPFullClause(OMPFullClause *Node) { OS << "full"; }
|
|
|
|
void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) {
|
|
OS << "partial";
|
|
|
|
if (Expr *Factor = Node->getFactor()) {
|
|
OS << '(';
|
|
Factor->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ')';
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
|
|
OS << "allocator(";
|
|
Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
|
|
OS << "collapse(";
|
|
Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {
|
|
OS << "detach(";
|
|
Node->getEventHandler()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
|
|
OS << "default("
|
|
<< getOpenMPSimpleClauseTypeName(OMPC_default,
|
|
unsigned(Node->getDefaultKind()))
|
|
<< ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
|
|
OS << "proc_bind("
|
|
<< getOpenMPSimpleClauseTypeName(OMPC_proc_bind,
|
|
unsigned(Node->getProcBindKind()))
|
|
<< ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
|
|
OS << "unified_address";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(
|
|
OMPUnifiedSharedMemoryClause *) {
|
|
OS << "unified_shared_memory";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {
|
|
OS << "reverse_offload";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(
|
|
OMPDynamicAllocatorsClause *) {
|
|
OS << "dynamic_allocators";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
|
|
OMPAtomicDefaultMemOrderClause *Node) {
|
|
OS << "atomic_default_mem_order("
|
|
<< getOpenMPSimpleClauseTypeName(OMPC_atomic_default_mem_order,
|
|
Node->getAtomicDefaultMemOrderKind())
|
|
<< ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
|
|
OS << "schedule(";
|
|
if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
|
|
OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
|
|
Node->getFirstScheduleModifier());
|
|
if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
|
|
OS << ", ";
|
|
OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
|
|
Node->getSecondScheduleModifier());
|
|
}
|
|
OS << ": ";
|
|
}
|
|
OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
|
|
if (auto *E = Node->getChunkSize()) {
|
|
OS << ", ";
|
|
E->printPretty(OS, nullptr, Policy);
|
|
}
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
|
|
OS << "ordered";
|
|
if (auto *Num = Node->getNumForLoops()) {
|
|
OS << "(";
|
|
Num->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
|
|
OS << "nowait";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
|
|
OS << "untied";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
|
|
OS << "nogroup";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
|
|
OS << "mergeable";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }
|
|
|
|
void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
|
|
|
|
void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *Node) {
|
|
OS << "update";
|
|
if (Node->isExtended()) {
|
|
OS << "(";
|
|
OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
|
|
Node->getDependencyKind());
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
|
|
OS << "capture";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
|
|
OS << "seq_cst";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {
|
|
OS << "acq_rel";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) {
|
|
OS << "acquire";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {
|
|
OS << "release";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {
|
|
OS << "relaxed";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
|
|
OS << "threads";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
|
|
|
|
void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
|
|
OS << "device(";
|
|
OpenMPDeviceClauseModifier Modifier = Node->getModifier();
|
|
if (Modifier != OMPC_DEVICE_unknown) {
|
|
OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
|
|
<< ": ";
|
|
}
|
|
Node->getDevice()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
|
|
OS << "num_teams(";
|
|
Node->getNumTeams()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
|
|
OS << "thread_limit(";
|
|
Node->getThreadLimit()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
|
|
OS << "priority(";
|
|
Node->getPriority()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
|
|
OS << "grainsize(";
|
|
Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
|
|
OS << "num_tasks(";
|
|
Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
|
|
OS << "hint(";
|
|
Node->getHint()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {
|
|
OS << "init(";
|
|
bool First = true;
|
|
for (const Expr *E : Node->prefs()) {
|
|
if (First)
|
|
OS << "prefer_type(";
|
|
else
|
|
OS << ",";
|
|
E->printPretty(OS, nullptr, Policy);
|
|
First = false;
|
|
}
|
|
if (!First)
|
|
OS << "), ";
|
|
if (Node->getIsTarget())
|
|
OS << "target";
|
|
if (Node->getIsTargetSync()) {
|
|
if (Node->getIsTarget())
|
|
OS << ", ";
|
|
OS << "targetsync";
|
|
}
|
|
OS << " : ";
|
|
Node->getInteropVar()->printPretty(OS, nullptr, Policy);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {
|
|
OS << "use(";
|
|
Node->getInteropVar()->printPretty(OS, nullptr, Policy);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *Node) {
|
|
OS << "destroy";
|
|
if (Expr *E = Node->getInteropVar()) {
|
|
OS << "(";
|
|
E->printPretty(OS, nullptr, Policy);
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPNovariantsClause(OMPNovariantsClause *Node) {
|
|
OS << "novariants";
|
|
if (Expr *E = Node->getCondition()) {
|
|
OS << "(";
|
|
E->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPNocontextClause(OMPNocontextClause *Node) {
|
|
OS << "nocontext";
|
|
if (Expr *E = Node->getCondition()) {
|
|
OS << "(";
|
|
E->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
|
|
for (typename T::varlist_iterator I = Node->varlist_begin(),
|
|
E = Node->varlist_end();
|
|
I != E; ++I) {
|
|
assert(*I && "Expected non-null Stmt");
|
|
OS << (I == Node->varlist_begin() ? StartSym : ',');
|
|
if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {
|
|
if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
|
|
DRE->printPretty(OS, nullptr, Policy, 0);
|
|
else
|
|
DRE->getDecl()->printQualifiedName(OS);
|
|
} else
|
|
(*I)->printPretty(OS, nullptr, Policy, 0);
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
|
|
if (Node->varlist_empty())
|
|
return;
|
|
OS << "allocate";
|
|
if (Expr *Allocator = Node->getAllocator()) {
|
|
OS << "(";
|
|
Allocator->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ":";
|
|
VisitOMPClauseList(Node, ' ');
|
|
} else {
|
|
VisitOMPClauseList(Node, '(');
|
|
}
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "private";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "firstprivate";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "lastprivate";
|
|
OpenMPLastprivateModifier LPKind = Node->getKind();
|
|
if (LPKind != OMPC_LASTPRIVATE_unknown) {
|
|
OS << "("
|
|
<< getOpenMPSimpleClauseTypeName(OMPC_lastprivate, Node->getKind())
|
|
<< ":";
|
|
}
|
|
VisitOMPClauseList(Node, LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "shared";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "reduction(";
|
|
if (Node->getModifierLoc().isValid())
|
|
OS << getOpenMPSimpleClauseTypeName(OMPC_reduction, Node->getModifier())
|
|
<< ", ";
|
|
NestedNameSpecifier *QualifierLoc =
|
|
Node->getQualifierLoc().getNestedNameSpecifier();
|
|
OverloadedOperatorKind OOK =
|
|
Node->getNameInfo().getName().getCXXOverloadedOperator();
|
|
if (QualifierLoc == nullptr && OOK != OO_None) {
|
|
// Print reduction identifier in C format
|
|
OS << getOperatorSpelling(OOK);
|
|
} else {
|
|
// Use C++ format
|
|
if (QualifierLoc != nullptr)
|
|
QualifierLoc->print(OS, Policy);
|
|
OS << Node->getNameInfo();
|
|
}
|
|
OS << ":";
|
|
VisitOMPClauseList(Node, ' ');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPTaskReductionClause(
|
|
OMPTaskReductionClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "task_reduction(";
|
|
NestedNameSpecifier *QualifierLoc =
|
|
Node->getQualifierLoc().getNestedNameSpecifier();
|
|
OverloadedOperatorKind OOK =
|
|
Node->getNameInfo().getName().getCXXOverloadedOperator();
|
|
if (QualifierLoc == nullptr && OOK != OO_None) {
|
|
// Print reduction identifier in C format
|
|
OS << getOperatorSpelling(OOK);
|
|
} else {
|
|
// Use C++ format
|
|
if (QualifierLoc != nullptr)
|
|
QualifierLoc->print(OS, Policy);
|
|
OS << Node->getNameInfo();
|
|
}
|
|
OS << ":";
|
|
VisitOMPClauseList(Node, ' ');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "in_reduction(";
|
|
NestedNameSpecifier *QualifierLoc =
|
|
Node->getQualifierLoc().getNestedNameSpecifier();
|
|
OverloadedOperatorKind OOK =
|
|
Node->getNameInfo().getName().getCXXOverloadedOperator();
|
|
if (QualifierLoc == nullptr && OOK != OO_None) {
|
|
// Print reduction identifier in C format
|
|
OS << getOperatorSpelling(OOK);
|
|
} else {
|
|
// Use C++ format
|
|
if (QualifierLoc != nullptr)
|
|
QualifierLoc->print(OS, Policy);
|
|
OS << Node->getNameInfo();
|
|
}
|
|
OS << ":";
|
|
VisitOMPClauseList(Node, ' ');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "linear";
|
|
if (Node->getModifierLoc().isValid()) {
|
|
OS << '('
|
|
<< getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
|
|
}
|
|
VisitOMPClauseList(Node, '(');
|
|
if (Node->getModifierLoc().isValid())
|
|
OS << ')';
|
|
if (Node->getStep() != nullptr) {
|
|
OS << ": ";
|
|
Node->getStep()->printPretty(OS, nullptr, Policy, 0);
|
|
}
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "aligned";
|
|
VisitOMPClauseList(Node, '(');
|
|
if (Node->getAlignment() != nullptr) {
|
|
OS << ": ";
|
|
Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
|
|
}
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "copyin";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "copyprivate";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {
|
|
OS << "(";
|
|
Node->getDepobj()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
|
|
OS << "depend(";
|
|
if (Expr *DepModifier = Node->getModifier()) {
|
|
DepModifier->printPretty(OS, nullptr, Policy);
|
|
OS << ", ";
|
|
}
|
|
OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
|
|
Node->getDependencyKind());
|
|
if (!Node->varlist_empty()) {
|
|
OS << " :";
|
|
VisitOMPClauseList(Node, ' ');
|
|
}
|
|
OS << ")";
|
|
}
|
|
|
|
template <typename T>
|
|
static void PrintMapper(raw_ostream &OS, T *Node,
|
|
const PrintingPolicy &Policy) {
|
|
OS << '(';
|
|
NestedNameSpecifier *MapperNNS =
|
|
Node->getMapperQualifierLoc().getNestedNameSpecifier();
|
|
if (MapperNNS)
|
|
MapperNNS->print(OS, Policy);
|
|
OS << Node->getMapperIdInfo() << ')';
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "map(";
|
|
if (Node->getMapType() != OMPC_MAP_unknown) {
|
|
for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
|
|
if (Node->getMapTypeModifier(I) != OMPC_MAP_MODIFIER_unknown) {
|
|
OS << getOpenMPSimpleClauseTypeName(OMPC_map,
|
|
Node->getMapTypeModifier(I));
|
|
if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_mapper)
|
|
PrintMapper(OS, Node, Policy);
|
|
OS << ',';
|
|
}
|
|
}
|
|
OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType());
|
|
OS << ':';
|
|
}
|
|
VisitOMPClauseList(Node, ' ');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
template <typename T> void OMPClausePrinter::VisitOMPMotionClause(T *Node) {
|
|
if (Node->varlist_empty())
|
|
return;
|
|
OS << getOpenMPClauseName(Node->getClauseKind());
|
|
unsigned ModifierCount = 0;
|
|
for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
|
|
if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown)
|
|
++ModifierCount;
|
|
}
|
|
if (ModifierCount) {
|
|
OS << '(';
|
|
for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
|
|
if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown) {
|
|
OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
|
|
Node->getMotionModifier(I));
|
|
if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_mapper)
|
|
PrintMapper(OS, Node, Policy);
|
|
if (I < ModifierCount - 1)
|
|
OS << ", ";
|
|
}
|
|
}
|
|
OS << ':';
|
|
VisitOMPClauseList(Node, ' ');
|
|
} else {
|
|
VisitOMPClauseList(Node, '(');
|
|
}
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
|
|
VisitOMPMotionClause(Node);
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
|
|
VisitOMPMotionClause(Node);
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
|
|
OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
|
|
OMPC_dist_schedule, Node->getDistScheduleKind());
|
|
if (auto *E = Node->getChunkSize()) {
|
|
OS << ", ";
|
|
E->printPretty(OS, nullptr, Policy);
|
|
}
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
|
|
OS << "defaultmap(";
|
|
OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
|
|
Node->getDefaultmapModifier());
|
|
if (Node->getDefaultmapKind() != OMPC_DEFAULTMAP_unknown) {
|
|
OS << ": ";
|
|
OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
|
|
Node->getDefaultmapKind());
|
|
}
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "use_device_ptr";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPUseDeviceAddrClause(
|
|
OMPUseDeviceAddrClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "use_device_addr";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "is_device_ptr";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "nontemporal";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
|
|
OS << "order(" << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getKind())
|
|
<< ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "inclusive";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {
|
|
if (!Node->varlist_empty()) {
|
|
OS << "exclusive";
|
|
VisitOMPClauseList(Node, '(');
|
|
OS << ")";
|
|
}
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPUsesAllocatorsClause(
|
|
OMPUsesAllocatorsClause *Node) {
|
|
if (Node->getNumberOfAllocators() == 0)
|
|
return;
|
|
OS << "uses_allocators(";
|
|
for (unsigned I = 0, E = Node->getNumberOfAllocators(); I < E; ++I) {
|
|
OMPUsesAllocatorsClause::Data Data = Node->getAllocatorData(I);
|
|
Data.Allocator->printPretty(OS, nullptr, Policy);
|
|
if (Data.AllocatorTraits) {
|
|
OS << "(";
|
|
Data.AllocatorTraits->printPretty(OS, nullptr, Policy);
|
|
OS << ")";
|
|
}
|
|
if (I < E - 1)
|
|
OS << ",";
|
|
}
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {
|
|
if (Node->varlist_empty())
|
|
return;
|
|
OS << "affinity";
|
|
char StartSym = '(';
|
|
if (Expr *Modifier = Node->getModifier()) {
|
|
OS << "(";
|
|
Modifier->printPretty(OS, nullptr, Policy);
|
|
OS << " :";
|
|
StartSym = ' ';
|
|
}
|
|
VisitOMPClauseList(Node, StartSym);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPClausePrinter::VisitOMPFilterClause(OMPFilterClause *Node) {
|
|
OS << "filter(";
|
|
Node->getThreadID()->printPretty(OS, nullptr, Policy, 0);
|
|
OS << ")";
|
|
}
|
|
|
|
void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,
|
|
VariantMatchInfo &VMI) const {
|
|
for (const OMPTraitSet &Set : Sets) {
|
|
for (const OMPTraitSelector &Selector : Set.Selectors) {
|
|
|
|
// User conditions are special as we evaluate the condition here.
|
|
if (Selector.Kind == TraitSelector::user_condition) {
|
|
assert(Selector.ScoreOrCondition &&
|
|
"Ill-formed user condition, expected condition expression!");
|
|
assert(Selector.Properties.size() == 1 &&
|
|
Selector.Properties.front().Kind ==
|
|
TraitProperty::user_condition_unknown &&
|
|
"Ill-formed user condition, expected unknown trait property!");
|
|
|
|
if (Optional<APSInt> CondVal =
|
|
Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx))
|
|
VMI.addTrait(CondVal->isZero() ? TraitProperty::user_condition_false
|
|
: TraitProperty::user_condition_true,
|
|
"<condition>");
|
|
else
|
|
VMI.addTrait(TraitProperty::user_condition_false, "<condition>");
|
|
continue;
|
|
}
|
|
|
|
Optional<llvm::APSInt> Score;
|
|
llvm::APInt *ScorePtr = nullptr;
|
|
if (Selector.ScoreOrCondition) {
|
|
if ((Score = Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx)))
|
|
ScorePtr = &*Score;
|
|
else
|
|
VMI.addTrait(TraitProperty::user_condition_false,
|
|
"<non-constant-score>");
|
|
}
|
|
|
|
for (const OMPTraitProperty &Property : Selector.Properties)
|
|
VMI.addTrait(Set.Kind, Property.Kind, Property.RawString, ScorePtr);
|
|
|
|
if (Set.Kind != TraitSet::construct)
|
|
continue;
|
|
|
|
// TODO: This might not hold once we implement SIMD properly.
|
|
assert(Selector.Properties.size() == 1 &&
|
|
Selector.Properties.front().Kind ==
|
|
getOpenMPContextTraitPropertyForSelector(
|
|
Selector.Kind) &&
|
|
"Ill-formed construct selector!");
|
|
}
|
|
}
|
|
}
|
|
|
|
void OMPTraitInfo::print(llvm::raw_ostream &OS,
|
|
const PrintingPolicy &Policy) const {
|
|
bool FirstSet = true;
|
|
for (const OMPTraitSet &Set : Sets) {
|
|
if (!FirstSet)
|
|
OS << ", ";
|
|
FirstSet = false;
|
|
OS << getOpenMPContextTraitSetName(Set.Kind) << "={";
|
|
|
|
bool FirstSelector = true;
|
|
for (const OMPTraitSelector &Selector : Set.Selectors) {
|
|
if (!FirstSelector)
|
|
OS << ", ";
|
|
FirstSelector = false;
|
|
OS << getOpenMPContextTraitSelectorName(Selector.Kind);
|
|
|
|
bool AllowsTraitScore = false;
|
|
bool RequiresProperty = false;
|
|
isValidTraitSelectorForTraitSet(
|
|
Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);
|
|
|
|
if (!RequiresProperty)
|
|
continue;
|
|
|
|
OS << "(";
|
|
if (Selector.Kind == TraitSelector::user_condition) {
|
|
if (Selector.ScoreOrCondition)
|
|
Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
|
|
else
|
|
OS << "...";
|
|
} else {
|
|
|
|
if (Selector.ScoreOrCondition) {
|
|
OS << "score(";
|
|
Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
|
|
OS << "): ";
|
|
}
|
|
|
|
bool FirstProperty = true;
|
|
for (const OMPTraitProperty &Property : Selector.Properties) {
|
|
if (!FirstProperty)
|
|
OS << ", ";
|
|
FirstProperty = false;
|
|
OS << getOpenMPContextTraitPropertyName(Property.Kind,
|
|
Property.RawString);
|
|
}
|
|
}
|
|
OS << ")";
|
|
}
|
|
OS << "}";
|
|
}
|
|
}
|
|
|
|
std::string OMPTraitInfo::getMangledName() const {
|
|
std::string MangledName;
|
|
llvm::raw_string_ostream OS(MangledName);
|
|
for (const OMPTraitSet &Set : Sets) {
|
|
OS << '$' << 'S' << unsigned(Set.Kind);
|
|
for (const OMPTraitSelector &Selector : Set.Selectors) {
|
|
|
|
bool AllowsTraitScore = false;
|
|
bool RequiresProperty = false;
|
|
isValidTraitSelectorForTraitSet(
|
|
Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);
|
|
OS << '$' << 's' << unsigned(Selector.Kind);
|
|
|
|
if (!RequiresProperty ||
|
|
Selector.Kind == TraitSelector::user_condition)
|
|
continue;
|
|
|
|
for (const OMPTraitProperty &Property : Selector.Properties)
|
|
OS << '$' << 'P'
|
|
<< getOpenMPContextTraitPropertyName(Property.Kind,
|
|
Property.RawString);
|
|
}
|
|
}
|
|
return OS.str();
|
|
}
|
|
|
|
OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {
|
|
unsigned long U;
|
|
do {
|
|
if (!MangledName.consume_front("$S"))
|
|
break;
|
|
if (MangledName.consumeInteger(10, U))
|
|
break;
|
|
Sets.push_back(OMPTraitSet());
|
|
OMPTraitSet &Set = Sets.back();
|
|
Set.Kind = TraitSet(U);
|
|
do {
|
|
if (!MangledName.consume_front("$s"))
|
|
break;
|
|
if (MangledName.consumeInteger(10, U))
|
|
break;
|
|
Set.Selectors.push_back(OMPTraitSelector());
|
|
OMPTraitSelector &Selector = Set.Selectors.back();
|
|
Selector.Kind = TraitSelector(U);
|
|
do {
|
|
if (!MangledName.consume_front("$P"))
|
|
break;
|
|
Selector.Properties.push_back(OMPTraitProperty());
|
|
OMPTraitProperty &Property = Selector.Properties.back();
|
|
std::pair<StringRef, StringRef> PropRestPair = MangledName.split('$');
|
|
Property.RawString = PropRestPair.first;
|
|
Property.Kind = getOpenMPContextTraitPropertyKind(
|
|
Set.Kind, Selector.Kind, PropRestPair.first);
|
|
MangledName = MangledName.drop_front(PropRestPair.first.size());
|
|
} while (true);
|
|
} while (true);
|
|
} while (true);
|
|
}
|
|
|
|
llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
|
|
const OMPTraitInfo &TI) {
|
|
LangOptions LO;
|
|
PrintingPolicy Policy(LO);
|
|
TI.print(OS, Policy);
|
|
return OS;
|
|
}
|
|
llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
|
|
const OMPTraitInfo *TI) {
|
|
return TI ? OS << *TI : OS;
|
|
}
|
|
|
|
TargetOMPContext::TargetOMPContext(
|
|
ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,
|
|
const FunctionDecl *CurrentFunctionDecl,
|
|
ArrayRef<llvm::omp::TraitProperty> ConstructTraits)
|
|
: OMPContext(ASTCtx.getLangOpts().OpenMPIsDevice,
|
|
ASTCtx.getTargetInfo().getTriple()),
|
|
FeatureValidityCheck([&](StringRef FeatureName) {
|
|
return ASTCtx.getTargetInfo().isValidFeatureName(FeatureName);
|
|
}),
|
|
DiagUnknownTrait(std::move(DiagUnknownTrait)) {
|
|
ASTCtx.getFunctionFeatureMap(FeatureMap, CurrentFunctionDecl);
|
|
|
|
for (llvm::omp::TraitProperty Property : ConstructTraits)
|
|
addTrait(Property);
|
|
}
|
|
|
|
bool TargetOMPContext::matchesISATrait(StringRef RawString) const {
|
|
auto It = FeatureMap.find(RawString);
|
|
if (It != FeatureMap.end())
|
|
return It->second;
|
|
if (!FeatureValidityCheck(RawString))
|
|
DiagUnknownTrait(RawString);
|
|
return false;
|
|
}
|