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