1303233Sdim//===-- MPIFunctionClassifier.cpp - classifies MPI functions ----*- C++ -*-===//
2303233Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6303233Sdim//
7303233Sdim//===----------------------------------------------------------------------===//
8303233Sdim///
9303233Sdim/// \file
10303233Sdim/// This file defines functionality to identify and classify MPI functions.
11303233Sdim///
12303233Sdim//===----------------------------------------------------------------------===//
13303233Sdim
14314564Sdim#include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h"
15303233Sdim#include "llvm/ADT/STLExtras.h"
16303233Sdim
17303233Sdimnamespace clang {
18303233Sdimnamespace ento {
19303233Sdimnamespace mpi {
20303233Sdim
21303233Sdimvoid MPIFunctionClassifier::identifierInit(ASTContext &ASTCtx) {
22303233Sdim  // Initialize function identifiers.
23303233Sdim  initPointToPointIdentifiers(ASTCtx);
24303233Sdim  initCollectiveIdentifiers(ASTCtx);
25303233Sdim  initAdditionalIdentifiers(ASTCtx);
26303233Sdim}
27303233Sdim
28303233Sdimvoid MPIFunctionClassifier::initPointToPointIdentifiers(ASTContext &ASTCtx) {
29303233Sdim  // Copy identifiers into the correct classification containers.
30303233Sdim  IdentInfo_MPI_Send = &ASTCtx.Idents.get("MPI_Send");
31303233Sdim  MPIPointToPointTypes.push_back(IdentInfo_MPI_Send);
32303233Sdim  MPIType.push_back(IdentInfo_MPI_Send);
33303233Sdim  assert(IdentInfo_MPI_Send);
34303233Sdim
35303233Sdim  IdentInfo_MPI_Isend = &ASTCtx.Idents.get("MPI_Isend");
36303233Sdim  MPIPointToPointTypes.push_back(IdentInfo_MPI_Isend);
37303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Isend);
38303233Sdim  MPIType.push_back(IdentInfo_MPI_Isend);
39303233Sdim  assert(IdentInfo_MPI_Isend);
40303233Sdim
41303233Sdim  IdentInfo_MPI_Ssend = &ASTCtx.Idents.get("MPI_Ssend");
42303233Sdim  MPIPointToPointTypes.push_back(IdentInfo_MPI_Ssend);
43303233Sdim  MPIType.push_back(IdentInfo_MPI_Ssend);
44303233Sdim  assert(IdentInfo_MPI_Ssend);
45303233Sdim
46303233Sdim  IdentInfo_MPI_Issend = &ASTCtx.Idents.get("MPI_Issend");
47303233Sdim  MPIPointToPointTypes.push_back(IdentInfo_MPI_Issend);
48303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Issend);
49303233Sdim  MPIType.push_back(IdentInfo_MPI_Issend);
50303233Sdim  assert(IdentInfo_MPI_Issend);
51303233Sdim
52303233Sdim  IdentInfo_MPI_Bsend = &ASTCtx.Idents.get("MPI_Bsend");
53303233Sdim  MPIPointToPointTypes.push_back(IdentInfo_MPI_Bsend);
54303233Sdim  MPIType.push_back(IdentInfo_MPI_Bsend);
55303233Sdim  assert(IdentInfo_MPI_Bsend);
56303233Sdim
57303233Sdim  IdentInfo_MPI_Ibsend = &ASTCtx.Idents.get("MPI_Ibsend");
58303233Sdim  MPIPointToPointTypes.push_back(IdentInfo_MPI_Ibsend);
59303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Ibsend);
60303233Sdim  MPIType.push_back(IdentInfo_MPI_Ibsend);
61303233Sdim  assert(IdentInfo_MPI_Ibsend);
62303233Sdim
63303233Sdim  IdentInfo_MPI_Rsend = &ASTCtx.Idents.get("MPI_Rsend");
64303233Sdim  MPIPointToPointTypes.push_back(IdentInfo_MPI_Rsend);
65303233Sdim  MPIType.push_back(IdentInfo_MPI_Rsend);
66303233Sdim  assert(IdentInfo_MPI_Rsend);
67303233Sdim
68303233Sdim  IdentInfo_MPI_Irsend = &ASTCtx.Idents.get("MPI_Irsend");
69303233Sdim  MPIPointToPointTypes.push_back(IdentInfo_MPI_Irsend);
70303233Sdim  MPIType.push_back(IdentInfo_MPI_Irsend);
71303233Sdim  assert(IdentInfo_MPI_Irsend);
72303233Sdim
73303233Sdim  IdentInfo_MPI_Recv = &ASTCtx.Idents.get("MPI_Recv");
74303233Sdim  MPIPointToPointTypes.push_back(IdentInfo_MPI_Recv);
75303233Sdim  MPIType.push_back(IdentInfo_MPI_Recv);
76303233Sdim  assert(IdentInfo_MPI_Recv);
77303233Sdim
78303233Sdim  IdentInfo_MPI_Irecv = &ASTCtx.Idents.get("MPI_Irecv");
79303233Sdim  MPIPointToPointTypes.push_back(IdentInfo_MPI_Irecv);
80303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Irecv);
81303233Sdim  MPIType.push_back(IdentInfo_MPI_Irecv);
82303233Sdim  assert(IdentInfo_MPI_Irecv);
83303233Sdim}
84303233Sdim
85303233Sdimvoid MPIFunctionClassifier::initCollectiveIdentifiers(ASTContext &ASTCtx) {
86303233Sdim  // Copy identifiers into the correct classification containers.
87303233Sdim  IdentInfo_MPI_Scatter = &ASTCtx.Idents.get("MPI_Scatter");
88303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Scatter);
89303233Sdim  MPIPointToCollTypes.push_back(IdentInfo_MPI_Scatter);
90303233Sdim  MPIType.push_back(IdentInfo_MPI_Scatter);
91303233Sdim  assert(IdentInfo_MPI_Scatter);
92303233Sdim
93303233Sdim  IdentInfo_MPI_Iscatter = &ASTCtx.Idents.get("MPI_Iscatter");
94303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Iscatter);
95303233Sdim  MPIPointToCollTypes.push_back(IdentInfo_MPI_Iscatter);
96303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Iscatter);
97303233Sdim  MPIType.push_back(IdentInfo_MPI_Iscatter);
98303233Sdim  assert(IdentInfo_MPI_Iscatter);
99303233Sdim
100303233Sdim  IdentInfo_MPI_Gather = &ASTCtx.Idents.get("MPI_Gather");
101303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Gather);
102303233Sdim  MPICollToPointTypes.push_back(IdentInfo_MPI_Gather);
103303233Sdim  MPIType.push_back(IdentInfo_MPI_Gather);
104303233Sdim  assert(IdentInfo_MPI_Gather);
105303233Sdim
106303233Sdim  IdentInfo_MPI_Igather = &ASTCtx.Idents.get("MPI_Igather");
107303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Igather);
108303233Sdim  MPICollToPointTypes.push_back(IdentInfo_MPI_Igather);
109303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Igather);
110303233Sdim  MPIType.push_back(IdentInfo_MPI_Igather);
111303233Sdim  assert(IdentInfo_MPI_Igather);
112303233Sdim
113303233Sdim  IdentInfo_MPI_Allgather = &ASTCtx.Idents.get("MPI_Allgather");
114303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Allgather);
115303233Sdim  MPICollToCollTypes.push_back(IdentInfo_MPI_Allgather);
116303233Sdim  MPIType.push_back(IdentInfo_MPI_Allgather);
117303233Sdim  assert(IdentInfo_MPI_Allgather);
118303233Sdim
119303233Sdim  IdentInfo_MPI_Iallgather = &ASTCtx.Idents.get("MPI_Iallgather");
120303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Iallgather);
121303233Sdim  MPICollToCollTypes.push_back(IdentInfo_MPI_Iallgather);
122303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Iallgather);
123303233Sdim  MPIType.push_back(IdentInfo_MPI_Iallgather);
124303233Sdim  assert(IdentInfo_MPI_Iallgather);
125303233Sdim
126303233Sdim  IdentInfo_MPI_Bcast = &ASTCtx.Idents.get("MPI_Bcast");
127303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Bcast);
128303233Sdim  MPIPointToCollTypes.push_back(IdentInfo_MPI_Bcast);
129303233Sdim  MPIType.push_back(IdentInfo_MPI_Bcast);
130303233Sdim  assert(IdentInfo_MPI_Bcast);
131303233Sdim
132303233Sdim  IdentInfo_MPI_Ibcast = &ASTCtx.Idents.get("MPI_Ibcast");
133303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Ibcast);
134303233Sdim  MPIPointToCollTypes.push_back(IdentInfo_MPI_Ibcast);
135303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Ibcast);
136303233Sdim  MPIType.push_back(IdentInfo_MPI_Ibcast);
137303233Sdim  assert(IdentInfo_MPI_Ibcast);
138303233Sdim
139303233Sdim  IdentInfo_MPI_Reduce = &ASTCtx.Idents.get("MPI_Reduce");
140303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Reduce);
141303233Sdim  MPICollToPointTypes.push_back(IdentInfo_MPI_Reduce);
142303233Sdim  MPIType.push_back(IdentInfo_MPI_Reduce);
143303233Sdim  assert(IdentInfo_MPI_Reduce);
144303233Sdim
145303233Sdim  IdentInfo_MPI_Ireduce = &ASTCtx.Idents.get("MPI_Ireduce");
146303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Ireduce);
147303233Sdim  MPICollToPointTypes.push_back(IdentInfo_MPI_Ireduce);
148303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Ireduce);
149303233Sdim  MPIType.push_back(IdentInfo_MPI_Ireduce);
150303233Sdim  assert(IdentInfo_MPI_Ireduce);
151303233Sdim
152303233Sdim  IdentInfo_MPI_Allreduce = &ASTCtx.Idents.get("MPI_Allreduce");
153303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Allreduce);
154303233Sdim  MPICollToCollTypes.push_back(IdentInfo_MPI_Allreduce);
155303233Sdim  MPIType.push_back(IdentInfo_MPI_Allreduce);
156303233Sdim  assert(IdentInfo_MPI_Allreduce);
157303233Sdim
158303233Sdim  IdentInfo_MPI_Iallreduce = &ASTCtx.Idents.get("MPI_Iallreduce");
159303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Iallreduce);
160303233Sdim  MPICollToCollTypes.push_back(IdentInfo_MPI_Iallreduce);
161303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Iallreduce);
162303233Sdim  MPIType.push_back(IdentInfo_MPI_Iallreduce);
163303233Sdim  assert(IdentInfo_MPI_Iallreduce);
164303233Sdim
165303233Sdim  IdentInfo_MPI_Alltoall = &ASTCtx.Idents.get("MPI_Alltoall");
166303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Alltoall);
167303233Sdim  MPICollToCollTypes.push_back(IdentInfo_MPI_Alltoall);
168303233Sdim  MPIType.push_back(IdentInfo_MPI_Alltoall);
169303233Sdim  assert(IdentInfo_MPI_Alltoall);
170303233Sdim
171303233Sdim  IdentInfo_MPI_Ialltoall = &ASTCtx.Idents.get("MPI_Ialltoall");
172303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Ialltoall);
173303233Sdim  MPICollToCollTypes.push_back(IdentInfo_MPI_Ialltoall);
174303233Sdim  MPINonBlockingTypes.push_back(IdentInfo_MPI_Ialltoall);
175303233Sdim  MPIType.push_back(IdentInfo_MPI_Ialltoall);
176303233Sdim  assert(IdentInfo_MPI_Ialltoall);
177303233Sdim}
178303233Sdim
179303233Sdimvoid MPIFunctionClassifier::initAdditionalIdentifiers(ASTContext &ASTCtx) {
180303233Sdim  IdentInfo_MPI_Comm_rank = &ASTCtx.Idents.get("MPI_Comm_rank");
181303233Sdim  MPIType.push_back(IdentInfo_MPI_Comm_rank);
182303233Sdim  assert(IdentInfo_MPI_Comm_rank);
183303233Sdim
184303233Sdim  IdentInfo_MPI_Comm_size = &ASTCtx.Idents.get("MPI_Comm_size");
185303233Sdim  MPIType.push_back(IdentInfo_MPI_Comm_size);
186303233Sdim  assert(IdentInfo_MPI_Comm_size);
187303233Sdim
188303233Sdim  IdentInfo_MPI_Wait = &ASTCtx.Idents.get("MPI_Wait");
189303233Sdim  MPIType.push_back(IdentInfo_MPI_Wait);
190303233Sdim  assert(IdentInfo_MPI_Wait);
191303233Sdim
192303233Sdim  IdentInfo_MPI_Waitall = &ASTCtx.Idents.get("MPI_Waitall");
193303233Sdim  MPIType.push_back(IdentInfo_MPI_Waitall);
194303233Sdim  assert(IdentInfo_MPI_Waitall);
195303233Sdim
196303233Sdim  IdentInfo_MPI_Barrier = &ASTCtx.Idents.get("MPI_Barrier");
197303233Sdim  MPICollectiveTypes.push_back(IdentInfo_MPI_Barrier);
198303233Sdim  MPIType.push_back(IdentInfo_MPI_Barrier);
199303233Sdim  assert(IdentInfo_MPI_Barrier);
200303233Sdim}
201303233Sdim
202303233Sdim// general identifiers
203303233Sdimbool MPIFunctionClassifier::isMPIType(const IdentifierInfo *IdentInfo) const {
204303233Sdim  return llvm::is_contained(MPIType, IdentInfo);
205303233Sdim}
206303233Sdim
207303233Sdimbool MPIFunctionClassifier::isNonBlockingType(
208303233Sdim    const IdentifierInfo *IdentInfo) const {
209303233Sdim  return llvm::is_contained(MPINonBlockingTypes, IdentInfo);
210303233Sdim}
211303233Sdim
212303233Sdim// point-to-point identifiers
213303233Sdimbool MPIFunctionClassifier::isPointToPointType(
214303233Sdim    const IdentifierInfo *IdentInfo) const {
215303233Sdim  return llvm::is_contained(MPIPointToPointTypes, IdentInfo);
216303233Sdim}
217303233Sdim
218303233Sdim// collective identifiers
219303233Sdimbool MPIFunctionClassifier::isCollectiveType(
220303233Sdim    const IdentifierInfo *IdentInfo) const {
221303233Sdim  return llvm::is_contained(MPICollectiveTypes, IdentInfo);
222303233Sdim}
223303233Sdim
224303233Sdimbool MPIFunctionClassifier::isCollToColl(
225303233Sdim    const IdentifierInfo *IdentInfo) const {
226303233Sdim  return llvm::is_contained(MPICollToCollTypes, IdentInfo);
227303233Sdim}
228303233Sdim
229303233Sdimbool MPIFunctionClassifier::isScatterType(
230303233Sdim    const IdentifierInfo *IdentInfo) const {
231303233Sdim  return IdentInfo == IdentInfo_MPI_Scatter ||
232303233Sdim         IdentInfo == IdentInfo_MPI_Iscatter;
233303233Sdim}
234303233Sdim
235303233Sdimbool MPIFunctionClassifier::isGatherType(
236303233Sdim    const IdentifierInfo *IdentInfo) const {
237303233Sdim  return IdentInfo == IdentInfo_MPI_Gather ||
238303233Sdim         IdentInfo == IdentInfo_MPI_Igather ||
239303233Sdim         IdentInfo == IdentInfo_MPI_Allgather ||
240303233Sdim         IdentInfo == IdentInfo_MPI_Iallgather;
241303233Sdim}
242303233Sdim
243303233Sdimbool MPIFunctionClassifier::isAllgatherType(
244303233Sdim    const IdentifierInfo *IdentInfo) const {
245303233Sdim  return IdentInfo == IdentInfo_MPI_Allgather ||
246303233Sdim         IdentInfo == IdentInfo_MPI_Iallgather;
247303233Sdim}
248303233Sdim
249303233Sdimbool MPIFunctionClassifier::isAlltoallType(
250303233Sdim    const IdentifierInfo *IdentInfo) const {
251303233Sdim  return IdentInfo == IdentInfo_MPI_Alltoall ||
252303233Sdim         IdentInfo == IdentInfo_MPI_Ialltoall;
253303233Sdim}
254303233Sdim
255303233Sdimbool MPIFunctionClassifier::isBcastType(const IdentifierInfo *IdentInfo) const {
256303233Sdim  return IdentInfo == IdentInfo_MPI_Bcast || IdentInfo == IdentInfo_MPI_Ibcast;
257303233Sdim}
258303233Sdim
259303233Sdimbool MPIFunctionClassifier::isReduceType(
260303233Sdim    const IdentifierInfo *IdentInfo) const {
261303233Sdim  return IdentInfo == IdentInfo_MPI_Reduce ||
262303233Sdim         IdentInfo == IdentInfo_MPI_Ireduce ||
263303233Sdim         IdentInfo == IdentInfo_MPI_Allreduce ||
264303233Sdim         IdentInfo == IdentInfo_MPI_Iallreduce;
265303233Sdim}
266303233Sdim
267303233Sdim// additional identifiers
268303233Sdimbool MPIFunctionClassifier::isMPI_Wait(const IdentifierInfo *IdentInfo) const {
269303233Sdim  return IdentInfo == IdentInfo_MPI_Wait;
270303233Sdim}
271303233Sdim
272303233Sdimbool MPIFunctionClassifier::isMPI_Waitall(
273303233Sdim    const IdentifierInfo *IdentInfo) const {
274303233Sdim  return IdentInfo == IdentInfo_MPI_Waitall;
275303233Sdim}
276303233Sdim
277303233Sdimbool MPIFunctionClassifier::isWaitType(const IdentifierInfo *IdentInfo) const {
278303233Sdim  return IdentInfo == IdentInfo_MPI_Wait || IdentInfo == IdentInfo_MPI_Waitall;
279303233Sdim}
280303233Sdim
281303233Sdim} // end of namespace: mpi
282303233Sdim} // end of namespace: ento
283303233Sdim} // end of namespace: clang
284