1//===-- MPIFunctionClassifier.cpp - classifies MPI functions ----*- C++ -*-===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines functionality to identify and classify MPI functions.
11///
12//===----------------------------------------------------------------------===//
13
14#include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h"
15#include "llvm/ADT/STLExtras.h"
16
17namespace clang {
18namespace ento {
19namespace mpi {
20
21void MPIFunctionClassifier::identifierInit(ASTContext &ASTCtx) {
22 // Initialize function identifiers.
23 initPointToPointIdentifiers(ASTCtx);
24 initCollectiveIdentifiers(ASTCtx);
25 initAdditionalIdentifiers(ASTCtx);
26}
27
28void MPIFunctionClassifier::initPointToPointIdentifiers(ASTContext &ASTCtx) {
29 // Copy identifiers into the correct classification containers.
30 IdentInfo_MPI_Send = &ASTCtx.Idents.get(Name: "MPI_Send");
31 MPIPointToPointTypes.push_back(Elt: IdentInfo_MPI_Send);
32 MPIType.push_back(Elt: IdentInfo_MPI_Send);
33 assert(IdentInfo_MPI_Send);
34
35 IdentInfo_MPI_Isend = &ASTCtx.Idents.get(Name: "MPI_Isend");
36 MPIPointToPointTypes.push_back(Elt: IdentInfo_MPI_Isend);
37 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Isend);
38 MPIType.push_back(Elt: IdentInfo_MPI_Isend);
39 assert(IdentInfo_MPI_Isend);
40
41 IdentInfo_MPI_Ssend = &ASTCtx.Idents.get(Name: "MPI_Ssend");
42 MPIPointToPointTypes.push_back(Elt: IdentInfo_MPI_Ssend);
43 MPIType.push_back(Elt: IdentInfo_MPI_Ssend);
44 assert(IdentInfo_MPI_Ssend);
45
46 IdentInfo_MPI_Issend = &ASTCtx.Idents.get(Name: "MPI_Issend");
47 MPIPointToPointTypes.push_back(Elt: IdentInfo_MPI_Issend);
48 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Issend);
49 MPIType.push_back(Elt: IdentInfo_MPI_Issend);
50 assert(IdentInfo_MPI_Issend);
51
52 IdentInfo_MPI_Bsend = &ASTCtx.Idents.get(Name: "MPI_Bsend");
53 MPIPointToPointTypes.push_back(Elt: IdentInfo_MPI_Bsend);
54 MPIType.push_back(Elt: IdentInfo_MPI_Bsend);
55 assert(IdentInfo_MPI_Bsend);
56
57 IdentInfo_MPI_Ibsend = &ASTCtx.Idents.get(Name: "MPI_Ibsend");
58 MPIPointToPointTypes.push_back(Elt: IdentInfo_MPI_Ibsend);
59 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Ibsend);
60 MPIType.push_back(Elt: IdentInfo_MPI_Ibsend);
61 assert(IdentInfo_MPI_Ibsend);
62
63 IdentInfo_MPI_Rsend = &ASTCtx.Idents.get(Name: "MPI_Rsend");
64 MPIPointToPointTypes.push_back(Elt: IdentInfo_MPI_Rsend);
65 MPIType.push_back(Elt: IdentInfo_MPI_Rsend);
66 assert(IdentInfo_MPI_Rsend);
67
68 IdentInfo_MPI_Irsend = &ASTCtx.Idents.get(Name: "MPI_Irsend");
69 MPIPointToPointTypes.push_back(Elt: IdentInfo_MPI_Irsend);
70 MPIType.push_back(Elt: IdentInfo_MPI_Irsend);
71 assert(IdentInfo_MPI_Irsend);
72
73 IdentInfo_MPI_Recv = &ASTCtx.Idents.get(Name: "MPI_Recv");
74 MPIPointToPointTypes.push_back(Elt: IdentInfo_MPI_Recv);
75 MPIType.push_back(Elt: IdentInfo_MPI_Recv);
76 assert(IdentInfo_MPI_Recv);
77
78 IdentInfo_MPI_Irecv = &ASTCtx.Idents.get(Name: "MPI_Irecv");
79 MPIPointToPointTypes.push_back(Elt: IdentInfo_MPI_Irecv);
80 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Irecv);
81 MPIType.push_back(Elt: IdentInfo_MPI_Irecv);
82 assert(IdentInfo_MPI_Irecv);
83}
84
85void MPIFunctionClassifier::initCollectiveIdentifiers(ASTContext &ASTCtx) {
86 // Copy identifiers into the correct classification containers.
87 IdentInfo_MPI_Scatter = &ASTCtx.Idents.get(Name: "MPI_Scatter");
88 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Scatter);
89 MPIPointToCollTypes.push_back(Elt: IdentInfo_MPI_Scatter);
90 MPIType.push_back(Elt: IdentInfo_MPI_Scatter);
91 assert(IdentInfo_MPI_Scatter);
92
93 IdentInfo_MPI_Iscatter = &ASTCtx.Idents.get(Name: "MPI_Iscatter");
94 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Iscatter);
95 MPIPointToCollTypes.push_back(Elt: IdentInfo_MPI_Iscatter);
96 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Iscatter);
97 MPIType.push_back(Elt: IdentInfo_MPI_Iscatter);
98 assert(IdentInfo_MPI_Iscatter);
99
100 IdentInfo_MPI_Gather = &ASTCtx.Idents.get(Name: "MPI_Gather");
101 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Gather);
102 MPICollToPointTypes.push_back(Elt: IdentInfo_MPI_Gather);
103 MPIType.push_back(Elt: IdentInfo_MPI_Gather);
104 assert(IdentInfo_MPI_Gather);
105
106 IdentInfo_MPI_Igather = &ASTCtx.Idents.get(Name: "MPI_Igather");
107 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Igather);
108 MPICollToPointTypes.push_back(Elt: IdentInfo_MPI_Igather);
109 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Igather);
110 MPIType.push_back(Elt: IdentInfo_MPI_Igather);
111 assert(IdentInfo_MPI_Igather);
112
113 IdentInfo_MPI_Allgather = &ASTCtx.Idents.get(Name: "MPI_Allgather");
114 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Allgather);
115 MPICollToCollTypes.push_back(Elt: IdentInfo_MPI_Allgather);
116 MPIType.push_back(Elt: IdentInfo_MPI_Allgather);
117 assert(IdentInfo_MPI_Allgather);
118
119 IdentInfo_MPI_Iallgather = &ASTCtx.Idents.get(Name: "MPI_Iallgather");
120 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Iallgather);
121 MPICollToCollTypes.push_back(Elt: IdentInfo_MPI_Iallgather);
122 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Iallgather);
123 MPIType.push_back(Elt: IdentInfo_MPI_Iallgather);
124 assert(IdentInfo_MPI_Iallgather);
125
126 IdentInfo_MPI_Bcast = &ASTCtx.Idents.get(Name: "MPI_Bcast");
127 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Bcast);
128 MPIPointToCollTypes.push_back(Elt: IdentInfo_MPI_Bcast);
129 MPIType.push_back(Elt: IdentInfo_MPI_Bcast);
130 assert(IdentInfo_MPI_Bcast);
131
132 IdentInfo_MPI_Ibcast = &ASTCtx.Idents.get(Name: "MPI_Ibcast");
133 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Ibcast);
134 MPIPointToCollTypes.push_back(Elt: IdentInfo_MPI_Ibcast);
135 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Ibcast);
136 MPIType.push_back(Elt: IdentInfo_MPI_Ibcast);
137 assert(IdentInfo_MPI_Ibcast);
138
139 IdentInfo_MPI_Reduce = &ASTCtx.Idents.get(Name: "MPI_Reduce");
140 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Reduce);
141 MPICollToPointTypes.push_back(Elt: IdentInfo_MPI_Reduce);
142 MPIType.push_back(Elt: IdentInfo_MPI_Reduce);
143 assert(IdentInfo_MPI_Reduce);
144
145 IdentInfo_MPI_Ireduce = &ASTCtx.Idents.get(Name: "MPI_Ireduce");
146 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Ireduce);
147 MPICollToPointTypes.push_back(Elt: IdentInfo_MPI_Ireduce);
148 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Ireduce);
149 MPIType.push_back(Elt: IdentInfo_MPI_Ireduce);
150 assert(IdentInfo_MPI_Ireduce);
151
152 IdentInfo_MPI_Allreduce = &ASTCtx.Idents.get(Name: "MPI_Allreduce");
153 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Allreduce);
154 MPICollToCollTypes.push_back(Elt: IdentInfo_MPI_Allreduce);
155 MPIType.push_back(Elt: IdentInfo_MPI_Allreduce);
156 assert(IdentInfo_MPI_Allreduce);
157
158 IdentInfo_MPI_Iallreduce = &ASTCtx.Idents.get(Name: "MPI_Iallreduce");
159 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Iallreduce);
160 MPICollToCollTypes.push_back(Elt: IdentInfo_MPI_Iallreduce);
161 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Iallreduce);
162 MPIType.push_back(Elt: IdentInfo_MPI_Iallreduce);
163 assert(IdentInfo_MPI_Iallreduce);
164
165 IdentInfo_MPI_Alltoall = &ASTCtx.Idents.get(Name: "MPI_Alltoall");
166 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Alltoall);
167 MPICollToCollTypes.push_back(Elt: IdentInfo_MPI_Alltoall);
168 MPIType.push_back(Elt: IdentInfo_MPI_Alltoall);
169 assert(IdentInfo_MPI_Alltoall);
170
171 IdentInfo_MPI_Ialltoall = &ASTCtx.Idents.get(Name: "MPI_Ialltoall");
172 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Ialltoall);
173 MPICollToCollTypes.push_back(Elt: IdentInfo_MPI_Ialltoall);
174 MPINonBlockingTypes.push_back(Elt: IdentInfo_MPI_Ialltoall);
175 MPIType.push_back(Elt: IdentInfo_MPI_Ialltoall);
176 assert(IdentInfo_MPI_Ialltoall);
177}
178
179void MPIFunctionClassifier::initAdditionalIdentifiers(ASTContext &ASTCtx) {
180 IdentInfo_MPI_Comm_rank = &ASTCtx.Idents.get(Name: "MPI_Comm_rank");
181 MPIType.push_back(Elt: IdentInfo_MPI_Comm_rank);
182 assert(IdentInfo_MPI_Comm_rank);
183
184 IdentInfo_MPI_Comm_size = &ASTCtx.Idents.get(Name: "MPI_Comm_size");
185 MPIType.push_back(Elt: IdentInfo_MPI_Comm_size);
186 assert(IdentInfo_MPI_Comm_size);
187
188 IdentInfo_MPI_Wait = &ASTCtx.Idents.get(Name: "MPI_Wait");
189 MPIType.push_back(Elt: IdentInfo_MPI_Wait);
190 assert(IdentInfo_MPI_Wait);
191
192 IdentInfo_MPI_Waitall = &ASTCtx.Idents.get(Name: "MPI_Waitall");
193 MPIType.push_back(Elt: IdentInfo_MPI_Waitall);
194 assert(IdentInfo_MPI_Waitall);
195
196 IdentInfo_MPI_Barrier = &ASTCtx.Idents.get(Name: "MPI_Barrier");
197 MPICollectiveTypes.push_back(Elt: IdentInfo_MPI_Barrier);
198 MPIType.push_back(Elt: IdentInfo_MPI_Barrier);
199 assert(IdentInfo_MPI_Barrier);
200}
201
202// general identifiers
203bool MPIFunctionClassifier::isMPIType(const IdentifierInfo *IdentInfo) const {
204 return llvm::is_contained(Range: MPIType, Element: IdentInfo);
205}
206
207bool MPIFunctionClassifier::isNonBlockingType(
208 const IdentifierInfo *IdentInfo) const {
209 return llvm::is_contained(Range: MPINonBlockingTypes, Element: IdentInfo);
210}
211
212// point-to-point identifiers
213bool MPIFunctionClassifier::isPointToPointType(
214 const IdentifierInfo *IdentInfo) const {
215 return llvm::is_contained(Range: MPIPointToPointTypes, Element: IdentInfo);
216}
217
218// collective identifiers
219bool MPIFunctionClassifier::isCollectiveType(
220 const IdentifierInfo *IdentInfo) const {
221 return llvm::is_contained(Range: MPICollectiveTypes, Element: IdentInfo);
222}
223
224bool MPIFunctionClassifier::isCollToColl(
225 const IdentifierInfo *IdentInfo) const {
226 return llvm::is_contained(Range: MPICollToCollTypes, Element: IdentInfo);
227}
228
229bool MPIFunctionClassifier::isScatterType(
230 const IdentifierInfo *IdentInfo) const {
231 return IdentInfo == IdentInfo_MPI_Scatter ||
232 IdentInfo == IdentInfo_MPI_Iscatter;
233}
234
235bool MPIFunctionClassifier::isGatherType(
236 const IdentifierInfo *IdentInfo) const {
237 return IdentInfo == IdentInfo_MPI_Gather ||
238 IdentInfo == IdentInfo_MPI_Igather ||
239 IdentInfo == IdentInfo_MPI_Allgather ||
240 IdentInfo == IdentInfo_MPI_Iallgather;
241}
242
243bool MPIFunctionClassifier::isAllgatherType(
244 const IdentifierInfo *IdentInfo) const {
245 return IdentInfo == IdentInfo_MPI_Allgather ||
246 IdentInfo == IdentInfo_MPI_Iallgather;
247}
248
249bool MPIFunctionClassifier::isAlltoallType(
250 const IdentifierInfo *IdentInfo) const {
251 return IdentInfo == IdentInfo_MPI_Alltoall ||
252 IdentInfo == IdentInfo_MPI_Ialltoall;
253}
254
255bool MPIFunctionClassifier::isBcastType(const IdentifierInfo *IdentInfo) const {
256 return IdentInfo == IdentInfo_MPI_Bcast || IdentInfo == IdentInfo_MPI_Ibcast;
257}
258
259bool MPIFunctionClassifier::isReduceType(
260 const IdentifierInfo *IdentInfo) const {
261 return IdentInfo == IdentInfo_MPI_Reduce ||
262 IdentInfo == IdentInfo_MPI_Ireduce ||
263 IdentInfo == IdentInfo_MPI_Allreduce ||
264 IdentInfo == IdentInfo_MPI_Iallreduce;
265}
266
267// additional identifiers
268bool MPIFunctionClassifier::isMPI_Wait(const IdentifierInfo *IdentInfo) const {
269 return IdentInfo == IdentInfo_MPI_Wait;
270}
271
272bool MPIFunctionClassifier::isMPI_Waitall(
273 const IdentifierInfo *IdentInfo) const {
274 return IdentInfo == IdentInfo_MPI_Waitall;
275}
276
277bool MPIFunctionClassifier::isWaitType(const IdentifierInfo *IdentInfo) const {
278 return IdentInfo == IdentInfo_MPI_Wait || IdentInfo == IdentInfo_MPI_Waitall;
279}
280
281} // end of namespace: mpi
282} // end of namespace: ento
283} // end of namespace: clang
284