forked from OSchip/llvm-project
[OpenMP] Make the filetered clause iterator a real iterator and type safe.
This replaces the filtered generic iterator with a type-specfic one based on dyn_cast instead of comparing the kind enum. This allows us to use range-based for loops and eliminates casts. No functionality change intended. llvm-svn: 246384
This commit is contained in:
parent
2985400a0e
commit
fc600dc2ec
|
@ -92,65 +92,91 @@ public:
|
|||
/// \brief Iterates over a filtered subrange of clauses applied to a
|
||||
/// directive.
|
||||
///
|
||||
/// This iterator visits only those declarations that meet some run-time
|
||||
/// criteria.
|
||||
template <class FilterPredicate> class filtered_clause_iterator {
|
||||
protected:
|
||||
/// This iterator visits only clauses of type SpecificClause.
|
||||
template <typename SpecificClause>
|
||||
class specific_clause_iterator
|
||||
: public std::iterator<std::forward_iterator_tag, const SpecificClause *,
|
||||
ptrdiff_t, const SpecificClause *,
|
||||
const SpecificClause *> {
|
||||
ArrayRef<OMPClause *>::const_iterator Current;
|
||||
ArrayRef<OMPClause *>::const_iterator End;
|
||||
FilterPredicate Pred;
|
||||
|
||||
void SkipToNextClause() {
|
||||
while (Current != End && !Pred(*Current))
|
||||
while (Current != End && !isa<SpecificClause>(*Current))
|
||||
++Current;
|
||||
}
|
||||
|
||||
public:
|
||||
typedef const OMPClause *value_type;
|
||||
filtered_clause_iterator() : Current(), End() {}
|
||||
filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
|
||||
: Current(Arr.begin()), End(Arr.end()), Pred(std::move(Pred)) {
|
||||
explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
|
||||
: Current(Clauses.begin()), End(Clauses.end()) {
|
||||
SkipToNextClause();
|
||||
}
|
||||
value_type operator*() const { return *Current; }
|
||||
value_type operator->() const { return *Current; }
|
||||
filtered_clause_iterator &operator++() {
|
||||
|
||||
const SpecificClause *operator*() const {
|
||||
return cast<SpecificClause>(*Current);
|
||||
}
|
||||
const SpecificClause *operator->() const {
|
||||
return cast<SpecificClause>(*Current);
|
||||
}
|
||||
|
||||
specific_clause_iterator &operator++() {
|
||||
++Current;
|
||||
SkipToNextClause();
|
||||
return *this;
|
||||
}
|
||||
|
||||
filtered_clause_iterator operator++(int) {
|
||||
filtered_clause_iterator tmp(*this);
|
||||
specific_clause_iterator operator++(int) {
|
||||
specific_clause_iterator tmp(*this);
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator!() { return Current == End; }
|
||||
explicit operator bool() { return Current != End; }
|
||||
bool empty() const { return Current == End; }
|
||||
};
|
||||
|
||||
template <typename Fn>
|
||||
filtered_clause_iterator<Fn> getFilteredClauses(Fn &&fn) const {
|
||||
return filtered_clause_iterator<Fn>(clauses(), std::move(fn));
|
||||
bool operator==(const specific_clause_iterator &RHS) const {
|
||||
assert(End == RHS.End && "Comparing iterators of different directives!");
|
||||
return Current == RHS.Current;
|
||||
}
|
||||
struct ClauseKindFilter {
|
||||
OpenMPClauseKind Kind;
|
||||
bool operator()(const OMPClause *clause) const {
|
||||
return clause->getClauseKind() == Kind;
|
||||
bool operator!=(const specific_clause_iterator &RHS) const {
|
||||
return !(*this == RHS);
|
||||
}
|
||||
};
|
||||
filtered_clause_iterator<ClauseKindFilter>
|
||||
getClausesOfKind(OpenMPClauseKind Kind) const {
|
||||
return getFilteredClauses(ClauseKindFilter{Kind});
|
||||
|
||||
template <typename SpecificClause>
|
||||
static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
|
||||
getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
|
||||
return {specific_clause_iterator<SpecificClause>(Clauses),
|
||||
specific_clause_iterator<SpecificClause>(
|
||||
llvm::makeArrayRef(Clauses.end(), 0))};
|
||||
}
|
||||
|
||||
/// \brief Gets a single clause of the specified kind \a K associated with the
|
||||
template <typename SpecificClause>
|
||||
llvm::iterator_range<specific_clause_iterator<SpecificClause>>
|
||||
getClausesOfKind() const {
|
||||
return getClausesOfKind<SpecificClause>(clauses());
|
||||
}
|
||||
|
||||
/// Gets a single clause of the specified kind associated with the
|
||||
/// current directive iff there is only one clause of this kind (and assertion
|
||||
/// is fired if there is more than one clause is associated with the
|
||||
/// directive). Returns nullptr if no clause of kind \a K is associated with
|
||||
/// directive). Returns nullptr if no clause of this kind is associated with
|
||||
/// the directive.
|
||||
const OMPClause *getSingleClause(OpenMPClauseKind K) const;
|
||||
template <typename SpecificClause>
|
||||
const SpecificClause *getSingleClause() const {
|
||||
auto Clauses = getClausesOfKind<SpecificClause>();
|
||||
|
||||
if (Clauses.begin() != Clauses.end()) {
|
||||
assert(std::next(Clauses.begin()) == Clauses.end() &&
|
||||
"There are at least 2 clauses of the specified kind");
|
||||
return *Clauses.begin();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// Returns true if the current directive has one or more clauses of a
|
||||
/// specific kind.
|
||||
template <typename SpecificClause>
|
||||
bool hasClausesOfKind() const {
|
||||
auto Clauses = getClausesOfKind<SpecificClause>();
|
||||
return Clauses.begin() != Clauses.end();
|
||||
}
|
||||
|
||||
/// \brief Returns starting location of directive kind.
|
||||
SourceLocation getLocStart() const { return StartLoc; }
|
||||
|
|
|
@ -1621,18 +1621,6 @@ OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) {
|
|||
return new (Mem) OMPDependClause(N);
|
||||
}
|
||||
|
||||
const OMPClause *
|
||||
OMPExecutableDirective::getSingleClause(OpenMPClauseKind K) const {
|
||||
auto &&I = getClausesOfKind(K);
|
||||
|
||||
if (I) {
|
||||
auto *Clause = *I;
|
||||
assert(!++I && "There are at least 2 clauses of the specified kind");
|
||||
return Clause;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OMPParallelDirective *OMPParallelDirective::Create(
|
||||
const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
|
|
|
@ -115,8 +115,7 @@ void CodeGenFunction::EmitOMPCopy(CodeGenFunction &CGF,
|
|||
bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D,
|
||||
OMPPrivateScope &PrivateScope) {
|
||||
llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate;
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_firstprivate); I; ++I) {
|
||||
auto *C = cast<OMPFirstprivateClause>(*I);
|
||||
for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) {
|
||||
auto IRef = C->varlist_begin();
|
||||
auto InitsRef = C->inits().begin();
|
||||
for (auto IInit : C->private_copies()) {
|
||||
|
@ -189,8 +188,7 @@ void CodeGenFunction::EmitOMPPrivateClause(
|
|||
const OMPExecutableDirective &D,
|
||||
CodeGenFunction::OMPPrivateScope &PrivateScope) {
|
||||
llvm::DenseSet<const VarDecl *> EmittedAsPrivate;
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_private); I; ++I) {
|
||||
auto *C = cast<OMPPrivateClause>(*I);
|
||||
for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) {
|
||||
auto IRef = C->varlist_begin();
|
||||
for (auto IInit : C->private_copies()) {
|
||||
auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
|
||||
|
@ -218,8 +216,7 @@ bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) {
|
|||
// __kmpc_barrier(&loc, global_tid);
|
||||
llvm::DenseSet<const VarDecl *> CopiedVars;
|
||||
llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr;
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_copyin); I; ++I) {
|
||||
auto *C = cast<OMPCopyinClause>(*I);
|
||||
for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) {
|
||||
auto IRef = C->varlist_begin();
|
||||
auto ISrcRef = C->source_exprs().begin();
|
||||
auto IDestRef = C->destination_exprs().begin();
|
||||
|
@ -279,9 +276,8 @@ bool CodeGenFunction::EmitOMPLastprivateClauseInit(
|
|||
const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) {
|
||||
bool HasAtLeastOneLastprivate = false;
|
||||
llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_lastprivate); I; ++I) {
|
||||
for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
|
||||
HasAtLeastOneLastprivate = true;
|
||||
auto *C = cast<OMPLastprivateClause>(*I);
|
||||
auto IRef = C->varlist_begin();
|
||||
auto IDestRef = C->destination_exprs().begin();
|
||||
for (auto *IInit : C->private_copies()) {
|
||||
|
@ -359,8 +355,7 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal(
|
|||
{
|
||||
llvm::DenseSet<const VarDecl *> AlreadyEmittedVars;
|
||||
bool FirstLCV = true;
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_lastprivate); I; ++I) {
|
||||
auto *C = cast<OMPLastprivateClause>(*I);
|
||||
for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) {
|
||||
auto IRef = C->varlist_begin();
|
||||
auto ISrcRef = C->source_exprs().begin();
|
||||
auto IDestRef = C->destination_exprs().begin();
|
||||
|
@ -405,8 +400,7 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal(
|
|||
void CodeGenFunction::EmitOMPReductionClauseInit(
|
||||
const OMPExecutableDirective &D,
|
||||
CodeGenFunction::OMPPrivateScope &PrivateScope) {
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_reduction); I; ++I) {
|
||||
auto *C = cast<OMPReductionClause>(*I);
|
||||
for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
|
||||
auto ILHS = C->lhs_exprs().begin();
|
||||
auto IRHS = C->rhs_exprs().begin();
|
||||
for (auto IRef : C->varlists()) {
|
||||
|
@ -442,9 +436,8 @@ void CodeGenFunction::EmitOMPReductionClauseFinal(
|
|||
llvm::SmallVector<const Expr *, 8> RHSExprs;
|
||||
llvm::SmallVector<const Expr *, 8> ReductionOps;
|
||||
bool HasAtLeastOneReduction = false;
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_reduction); I; ++I) {
|
||||
for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
|
||||
HasAtLeastOneReduction = true;
|
||||
auto *C = cast<OMPReductionClause>(*I);
|
||||
LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end());
|
||||
RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end());
|
||||
ReductionOps.append(C->reduction_ops().begin(), C->reduction_ops().end());
|
||||
|
@ -454,7 +447,7 @@ void CodeGenFunction::EmitOMPReductionClauseFinal(
|
|||
// parallel directive (it always has implicit barrier).
|
||||
CGM.getOpenMPRuntime().emitReduction(
|
||||
*this, D.getLocEnd(), LHSExprs, RHSExprs, ReductionOps,
|
||||
D.getSingleClause(OMPC_nowait) ||
|
||||
D.getSingleClause<OMPNowaitClause>() ||
|
||||
isOpenMPParallelDirective(D.getDirectiveKind()) ||
|
||||
D.getDirectiveKind() == OMPD_simd,
|
||||
D.getDirectiveKind() == OMPD_simd);
|
||||
|
@ -469,23 +462,21 @@ static void emitCommonOMPParallelDirective(CodeGenFunction &CGF,
|
|||
auto CapturedStruct = CGF.GenerateCapturedStmtArgument(*CS);
|
||||
auto OutlinedFn = CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction(
|
||||
S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen);
|
||||
if (auto C = S.getSingleClause(OMPC_num_threads)) {
|
||||
if (const auto *NumThreadsClause = S.getSingleClause<OMPNumThreadsClause>()) {
|
||||
CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
|
||||
auto NumThreadsClause = cast<OMPNumThreadsClause>(C);
|
||||
auto NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(),
|
||||
/*IgnoreResultAssign*/ true);
|
||||
CGF.CGM.getOpenMPRuntime().emitNumThreadsClause(
|
||||
CGF, NumThreads, NumThreadsClause->getLocStart());
|
||||
}
|
||||
if (auto *C = S.getSingleClause(OMPC_proc_bind)) {
|
||||
if (const auto *ProcBindClause = S.getSingleClause<OMPProcBindClause>()) {
|
||||
CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
|
||||
auto *ProcBindClause = cast<OMPProcBindClause>(C);
|
||||
CGF.CGM.getOpenMPRuntime().emitProcBindClause(
|
||||
CGF, ProcBindClause->getProcBindKind(), ProcBindClause->getLocStart());
|
||||
}
|
||||
const Expr *IfCond = nullptr;
|
||||
if (auto C = S.getSingleClause(OMPC_if)) {
|
||||
IfCond = cast<OMPIfClause>(C)->getCondition();
|
||||
if (const auto *C = S.getSingleClause<OMPIfClause>()) {
|
||||
IfCond = C->getCondition();
|
||||
}
|
||||
CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), OutlinedFn,
|
||||
CapturedStruct, IfCond);
|
||||
|
@ -526,8 +517,7 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
|
|||
EmitIgnoredExpr(I);
|
||||
}
|
||||
// Update the linear variables.
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) {
|
||||
auto *C = cast<OMPLinearClause>(*I);
|
||||
for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
|
||||
for (auto U : C->updates()) {
|
||||
EmitIgnoredExpr(U);
|
||||
}
|
||||
|
@ -596,8 +586,7 @@ void CodeGenFunction::EmitOMPInnerLoop(
|
|||
|
||||
void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
|
||||
// Emit inits for the linear variables.
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) {
|
||||
auto *C = cast<OMPLinearClause>(*I);
|
||||
for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
|
||||
for (auto Init : C->inits()) {
|
||||
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl());
|
||||
auto *OrigVD = cast<VarDecl>(
|
||||
|
@ -627,8 +616,7 @@ void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) {
|
|||
static void emitLinearClauseFinal(CodeGenFunction &CGF,
|
||||
const OMPLoopDirective &D) {
|
||||
// Emit the final values of the linear variables.
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) {
|
||||
auto *C = cast<OMPLinearClause>(*I);
|
||||
for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
|
||||
auto IC = C->varlist_begin();
|
||||
for (auto F : C->finals()) {
|
||||
auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl());
|
||||
|
@ -648,8 +636,7 @@ static void emitLinearClauseFinal(CodeGenFunction &CGF,
|
|||
|
||||
static void emitAlignedClause(CodeGenFunction &CGF,
|
||||
const OMPExecutableDirective &D) {
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_aligned); I; ++I) {
|
||||
auto *Clause = cast<OMPAlignedClause>(*I);
|
||||
for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) {
|
||||
unsigned ClauseAlignment = 0;
|
||||
if (auto AlignmentExpr = Clause->getAlignment()) {
|
||||
auto AlignmentCI =
|
||||
|
@ -719,8 +706,7 @@ static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S,
|
|||
static void
|
||||
emitPrivateLinearVars(CodeGenFunction &CGF, const OMPExecutableDirective &D,
|
||||
CodeGenFunction::OMPPrivateScope &PrivateScope) {
|
||||
for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) {
|
||||
auto *C = cast<OMPLinearClause>(*I);
|
||||
for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) {
|
||||
auto CurPrivate = C->privates().begin();
|
||||
for (auto *E : C->varlists()) {
|
||||
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
|
||||
|
@ -741,8 +727,7 @@ emitPrivateLinearVars(CodeGenFunction &CGF, const OMPExecutableDirective &D,
|
|||
|
||||
static void emitSimdlenSafelenClause(CodeGenFunction &CGF,
|
||||
const OMPExecutableDirective &D) {
|
||||
if (auto *C =
|
||||
cast_or_null<OMPSimdlenClause>(D.getSingleClause(OMPC_simdlen))) {
|
||||
if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) {
|
||||
RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), AggValueSlot::ignored(),
|
||||
/*ignoreResult=*/true);
|
||||
llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
|
||||
|
@ -750,9 +735,8 @@ static void emitSimdlenSafelenClause(CodeGenFunction &CGF,
|
|||
// In presence of finite 'safelen', it may be unsafe to mark all
|
||||
// the memory instructions parallel, because loop-carried
|
||||
// dependences of 'safelen' iterations are possible.
|
||||
CGF.LoopStack.setParallel(!D.getSingleClause(OMPC_safelen));
|
||||
} else if (auto *C = cast_or_null<OMPSafelenClause>(
|
||||
D.getSingleClause(OMPC_safelen))) {
|
||||
CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>());
|
||||
} else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) {
|
||||
RValue Len = CGF.EmitAnyExpr(C->getSafelen(), AggValueSlot::ignored(),
|
||||
/*ignoreResult=*/true);
|
||||
llvm::ConstantInt *Val = cast<llvm::ConstantInt>(Len.getScalarVal());
|
||||
|
@ -1041,8 +1025,7 @@ emitScheduleClause(CodeGenFunction &CGF, const OMPLoopDirective &S,
|
|||
// Detect the loop schedule kind and chunk.
|
||||
auto ScheduleKind = OMPC_SCHEDULE_unknown;
|
||||
llvm::Value *Chunk = nullptr;
|
||||
if (auto *C =
|
||||
cast_or_null<OMPScheduleClause>(S.getSingleClause(OMPC_schedule))) {
|
||||
if (const auto *C = S.getSingleClause<OMPScheduleClause>()) {
|
||||
ScheduleKind = C->getScheduleKind();
|
||||
if (const auto *Ch = C->getChunkSize()) {
|
||||
if (auto *ImpRef = cast_or_null<DeclRefExpr>(C->getHelperChunkSize())) {
|
||||
|
@ -1143,7 +1126,7 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
|
|||
ScheduleKind = ScheduleInfo.second;
|
||||
const unsigned IVSize = getContext().getTypeSize(IVExpr->getType());
|
||||
const bool IVSigned = IVExpr->getType()->hasSignedIntegerRepresentation();
|
||||
const bool Ordered = S.getSingleClause(OMPC_ordered) != nullptr;
|
||||
const bool Ordered = S.getSingleClause<OMPOrderedClause>() != nullptr;
|
||||
if (RT.isStaticNonchunked(ScheduleKind,
|
||||
/* Chunked */ Chunk != nullptr) &&
|
||||
!Ordered) {
|
||||
|
@ -1208,7 +1191,7 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
|
|||
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen);
|
||||
|
||||
// Emit an implicit barrier at the end.
|
||||
if (!S.getSingleClause(OMPC_nowait) || HasLastprivates) {
|
||||
if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) {
|
||||
CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for);
|
||||
}
|
||||
}
|
||||
|
@ -1222,7 +1205,7 @@ void CodeGenFunction::EmitOMPForSimdDirective(const OMPForSimdDirective &S) {
|
|||
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, CodeGen);
|
||||
|
||||
// Emit an implicit barrier at the end.
|
||||
if (!S.getSingleClause(OMPC_nowait) || HasLastprivates) {
|
||||
if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) {
|
||||
CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_for);
|
||||
}
|
||||
}
|
||||
|
@ -1338,7 +1321,7 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
|
|||
// Emit barrier for lastprivates only if 'sections' directive has 'nowait'
|
||||
// clause. Otherwise the barrier will be generated by the codegen for the
|
||||
// directive.
|
||||
if (HasLastprivates && S.getSingleClause(OMPC_nowait)) {
|
||||
if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) {
|
||||
// Emit implicit barrier to synchronize threads and avoid data races on
|
||||
// initialization of firstprivate variables.
|
||||
CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(),
|
||||
|
@ -1351,11 +1334,11 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
|
|||
bool HasFirstprivates;
|
||||
// No need to generate reductions for sections with single section region, we
|
||||
// can use original shared variables for all operations.
|
||||
bool HasReductions = !S.getClausesOfKind(OMPC_reduction).empty();
|
||||
bool HasReductions = S.hasClausesOfKind<OMPReductionClause>();
|
||||
// No need to generate lastprivates for sections with single section region,
|
||||
// we can use original shared variable for all calculations with barrier at
|
||||
// the end of the sections.
|
||||
bool HasLastprivates = !S.getClausesOfKind(OMPC_lastprivate).empty();
|
||||
bool HasLastprivates = S.hasClausesOfKind<OMPLastprivateClause>();
|
||||
auto &&CodeGen = [Stmt, &S, &HasFirstprivates](CodeGenFunction &CGF) {
|
||||
CodeGenFunction::OMPPrivateScope SingleScope(CGF);
|
||||
HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope);
|
||||
|
@ -1371,7 +1354,7 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
|
|||
// 'sections' directive has 'nowait' clause. Otherwise the barrier will be
|
||||
// generated by the codegen for the directive.
|
||||
if ((HasFirstprivates || HasLastprivates || HasReductions) &&
|
||||
S.getSingleClause(OMPC_nowait)) {
|
||||
S.getSingleClause<OMPNowaitClause>()) {
|
||||
// Emit implicit barrier to synchronize threads and avoid data races on
|
||||
// initialization of firstprivate variables.
|
||||
CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown);
|
||||
|
@ -1383,7 +1366,7 @@ void CodeGenFunction::EmitOMPSectionsDirective(const OMPSectionsDirective &S) {
|
|||
LexicalScope Scope(*this, S.getSourceRange());
|
||||
OpenMPDirectiveKind EmittedAs = EmitSections(S);
|
||||
// Emit an implicit barrier at the end.
|
||||
if (!S.getSingleClause(OMPC_nowait)) {
|
||||
if (!S.getSingleClause<OMPNowaitClause>()) {
|
||||
CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), EmittedAs);
|
||||
}
|
||||
}
|
||||
|
@ -1407,8 +1390,7 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
|
|||
// construct.
|
||||
// Build a list of copyprivate variables along with helper expressions
|
||||
// (<source>, <destination>, <destination>=<source> expressions)
|
||||
for (auto &&I = S.getClausesOfKind(OMPC_copyprivate); I; ++I) {
|
||||
auto *C = cast<OMPCopyprivateClause>(*I);
|
||||
for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) {
|
||||
CopyprivateVars.append(C->varlists().begin(), C->varlists().end());
|
||||
DestExprs.append(C->destination_exprs().begin(),
|
||||
C->destination_exprs().end());
|
||||
|
@ -1433,11 +1415,11 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) {
|
|||
AssignmentOps);
|
||||
// Emit an implicit barrier at the end (to avoid data race on firstprivate
|
||||
// init or if no 'nowait' clause was specified and no 'copyprivate' clause).
|
||||
if ((!S.getSingleClause(OMPC_nowait) || HasFirstprivates) &&
|
||||
if ((!S.getSingleClause<OMPNowaitClause>() || HasFirstprivates) &&
|
||||
CopyprivateVars.empty()) {
|
||||
CGM.getOpenMPRuntime().emitBarrierCall(
|
||||
*this, S.getLocStart(),
|
||||
S.getSingleClause(OMPC_nowait) ? OMPD_unknown : OMPD_single);
|
||||
S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : OMPD_single);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1521,8 +1503,7 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
|
|||
// Get list of private variables.
|
||||
llvm::SmallVector<const Expr *, 8> PrivateVars;
|
||||
llvm::SmallVector<const Expr *, 8> PrivateCopies;
|
||||
for (auto &&I = S.getClausesOfKind(OMPC_private); I; ++I) {
|
||||
auto *C = cast<OMPPrivateClause>(*I);
|
||||
for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
|
||||
auto IRef = C->varlist_begin();
|
||||
for (auto *IInit : C->private_copies()) {
|
||||
auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl());
|
||||
|
@ -1538,8 +1519,7 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
|
|||
llvm::SmallVector<const Expr *, 8> FirstprivateVars;
|
||||
llvm::SmallVector<const Expr *, 8> FirstprivateCopies;
|
||||
llvm::SmallVector<const Expr *, 8> FirstprivateInits;
|
||||
for (auto &&I = S.getClausesOfKind(OMPC_firstprivate); I; ++I) {
|
||||
auto *C = cast<OMPFirstprivateClause>(*I);
|
||||
for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
|
||||
auto IRef = C->varlist_begin();
|
||||
auto IElemInitRef = C->inits().begin();
|
||||
for (auto *IInit : C->private_copies()) {
|
||||
|
@ -1555,8 +1535,7 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
|
|||
// Build list of dependences.
|
||||
llvm::SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 8>
|
||||
Dependences;
|
||||
for (auto &&I = S.getClausesOfKind(OMPC_depend); I; ++I) {
|
||||
auto *C = cast<OMPDependClause>(*I);
|
||||
for (const auto *C : S.getClausesOfKind<OMPDependClause>()) {
|
||||
for (auto *IRef : C->varlists()) {
|
||||
Dependences.push_back(std::make_pair(C->getDependencyKind(), IRef));
|
||||
}
|
||||
|
@ -1608,13 +1587,13 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
|
|||
auto OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction(
|
||||
S, *I, OMPD_task, CodeGen);
|
||||
// Check if we should emit tied or untied task.
|
||||
bool Tied = !S.getSingleClause(OMPC_untied);
|
||||
bool Tied = !S.getSingleClause<OMPUntiedClause>();
|
||||
// Check if the task is final
|
||||
llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
|
||||
if (auto *Clause = S.getSingleClause(OMPC_final)) {
|
||||
if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) {
|
||||
// If the condition constant folds and can be elided, try to avoid emitting
|
||||
// the condition and the dead arm of the if/else.
|
||||
auto *Cond = cast<OMPFinalClause>(Clause)->getCondition();
|
||||
auto *Cond = Clause->getCondition();
|
||||
bool CondConstant;
|
||||
if (ConstantFoldsToSimpleInteger(Cond, CondConstant))
|
||||
Final.setInt(CondConstant);
|
||||
|
@ -1626,8 +1605,8 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
|
|||
}
|
||||
auto SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
|
||||
const Expr *IfCond = nullptr;
|
||||
if (auto C = S.getSingleClause(OMPC_if)) {
|
||||
IfCond = cast<OMPIfClause>(C)->getCondition();
|
||||
if (const auto *C = S.getSingleClause<OMPIfClause>()) {
|
||||
IfCond = C->getCondition();
|
||||
}
|
||||
CGM.getOpenMPRuntime().emitTaskCall(
|
||||
*this, S.getLocStart(), S, Tied, Final, OutlinedFn, SharedsTy,
|
||||
|
@ -1660,8 +1639,7 @@ void CodeGenFunction::EmitOMPTaskgroupDirective(
|
|||
|
||||
void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
|
||||
CGM.getOpenMPRuntime().emitFlush(*this, [&]() -> ArrayRef<const Expr *> {
|
||||
if (auto C = S.getSingleClause(/*K*/ OMPC_flush)) {
|
||||
auto FlushClause = cast<OMPFlushClause>(C);
|
||||
if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>()) {
|
||||
return llvm::makeArrayRef(FlushClause->varlist_begin(),
|
||||
FlushClause->varlist_end());
|
||||
}
|
||||
|
@ -2084,7 +2062,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
|
|||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective &S) {
|
||||
bool IsSeqCst = S.getSingleClause(/*K=*/OMPC_seq_cst);
|
||||
bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>();
|
||||
OpenMPClauseKind Kind = OMPC_unknown;
|
||||
for (auto *C : S.clauses()) {
|
||||
// Find first clause (skip seq_cst clause, if it is first).
|
||||
|
|
|
@ -3514,24 +3514,18 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
|||
}
|
||||
|
||||
static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
|
||||
auto &&CollapseFilter = [](const OMPClause *C) -> bool {
|
||||
return C->getClauseKind() == OMPC_collapse;
|
||||
};
|
||||
OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> I(
|
||||
Clauses, std::move(CollapseFilter));
|
||||
if (I)
|
||||
return cast<OMPCollapseClause>(*I)->getNumForLoops();
|
||||
auto CollapseClauses =
|
||||
OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
|
||||
if (CollapseClauses.begin() != CollapseClauses.end())
|
||||
return (*CollapseClauses.begin())->getNumForLoops();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
|
||||
auto &&OrderedFilter = [](const OMPClause *C) -> bool {
|
||||
return C->getClauseKind() == OMPC_ordered;
|
||||
};
|
||||
OMPExecutableDirective::filtered_clause_iterator<decltype(OrderedFilter)> I(
|
||||
Clauses, std::move(OrderedFilter));
|
||||
if (I)
|
||||
return cast<OMPOrderedClause>(*I)->getNumForLoops();
|
||||
auto OrderedClauses =
|
||||
OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
|
||||
if (OrderedClauses.begin() != OrderedClauses.end())
|
||||
return (*OrderedClauses.begin())->getNumForLoops();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue