xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/StmtOpenACC.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===--- StmtOpenACC.cpp - Classes for OpenACC Constructs -----------------===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric // This file implements the subclasses of Stmt class declared in StmtOpenACC.h
10*0fca6ea1SDimitry Andric //
11*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
12*0fca6ea1SDimitry Andric 
13*0fca6ea1SDimitry Andric #include "clang/AST/StmtOpenACC.h"
14*0fca6ea1SDimitry Andric #include "clang/AST/ASTContext.h"
15*0fca6ea1SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h"
16*0fca6ea1SDimitry Andric #include "clang/AST/StmtCXX.h"
17*0fca6ea1SDimitry Andric using namespace clang;
18*0fca6ea1SDimitry Andric 
19*0fca6ea1SDimitry Andric OpenACCComputeConstruct *
20*0fca6ea1SDimitry Andric OpenACCComputeConstruct::CreateEmpty(const ASTContext &C, unsigned NumClauses) {
21*0fca6ea1SDimitry Andric   void *Mem = C.Allocate(
22*0fca6ea1SDimitry Andric       OpenACCComputeConstruct::totalSizeToAlloc<const OpenACCClause *>(
23*0fca6ea1SDimitry Andric           NumClauses));
24*0fca6ea1SDimitry Andric   auto *Inst = new (Mem) OpenACCComputeConstruct(NumClauses);
25*0fca6ea1SDimitry Andric   return Inst;
26*0fca6ea1SDimitry Andric }
27*0fca6ea1SDimitry Andric 
28*0fca6ea1SDimitry Andric OpenACCComputeConstruct *OpenACCComputeConstruct::Create(
29*0fca6ea1SDimitry Andric     const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc,
30*0fca6ea1SDimitry Andric     SourceLocation DirLoc, SourceLocation EndLoc,
31*0fca6ea1SDimitry Andric     ArrayRef<const OpenACCClause *> Clauses, Stmt *StructuredBlock,
32*0fca6ea1SDimitry Andric     ArrayRef<OpenACCLoopConstruct *> AssociatedLoopConstructs) {
33*0fca6ea1SDimitry Andric   void *Mem = C.Allocate(
34*0fca6ea1SDimitry Andric       OpenACCComputeConstruct::totalSizeToAlloc<const OpenACCClause *>(
35*0fca6ea1SDimitry Andric           Clauses.size()));
36*0fca6ea1SDimitry Andric   auto *Inst = new (Mem) OpenACCComputeConstruct(K, BeginLoc, DirLoc, EndLoc,
37*0fca6ea1SDimitry Andric                                                  Clauses, StructuredBlock);
38*0fca6ea1SDimitry Andric 
39*0fca6ea1SDimitry Andric   llvm::for_each(AssociatedLoopConstructs, [&](OpenACCLoopConstruct *C) {
40*0fca6ea1SDimitry Andric     C->setParentComputeConstruct(Inst);
41*0fca6ea1SDimitry Andric   });
42*0fca6ea1SDimitry Andric 
43*0fca6ea1SDimitry Andric   return Inst;
44*0fca6ea1SDimitry Andric }
45*0fca6ea1SDimitry Andric 
46*0fca6ea1SDimitry Andric void OpenACCComputeConstruct::findAndSetChildLoops() {
47*0fca6ea1SDimitry Andric   struct LoopConstructFinder : RecursiveASTVisitor<LoopConstructFinder> {
48*0fca6ea1SDimitry Andric     OpenACCComputeConstruct *Construct = nullptr;
49*0fca6ea1SDimitry Andric 
50*0fca6ea1SDimitry Andric     LoopConstructFinder(OpenACCComputeConstruct *Construct)
51*0fca6ea1SDimitry Andric         : Construct(Construct) {}
52*0fca6ea1SDimitry Andric 
53*0fca6ea1SDimitry Andric     bool TraverseOpenACCComputeConstruct(OpenACCComputeConstruct *C) {
54*0fca6ea1SDimitry Andric       // Stop searching if we find a compute construct.
55*0fca6ea1SDimitry Andric       return true;
56*0fca6ea1SDimitry Andric     }
57*0fca6ea1SDimitry Andric     bool TraverseOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
58*0fca6ea1SDimitry Andric       // Stop searching if we find a loop construct, after taking ownership of
59*0fca6ea1SDimitry Andric       // it.
60*0fca6ea1SDimitry Andric       C->setParentComputeConstruct(Construct);
61*0fca6ea1SDimitry Andric       return true;
62*0fca6ea1SDimitry Andric     }
63*0fca6ea1SDimitry Andric   };
64*0fca6ea1SDimitry Andric 
65*0fca6ea1SDimitry Andric   LoopConstructFinder f(this);
66*0fca6ea1SDimitry Andric   f.TraverseStmt(getAssociatedStmt());
67*0fca6ea1SDimitry Andric }
68*0fca6ea1SDimitry Andric 
69*0fca6ea1SDimitry Andric OpenACCLoopConstruct::OpenACCLoopConstruct(unsigned NumClauses)
70*0fca6ea1SDimitry Andric     : OpenACCAssociatedStmtConstruct(
71*0fca6ea1SDimitry Andric           OpenACCLoopConstructClass, OpenACCDirectiveKind::Loop,
72*0fca6ea1SDimitry Andric           SourceLocation{}, SourceLocation{}, SourceLocation{},
73*0fca6ea1SDimitry Andric           /*AssociatedStmt=*/nullptr) {
74*0fca6ea1SDimitry Andric   std::uninitialized_value_construct(
75*0fca6ea1SDimitry Andric       getTrailingObjects<const OpenACCClause *>(),
76*0fca6ea1SDimitry Andric       getTrailingObjects<const OpenACCClause *>() + NumClauses);
77*0fca6ea1SDimitry Andric   setClauseList(
78*0fca6ea1SDimitry Andric       MutableArrayRef(getTrailingObjects<const OpenACCClause *>(), NumClauses));
79*0fca6ea1SDimitry Andric }
80*0fca6ea1SDimitry Andric 
81*0fca6ea1SDimitry Andric OpenACCLoopConstruct::OpenACCLoopConstruct(
82*0fca6ea1SDimitry Andric     SourceLocation Start, SourceLocation DirLoc, SourceLocation End,
83*0fca6ea1SDimitry Andric     ArrayRef<const OpenACCClause *> Clauses, Stmt *Loop)
84*0fca6ea1SDimitry Andric     : OpenACCAssociatedStmtConstruct(OpenACCLoopConstructClass,
85*0fca6ea1SDimitry Andric                                      OpenACCDirectiveKind::Loop, Start, DirLoc,
86*0fca6ea1SDimitry Andric                                      End, Loop) {
87*0fca6ea1SDimitry Andric   // accept 'nullptr' for the loop. This is diagnosed somewhere, but this gives
88*0fca6ea1SDimitry Andric   // us some level of AST fidelity in the error case.
89*0fca6ea1SDimitry Andric   assert((Loop == nullptr || isa<ForStmt, CXXForRangeStmt>(Loop)) &&
90*0fca6ea1SDimitry Andric          "Associated Loop not a for loop?");
91*0fca6ea1SDimitry Andric   // Initialize the trailing storage.
92*0fca6ea1SDimitry Andric   std::uninitialized_copy(Clauses.begin(), Clauses.end(),
93*0fca6ea1SDimitry Andric                           getTrailingObjects<const OpenACCClause *>());
94*0fca6ea1SDimitry Andric 
95*0fca6ea1SDimitry Andric   setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
96*0fca6ea1SDimitry Andric                                 Clauses.size()));
97*0fca6ea1SDimitry Andric }
98*0fca6ea1SDimitry Andric 
99*0fca6ea1SDimitry Andric void OpenACCLoopConstruct::setLoop(Stmt *Loop) {
100*0fca6ea1SDimitry Andric   assert((isa<ForStmt, CXXForRangeStmt>(Loop)) &&
101*0fca6ea1SDimitry Andric          "Associated Loop not a for loop?");
102*0fca6ea1SDimitry Andric   setAssociatedStmt(Loop);
103*0fca6ea1SDimitry Andric }
104*0fca6ea1SDimitry Andric 
105*0fca6ea1SDimitry Andric OpenACCLoopConstruct *OpenACCLoopConstruct::CreateEmpty(const ASTContext &C,
106*0fca6ea1SDimitry Andric                                                         unsigned NumClauses) {
107*0fca6ea1SDimitry Andric   void *Mem =
108*0fca6ea1SDimitry Andric       C.Allocate(OpenACCLoopConstruct::totalSizeToAlloc<const OpenACCClause *>(
109*0fca6ea1SDimitry Andric           NumClauses));
110*0fca6ea1SDimitry Andric   auto *Inst = new (Mem) OpenACCLoopConstruct(NumClauses);
111*0fca6ea1SDimitry Andric   return Inst;
112*0fca6ea1SDimitry Andric }
113*0fca6ea1SDimitry Andric 
114*0fca6ea1SDimitry Andric OpenACCLoopConstruct *
115*0fca6ea1SDimitry Andric OpenACCLoopConstruct::Create(const ASTContext &C, SourceLocation BeginLoc,
116*0fca6ea1SDimitry Andric                              SourceLocation DirLoc, SourceLocation EndLoc,
117*0fca6ea1SDimitry Andric                              ArrayRef<const OpenACCClause *> Clauses,
118*0fca6ea1SDimitry Andric                              Stmt *Loop) {
119*0fca6ea1SDimitry Andric   void *Mem =
120*0fca6ea1SDimitry Andric       C.Allocate(OpenACCLoopConstruct::totalSizeToAlloc<const OpenACCClause *>(
121*0fca6ea1SDimitry Andric           Clauses.size()));
122*0fca6ea1SDimitry Andric   auto *Inst =
123*0fca6ea1SDimitry Andric       new (Mem) OpenACCLoopConstruct(BeginLoc, DirLoc, EndLoc, Clauses, Loop);
124*0fca6ea1SDimitry Andric   return Inst;
125*0fca6ea1SDimitry Andric }
126