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