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