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