3132 lines · cpp
1//===- OpenMPClause.cpp - Classes for OpenMP clauses ----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the subclesses of Stmt class declared in OpenMPClause.h10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/OpenMPClause.h"14#include "clang/AST/ASTContext.h"15#include "clang/AST/Attr.h"16#include "clang/AST/Decl.h"17#include "clang/AST/DeclOpenMP.h"18#include "clang/AST/ExprOpenMP.h"19#include "clang/Basic/LLVM.h"20#include "clang/Basic/OpenMPKinds.h"21#include "clang/Basic/TargetInfo.h"22#include "llvm/ADT/SmallPtrSet.h"23#include "llvm/Support/ErrorHandling.h"24#include <algorithm>25#include <cassert>26#include <optional>27 28using namespace clang;29using namespace llvm;30using namespace omp;31 32OMPClause::child_range OMPClause::children() {33 switch (getClauseKind()) {34 default:35 break;36#define GEN_CLANG_CLAUSE_CLASS37#define CLAUSE_CLASS(Enum, Str, Class) \38 case Enum: \39 return static_cast<Class *>(this)->children();40#include "llvm/Frontend/OpenMP/OMP.inc"41 }42 llvm_unreachable("unknown OMPClause");43}44 45OMPClause::child_range OMPClause::used_children() {46 switch (getClauseKind()) {47#define GEN_CLANG_CLAUSE_CLASS48#define CLAUSE_CLASS(Enum, Str, Class) \49 case Enum: \50 return static_cast<Class *>(this)->used_children();51#define CLAUSE_NO_CLASS(Enum, Str) \52 case Enum: \53 break;54#include "llvm/Frontend/OpenMP/OMP.inc"55 }56 llvm_unreachable("unknown OMPClause");57}58 59OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) {60 auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C));61 return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;62}63 64const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {65 switch (C->getClauseKind()) {66 case OMPC_schedule:67 return static_cast<const OMPScheduleClause *>(C);68 case OMPC_dist_schedule:69 return static_cast<const OMPDistScheduleClause *>(C);70 case OMPC_firstprivate:71 return static_cast<const OMPFirstprivateClause *>(C);72 case OMPC_lastprivate:73 return static_cast<const OMPLastprivateClause *>(C);74 case OMPC_reduction:75 return static_cast<const OMPReductionClause *>(C);76 case OMPC_task_reduction:77 return static_cast<const OMPTaskReductionClause *>(C);78 case OMPC_in_reduction:79 return static_cast<const OMPInReductionClause *>(C);80 case OMPC_linear:81 return static_cast<const OMPLinearClause *>(C);82 case OMPC_if:83 return static_cast<const OMPIfClause *>(C);84 case OMPC_num_threads:85 return static_cast<const OMPNumThreadsClause *>(C);86 case OMPC_num_teams:87 return static_cast<const OMPNumTeamsClause *>(C);88 case OMPC_thread_limit:89 return static_cast<const OMPThreadLimitClause *>(C);90 case OMPC_device:91 return static_cast<const OMPDeviceClause *>(C);92 case OMPC_grainsize:93 return static_cast<const OMPGrainsizeClause *>(C);94 case OMPC_num_tasks:95 return static_cast<const OMPNumTasksClause *>(C);96 case OMPC_final:97 return static_cast<const OMPFinalClause *>(C);98 case OMPC_priority:99 return static_cast<const OMPPriorityClause *>(C);100 case OMPC_novariants:101 return static_cast<const OMPNovariantsClause *>(C);102 case OMPC_nocontext:103 return static_cast<const OMPNocontextClause *>(C);104 case OMPC_filter:105 return static_cast<const OMPFilterClause *>(C);106 case OMPC_ompx_dyn_cgroup_mem:107 return static_cast<const OMPXDynCGroupMemClause *>(C);108 case OMPC_dyn_groupprivate:109 return static_cast<const OMPDynGroupprivateClause *>(C);110 case OMPC_message:111 return static_cast<const OMPMessageClause *>(C);112 case OMPC_default:113 case OMPC_proc_bind:114 case OMPC_safelen:115 case OMPC_simdlen:116 case OMPC_sizes:117 case OMPC_allocator:118 case OMPC_allocate:119 case OMPC_collapse:120 case OMPC_private:121 case OMPC_shared:122 case OMPC_aligned:123 case OMPC_copyin:124 case OMPC_copyprivate:125 case OMPC_ordered:126 case OMPC_nowait:127 case OMPC_untied:128 case OMPC_mergeable:129 case OMPC_threadset:130 case OMPC_threadprivate:131 case OMPC_groupprivate:132 case OMPC_flush:133 case OMPC_depobj:134 case OMPC_read:135 case OMPC_write:136 case OMPC_update:137 case OMPC_capture:138 case OMPC_compare:139 case OMPC_fail:140 case OMPC_seq_cst:141 case OMPC_acq_rel:142 case OMPC_acquire:143 case OMPC_release:144 case OMPC_relaxed:145 case OMPC_depend:146 case OMPC_threads:147 case OMPC_simd:148 case OMPC_map:149 case OMPC_nogroup:150 case OMPC_hint:151 case OMPC_defaultmap:152 case OMPC_unknown:153 case OMPC_uniform:154 case OMPC_to:155 case OMPC_from:156 case OMPC_use_device_ptr:157 case OMPC_use_device_addr:158 case OMPC_is_device_ptr:159 case OMPC_has_device_addr:160 case OMPC_unified_address:161 case OMPC_unified_shared_memory:162 case OMPC_reverse_offload:163 case OMPC_dynamic_allocators:164 case OMPC_atomic_default_mem_order:165 case OMPC_self_maps:166 case OMPC_at:167 case OMPC_severity:168 case OMPC_device_type:169 case OMPC_match:170 case OMPC_nontemporal:171 case OMPC_order:172 case OMPC_destroy:173 case OMPC_detach:174 case OMPC_inclusive:175 case OMPC_exclusive:176 case OMPC_uses_allocators:177 case OMPC_affinity:178 case OMPC_when:179 case OMPC_bind:180 case OMPC_ompx_bare:181 break;182 default:183 break;184 }185 186 return nullptr;187}188 189OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(OMPClause *C) {190 auto *Res = OMPClauseWithPostUpdate::get(const_cast<const OMPClause *>(C));191 return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;192}193 194const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) {195 switch (C->getClauseKind()) {196 case OMPC_lastprivate:197 return static_cast<const OMPLastprivateClause *>(C);198 case OMPC_reduction:199 return static_cast<const OMPReductionClause *>(C);200 case OMPC_task_reduction:201 return static_cast<const OMPTaskReductionClause *>(C);202 case OMPC_in_reduction:203 return static_cast<const OMPInReductionClause *>(C);204 case OMPC_linear:205 return static_cast<const OMPLinearClause *>(C);206 case OMPC_schedule:207 case OMPC_dist_schedule:208 case OMPC_firstprivate:209 case OMPC_default:210 case OMPC_proc_bind:211 case OMPC_if:212 case OMPC_final:213 case OMPC_num_threads:214 case OMPC_safelen:215 case OMPC_simdlen:216 case OMPC_sizes:217 case OMPC_allocator:218 case OMPC_allocate:219 case OMPC_collapse:220 case OMPC_private:221 case OMPC_shared:222 case OMPC_aligned:223 case OMPC_copyin:224 case OMPC_copyprivate:225 case OMPC_ordered:226 case OMPC_nowait:227 case OMPC_untied:228 case OMPC_mergeable:229 case OMPC_threadprivate:230 case OMPC_groupprivate:231 case OMPC_flush:232 case OMPC_depobj:233 case OMPC_read:234 case OMPC_write:235 case OMPC_update:236 case OMPC_capture:237 case OMPC_compare:238 case OMPC_fail:239 case OMPC_seq_cst:240 case OMPC_acq_rel:241 case OMPC_acquire:242 case OMPC_release:243 case OMPC_relaxed:244 case OMPC_depend:245 case OMPC_device:246 case OMPC_threads:247 case OMPC_simd:248 case OMPC_map:249 case OMPC_num_teams:250 case OMPC_thread_limit:251 case OMPC_priority:252 case OMPC_grainsize:253 case OMPC_nogroup:254 case OMPC_num_tasks:255 case OMPC_hint:256 case OMPC_defaultmap:257 case OMPC_unknown:258 case OMPC_uniform:259 case OMPC_to:260 case OMPC_from:261 case OMPC_use_device_ptr:262 case OMPC_use_device_addr:263 case OMPC_is_device_ptr:264 case OMPC_has_device_addr:265 case OMPC_unified_address:266 case OMPC_unified_shared_memory:267 case OMPC_reverse_offload:268 case OMPC_dynamic_allocators:269 case OMPC_atomic_default_mem_order:270 case OMPC_self_maps:271 case OMPC_at:272 case OMPC_severity:273 case OMPC_message:274 case OMPC_device_type:275 case OMPC_match:276 case OMPC_nontemporal:277 case OMPC_order:278 case OMPC_destroy:279 case OMPC_novariants:280 case OMPC_nocontext:281 case OMPC_detach:282 case OMPC_inclusive:283 case OMPC_exclusive:284 case OMPC_uses_allocators:285 case OMPC_affinity:286 case OMPC_when:287 case OMPC_bind:288 break;289 default:290 break;291 }292 293 return nullptr;294}295 296/// Gets the address of the original, non-captured, expression used in the297/// clause as the preinitializer.298static Stmt **getAddrOfExprAsWritten(Stmt *S) {299 if (!S)300 return nullptr;301 if (auto *DS = dyn_cast<DeclStmt>(S)) {302 assert(DS->isSingleDecl() && "Only single expression must be captured.");303 if (auto *OED = dyn_cast<OMPCapturedExprDecl>(DS->getSingleDecl()))304 return OED->getInitAddress();305 }306 return nullptr;307}308 309OMPClause::child_range OMPIfClause::used_children() {310 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))311 return child_range(C, C + 1);312 return child_range(&Condition, &Condition + 1);313}314 315OMPClause::child_range OMPNowaitClause::used_children() {316 if (Condition)317 return child_range(&Condition, &Condition + 1);318 return children();319}320 321OMPClause::child_range OMPGrainsizeClause::used_children() {322 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))323 return child_range(C, C + 1);324 return child_range(&Grainsize, &Grainsize + 1);325}326 327OMPClause::child_range OMPNumTasksClause::used_children() {328 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))329 return child_range(C, C + 1);330 return child_range(&NumTasks, &NumTasks + 1);331}332 333OMPClause::child_range OMPFinalClause::used_children() {334 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))335 return child_range(C, C + 1);336 return children();337}338 339OMPClause::child_range OMPPriorityClause::used_children() {340 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))341 return child_range(C, C + 1);342 return child_range(&Priority, &Priority + 1);343}344 345OMPClause::child_range OMPNovariantsClause::used_children() {346 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))347 return child_range(C, C + 1);348 return children();349}350 351OMPClause::child_range OMPNocontextClause::used_children() {352 if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))353 return child_range(C, C + 1);354 return children();355}356 357OMPOrderedClause *OMPOrderedClause::Create(const ASTContext &C, Expr *Num,358 unsigned NumLoops,359 SourceLocation StartLoc,360 SourceLocation LParenLoc,361 SourceLocation EndLoc) {362 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));363 auto *Clause =364 new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc, LParenLoc, EndLoc);365 for (unsigned I = 0; I < NumLoops; ++I) {366 Clause->setLoopNumIterations(I, nullptr);367 Clause->setLoopCounter(I, nullptr);368 }369 return Clause;370}371 372OMPOrderedClause *OMPOrderedClause::CreateEmpty(const ASTContext &C,373 unsigned NumLoops) {374 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));375 auto *Clause = new (Mem) OMPOrderedClause(NumLoops);376 for (unsigned I = 0; I < NumLoops; ++I) {377 Clause->setLoopNumIterations(I, nullptr);378 Clause->setLoopCounter(I, nullptr);379 }380 return Clause;381}382 383void OMPOrderedClause::setLoopNumIterations(unsigned NumLoop,384 Expr *NumIterations) {385 assert(NumLoop < NumberOfLoops && "out of loops number.");386 getTrailingObjects()[NumLoop] = NumIterations;387}388 389ArrayRef<Expr *> OMPOrderedClause::getLoopNumIterations() const {390 return getTrailingObjects(NumberOfLoops);391}392 393void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) {394 assert(NumLoop < NumberOfLoops && "out of loops number.");395 getTrailingObjects()[NumberOfLoops + NumLoop] = Counter;396}397 398Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) {399 assert(NumLoop < NumberOfLoops && "out of loops number.");400 return getTrailingObjects()[NumberOfLoops + NumLoop];401}402 403const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const {404 assert(NumLoop < NumberOfLoops && "out of loops number.");405 return getTrailingObjects()[NumberOfLoops + NumLoop];406}407 408OMPUpdateClause *OMPUpdateClause::Create(const ASTContext &C,409 SourceLocation StartLoc,410 SourceLocation EndLoc) {411 return new (C) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/false);412}413 414OMPUpdateClause *415OMPUpdateClause::Create(const ASTContext &C, SourceLocation StartLoc,416 SourceLocation LParenLoc, SourceLocation ArgumentLoc,417 OpenMPDependClauseKind DK, SourceLocation EndLoc) {418 void *Mem =419 C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),420 alignof(OMPUpdateClause));421 auto *Clause =422 new (Mem) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/true);423 Clause->setLParenLoc(LParenLoc);424 Clause->setArgumentLoc(ArgumentLoc);425 Clause->setDependencyKind(DK);426 return Clause;427}428 429OMPUpdateClause *OMPUpdateClause::CreateEmpty(const ASTContext &C,430 bool IsExtended) {431 if (!IsExtended)432 return new (C) OMPUpdateClause(/*IsExtended=*/false);433 void *Mem =434 C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),435 alignof(OMPUpdateClause));436 auto *Clause = new (Mem) OMPUpdateClause(/*IsExtended=*/true);437 Clause->IsExtended = true;438 return Clause;439}440 441void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {442 assert(VL.size() == varlist_size() &&443 "Number of private copies is not the same as the preallocated buffer");444 llvm::copy(VL, varlist_end());445}446 447OMPPrivateClause *448OMPPrivateClause::Create(const ASTContext &C, SourceLocation StartLoc,449 SourceLocation LParenLoc, SourceLocation EndLoc,450 ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {451 // Allocate space for private variables and initializer expressions.452 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));453 OMPPrivateClause *Clause =454 new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());455 Clause->setVarRefs(VL);456 Clause->setPrivateCopies(PrivateVL);457 return Clause;458}459 460OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,461 unsigned N) {462 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));463 return new (Mem) OMPPrivateClause(N);464}465 466void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {467 assert(VL.size() == varlist_size() &&468 "Number of private copies is not the same as the preallocated buffer");469 llvm::copy(VL, varlist_end());470}471 472void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {473 assert(VL.size() == varlist_size() &&474 "Number of inits is not the same as the preallocated buffer");475 llvm::copy(VL, getPrivateCopies().end());476}477 478OMPFirstprivateClause *479OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,480 SourceLocation LParenLoc, SourceLocation EndLoc,481 ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,482 ArrayRef<Expr *> InitVL, Stmt *PreInit) {483 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * VL.size()));484 OMPFirstprivateClause *Clause =485 new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());486 Clause->setVarRefs(VL);487 Clause->setPrivateCopies(PrivateVL);488 Clause->setInits(InitVL);489 Clause->setPreInitStmt(PreInit);490 return Clause;491}492 493OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,494 unsigned N) {495 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * N));496 return new (Mem) OMPFirstprivateClause(N);497}498 499void OMPLastprivateClause::setPrivateCopies(ArrayRef<Expr *> PrivateCopies) {500 assert(PrivateCopies.size() == varlist_size() &&501 "Number of private copies is not the same as the preallocated buffer");502 llvm::copy(PrivateCopies, varlist_end());503}504 505void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {506 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "507 "not the same as the "508 "preallocated buffer");509 llvm::copy(SrcExprs, getPrivateCopies().end());510}511 512void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {513 assert(DstExprs.size() == varlist_size() && "Number of destination "514 "expressions is not the same as "515 "the preallocated buffer");516 llvm::copy(DstExprs, getSourceExprs().end());517}518 519void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {520 assert(AssignmentOps.size() == varlist_size() &&521 "Number of assignment expressions is not the same as the preallocated "522 "buffer");523 llvm::copy(AssignmentOps, getDestinationExprs().end());524}525 526OMPLastprivateClause *OMPLastprivateClause::Create(527 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,528 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,529 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,530 OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc,531 SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate) {532 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));533 OMPLastprivateClause *Clause = new (Mem) OMPLastprivateClause(534 StartLoc, LParenLoc, EndLoc, LPKind, LPKindLoc, ColonLoc, VL.size());535 Clause->setVarRefs(VL);536 Clause->setSourceExprs(SrcExprs);537 Clause->setDestinationExprs(DstExprs);538 Clause->setAssignmentOps(AssignmentOps);539 Clause->setPreInitStmt(PreInit);540 Clause->setPostUpdateExpr(PostUpdate);541 return Clause;542}543 544OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,545 unsigned N) {546 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));547 return new (Mem) OMPLastprivateClause(N);548}549 550OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,551 SourceLocation StartLoc,552 SourceLocation LParenLoc,553 SourceLocation EndLoc,554 ArrayRef<Expr *> VL) {555 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));556 OMPSharedClause *Clause =557 new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());558 Clause->setVarRefs(VL);559 return Clause;560}561 562OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {563 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));564 return new (Mem) OMPSharedClause(N);565}566 567void OMPLinearClause::setPrivates(ArrayRef<Expr *> PL) {568 assert(PL.size() == varlist_size() &&569 "Number of privates is not the same as the preallocated buffer");570 llvm::copy(PL, varlist_end());571}572 573void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {574 assert(IL.size() == varlist_size() &&575 "Number of inits is not the same as the preallocated buffer");576 llvm::copy(IL, getPrivates().end());577}578 579void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {580 assert(UL.size() == varlist_size() &&581 "Number of updates is not the same as the preallocated buffer");582 llvm::copy(UL, getInits().end());583}584 585void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {586 assert(FL.size() == varlist_size() &&587 "Number of final updates is not the same as the preallocated buffer");588 llvm::copy(FL, getUpdates().end());589}590 591void OMPLinearClause::setUsedExprs(ArrayRef<Expr *> UE) {592 assert(593 UE.size() == varlist_size() + 1 &&594 "Number of used expressions is not the same as the preallocated buffer");595 llvm::copy(UE, getFinals().end() + 2);596}597 598OMPLinearClause *OMPLinearClause::Create(599 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,600 OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,601 SourceLocation ColonLoc, SourceLocation StepModifierLoc,602 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL,603 ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,604 Expr *PostUpdate) {605 // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions606 // (Step and CalcStep), list of used expression + step.607 void *Mem =608 C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2 + VL.size() + 1));609 OMPLinearClause *Clause =610 new (Mem) OMPLinearClause(StartLoc, LParenLoc, Modifier, ModifierLoc,611 ColonLoc, StepModifierLoc, EndLoc, VL.size());612 Clause->setVarRefs(VL);613 Clause->setPrivates(PL);614 Clause->setInits(IL);615 // Fill update and final expressions with zeroes, they are provided later,616 // after the directive construction.617 std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),618 nullptr);619 std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),620 nullptr);621 std::fill(Clause->getUsedExprs().begin(), Clause->getUsedExprs().end(),622 nullptr);623 Clause->setStep(Step);624 Clause->setCalcStep(CalcStep);625 Clause->setPreInitStmt(PreInit);626 Clause->setPostUpdateExpr(PostUpdate);627 return Clause;628}629 630OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,631 unsigned NumVars) {632 // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions633 // (Step and CalcStep), list of used expression + step.634 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * NumVars + 2 + NumVars +1));635 return new (Mem) OMPLinearClause(NumVars);636}637 638OMPClause::child_range OMPLinearClause::used_children() {639 // Range includes only non-nullptr elements.640 return child_range(641 reinterpret_cast<Stmt **>(getUsedExprs().begin()),642 reinterpret_cast<Stmt **>(llvm::find(getUsedExprs(), nullptr)));643}644 645OMPAlignedClause *646OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,647 SourceLocation LParenLoc, SourceLocation ColonLoc,648 SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {649 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));650 OMPAlignedClause *Clause = new (Mem)651 OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());652 Clause->setVarRefs(VL);653 Clause->setAlignment(A);654 return Clause;655}656 657OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,658 unsigned NumVars) {659 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumVars + 1));660 return new (Mem) OMPAlignedClause(NumVars);661}662 663OMPAlignClause *OMPAlignClause::Create(const ASTContext &C, Expr *A,664 SourceLocation StartLoc,665 SourceLocation LParenLoc,666 SourceLocation EndLoc) {667 return new (C) OMPAlignClause(A, StartLoc, LParenLoc, EndLoc);668}669 670void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {671 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "672 "not the same as the "673 "preallocated buffer");674 llvm::copy(SrcExprs, varlist_end());675}676 677void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {678 assert(DstExprs.size() == varlist_size() && "Number of destination "679 "expressions is not the same as "680 "the preallocated buffer");681 llvm::copy(DstExprs, getSourceExprs().end());682}683 684void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {685 assert(AssignmentOps.size() == varlist_size() &&686 "Number of assignment expressions is not the same as the preallocated "687 "buffer");688 llvm::copy(AssignmentOps, getDestinationExprs().end());689}690 691OMPCopyinClause *OMPCopyinClause::Create(692 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,693 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,694 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {695 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));696 OMPCopyinClause *Clause =697 new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());698 Clause->setVarRefs(VL);699 Clause->setSourceExprs(SrcExprs);700 Clause->setDestinationExprs(DstExprs);701 Clause->setAssignmentOps(AssignmentOps);702 return Clause;703}704 705OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {706 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));707 return new (Mem) OMPCopyinClause(N);708}709 710void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {711 assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "712 "not the same as the "713 "preallocated buffer");714 llvm::copy(SrcExprs, varlist_end());715}716 717void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {718 assert(DstExprs.size() == varlist_size() && "Number of destination "719 "expressions is not the same as "720 "the preallocated buffer");721 llvm::copy(DstExprs, getSourceExprs().end());722}723 724void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {725 assert(AssignmentOps.size() == varlist_size() &&726 "Number of assignment expressions is not the same as the preallocated "727 "buffer");728 llvm::copy(AssignmentOps, getDestinationExprs().end());729}730 731OMPCopyprivateClause *OMPCopyprivateClause::Create(732 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,733 SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,734 ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {735 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));736 OMPCopyprivateClause *Clause =737 new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());738 Clause->setVarRefs(VL);739 Clause->setSourceExprs(SrcExprs);740 Clause->setDestinationExprs(DstExprs);741 Clause->setAssignmentOps(AssignmentOps);742 return Clause;743}744 745OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,746 unsigned N) {747 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));748 return new (Mem) OMPCopyprivateClause(N);749}750 751void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {752 assert(Privates.size() == varlist_size() &&753 "Number of private copies is not the same as the preallocated buffer");754 llvm::copy(Privates, varlist_end());755}756 757void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {758 assert(759 LHSExprs.size() == varlist_size() &&760 "Number of LHS expressions is not the same as the preallocated buffer");761 llvm::copy(LHSExprs, getPrivates().end());762}763 764void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {765 assert(766 RHSExprs.size() == varlist_size() &&767 "Number of RHS expressions is not the same as the preallocated buffer");768 llvm::copy(RHSExprs, getLHSExprs().end());769}770 771void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {772 assert(ReductionOps.size() == varlist_size() && "Number of reduction "773 "expressions is not the same "774 "as the preallocated buffer");775 llvm::copy(ReductionOps, getRHSExprs().end());776}777 778void OMPReductionClause::setInscanCopyOps(ArrayRef<Expr *> Ops) {779 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");780 assert(Ops.size() == varlist_size() && "Number of copy "781 "expressions is not the same "782 "as the preallocated buffer");783 llvm::copy(Ops, getReductionOps().end());784}785 786void OMPReductionClause::setInscanCopyArrayTemps(787 ArrayRef<Expr *> CopyArrayTemps) {788 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");789 assert(CopyArrayTemps.size() == varlist_size() &&790 "Number of copy temp expressions is not the same as the preallocated "791 "buffer");792 llvm::copy(CopyArrayTemps, getInscanCopyOps().end());793}794 795void OMPReductionClause::setInscanCopyArrayElems(796 ArrayRef<Expr *> CopyArrayElems) {797 assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");798 assert(CopyArrayElems.size() == varlist_size() &&799 "Number of copy temp expressions is not the same as the preallocated "800 "buffer");801 llvm::copy(CopyArrayElems, getInscanCopyArrayTemps().end());802}803 804OMPReductionClause *OMPReductionClause::Create(805 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,806 SourceLocation ModifierLoc, SourceLocation EndLoc, SourceLocation ColonLoc,807 OpenMPReductionClauseModifier Modifier, ArrayRef<Expr *> VL,808 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,809 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,810 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,811 ArrayRef<Expr *> CopyOps, ArrayRef<Expr *> CopyArrayTemps,812 ArrayRef<Expr *> CopyArrayElems, Stmt *PreInit, Expr *PostUpdate,813 ArrayRef<bool> IsPrivateVarReduction,814 OpenMPOriginalSharingModifier OrignalSharingModifier) {815 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, bool>(816 (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * VL.size(), VL.size()));817 auto *Clause = new (Mem) OMPReductionClause(818 StartLoc, LParenLoc, ModifierLoc, EndLoc, ColonLoc, Modifier,819 OrignalSharingModifier, VL.size(), QualifierLoc, NameInfo);820 Clause->setVarRefs(VL);821 Clause->setPrivates(Privates);822 Clause->setLHSExprs(LHSExprs);823 Clause->setRHSExprs(RHSExprs);824 Clause->setReductionOps(ReductionOps);825 Clause->setPreInitStmt(PreInit);826 Clause->setPostUpdateExpr(PostUpdate);827 Clause->setPrivateVariableReductionFlags(IsPrivateVarReduction);828 if (Modifier == OMPC_REDUCTION_inscan) {829 Clause->setInscanCopyOps(CopyOps);830 Clause->setInscanCopyArrayTemps(CopyArrayTemps);831 Clause->setInscanCopyArrayElems(CopyArrayElems);832 } else {833 assert(CopyOps.empty() &&834 "copy operations are expected in inscan reductions only.");835 assert(CopyArrayTemps.empty() &&836 "copy array temps are expected in inscan reductions only.");837 assert(CopyArrayElems.empty() &&838 "copy array temps are expected in inscan reductions only.");839 }840 return Clause;841}842 843OMPReductionClause *844OMPReductionClause::CreateEmpty(const ASTContext &C, unsigned N,845 OpenMPReductionClauseModifier Modifier) {846 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, bool>(847 (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * N, N));848 auto *Clause = new (Mem) OMPReductionClause(N);849 Clause->setModifier(Modifier);850 return Clause;851}852 853void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {854 assert(Privates.size() == varlist_size() &&855 "Number of private copies is not the same as the preallocated buffer");856 llvm::copy(Privates, varlist_end());857}858 859void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {860 assert(861 LHSExprs.size() == varlist_size() &&862 "Number of LHS expressions is not the same as the preallocated buffer");863 llvm::copy(LHSExprs, getPrivates().end());864}865 866void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {867 assert(868 RHSExprs.size() == varlist_size() &&869 "Number of RHS expressions is not the same as the preallocated buffer");870 llvm::copy(RHSExprs, getLHSExprs().end());871}872 873void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {874 assert(ReductionOps.size() == varlist_size() && "Number of task reduction "875 "expressions is not the same "876 "as the preallocated buffer");877 llvm::copy(ReductionOps, getRHSExprs().end());878}879 880OMPTaskReductionClause *OMPTaskReductionClause::Create(881 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,882 SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,883 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,884 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,885 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,886 Expr *PostUpdate) {887 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));888 OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause(889 StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);890 Clause->setVarRefs(VL);891 Clause->setPrivates(Privates);892 Clause->setLHSExprs(LHSExprs);893 Clause->setRHSExprs(RHSExprs);894 Clause->setReductionOps(ReductionOps);895 Clause->setPreInitStmt(PreInit);896 Clause->setPostUpdateExpr(PostUpdate);897 return Clause;898}899 900OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,901 unsigned N) {902 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));903 return new (Mem) OMPTaskReductionClause(N);904}905 906void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {907 assert(Privates.size() == varlist_size() &&908 "Number of private copies is not the same as the preallocated buffer");909 llvm::copy(Privates, varlist_end());910}911 912void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {913 assert(914 LHSExprs.size() == varlist_size() &&915 "Number of LHS expressions is not the same as the preallocated buffer");916 llvm::copy(LHSExprs, getPrivates().end());917}918 919void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {920 assert(921 RHSExprs.size() == varlist_size() &&922 "Number of RHS expressions is not the same as the preallocated buffer");923 llvm::copy(RHSExprs, getLHSExprs().end());924}925 926void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {927 assert(ReductionOps.size() == varlist_size() && "Number of in reduction "928 "expressions is not the same "929 "as the preallocated buffer");930 llvm::copy(ReductionOps, getRHSExprs().end());931}932 933void OMPInReductionClause::setTaskgroupDescriptors(934 ArrayRef<Expr *> TaskgroupDescriptors) {935 assert(TaskgroupDescriptors.size() == varlist_size() &&936 "Number of in reduction descriptors is not the same as the "937 "preallocated buffer");938 llvm::copy(TaskgroupDescriptors, getReductionOps().end());939}940 941OMPInReductionClause *OMPInReductionClause::Create(942 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,943 SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,944 NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,945 ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,946 ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,947 ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {948 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * VL.size()));949 OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(950 StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);951 Clause->setVarRefs(VL);952 Clause->setPrivates(Privates);953 Clause->setLHSExprs(LHSExprs);954 Clause->setRHSExprs(RHSExprs);955 Clause->setReductionOps(ReductionOps);956 Clause->setTaskgroupDescriptors(TaskgroupDescriptors);957 Clause->setPreInitStmt(PreInit);958 Clause->setPostUpdateExpr(PostUpdate);959 return Clause;960}961 962OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,963 unsigned N) {964 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * N));965 return new (Mem) OMPInReductionClause(N);966}967 968OMPSizesClause *OMPSizesClause::Create(const ASTContext &C,969 SourceLocation StartLoc,970 SourceLocation LParenLoc,971 SourceLocation EndLoc,972 ArrayRef<Expr *> Sizes) {973 OMPSizesClause *Clause = CreateEmpty(C, Sizes.size());974 Clause->setLocStart(StartLoc);975 Clause->setLParenLoc(LParenLoc);976 Clause->setLocEnd(EndLoc);977 Clause->setSizesRefs(Sizes);978 return Clause;979}980 981OMPSizesClause *OMPSizesClause::CreateEmpty(const ASTContext &C,982 unsigned NumSizes) {983 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumSizes));984 return new (Mem) OMPSizesClause(NumSizes);985}986 987OMPPermutationClause *OMPPermutationClause::Create(const ASTContext &C,988 SourceLocation StartLoc,989 SourceLocation LParenLoc,990 SourceLocation EndLoc,991 ArrayRef<Expr *> Args) {992 OMPPermutationClause *Clause = CreateEmpty(C, Args.size());993 Clause->setLocStart(StartLoc);994 Clause->setLParenLoc(LParenLoc);995 Clause->setLocEnd(EndLoc);996 Clause->setArgRefs(Args);997 return Clause;998}999 1000OMPPermutationClause *OMPPermutationClause::CreateEmpty(const ASTContext &C,1001 unsigned NumLoops) {1002 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumLoops));1003 return new (Mem) OMPPermutationClause(NumLoops);1004}1005 1006OMPFullClause *OMPFullClause::Create(const ASTContext &C,1007 SourceLocation StartLoc,1008 SourceLocation EndLoc) {1009 OMPFullClause *Clause = CreateEmpty(C);1010 Clause->setLocStart(StartLoc);1011 Clause->setLocEnd(EndLoc);1012 return Clause;1013}1014 1015OMPFullClause *OMPFullClause::CreateEmpty(const ASTContext &C) {1016 return new (C) OMPFullClause();1017}1018 1019OMPPartialClause *OMPPartialClause::Create(const ASTContext &C,1020 SourceLocation StartLoc,1021 SourceLocation LParenLoc,1022 SourceLocation EndLoc,1023 Expr *Factor) {1024 OMPPartialClause *Clause = CreateEmpty(C);1025 Clause->setLocStart(StartLoc);1026 Clause->setLParenLoc(LParenLoc);1027 Clause->setLocEnd(EndLoc);1028 Clause->setFactor(Factor);1029 return Clause;1030}1031 1032OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {1033 return new (C) OMPPartialClause();1034}1035 1036OMPLoopRangeClause *1037OMPLoopRangeClause::Create(const ASTContext &C, SourceLocation StartLoc,1038 SourceLocation LParenLoc, SourceLocation FirstLoc,1039 SourceLocation CountLoc, SourceLocation EndLoc,1040 Expr *First, Expr *Count) {1041 OMPLoopRangeClause *Clause = CreateEmpty(C);1042 Clause->setLocStart(StartLoc);1043 Clause->setLParenLoc(LParenLoc);1044 Clause->setFirstLoc(FirstLoc);1045 Clause->setCountLoc(CountLoc);1046 Clause->setLocEnd(EndLoc);1047 Clause->setFirst(First);1048 Clause->setCount(Count);1049 return Clause;1050}1051 1052OMPLoopRangeClause *OMPLoopRangeClause::CreateEmpty(const ASTContext &C) {1053 return new (C) OMPLoopRangeClause();1054}1055 1056OMPAllocateClause *OMPAllocateClause::Create(1057 const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,1058 Expr *Allocator, Expr *Alignment, SourceLocation ColonLoc,1059 OpenMPAllocateClauseModifier Modifier1, SourceLocation Modifier1Loc,1060 OpenMPAllocateClauseModifier Modifier2, SourceLocation Modifier2Loc,1061 SourceLocation EndLoc, ArrayRef<Expr *> VL) {1062 1063 // Allocate space for private variables and initializer expressions.1064 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));1065 auto *Clause = new (Mem) OMPAllocateClause(1066 StartLoc, LParenLoc, Allocator, Alignment, ColonLoc, Modifier1,1067 Modifier1Loc, Modifier2, Modifier2Loc, EndLoc, VL.size());1068 1069 Clause->setVarRefs(VL);1070 return Clause;1071}1072 1073OMPAllocateClause *OMPAllocateClause::CreateEmpty(const ASTContext &C,1074 unsigned N) {1075 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));1076 return new (Mem) OMPAllocateClause(N);1077}1078 1079OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,1080 SourceLocation StartLoc,1081 SourceLocation LParenLoc,1082 SourceLocation EndLoc,1083 ArrayRef<Expr *> VL) {1084 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));1085 OMPFlushClause *Clause =1086 new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());1087 Clause->setVarRefs(VL);1088 return Clause;1089}1090 1091OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {1092 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));1093 return new (Mem) OMPFlushClause(N);1094}1095 1096OMPDepobjClause *OMPDepobjClause::Create(const ASTContext &C,1097 SourceLocation StartLoc,1098 SourceLocation LParenLoc,1099 SourceLocation RParenLoc,1100 Expr *Depobj) {1101 auto *Clause = new (C) OMPDepobjClause(StartLoc, LParenLoc, RParenLoc);1102 Clause->setDepobj(Depobj);1103 return Clause;1104}1105 1106OMPDepobjClause *OMPDepobjClause::CreateEmpty(const ASTContext &C) {1107 return new (C) OMPDepobjClause();1108}1109 1110OMPDependClause *1111OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,1112 SourceLocation LParenLoc, SourceLocation EndLoc,1113 DependDataTy Data, Expr *DepModifier,1114 ArrayRef<Expr *> VL, unsigned NumLoops) {1115 void *Mem = C.Allocate(1116 totalSizeToAlloc<Expr *>(VL.size() + /*depend-modifier*/ 1 + NumLoops),1117 alignof(OMPDependClause));1118 OMPDependClause *Clause = new (Mem)1119 OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);1120 Clause->setDependencyKind(Data.DepKind);1121 Clause->setDependencyLoc(Data.DepLoc);1122 Clause->setColonLoc(Data.ColonLoc);1123 Clause->setOmpAllMemoryLoc(Data.OmpAllMemoryLoc);1124 Clause->setModifier(DepModifier);1125 Clause->setVarRefs(VL);1126 for (unsigned I = 0 ; I < NumLoops; ++I)1127 Clause->setLoopData(I, nullptr);1128 return Clause;1129}1130 1131OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N,1132 unsigned NumLoops) {1133 void *Mem =1134 C.Allocate(totalSizeToAlloc<Expr *>(N + /*depend-modifier*/ 1 + NumLoops),1135 alignof(OMPDependClause));1136 return new (Mem) OMPDependClause(N, NumLoops);1137}1138 1139void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) {1140 assert((getDependencyKind() == OMPC_DEPEND_sink ||1141 getDependencyKind() == OMPC_DEPEND_source) &&1142 NumLoop < NumLoops &&1143 "Expected sink or source depend + loop index must be less number of "1144 "loops.");1145 auto *It = std::next(getVarRefs().end(), NumLoop + 1);1146 *It = Cnt;1147}1148 1149Expr *OMPDependClause::getLoopData(unsigned NumLoop) {1150 assert((getDependencyKind() == OMPC_DEPEND_sink ||1151 getDependencyKind() == OMPC_DEPEND_source) &&1152 NumLoop < NumLoops &&1153 "Expected sink or source depend + loop index must be less number of "1154 "loops.");1155 auto *It = std::next(getVarRefs().end(), NumLoop + 1);1156 return *It;1157}1158 1159const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const {1160 assert((getDependencyKind() == OMPC_DEPEND_sink ||1161 getDependencyKind() == OMPC_DEPEND_source) &&1162 NumLoop < NumLoops &&1163 "Expected sink or source depend + loop index must be less number of "1164 "loops.");1165 const auto *It = std::next(getVarRefs().end(), NumLoop + 1);1166 return *It;1167}1168 1169void OMPDependClause::setModifier(Expr *DepModifier) {1170 *getVarRefs().end() = DepModifier;1171}1172Expr *OMPDependClause::getModifier() { return *getVarRefs().end(); }1173 1174unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber(1175 MappableExprComponentListsRef ComponentLists) {1176 unsigned TotalNum = 0u;1177 for (auto &C : ComponentLists)1178 TotalNum += C.size();1179 return TotalNum;1180}1181 1182unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(1183 ArrayRef<const ValueDecl *> Declarations) {1184 llvm::SmallPtrSet<const ValueDecl *, 8> UniqueDecls;1185 for (const ValueDecl *D : Declarations) {1186 const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;1187 UniqueDecls.insert(VD);1188 }1189 return UniqueDecls.size();1190}1191 1192QualType1193OMPClauseMappableExprCommon::getComponentExprElementType(const Expr *Exp) {1194 assert(!isa<OMPArrayShapingExpr>(Exp) &&1195 "Cannot get element-type from array-shaping expr.");1196 1197 // Unless we are handling array-section expressions, including1198 // array-subscripts, derefs, we can rely on getType.1199 if (!isa<ArraySectionExpr>(Exp))1200 return Exp->getType().getNonReferenceType().getCanonicalType();1201 1202 // For array-sections, we need to find the type of one element of1203 // the section.1204 const auto *OASE = cast<ArraySectionExpr>(Exp);1205 1206 QualType BaseType = ArraySectionExpr::getBaseOriginalType(OASE->getBase());1207 1208 QualType ElemTy;1209 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())1210 ElemTy = ATy->getElementType();1211 else1212 ElemTy = BaseType->getPointeeType();1213 1214 ElemTy = ElemTy.getNonReferenceType().getCanonicalType();1215 return ElemTy;1216}1217 1218std::pair<const Expr *, std::optional<size_t>>1219OMPClauseMappableExprCommon::findAttachPtrExpr(1220 MappableExprComponentListRef Components, OpenMPDirectiveKind CurDirKind) {1221 1222 // If we only have a single component, we have a map like "map(p)", which1223 // cannot have a base-pointer.1224 if (Components.size() < 2)1225 return {nullptr, std::nullopt};1226 1227 // Only check for non-contiguous sections on target_update, since we can1228 // assume array-sections are contiguous on maps on other constructs, even if1229 // we are not sure of it at compile-time, like for a[1:x][2].1230 if (Components.back().isNonContiguous() && CurDirKind == OMPD_target_update)1231 return {nullptr, std::nullopt};1232 1233 // To find the attach base-pointer, we start with the second component,1234 // stripping away one component at a time, until we reach a pointer Expr1235 // (that is not a binary operator). The first such pointer should be the1236 // attach base-pointer for the component list.1237 for (auto [I, Component] : llvm::enumerate(Components)) {1238 // Skip past the first component.1239 if (I == 0)1240 continue;1241 1242 const Expr *CurExpr = Component.getAssociatedExpression();1243 if (!CurExpr)1244 break;1245 1246 // If CurExpr is something like `p + 10`, we need to ignore it, since1247 // we are looking for `p`.1248 if (isa<BinaryOperator>(CurExpr))1249 continue;1250 1251 // Keep going until we reach an Expr of pointer type.1252 QualType CurType = getComponentExprElementType(CurExpr);1253 if (!CurType->isPointerType())1254 continue;1255 1256 // We have found a pointer Expr. This must be the attach pointer.1257 return {CurExpr, Components.size() - I};1258 }1259 1260 return {nullptr, std::nullopt};1261}1262 1263OMPMapClause *OMPMapClause::Create(1264 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,1265 ArrayRef<ValueDecl *> Declarations,1266 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,1267 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapModifiers,1268 ArrayRef<SourceLocation> MapModifiersLoc,1269 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,1270 OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc) {1271 OMPMappableExprListSizeTy Sizes;1272 Sizes.NumVars = Vars.size();1273 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);1274 Sizes.NumComponentLists = ComponentLists.size();1275 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);1276 1277 // We need to allocate:1278 // 2 x NumVars x Expr* - we have an original list expression and an associated1279 // user-defined mapper for each clause list entry.1280 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated1281 // with each component list.1282 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the1283 // number of lists for each unique declaration and the size of each component1284 // list.1285 // NumComponents x MappableComponent - the total of all the components in all1286 // the lists.1287 void *Mem = C.Allocate(1288 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1289 OMPClauseMappableExprCommon::MappableComponent>(1290 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,1291 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1292 Sizes.NumComponents));1293 OMPMapClause *Clause = new (Mem)1294 OMPMapClause(MapModifiers, MapModifiersLoc, UDMQualifierLoc, MapperId,1295 Type, TypeIsImplicit, TypeLoc, Locs, Sizes);1296 1297 Clause->setVarRefs(Vars);1298 Clause->setUDMapperRefs(UDMapperRefs);1299 Clause->setIteratorModifier(IteratorModifier);1300 Clause->setClauseInfo(Declarations, ComponentLists);1301 Clause->setMapType(Type);1302 Clause->setMapLoc(TypeLoc);1303 return Clause;1304}1305 1306OMPMapClause *1307OMPMapClause::CreateEmpty(const ASTContext &C,1308 const OMPMappableExprListSizeTy &Sizes) {1309 void *Mem = C.Allocate(1310 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1311 OMPClauseMappableExprCommon::MappableComponent>(1312 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,1313 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1314 Sizes.NumComponents));1315 OMPMapClause *Clause = new (Mem) OMPMapClause(Sizes);1316 Clause->setIteratorModifier(nullptr);1317 return Clause;1318}1319 1320OMPToClause *OMPToClause::Create(1321 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,1322 ArrayRef<ValueDecl *> Declarations,1323 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,1324 Expr *IteratorModifier, ArrayRef<OpenMPMotionModifierKind> MotionModifiers,1325 ArrayRef<SourceLocation> MotionModifiersLoc,1326 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {1327 OMPMappableExprListSizeTy Sizes;1328 Sizes.NumVars = Vars.size();1329 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);1330 Sizes.NumComponentLists = ComponentLists.size();1331 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);1332 1333 // We need to allocate:1334 // 2 x NumVars x Expr* - we have an original list expression and an associated1335 // user-defined mapper for each clause list entry.1336 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated1337 // with each component list.1338 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the1339 // number of lists for each unique declaration and the size of each component1340 // list.1341 // NumComponents x MappableComponent - the total of all the components in all1342 // the lists.1343 void *Mem = C.Allocate(1344 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1345 OMPClauseMappableExprCommon::MappableComponent>(1346 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,1347 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1348 Sizes.NumComponents));1349 1350 auto *Clause = new (Mem) OMPToClause(MotionModifiers, MotionModifiersLoc,1351 UDMQualifierLoc, MapperId, Locs, Sizes);1352 1353 Clause->setVarRefs(Vars);1354 Clause->setUDMapperRefs(UDMapperRefs);1355 Clause->setClauseInfo(Declarations, ComponentLists);1356 Clause->setIteratorModifier(IteratorModifier);1357 return Clause;1358}1359 1360OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C,1361 const OMPMappableExprListSizeTy &Sizes) {1362 void *Mem = C.Allocate(1363 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1364 OMPClauseMappableExprCommon::MappableComponent>(1365 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,1366 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1367 Sizes.NumComponents));1368 OMPToClause *Clause = new (Mem) OMPToClause(Sizes);1369 Clause->setIteratorModifier(nullptr);1370 return Clause;1371}1372 1373OMPFromClause *OMPFromClause::Create(1374 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,1375 ArrayRef<ValueDecl *> Declarations,1376 MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,1377 Expr *IteratorModifier, ArrayRef<OpenMPMotionModifierKind> MotionModifiers,1378 ArrayRef<SourceLocation> MotionModifiersLoc,1379 NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {1380 OMPMappableExprListSizeTy Sizes;1381 Sizes.NumVars = Vars.size();1382 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);1383 Sizes.NumComponentLists = ComponentLists.size();1384 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);1385 1386 // We need to allocate:1387 // 2 x NumVars x Expr* - we have an original list expression and an associated1388 // user-defined mapper for each clause list entry.1389 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated1390 // with each component list.1391 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the1392 // number of lists for each unique declaration and the size of each component1393 // list.1394 // NumComponents x MappableComponent - the total of all the components in all1395 // the lists.1396 void *Mem = C.Allocate(1397 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1398 OMPClauseMappableExprCommon::MappableComponent>(1399 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,1400 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1401 Sizes.NumComponents));1402 1403 auto *Clause =1404 new (Mem) OMPFromClause(MotionModifiers, MotionModifiersLoc,1405 UDMQualifierLoc, MapperId, Locs, Sizes);1406 1407 Clause->setVarRefs(Vars);1408 Clause->setUDMapperRefs(UDMapperRefs);1409 Clause->setClauseInfo(Declarations, ComponentLists);1410 Clause->setIteratorModifier(IteratorModifier);1411 return Clause;1412}1413 1414OMPFromClause *1415OMPFromClause::CreateEmpty(const ASTContext &C,1416 const OMPMappableExprListSizeTy &Sizes) {1417 void *Mem = C.Allocate(1418 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1419 OMPClauseMappableExprCommon::MappableComponent>(1420 2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,1421 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1422 Sizes.NumComponents));1423 OMPFromClause *Clause = new (Mem) OMPFromClause(Sizes);1424 Clause->setIteratorModifier(nullptr);1425 return Clause;1426}1427 1428void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {1429 assert(VL.size() == varlist_size() &&1430 "Number of private copies is not the same as the preallocated buffer");1431 llvm::copy(VL, varlist_end());1432}1433 1434void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {1435 assert(VL.size() == varlist_size() &&1436 "Number of inits is not the same as the preallocated buffer");1437 llvm::copy(VL, getPrivateCopies().end());1438}1439 1440OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(1441 const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,1442 ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,1443 ArrayRef<ValueDecl *> Declarations,1444 MappableExprComponentListsRef ComponentLists) {1445 OMPMappableExprListSizeTy Sizes;1446 Sizes.NumVars = Vars.size();1447 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);1448 Sizes.NumComponentLists = ComponentLists.size();1449 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);1450 1451 // We need to allocate:1452 // NumVars x Expr* - we have an original list expression for each clause1453 // list entry.1454 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated1455 // with each component list.1456 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the1457 // number of lists for each unique declaration and the size of each component1458 // list.1459 // NumComponents x MappableComponent - the total of all the components in all1460 // the lists.1461 void *Mem = C.Allocate(1462 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1463 OMPClauseMappableExprCommon::MappableComponent>(1464 3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,1465 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1466 Sizes.NumComponents));1467 1468 OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);1469 1470 Clause->setVarRefs(Vars);1471 Clause->setPrivateCopies(PrivateVars);1472 Clause->setInits(Inits);1473 Clause->setClauseInfo(Declarations, ComponentLists);1474 return Clause;1475}1476 1477OMPUseDevicePtrClause *1478OMPUseDevicePtrClause::CreateEmpty(const ASTContext &C,1479 const OMPMappableExprListSizeTy &Sizes) {1480 void *Mem = C.Allocate(1481 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1482 OMPClauseMappableExprCommon::MappableComponent>(1483 3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,1484 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1485 Sizes.NumComponents));1486 return new (Mem) OMPUseDevicePtrClause(Sizes);1487}1488 1489OMPUseDeviceAddrClause *1490OMPUseDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,1491 ArrayRef<Expr *> Vars,1492 ArrayRef<ValueDecl *> Declarations,1493 MappableExprComponentListsRef ComponentLists) {1494 OMPMappableExprListSizeTy Sizes;1495 Sizes.NumVars = Vars.size();1496 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);1497 Sizes.NumComponentLists = ComponentLists.size();1498 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);1499 1500 // We need to allocate:1501 // 3 x NumVars x Expr* - we have an original list expression for each clause1502 // list entry and an equal number of private copies and inits.1503 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated1504 // with each component list.1505 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the1506 // number of lists for each unique declaration and the size of each component1507 // list.1508 // NumComponents x MappableComponent - the total of all the components in all1509 // the lists.1510 void *Mem = C.Allocate(1511 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1512 OMPClauseMappableExprCommon::MappableComponent>(1513 Sizes.NumVars, Sizes.NumUniqueDeclarations,1514 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1515 Sizes.NumComponents));1516 1517 auto *Clause = new (Mem) OMPUseDeviceAddrClause(Locs, Sizes);1518 1519 Clause->setVarRefs(Vars);1520 Clause->setClauseInfo(Declarations, ComponentLists);1521 return Clause;1522}1523 1524OMPUseDeviceAddrClause *1525OMPUseDeviceAddrClause::CreateEmpty(const ASTContext &C,1526 const OMPMappableExprListSizeTy &Sizes) {1527 void *Mem = C.Allocate(1528 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1529 OMPClauseMappableExprCommon::MappableComponent>(1530 Sizes.NumVars, Sizes.NumUniqueDeclarations,1531 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1532 Sizes.NumComponents));1533 return new (Mem) OMPUseDeviceAddrClause(Sizes);1534}1535 1536OMPIsDevicePtrClause *1537OMPIsDevicePtrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,1538 ArrayRef<Expr *> Vars,1539 ArrayRef<ValueDecl *> Declarations,1540 MappableExprComponentListsRef ComponentLists) {1541 OMPMappableExprListSizeTy Sizes;1542 Sizes.NumVars = Vars.size();1543 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);1544 Sizes.NumComponentLists = ComponentLists.size();1545 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);1546 1547 // We need to allocate:1548 // NumVars x Expr* - we have an original list expression for each clause list1549 // entry.1550 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated1551 // with each component list.1552 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the1553 // number of lists for each unique declaration and the size of each component1554 // list.1555 // NumComponents x MappableComponent - the total of all the components in all1556 // the lists.1557 void *Mem = C.Allocate(1558 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1559 OMPClauseMappableExprCommon::MappableComponent>(1560 Sizes.NumVars, Sizes.NumUniqueDeclarations,1561 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1562 Sizes.NumComponents));1563 1564 OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(Locs, Sizes);1565 1566 Clause->setVarRefs(Vars);1567 Clause->setClauseInfo(Declarations, ComponentLists);1568 return Clause;1569}1570 1571OMPIsDevicePtrClause *1572OMPIsDevicePtrClause::CreateEmpty(const ASTContext &C,1573 const OMPMappableExprListSizeTy &Sizes) {1574 void *Mem = C.Allocate(1575 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1576 OMPClauseMappableExprCommon::MappableComponent>(1577 Sizes.NumVars, Sizes.NumUniqueDeclarations,1578 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1579 Sizes.NumComponents));1580 return new (Mem) OMPIsDevicePtrClause(Sizes);1581}1582 1583OMPHasDeviceAddrClause *1584OMPHasDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,1585 ArrayRef<Expr *> Vars,1586 ArrayRef<ValueDecl *> Declarations,1587 MappableExprComponentListsRef ComponentLists) {1588 OMPMappableExprListSizeTy Sizes;1589 Sizes.NumVars = Vars.size();1590 Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);1591 Sizes.NumComponentLists = ComponentLists.size();1592 Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);1593 1594 // We need to allocate:1595 // NumVars x Expr* - we have an original list expression for each clause list1596 // entry.1597 // NumUniqueDeclarations x ValueDecl* - unique base declarations associated1598 // with each component list.1599 // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the1600 // number of lists for each unique declaration and the size of each component1601 // list.1602 // NumComponents x MappableComponent - the total of all the components in all1603 // the lists.1604 void *Mem = C.Allocate(1605 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1606 OMPClauseMappableExprCommon::MappableComponent>(1607 Sizes.NumVars, Sizes.NumUniqueDeclarations,1608 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1609 Sizes.NumComponents));1610 1611 auto *Clause = new (Mem) OMPHasDeviceAddrClause(Locs, Sizes);1612 1613 Clause->setVarRefs(Vars);1614 Clause->setClauseInfo(Declarations, ComponentLists);1615 return Clause;1616}1617 1618OMPHasDeviceAddrClause *1619OMPHasDeviceAddrClause::CreateEmpty(const ASTContext &C,1620 const OMPMappableExprListSizeTy &Sizes) {1621 void *Mem = C.Allocate(1622 totalSizeToAlloc<Expr *, ValueDecl *, unsigned,1623 OMPClauseMappableExprCommon::MappableComponent>(1624 Sizes.NumVars, Sizes.NumUniqueDeclarations,1625 Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,1626 Sizes.NumComponents));1627 return new (Mem) OMPHasDeviceAddrClause(Sizes);1628}1629 1630OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,1631 SourceLocation StartLoc,1632 SourceLocation LParenLoc,1633 SourceLocation EndLoc,1634 ArrayRef<Expr *> VL) {1635 // Allocate space for nontemporal variables + private references.1636 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));1637 auto *Clause =1638 new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());1639 Clause->setVarRefs(VL);1640 return Clause;1641}1642 1643OMPNontemporalClause *OMPNontemporalClause::CreateEmpty(const ASTContext &C,1644 unsigned N) {1645 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));1646 return new (Mem) OMPNontemporalClause(N);1647}1648 1649void OMPNontemporalClause::setPrivateRefs(ArrayRef<Expr *> VL) {1650 assert(VL.size() == varlist_size() && "Number of private references is not "1651 "the same as the preallocated buffer");1652 llvm::copy(VL, varlist_end());1653}1654 1655OMPInclusiveClause *OMPInclusiveClause::Create(const ASTContext &C,1656 SourceLocation StartLoc,1657 SourceLocation LParenLoc,1658 SourceLocation EndLoc,1659 ArrayRef<Expr *> VL) {1660 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));1661 auto *Clause =1662 new (Mem) OMPInclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());1663 Clause->setVarRefs(VL);1664 return Clause;1665}1666 1667OMPInclusiveClause *OMPInclusiveClause::CreateEmpty(const ASTContext &C,1668 unsigned N) {1669 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));1670 return new (Mem) OMPInclusiveClause(N);1671}1672 1673OMPExclusiveClause *OMPExclusiveClause::Create(const ASTContext &C,1674 SourceLocation StartLoc,1675 SourceLocation LParenLoc,1676 SourceLocation EndLoc,1677 ArrayRef<Expr *> VL) {1678 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));1679 auto *Clause =1680 new (Mem) OMPExclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());1681 Clause->setVarRefs(VL);1682 return Clause;1683}1684 1685OMPExclusiveClause *OMPExclusiveClause::CreateEmpty(const ASTContext &C,1686 unsigned N) {1687 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));1688 return new (Mem) OMPExclusiveClause(N);1689}1690 1691void OMPUsesAllocatorsClause::setAllocatorsData(1692 ArrayRef<OMPUsesAllocatorsClause::Data> Data) {1693 assert(Data.size() == NumOfAllocators &&1694 "Size of allocators data is not the same as the preallocated buffer.");1695 for (unsigned I = 0, E = Data.size(); I < E; ++I) {1696 const OMPUsesAllocatorsClause::Data &D = Data[I];1697 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +1698 static_cast<int>(ExprOffsets::Allocator)] =1699 D.Allocator;1700 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +1701 static_cast<int>(1702 ExprOffsets::AllocatorTraits)] =1703 D.AllocatorTraits;1704 getTrailingObjects<1705 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +1706 static_cast<int>(ParenLocsOffsets::LParen)] =1707 D.LParenLoc;1708 getTrailingObjects<1709 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +1710 static_cast<int>(ParenLocsOffsets::RParen)] =1711 D.RParenLoc;1712 }1713}1714 1715OMPUsesAllocatorsClause::Data1716OMPUsesAllocatorsClause::getAllocatorData(unsigned I) const {1717 OMPUsesAllocatorsClause::Data Data;1718 Data.Allocator =1719 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +1720 static_cast<int>(ExprOffsets::Allocator)];1721 Data.AllocatorTraits =1722 getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +1723 static_cast<int>(1724 ExprOffsets::AllocatorTraits)];1725 Data.LParenLoc = getTrailingObjects<1726 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +1727 static_cast<int>(ParenLocsOffsets::LParen)];1728 Data.RParenLoc = getTrailingObjects<1729 SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +1730 static_cast<int>(ParenLocsOffsets::RParen)];1731 return Data;1732}1733 1734OMPUsesAllocatorsClause *1735OMPUsesAllocatorsClause::Create(const ASTContext &C, SourceLocation StartLoc,1736 SourceLocation LParenLoc, SourceLocation EndLoc,1737 ArrayRef<OMPUsesAllocatorsClause::Data> Data) {1738 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(1739 static_cast<int>(ExprOffsets::Total) * Data.size(),1740 static_cast<int>(ParenLocsOffsets::Total) * Data.size()));1741 auto *Clause = new (Mem)1742 OMPUsesAllocatorsClause(StartLoc, LParenLoc, EndLoc, Data.size());1743 Clause->setAllocatorsData(Data);1744 return Clause;1745}1746 1747OMPUsesAllocatorsClause *1748OMPUsesAllocatorsClause::CreateEmpty(const ASTContext &C, unsigned N) {1749 void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(1750 static_cast<int>(ExprOffsets::Total) * N,1751 static_cast<int>(ParenLocsOffsets::Total) * N));1752 return new (Mem) OMPUsesAllocatorsClause(N);1753}1754 1755OMPAffinityClause *1756OMPAffinityClause::Create(const ASTContext &C, SourceLocation StartLoc,1757 SourceLocation LParenLoc, SourceLocation ColonLoc,1758 SourceLocation EndLoc, Expr *Modifier,1759 ArrayRef<Expr *> Locators) {1760 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Locators.size() + 1));1761 auto *Clause = new (Mem)1762 OMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, Locators.size());1763 Clause->setModifier(Modifier);1764 Clause->setVarRefs(Locators);1765 return Clause;1766}1767 1768OMPAffinityClause *OMPAffinityClause::CreateEmpty(const ASTContext &C,1769 unsigned N) {1770 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + 1));1771 return new (Mem) OMPAffinityClause(N);1772}1773 1774OMPInitClause *OMPInitClause::Create(const ASTContext &C, Expr *InteropVar,1775 OMPInteropInfo &InteropInfo,1776 SourceLocation StartLoc,1777 SourceLocation LParenLoc,1778 SourceLocation VarLoc,1779 SourceLocation EndLoc) {1780 1781 void *Mem =1782 C.Allocate(totalSizeToAlloc<Expr *>(InteropInfo.PreferTypes.size() + 1));1783 auto *Clause = new (Mem) OMPInitClause(1784 InteropInfo.IsTarget, InteropInfo.IsTargetSync, StartLoc, LParenLoc,1785 VarLoc, EndLoc, InteropInfo.PreferTypes.size() + 1);1786 Clause->setInteropVar(InteropVar);1787 llvm::copy(InteropInfo.PreferTypes, Clause->getTrailingObjects() + 1);1788 return Clause;1789}1790 1791OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C, unsigned N) {1792 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));1793 return new (Mem) OMPInitClause(N);1794}1795 1796OMPBindClause *1797OMPBindClause::Create(const ASTContext &C, OpenMPBindClauseKind K,1798 SourceLocation KLoc, SourceLocation StartLoc,1799 SourceLocation LParenLoc, SourceLocation EndLoc) {1800 return new (C) OMPBindClause(K, KLoc, StartLoc, LParenLoc, EndLoc);1801}1802 1803OMPBindClause *OMPBindClause::CreateEmpty(const ASTContext &C) {1804 return new (C) OMPBindClause();1805}1806 1807OMPDoacrossClause *1808OMPDoacrossClause::Create(const ASTContext &C, SourceLocation StartLoc,1809 SourceLocation LParenLoc, SourceLocation EndLoc,1810 OpenMPDoacrossClauseModifier DepType,1811 SourceLocation DepLoc, SourceLocation ColonLoc,1812 ArrayRef<Expr *> VL, unsigned NumLoops) {1813 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + NumLoops),1814 alignof(OMPDoacrossClause));1815 OMPDoacrossClause *Clause = new (Mem)1816 OMPDoacrossClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);1817 Clause->setDependenceType(DepType);1818 Clause->setDependenceLoc(DepLoc);1819 Clause->setColonLoc(ColonLoc);1820 Clause->setVarRefs(VL);1821 for (unsigned I = 0; I < NumLoops; ++I)1822 Clause->setLoopData(I, nullptr);1823 return Clause;1824}1825 1826OMPDoacrossClause *OMPDoacrossClause::CreateEmpty(const ASTContext &C,1827 unsigned N,1828 unsigned NumLoops) {1829 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + NumLoops),1830 alignof(OMPDoacrossClause));1831 return new (Mem) OMPDoacrossClause(N, NumLoops);1832}1833 1834void OMPDoacrossClause::setLoopData(unsigned NumLoop, Expr *Cnt) {1835 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");1836 auto *It = std::next(getVarRefs().end(), NumLoop);1837 *It = Cnt;1838}1839 1840Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) {1841 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");1842 auto *It = std::next(getVarRefs().end(), NumLoop);1843 return *It;1844}1845 1846const Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) const {1847 assert(NumLoop < NumLoops && "Loop index must be less number of loops.");1848 const auto *It = std::next(getVarRefs().end(), NumLoop);1849 return *It;1850}1851 1852OMPAbsentClause *OMPAbsentClause::Create(const ASTContext &C,1853 ArrayRef<OpenMPDirectiveKind> DKVec,1854 SourceLocation Loc,1855 SourceLocation LLoc,1856 SourceLocation RLoc) {1857 void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(DKVec.size()),1858 alignof(OMPAbsentClause));1859 auto *AC = new (Mem) OMPAbsentClause(Loc, LLoc, RLoc, DKVec.size());1860 AC->setDirectiveKinds(DKVec);1861 return AC;1862}1863 1864OMPAbsentClause *OMPAbsentClause::CreateEmpty(const ASTContext &C, unsigned K) {1865 void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(K),1866 alignof(OMPAbsentClause));1867 return new (Mem) OMPAbsentClause(K);1868}1869 1870OMPContainsClause *OMPContainsClause::Create(1871 const ASTContext &C, ArrayRef<OpenMPDirectiveKind> DKVec,1872 SourceLocation Loc, SourceLocation LLoc, SourceLocation RLoc) {1873 void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(DKVec.size()),1874 alignof(OMPContainsClause));1875 auto *CC = new (Mem) OMPContainsClause(Loc, LLoc, RLoc, DKVec.size());1876 CC->setDirectiveKinds(DKVec);1877 return CC;1878}1879 1880OMPContainsClause *OMPContainsClause::CreateEmpty(const ASTContext &C,1881 unsigned K) {1882 void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(K),1883 alignof(OMPContainsClause));1884 return new (Mem) OMPContainsClause(K);1885}1886 1887OMPNumTeamsClause *OMPNumTeamsClause::Create(1888 const ASTContext &C, OpenMPDirectiveKind CaptureRegion,1889 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,1890 ArrayRef<Expr *> VL, Stmt *PreInit) {1891 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));1892 OMPNumTeamsClause *Clause =1893 new (Mem) OMPNumTeamsClause(C, StartLoc, LParenLoc, EndLoc, VL.size());1894 Clause->setVarRefs(VL);1895 Clause->setPreInitStmt(PreInit, CaptureRegion);1896 return Clause;1897}1898 1899OMPNumTeamsClause *OMPNumTeamsClause::CreateEmpty(const ASTContext &C,1900 unsigned N) {1901 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));1902 return new (Mem) OMPNumTeamsClause(N);1903}1904 1905OMPThreadLimitClause *OMPThreadLimitClause::Create(1906 const ASTContext &C, OpenMPDirectiveKind CaptureRegion,1907 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,1908 ArrayRef<Expr *> VL, Stmt *PreInit) {1909 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));1910 OMPThreadLimitClause *Clause =1911 new (Mem) OMPThreadLimitClause(C, StartLoc, LParenLoc, EndLoc, VL.size());1912 Clause->setVarRefs(VL);1913 Clause->setPreInitStmt(PreInit, CaptureRegion);1914 return Clause;1915}1916 1917OMPThreadLimitClause *OMPThreadLimitClause::CreateEmpty(const ASTContext &C,1918 unsigned N) {1919 void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));1920 return new (Mem) OMPThreadLimitClause(N);1921}1922 1923//===----------------------------------------------------------------------===//1924// OpenMP clauses printing methods1925//===----------------------------------------------------------------------===//1926 1927void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {1928 OS << "if(";1929 if (Node->getNameModifier() != OMPD_unknown)1930 OS << getOpenMPDirectiveName(Node->getNameModifier(), Version) << ": ";1931 Node->getCondition()->printPretty(OS, nullptr, Policy, 0);1932 OS << ")";1933}1934 1935void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {1936 OS << "final(";1937 Node->getCondition()->printPretty(OS, nullptr, Policy, 0);1938 OS << ")";1939}1940 1941void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {1942 OS << "num_threads(";1943 OpenMPNumThreadsClauseModifier Modifier = Node->getModifier();1944 if (Modifier != OMPC_NUMTHREADS_unknown) {1945 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)1946 << ": ";1947 }1948 Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);1949 OS << ")";1950}1951 1952void OMPClausePrinter::VisitOMPAlignClause(OMPAlignClause *Node) {1953 OS << "align(";1954 Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);1955 OS << ")";1956}1957 1958void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {1959 OS << "safelen(";1960 Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);1961 OS << ")";1962}1963 1964void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {1965 OS << "simdlen(";1966 Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0);1967 OS << ")";1968}1969 1970void OMPClausePrinter::VisitOMPSizesClause(OMPSizesClause *Node) {1971 OS << "sizes(";1972 bool First = true;1973 for (auto *Size : Node->getSizesRefs()) {1974 if (!First)1975 OS << ", ";1976 Size->printPretty(OS, nullptr, Policy, 0);1977 First = false;1978 }1979 OS << ")";1980}1981 1982void OMPClausePrinter::VisitOMPPermutationClause(OMPPermutationClause *Node) {1983 OS << "permutation(";1984 llvm::interleaveComma(Node->getArgsRefs(), OS, [&](const Expr *E) {1985 E->printPretty(OS, nullptr, Policy, 0);1986 });1987 OS << ")";1988}1989 1990void OMPClausePrinter::VisitOMPFullClause(OMPFullClause *Node) { OS << "full"; }1991 1992void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) {1993 OS << "partial";1994 1995 if (Expr *Factor = Node->getFactor()) {1996 OS << '(';1997 Factor->printPretty(OS, nullptr, Policy, 0);1998 OS << ')';1999 }2000}2001 2002void OMPClausePrinter::VisitOMPLoopRangeClause(OMPLoopRangeClause *Node) {2003 OS << "looprange";2004 2005 Expr *First = Node->getFirst();2006 Expr *Count = Node->getCount();2007 2008 if (First && Count) {2009 OS << "(";2010 First->printPretty(OS, nullptr, Policy, 0);2011 OS << ",";2012 Count->printPretty(OS, nullptr, Policy, 0);2013 OS << ")";2014 }2015}2016 2017void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {2018 OS << "allocator(";2019 Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);2020 OS << ")";2021}2022 2023void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {2024 OS << "collapse(";2025 Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);2026 OS << ")";2027}2028 2029void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {2030 OS << "detach(";2031 Node->getEventHandler()->printPretty(OS, nullptr, Policy, 0);2032 OS << ")";2033}2034 2035void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {2036 OS << "default("2037 << getOpenMPSimpleClauseTypeName(OMPC_default,2038 unsigned(Node->getDefaultKind()));2039 if (Version >= 60 && Node->getDefaultVC() != OMPC_DEFAULT_VC_all) {2040 OS << ":"2041 << getOpenMPDefaultVariableCategoryName(unsigned(Node->getDefaultVC()));2042 }2043 2044 OS << ")";2045}2046 2047void OMPClausePrinter::VisitOMPThreadsetClause(OMPThreadsetClause *Node) {2048 OS << "threadset("2049 << getOpenMPSimpleClauseTypeName(OMPC_threadset,2050 unsigned(Node->getThreadsetKind()))2051 << ")";2052}2053 2054void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {2055 OS << "proc_bind("2056 << getOpenMPSimpleClauseTypeName(OMPC_proc_bind,2057 unsigned(Node->getProcBindKind()))2058 << ")";2059}2060 2061void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {2062 OS << "unified_address";2063}2064 2065void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(2066 OMPUnifiedSharedMemoryClause *) {2067 OS << "unified_shared_memory";2068}2069 2070void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {2071 OS << "reverse_offload";2072}2073 2074void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(2075 OMPDynamicAllocatorsClause *) {2076 OS << "dynamic_allocators";2077}2078 2079void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(2080 OMPAtomicDefaultMemOrderClause *Node) {2081 OS << "atomic_default_mem_order("2082 << getOpenMPSimpleClauseTypeName(OMPC_atomic_default_mem_order,2083 Node->getAtomicDefaultMemOrderKind())2084 << ")";2085}2086 2087void OMPClausePrinter::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {2088 OS << "self_maps";2089}2090 2091void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {2092 OS << "at(" << getOpenMPSimpleClauseTypeName(OMPC_at, Node->getAtKind())2093 << ")";2094}2095 2096void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {2097 OS << "severity("2098 << getOpenMPSimpleClauseTypeName(OMPC_severity, Node->getSeverityKind())2099 << ")";2100}2101 2102void OMPClausePrinter::VisitOMPMessageClause(OMPMessageClause *Node) {2103 OS << "message(";2104 if (Expr *E = Node->getMessageString())2105 E->printPretty(OS, nullptr, Policy);2106 OS << ")";2107}2108 2109void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {2110 OS << "schedule(";2111 if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {2112 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,2113 Node->getFirstScheduleModifier());2114 if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {2115 OS << ", ";2116 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,2117 Node->getSecondScheduleModifier());2118 }2119 OS << ": ";2120 }2121 OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());2122 if (auto *E = Node->getChunkSize()) {2123 OS << ", ";2124 E->printPretty(OS, nullptr, Policy);2125 }2126 OS << ")";2127}2128 2129void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {2130 OS << "ordered";2131 if (auto *Num = Node->getNumForLoops()) {2132 OS << "(";2133 Num->printPretty(OS, nullptr, Policy, 0);2134 OS << ")";2135 }2136}2137 2138void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *Node) {2139 OS << "nowait";2140 if (auto *Cond = Node->getCondition()) {2141 OS << "(";2142 Cond->printPretty(OS, nullptr, Policy, 0);2143 OS << ")";2144 }2145}2146 2147void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {2148 OS << "untied";2149}2150 2151void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {2152 OS << "nogroup";2153}2154 2155void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {2156 OS << "mergeable";2157}2158 2159void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }2160 2161void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }2162 2163void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *Node) {2164 OS << "update";2165 if (Node->isExtended()) {2166 OS << "(";2167 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),2168 Node->getDependencyKind());2169 OS << ")";2170 }2171}2172 2173void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {2174 OS << "capture";2175}2176 2177void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {2178 OS << "compare";2179}2180 2181void OMPClausePrinter::VisitOMPFailClause(OMPFailClause *Node) {2182 OS << "fail";2183 if (Node) {2184 OS << "(";2185 OS << getOpenMPSimpleClauseTypeName(2186 Node->getClauseKind(), static_cast<int>(Node->getFailParameter()));2187 OS << ")";2188 }2189}2190 2191void OMPClausePrinter::VisitOMPAbsentClause(OMPAbsentClause *Node) {2192 OS << "absent(";2193 bool First = true;2194 for (auto &D : Node->getDirectiveKinds()) {2195 if (!First)2196 OS << ", ";2197 OS << getOpenMPDirectiveName(D, Version);2198 First = false;2199 }2200 OS << ")";2201}2202 2203void OMPClausePrinter::VisitOMPHoldsClause(OMPHoldsClause *Node) {2204 OS << "holds(";2205 Node->getExpr()->printPretty(OS, nullptr, Policy, 0);2206 OS << ")";2207}2208 2209void OMPClausePrinter::VisitOMPContainsClause(OMPContainsClause *Node) {2210 OS << "contains(";2211 bool First = true;2212 for (auto &D : Node->getDirectiveKinds()) {2213 if (!First)2214 OS << ", ";2215 OS << getOpenMPDirectiveName(D, Version);2216 First = false;2217 }2218 OS << ")";2219}2220 2221void OMPClausePrinter::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {2222 OS << "no_openmp";2223}2224 2225void OMPClausePrinter::VisitOMPNoOpenMPRoutinesClause(2226 OMPNoOpenMPRoutinesClause *) {2227 OS << "no_openmp_routines";2228}2229 2230void OMPClausePrinter::VisitOMPNoOpenMPConstructsClause(2231 OMPNoOpenMPConstructsClause *) {2232 OS << "no_openmp_constructs";2233}2234 2235void OMPClausePrinter::VisitOMPNoParallelismClause(OMPNoParallelismClause *) {2236 OS << "no_parallelism";2237}2238 2239void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {2240 OS << "seq_cst";2241}2242 2243void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {2244 OS << "acq_rel";2245}2246 2247void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) {2248 OS << "acquire";2249}2250 2251void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {2252 OS << "release";2253}2254 2255void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {2256 OS << "relaxed";2257}2258 2259void OMPClausePrinter::VisitOMPWeakClause(OMPWeakClause *) { OS << "weak"; }2260 2261void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {2262 OS << "threads";2263}2264 2265void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }2266 2267void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {2268 OS << "device(";2269 OpenMPDeviceClauseModifier Modifier = Node->getModifier();2270 if (Modifier != OMPC_DEVICE_unknown) {2271 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)2272 << ": ";2273 }2274 Node->getDevice()->printPretty(OS, nullptr, Policy, 0);2275 OS << ")";2276}2277 2278void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {2279 if (!Node->varlist_empty()) {2280 OS << "num_teams";2281 VisitOMPClauseList(Node, '(');2282 OS << ")";2283 }2284}2285 2286void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {2287 if (!Node->varlist_empty()) {2288 OS << "thread_limit";2289 VisitOMPClauseList(Node, '(');2290 OS << ")";2291 }2292}2293 2294void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {2295 OS << "priority(";2296 Node->getPriority()->printPretty(OS, nullptr, Policy, 0);2297 OS << ")";2298}2299 2300void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {2301 OS << "grainsize(";2302 OpenMPGrainsizeClauseModifier Modifier = Node->getModifier();2303 if (Modifier != OMPC_GRAINSIZE_unknown) {2304 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)2305 << ": ";2306 }2307 Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0);2308 OS << ")";2309}2310 2311void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {2312 OS << "num_tasks(";2313 OpenMPNumTasksClauseModifier Modifier = Node->getModifier();2314 if (Modifier != OMPC_NUMTASKS_unknown) {2315 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)2316 << ": ";2317 }2318 Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0);2319 OS << ")";2320}2321 2322void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {2323 OS << "hint(";2324 Node->getHint()->printPretty(OS, nullptr, Policy, 0);2325 OS << ")";2326}2327 2328void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {2329 OS << "init(";2330 bool First = true;2331 for (const Expr *E : Node->prefs()) {2332 if (First)2333 OS << "prefer_type(";2334 else2335 OS << ",";2336 E->printPretty(OS, nullptr, Policy);2337 First = false;2338 }2339 if (!First)2340 OS << "), ";2341 if (Node->getIsTarget())2342 OS << "target";2343 if (Node->getIsTargetSync()) {2344 if (Node->getIsTarget())2345 OS << ", ";2346 OS << "targetsync";2347 }2348 OS << " : ";2349 Node->getInteropVar()->printPretty(OS, nullptr, Policy);2350 OS << ")";2351}2352 2353void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {2354 OS << "use(";2355 Node->getInteropVar()->printPretty(OS, nullptr, Policy);2356 OS << ")";2357}2358 2359void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *Node) {2360 OS << "destroy";2361 if (Expr *E = Node->getInteropVar()) {2362 OS << "(";2363 E->printPretty(OS, nullptr, Policy);2364 OS << ")";2365 }2366}2367 2368void OMPClausePrinter::VisitOMPNovariantsClause(OMPNovariantsClause *Node) {2369 OS << "novariants";2370 if (Expr *E = Node->getCondition()) {2371 OS << "(";2372 E->printPretty(OS, nullptr, Policy, 0);2373 OS << ")";2374 }2375}2376 2377void OMPClausePrinter::VisitOMPNocontextClause(OMPNocontextClause *Node) {2378 OS << "nocontext";2379 if (Expr *E = Node->getCondition()) {2380 OS << "(";2381 E->printPretty(OS, nullptr, Policy, 0);2382 OS << ")";2383 }2384}2385 2386template<typename T>2387void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {2388 for (typename T::varlist_iterator I = Node->varlist_begin(),2389 E = Node->varlist_end();2390 I != E; ++I) {2391 assert(*I && "Expected non-null Stmt");2392 OS << (I == Node->varlist_begin() ? StartSym : ',');2393 if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {2394 if (isa<OMPCapturedExprDecl>(DRE->getDecl()))2395 DRE->printPretty(OS, nullptr, Policy, 0);2396 else2397 DRE->getDecl()->printQualifiedName(OS);2398 } else2399 (*I)->printPretty(OS, nullptr, Policy, 0);2400 }2401}2402 2403void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {2404 if (Node->varlist_empty())2405 return;2406 2407 Expr *FirstModifier = nullptr;2408 Expr *SecondModifier = nullptr;2409 auto FirstAllocMod = Node->getFirstAllocateModifier();2410 auto SecondAllocMod = Node->getSecondAllocateModifier();2411 bool FirstUnknown = FirstAllocMod == OMPC_ALLOCATE_unknown;2412 bool SecondUnknown = SecondAllocMod == OMPC_ALLOCATE_unknown;2413 if (FirstAllocMod == OMPC_ALLOCATE_allocator ||2414 (FirstAllocMod == OMPC_ALLOCATE_unknown && Node->getAllocator())) {2415 FirstModifier = Node->getAllocator();2416 SecondModifier = Node->getAlignment();2417 } else {2418 FirstModifier = Node->getAlignment();2419 SecondModifier = Node->getAllocator();2420 }2421 2422 OS << "allocate";2423 // If we have any explicit modifiers.2424 if (FirstModifier) {2425 OS << "(";2426 if (!FirstUnknown) {2427 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), FirstAllocMod);2428 OS << "(";2429 }2430 FirstModifier->printPretty(OS, nullptr, Policy, 0);2431 if (!FirstUnknown)2432 OS << ")";2433 if (SecondModifier) {2434 OS << ", ";2435 if (!SecondUnknown) {2436 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),2437 SecondAllocMod);2438 OS << "(";2439 }2440 SecondModifier->printPretty(OS, nullptr, Policy, 0);2441 if (!SecondUnknown)2442 OS << ")";2443 }2444 OS << ":";2445 VisitOMPClauseList(Node, ' ');2446 } else {2447 // No modifiers. Just print the variable list.2448 VisitOMPClauseList(Node, '(');2449 }2450 OS << ")";2451}2452 2453void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {2454 if (!Node->varlist_empty()) {2455 OS << "private";2456 VisitOMPClauseList(Node, '(');2457 OS << ")";2458 }2459}2460 2461void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {2462 if (!Node->varlist_empty()) {2463 OS << "firstprivate";2464 VisitOMPClauseList(Node, '(');2465 OS << ")";2466 }2467}2468 2469void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {2470 if (!Node->varlist_empty()) {2471 OS << "lastprivate";2472 OpenMPLastprivateModifier LPKind = Node->getKind();2473 if (LPKind != OMPC_LASTPRIVATE_unknown) {2474 OS << "("2475 << getOpenMPSimpleClauseTypeName(OMPC_lastprivate, Node->getKind())2476 << ":";2477 }2478 VisitOMPClauseList(Node, LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');2479 OS << ")";2480 }2481}2482 2483void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {2484 if (!Node->varlist_empty()) {2485 OS << "shared";2486 VisitOMPClauseList(Node, '(');2487 OS << ")";2488 }2489}2490 2491void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {2492 if (!Node->varlist_empty()) {2493 OS << "reduction(";2494 if (Node->getModifierLoc().isValid())2495 OS << getOpenMPSimpleClauseTypeName(OMPC_reduction, Node->getModifier())2496 << ", ";2497 NestedNameSpecifier Qualifier =2498 Node->getQualifierLoc().getNestedNameSpecifier();2499 OverloadedOperatorKind OOK =2500 Node->getNameInfo().getName().getCXXOverloadedOperator();2501 if (!Qualifier && OOK != OO_None) {2502 // Print reduction identifier in C format2503 OS << getOperatorSpelling(OOK);2504 } else {2505 // Use C++ format2506 Qualifier.print(OS, Policy);2507 OS << Node->getNameInfo();2508 }2509 OS << ":";2510 VisitOMPClauseList(Node, ' ');2511 OS << ")";2512 }2513}2514 2515void OMPClausePrinter::VisitOMPTaskReductionClause(2516 OMPTaskReductionClause *Node) {2517 if (!Node->varlist_empty()) {2518 OS << "task_reduction(";2519 NestedNameSpecifier Qualifier =2520 Node->getQualifierLoc().getNestedNameSpecifier();2521 OverloadedOperatorKind OOK =2522 Node->getNameInfo().getName().getCXXOverloadedOperator();2523 if (!Qualifier && OOK != OO_None) {2524 // Print reduction identifier in C format2525 OS << getOperatorSpelling(OOK);2526 } else {2527 // Use C++ format2528 Qualifier.print(OS, Policy);2529 OS << Node->getNameInfo();2530 }2531 OS << ":";2532 VisitOMPClauseList(Node, ' ');2533 OS << ")";2534 }2535}2536 2537void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {2538 if (!Node->varlist_empty()) {2539 OS << "in_reduction(";2540 NestedNameSpecifier Qualifier =2541 Node->getQualifierLoc().getNestedNameSpecifier();2542 OverloadedOperatorKind OOK =2543 Node->getNameInfo().getName().getCXXOverloadedOperator();2544 if (!Qualifier && OOK != OO_None) {2545 // Print reduction identifier in C format2546 OS << getOperatorSpelling(OOK);2547 } else {2548 // Use C++ format2549 Qualifier.print(OS, Policy);2550 OS << Node->getNameInfo();2551 }2552 OS << ":";2553 VisitOMPClauseList(Node, ' ');2554 OS << ")";2555 }2556}2557 2558void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {2559 if (!Node->varlist_empty()) {2560 OS << "linear";2561 VisitOMPClauseList(Node, '(');2562 if (Node->getModifierLoc().isValid() || Node->getStep() != nullptr) {2563 OS << ": ";2564 }2565 if (Node->getModifierLoc().isValid()) {2566 OS << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());2567 }2568 if (Node->getStep() != nullptr) {2569 if (Node->getModifierLoc().isValid()) {2570 OS << ", ";2571 }2572 OS << "step(";2573 Node->getStep()->printPretty(OS, nullptr, Policy, 0);2574 OS << ")";2575 }2576 OS << ")";2577 }2578}2579 2580void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {2581 if (!Node->varlist_empty()) {2582 OS << "aligned";2583 VisitOMPClauseList(Node, '(');2584 if (Node->getAlignment() != nullptr) {2585 OS << ": ";2586 Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);2587 }2588 OS << ")";2589 }2590}2591 2592void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {2593 if (!Node->varlist_empty()) {2594 OS << "copyin";2595 VisitOMPClauseList(Node, '(');2596 OS << ")";2597 }2598}2599 2600void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {2601 if (!Node->varlist_empty()) {2602 OS << "copyprivate";2603 VisitOMPClauseList(Node, '(');2604 OS << ")";2605 }2606}2607 2608void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {2609 if (!Node->varlist_empty()) {2610 VisitOMPClauseList(Node, '(');2611 OS << ")";2612 }2613}2614 2615void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {2616 OS << "(";2617 Node->getDepobj()->printPretty(OS, nullptr, Policy, 0);2618 OS << ")";2619}2620 2621void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {2622 OS << "depend(";2623 if (Expr *DepModifier = Node->getModifier()) {2624 DepModifier->printPretty(OS, nullptr, Policy);2625 OS << ", ";2626 }2627 OpenMPDependClauseKind DepKind = Node->getDependencyKind();2628 OpenMPDependClauseKind PrintKind = DepKind;2629 bool IsOmpAllMemory = false;2630 if (PrintKind == OMPC_DEPEND_outallmemory) {2631 PrintKind = OMPC_DEPEND_out;2632 IsOmpAllMemory = true;2633 } else if (PrintKind == OMPC_DEPEND_inoutallmemory) {2634 PrintKind = OMPC_DEPEND_inout;2635 IsOmpAllMemory = true;2636 }2637 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), PrintKind);2638 if (!Node->varlist_empty() || IsOmpAllMemory)2639 OS << " :";2640 VisitOMPClauseList(Node, ' ');2641 if (IsOmpAllMemory) {2642 OS << (Node->varlist_empty() ? " " : ",");2643 OS << "omp_all_memory";2644 }2645 OS << ")";2646}2647 2648template <typename T>2649static void PrintMapper(raw_ostream &OS, T *Node,2650 const PrintingPolicy &Policy) {2651 OS << '(';2652 NestedNameSpecifier MapperNNS =2653 Node->getMapperQualifierLoc().getNestedNameSpecifier();2654 MapperNNS.print(OS, Policy);2655 OS << Node->getMapperIdInfo() << ')';2656}2657 2658template <typename T>2659static void PrintIterator(raw_ostream &OS, T *Node,2660 const PrintingPolicy &Policy) {2661 if (Expr *IteratorModifier = Node->getIteratorModifier())2662 IteratorModifier->printPretty(OS, nullptr, Policy);2663}2664 2665void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {2666 if (!Node->varlist_empty()) {2667 OS << "map(";2668 if (Node->getMapType() != OMPC_MAP_unknown) {2669 for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {2670 if (Node->getMapTypeModifier(I) != OMPC_MAP_MODIFIER_unknown) {2671 if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_iterator) {2672 PrintIterator(OS, Node, Policy);2673 } else {2674 OS << getOpenMPSimpleClauseTypeName(OMPC_map,2675 Node->getMapTypeModifier(I));2676 if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_mapper)2677 PrintMapper(OS, Node, Policy);2678 }2679 OS << ',';2680 }2681 }2682 OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType());2683 OS << ':';2684 }2685 VisitOMPClauseList(Node, ' ');2686 OS << ")";2687 }2688}2689 2690template <typename T> void OMPClausePrinter::VisitOMPMotionClause(T *Node) {2691 if (Node->varlist_empty())2692 return;2693 OS << getOpenMPClauseName(Node->getClauseKind());2694 unsigned ModifierCount = 0;2695 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {2696 if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown)2697 ++ModifierCount;2698 }2699 if (ModifierCount) {2700 OS << '(';2701 for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {2702 if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown) {2703 if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_iterator) {2704 PrintIterator(OS, Node, Policy);2705 } else {2706 OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),2707 Node->getMotionModifier(I));2708 if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_mapper)2709 PrintMapper(OS, Node, Policy);2710 if (I < ModifierCount - 1)2711 OS << ", ";2712 }2713 }2714 }2715 OS << ':';2716 VisitOMPClauseList(Node, ' ');2717 } else {2718 VisitOMPClauseList(Node, '(');2719 }2720 OS << ")";2721}2722 2723void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {2724 VisitOMPMotionClause(Node);2725}2726 2727void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {2728 VisitOMPMotionClause(Node);2729}2730 2731void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {2732 OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(2733 OMPC_dist_schedule, Node->getDistScheduleKind());2734 if (auto *E = Node->getChunkSize()) {2735 OS << ", ";2736 E->printPretty(OS, nullptr, Policy);2737 }2738 OS << ")";2739}2740 2741void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {2742 OS << "defaultmap(";2743 OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,2744 Node->getDefaultmapModifier());2745 if (Node->getDefaultmapKind() != OMPC_DEFAULTMAP_unknown) {2746 OS << ": ";2747 OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,2748 Node->getDefaultmapKind());2749 }2750 OS << ")";2751}2752 2753void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {2754 if (!Node->varlist_empty()) {2755 OS << "use_device_ptr";2756 VisitOMPClauseList(Node, '(');2757 OS << ")";2758 }2759}2760 2761void OMPClausePrinter::VisitOMPUseDeviceAddrClause(2762 OMPUseDeviceAddrClause *Node) {2763 if (!Node->varlist_empty()) {2764 OS << "use_device_addr";2765 VisitOMPClauseList(Node, '(');2766 OS << ")";2767 }2768}2769 2770void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {2771 if (!Node->varlist_empty()) {2772 OS << "is_device_ptr";2773 VisitOMPClauseList(Node, '(');2774 OS << ")";2775 }2776}2777 2778void OMPClausePrinter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *Node) {2779 if (!Node->varlist_empty()) {2780 OS << "has_device_addr";2781 VisitOMPClauseList(Node, '(');2782 OS << ")";2783 }2784}2785 2786void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {2787 if (!Node->varlist_empty()) {2788 OS << "nontemporal";2789 VisitOMPClauseList(Node, '(');2790 OS << ")";2791 }2792}2793 2794void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {2795 OS << "order(";2796 if (Node->getModifier() != OMPC_ORDER_MODIFIER_unknown) {2797 OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getModifier());2798 OS << ": ";2799 }2800 OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getKind()) << ")";2801}2802 2803void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {2804 if (!Node->varlist_empty()) {2805 OS << "inclusive";2806 VisitOMPClauseList(Node, '(');2807 OS << ")";2808 }2809}2810 2811void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {2812 if (!Node->varlist_empty()) {2813 OS << "exclusive";2814 VisitOMPClauseList(Node, '(');2815 OS << ")";2816 }2817}2818 2819void OMPClausePrinter::VisitOMPUsesAllocatorsClause(2820 OMPUsesAllocatorsClause *Node) {2821 if (Node->getNumberOfAllocators() == 0)2822 return;2823 OS << "uses_allocators(";2824 for (unsigned I = 0, E = Node->getNumberOfAllocators(); I < E; ++I) {2825 OMPUsesAllocatorsClause::Data Data = Node->getAllocatorData(I);2826 Data.Allocator->printPretty(OS, nullptr, Policy);2827 if (Data.AllocatorTraits) {2828 OS << "(";2829 Data.AllocatorTraits->printPretty(OS, nullptr, Policy);2830 OS << ")";2831 }2832 if (I < E - 1)2833 OS << ",";2834 }2835 OS << ")";2836}2837 2838void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {2839 if (Node->varlist_empty())2840 return;2841 OS << "affinity";2842 char StartSym = '(';2843 if (Expr *Modifier = Node->getModifier()) {2844 OS << "(";2845 Modifier->printPretty(OS, nullptr, Policy);2846 OS << " :";2847 StartSym = ' ';2848 }2849 VisitOMPClauseList(Node, StartSym);2850 OS << ")";2851}2852 2853void OMPClausePrinter::VisitOMPFilterClause(OMPFilterClause *Node) {2854 OS << "filter(";2855 Node->getThreadID()->printPretty(OS, nullptr, Policy, 0);2856 OS << ")";2857}2858 2859void OMPClausePrinter::VisitOMPBindClause(OMPBindClause *Node) {2860 OS << "bind("2861 << getOpenMPSimpleClauseTypeName(OMPC_bind, unsigned(Node->getBindKind()))2862 << ")";2863}2864 2865void OMPClausePrinter::VisitOMPXDynCGroupMemClause(2866 OMPXDynCGroupMemClause *Node) {2867 OS << "ompx_dyn_cgroup_mem(";2868 Node->getSize()->printPretty(OS, nullptr, Policy, 0);2869 OS << ")";2870}2871 2872void OMPClausePrinter::VisitOMPDynGroupprivateClause(2873 OMPDynGroupprivateClause *Node) {2874 OS << "dyn_groupprivate(";2875 if (Node->getDynGroupprivateModifier() != OMPC_DYN_GROUPPRIVATE_unknown) {2876 OS << getOpenMPSimpleClauseTypeName(OMPC_dyn_groupprivate,2877 Node->getDynGroupprivateModifier());2878 if (Node->getDynGroupprivateFallbackModifier() !=2879 OMPC_DYN_GROUPPRIVATE_FALLBACK_unknown) {2880 OS << ", ";2881 OS << getOpenMPSimpleClauseTypeName(2882 OMPC_dyn_groupprivate, Node->getDynGroupprivateFallbackModifier());2883 }2884 OS << ": ";2885 }2886 Node->getSize()->printPretty(OS, nullptr, Policy, 0);2887 OS << ')';2888}2889 2890void OMPClausePrinter::VisitOMPDoacrossClause(OMPDoacrossClause *Node) {2891 OS << "doacross(";2892 OpenMPDoacrossClauseModifier DepType = Node->getDependenceType();2893 2894 switch (DepType) {2895 case OMPC_DOACROSS_source:2896 OS << "source:";2897 break;2898 case OMPC_DOACROSS_sink:2899 OS << "sink:";2900 break;2901 case OMPC_DOACROSS_source_omp_cur_iteration:2902 OS << "source: omp_cur_iteration";2903 break;2904 case OMPC_DOACROSS_sink_omp_cur_iteration:2905 OS << "sink: omp_cur_iteration - 1";2906 break;2907 default:2908 llvm_unreachable("unknown docaross modifier");2909 }2910 VisitOMPClauseList(Node, ' ');2911 OS << ")";2912}2913 2914void OMPClausePrinter::VisitOMPXAttributeClause(OMPXAttributeClause *Node) {2915 OS << "ompx_attribute(";2916 bool IsFirst = true;2917 for (auto &Attr : Node->getAttrs()) {2918 if (!IsFirst)2919 OS << ", ";2920 Attr->printPretty(OS, Policy);2921 IsFirst = false;2922 }2923 OS << ")";2924}2925 2926void OMPClausePrinter::VisitOMPXBareClause(OMPXBareClause *Node) {2927 OS << "ompx_bare";2928}2929 2930void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,2931 VariantMatchInfo &VMI) const {2932 for (const OMPTraitSet &Set : Sets) {2933 for (const OMPTraitSelector &Selector : Set.Selectors) {2934 2935 // User conditions are special as we evaluate the condition here.2936 if (Selector.Kind == TraitSelector::user_condition) {2937 assert(Selector.ScoreOrCondition &&2938 "Ill-formed user condition, expected condition expression!");2939 assert(Selector.Properties.size() == 1 &&2940 Selector.Properties.front().Kind ==2941 TraitProperty::user_condition_unknown &&2942 "Ill-formed user condition, expected unknown trait property!");2943 2944 if (std::optional<APSInt> CondVal =2945 Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx))2946 VMI.addTrait(CondVal->isZero() ? TraitProperty::user_condition_false2947 : TraitProperty::user_condition_true,2948 "<condition>");2949 else2950 VMI.addTrait(TraitProperty::user_condition_false, "<condition>");2951 continue;2952 }2953 2954 std::optional<llvm::APSInt> Score;2955 llvm::APInt *ScorePtr = nullptr;2956 if (Selector.ScoreOrCondition) {2957 if ((Score = Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx)))2958 ScorePtr = &*Score;2959 else2960 VMI.addTrait(TraitProperty::user_condition_false,2961 "<non-constant-score>");2962 }2963 2964 for (const OMPTraitProperty &Property : Selector.Properties)2965 VMI.addTrait(Set.Kind, Property.Kind, Property.RawString, ScorePtr);2966 2967 if (Set.Kind != TraitSet::construct)2968 continue;2969 2970 // TODO: This might not hold once we implement SIMD properly.2971 assert(Selector.Properties.size() == 1 &&2972 Selector.Properties.front().Kind ==2973 getOpenMPContextTraitPropertyForSelector(2974 Selector.Kind) &&2975 "Ill-formed construct selector!");2976 }2977 }2978}2979 2980void OMPTraitInfo::print(llvm::raw_ostream &OS,2981 const PrintingPolicy &Policy) const {2982 bool FirstSet = true;2983 for (const OMPTraitSet &Set : Sets) {2984 if (!FirstSet)2985 OS << ", ";2986 FirstSet = false;2987 OS << getOpenMPContextTraitSetName(Set.Kind) << "={";2988 2989 bool FirstSelector = true;2990 for (const OMPTraitSelector &Selector : Set.Selectors) {2991 if (!FirstSelector)2992 OS << ", ";2993 FirstSelector = false;2994 OS << getOpenMPContextTraitSelectorName(Selector.Kind);2995 2996 bool AllowsTraitScore = false;2997 bool RequiresProperty = false;2998 isValidTraitSelectorForTraitSet(2999 Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);3000 3001 if (!RequiresProperty)3002 continue;3003 3004 OS << "(";3005 if (Selector.Kind == TraitSelector::user_condition) {3006 if (Selector.ScoreOrCondition)3007 Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);3008 else3009 OS << "...";3010 } else {3011 3012 if (Selector.ScoreOrCondition) {3013 OS << "score(";3014 Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);3015 OS << "): ";3016 }3017 3018 bool FirstProperty = true;3019 for (const OMPTraitProperty &Property : Selector.Properties) {3020 if (!FirstProperty)3021 OS << ", ";3022 FirstProperty = false;3023 OS << getOpenMPContextTraitPropertyName(Property.Kind,3024 Property.RawString);3025 }3026 }3027 OS << ")";3028 }3029 OS << "}";3030 }3031}3032 3033std::string OMPTraitInfo::getMangledName() const {3034 std::string MangledName;3035 llvm::raw_string_ostream OS(MangledName);3036 for (const OMPTraitSet &Set : Sets) {3037 OS << '$' << 'S' << unsigned(Set.Kind);3038 for (const OMPTraitSelector &Selector : Set.Selectors) {3039 3040 bool AllowsTraitScore = false;3041 bool RequiresProperty = false;3042 isValidTraitSelectorForTraitSet(3043 Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);3044 OS << '$' << 's' << unsigned(Selector.Kind);3045 3046 if (!RequiresProperty ||3047 Selector.Kind == TraitSelector::user_condition)3048 continue;3049 3050 for (const OMPTraitProperty &Property : Selector.Properties)3051 OS << '$' << 'P'3052 << getOpenMPContextTraitPropertyName(Property.Kind,3053 Property.RawString);3054 }3055 }3056 return MangledName;3057}3058 3059OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {3060 unsigned long U;3061 do {3062 if (!MangledName.consume_front("$S"))3063 break;3064 if (MangledName.consumeInteger(10, U))3065 break;3066 Sets.push_back(OMPTraitSet());3067 OMPTraitSet &Set = Sets.back();3068 Set.Kind = TraitSet(U);3069 do {3070 if (!MangledName.consume_front("$s"))3071 break;3072 if (MangledName.consumeInteger(10, U))3073 break;3074 Set.Selectors.push_back(OMPTraitSelector());3075 OMPTraitSelector &Selector = Set.Selectors.back();3076 Selector.Kind = TraitSelector(U);3077 do {3078 if (!MangledName.consume_front("$P"))3079 break;3080 Selector.Properties.push_back(OMPTraitProperty());3081 OMPTraitProperty &Property = Selector.Properties.back();3082 std::pair<StringRef, StringRef> PropRestPair = MangledName.split('$');3083 Property.RawString = PropRestPair.first;3084 Property.Kind = getOpenMPContextTraitPropertyKind(3085 Set.Kind, Selector.Kind, PropRestPair.first);3086 MangledName = MangledName.drop_front(PropRestPair.first.size());3087 } while (true);3088 } while (true);3089 } while (true);3090}3091 3092llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,3093 const OMPTraitInfo &TI) {3094 LangOptions LO;3095 PrintingPolicy Policy(LO);3096 TI.print(OS, Policy);3097 return OS;3098}3099llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,3100 const OMPTraitInfo *TI) {3101 return TI ? OS << *TI : OS;3102}3103 3104TargetOMPContext::TargetOMPContext(3105 ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,3106 const FunctionDecl *CurrentFunctionDecl,3107 ArrayRef<llvm::omp::TraitProperty> ConstructTraits, int DeviceNum)3108 : OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice,3109 ASTCtx.getTargetInfo().getTriple(),3110 ASTCtx.getLangOpts().OMPTargetTriples.empty()3111 ? llvm::Triple()3112 : ASTCtx.getLangOpts().OMPTargetTriples[0],3113 DeviceNum),3114 FeatureValidityCheck([&](StringRef FeatureName) {3115 return ASTCtx.getTargetInfo().isValidFeatureName(FeatureName);3116 }),3117 DiagUnknownTrait(std::move(DiagUnknownTrait)) {3118 ASTCtx.getFunctionFeatureMap(FeatureMap, CurrentFunctionDecl);3119 3120 for (llvm::omp::TraitProperty Property : ConstructTraits)3121 addTrait(Property);3122}3123 3124bool TargetOMPContext::matchesISATrait(StringRef RawString) const {3125 auto It = FeatureMap.find(RawString);3126 if (It != FeatureMap.end())3127 return It->second;3128 if (!FeatureValidityCheck(RawString))3129 DiagUnknownTrait(RawString);3130 return false;3131}3132