| //===-- MPIFunctionClassifier.cpp - classifies MPI functions ----*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// This file defines functionality to identify and classify MPI functions. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #include "clang/StaticAnalyzer/Checkers/MPIFunctionClassifier.h" |
| #include "llvm/ADT/STLExtras.h" |
| |
| namespace clang { |
| namespace ento { |
| namespace mpi { |
| |
| void MPIFunctionClassifier::identifierInit(ASTContext &ASTCtx) { |
| // Initialize function identifiers. |
| initPointToPointIdentifiers(ASTCtx); |
| initCollectiveIdentifiers(ASTCtx); |
| initAdditionalIdentifiers(ASTCtx); |
| } |
| |
| void MPIFunctionClassifier::initPointToPointIdentifiers(ASTContext &ASTCtx) { |
| // Copy identifiers into the correct classification containers. |
| IdentInfo_MPI_Send = &ASTCtx.Idents.get("MPI_Send"); |
| MPIPointToPointTypes.push_back(IdentInfo_MPI_Send); |
| MPIType.push_back(IdentInfo_MPI_Send); |
| assert(IdentInfo_MPI_Send); |
| |
| IdentInfo_MPI_Isend = &ASTCtx.Idents.get("MPI_Isend"); |
| MPIPointToPointTypes.push_back(IdentInfo_MPI_Isend); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Isend); |
| MPIType.push_back(IdentInfo_MPI_Isend); |
| assert(IdentInfo_MPI_Isend); |
| |
| IdentInfo_MPI_Ssend = &ASTCtx.Idents.get("MPI_Ssend"); |
| MPIPointToPointTypes.push_back(IdentInfo_MPI_Ssend); |
| MPIType.push_back(IdentInfo_MPI_Ssend); |
| assert(IdentInfo_MPI_Ssend); |
| |
| IdentInfo_MPI_Issend = &ASTCtx.Idents.get("MPI_Issend"); |
| MPIPointToPointTypes.push_back(IdentInfo_MPI_Issend); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Issend); |
| MPIType.push_back(IdentInfo_MPI_Issend); |
| assert(IdentInfo_MPI_Issend); |
| |
| IdentInfo_MPI_Bsend = &ASTCtx.Idents.get("MPI_Bsend"); |
| MPIPointToPointTypes.push_back(IdentInfo_MPI_Bsend); |
| MPIType.push_back(IdentInfo_MPI_Bsend); |
| assert(IdentInfo_MPI_Bsend); |
| |
| IdentInfo_MPI_Ibsend = &ASTCtx.Idents.get("MPI_Ibsend"); |
| MPIPointToPointTypes.push_back(IdentInfo_MPI_Ibsend); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Ibsend); |
| MPIType.push_back(IdentInfo_MPI_Ibsend); |
| assert(IdentInfo_MPI_Ibsend); |
| |
| IdentInfo_MPI_Rsend = &ASTCtx.Idents.get("MPI_Rsend"); |
| MPIPointToPointTypes.push_back(IdentInfo_MPI_Rsend); |
| MPIType.push_back(IdentInfo_MPI_Rsend); |
| assert(IdentInfo_MPI_Rsend); |
| |
| IdentInfo_MPI_Irsend = &ASTCtx.Idents.get("MPI_Irsend"); |
| MPIPointToPointTypes.push_back(IdentInfo_MPI_Irsend); |
| MPIType.push_back(IdentInfo_MPI_Irsend); |
| assert(IdentInfo_MPI_Irsend); |
| |
| IdentInfo_MPI_Recv = &ASTCtx.Idents.get("MPI_Recv"); |
| MPIPointToPointTypes.push_back(IdentInfo_MPI_Recv); |
| MPIType.push_back(IdentInfo_MPI_Recv); |
| assert(IdentInfo_MPI_Recv); |
| |
| IdentInfo_MPI_Irecv = &ASTCtx.Idents.get("MPI_Irecv"); |
| MPIPointToPointTypes.push_back(IdentInfo_MPI_Irecv); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Irecv); |
| MPIType.push_back(IdentInfo_MPI_Irecv); |
| assert(IdentInfo_MPI_Irecv); |
| } |
| |
| void MPIFunctionClassifier::initCollectiveIdentifiers(ASTContext &ASTCtx) { |
| // Copy identifiers into the correct classification containers. |
| IdentInfo_MPI_Scatter = &ASTCtx.Idents.get("MPI_Scatter"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Scatter); |
| MPIPointToCollTypes.push_back(IdentInfo_MPI_Scatter); |
| MPIType.push_back(IdentInfo_MPI_Scatter); |
| assert(IdentInfo_MPI_Scatter); |
| |
| IdentInfo_MPI_Iscatter = &ASTCtx.Idents.get("MPI_Iscatter"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Iscatter); |
| MPIPointToCollTypes.push_back(IdentInfo_MPI_Iscatter); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Iscatter); |
| MPIType.push_back(IdentInfo_MPI_Iscatter); |
| assert(IdentInfo_MPI_Iscatter); |
| |
| IdentInfo_MPI_Gather = &ASTCtx.Idents.get("MPI_Gather"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Gather); |
| MPICollToPointTypes.push_back(IdentInfo_MPI_Gather); |
| MPIType.push_back(IdentInfo_MPI_Gather); |
| assert(IdentInfo_MPI_Gather); |
| |
| IdentInfo_MPI_Igather = &ASTCtx.Idents.get("MPI_Igather"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Igather); |
| MPICollToPointTypes.push_back(IdentInfo_MPI_Igather); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Igather); |
| MPIType.push_back(IdentInfo_MPI_Igather); |
| assert(IdentInfo_MPI_Igather); |
| |
| IdentInfo_MPI_Allgather = &ASTCtx.Idents.get("MPI_Allgather"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Allgather); |
| MPICollToCollTypes.push_back(IdentInfo_MPI_Allgather); |
| MPIType.push_back(IdentInfo_MPI_Allgather); |
| assert(IdentInfo_MPI_Allgather); |
| |
| IdentInfo_MPI_Iallgather = &ASTCtx.Idents.get("MPI_Iallgather"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Iallgather); |
| MPICollToCollTypes.push_back(IdentInfo_MPI_Iallgather); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Iallgather); |
| MPIType.push_back(IdentInfo_MPI_Iallgather); |
| assert(IdentInfo_MPI_Iallgather); |
| |
| IdentInfo_MPI_Bcast = &ASTCtx.Idents.get("MPI_Bcast"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Bcast); |
| MPIPointToCollTypes.push_back(IdentInfo_MPI_Bcast); |
| MPIType.push_back(IdentInfo_MPI_Bcast); |
| assert(IdentInfo_MPI_Bcast); |
| |
| IdentInfo_MPI_Ibcast = &ASTCtx.Idents.get("MPI_Ibcast"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Ibcast); |
| MPIPointToCollTypes.push_back(IdentInfo_MPI_Ibcast); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Ibcast); |
| MPIType.push_back(IdentInfo_MPI_Ibcast); |
| assert(IdentInfo_MPI_Ibcast); |
| |
| IdentInfo_MPI_Reduce = &ASTCtx.Idents.get("MPI_Reduce"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Reduce); |
| MPICollToPointTypes.push_back(IdentInfo_MPI_Reduce); |
| MPIType.push_back(IdentInfo_MPI_Reduce); |
| assert(IdentInfo_MPI_Reduce); |
| |
| IdentInfo_MPI_Ireduce = &ASTCtx.Idents.get("MPI_Ireduce"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Ireduce); |
| MPICollToPointTypes.push_back(IdentInfo_MPI_Ireduce); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Ireduce); |
| MPIType.push_back(IdentInfo_MPI_Ireduce); |
| assert(IdentInfo_MPI_Ireduce); |
| |
| IdentInfo_MPI_Allreduce = &ASTCtx.Idents.get("MPI_Allreduce"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Allreduce); |
| MPICollToCollTypes.push_back(IdentInfo_MPI_Allreduce); |
| MPIType.push_back(IdentInfo_MPI_Allreduce); |
| assert(IdentInfo_MPI_Allreduce); |
| |
| IdentInfo_MPI_Iallreduce = &ASTCtx.Idents.get("MPI_Iallreduce"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Iallreduce); |
| MPICollToCollTypes.push_back(IdentInfo_MPI_Iallreduce); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Iallreduce); |
| MPIType.push_back(IdentInfo_MPI_Iallreduce); |
| assert(IdentInfo_MPI_Iallreduce); |
| |
| IdentInfo_MPI_Alltoall = &ASTCtx.Idents.get("MPI_Alltoall"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Alltoall); |
| MPICollToCollTypes.push_back(IdentInfo_MPI_Alltoall); |
| MPIType.push_back(IdentInfo_MPI_Alltoall); |
| assert(IdentInfo_MPI_Alltoall); |
| |
| IdentInfo_MPI_Ialltoall = &ASTCtx.Idents.get("MPI_Ialltoall"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Ialltoall); |
| MPICollToCollTypes.push_back(IdentInfo_MPI_Ialltoall); |
| MPINonBlockingTypes.push_back(IdentInfo_MPI_Ialltoall); |
| MPIType.push_back(IdentInfo_MPI_Ialltoall); |
| assert(IdentInfo_MPI_Ialltoall); |
| } |
| |
| void MPIFunctionClassifier::initAdditionalIdentifiers(ASTContext &ASTCtx) { |
| IdentInfo_MPI_Comm_rank = &ASTCtx.Idents.get("MPI_Comm_rank"); |
| MPIType.push_back(IdentInfo_MPI_Comm_rank); |
| assert(IdentInfo_MPI_Comm_rank); |
| |
| IdentInfo_MPI_Comm_size = &ASTCtx.Idents.get("MPI_Comm_size"); |
| MPIType.push_back(IdentInfo_MPI_Comm_size); |
| assert(IdentInfo_MPI_Comm_size); |
| |
| IdentInfo_MPI_Wait = &ASTCtx.Idents.get("MPI_Wait"); |
| MPIType.push_back(IdentInfo_MPI_Wait); |
| assert(IdentInfo_MPI_Wait); |
| |
| IdentInfo_MPI_Waitall = &ASTCtx.Idents.get("MPI_Waitall"); |
| MPIType.push_back(IdentInfo_MPI_Waitall); |
| assert(IdentInfo_MPI_Waitall); |
| |
| IdentInfo_MPI_Barrier = &ASTCtx.Idents.get("MPI_Barrier"); |
| MPICollectiveTypes.push_back(IdentInfo_MPI_Barrier); |
| MPIType.push_back(IdentInfo_MPI_Barrier); |
| assert(IdentInfo_MPI_Barrier); |
| } |
| |
| // general identifiers |
| bool MPIFunctionClassifier::isMPIType(const IdentifierInfo *IdentInfo) const { |
| return llvm::is_contained(MPIType, IdentInfo); |
| } |
| |
| bool MPIFunctionClassifier::isNonBlockingType( |
| const IdentifierInfo *IdentInfo) const { |
| return llvm::is_contained(MPINonBlockingTypes, IdentInfo); |
| } |
| |
| // point-to-point identifiers |
| bool MPIFunctionClassifier::isPointToPointType( |
| const IdentifierInfo *IdentInfo) const { |
| return llvm::is_contained(MPIPointToPointTypes, IdentInfo); |
| } |
| |
| // collective identifiers |
| bool MPIFunctionClassifier::isCollectiveType( |
| const IdentifierInfo *IdentInfo) const { |
| return llvm::is_contained(MPICollectiveTypes, IdentInfo); |
| } |
| |
| bool MPIFunctionClassifier::isCollToColl( |
| const IdentifierInfo *IdentInfo) const { |
| return llvm::is_contained(MPICollToCollTypes, IdentInfo); |
| } |
| |
| bool MPIFunctionClassifier::isScatterType( |
| const IdentifierInfo *IdentInfo) const { |
| return IdentInfo == IdentInfo_MPI_Scatter || |
| IdentInfo == IdentInfo_MPI_Iscatter; |
| } |
| |
| bool MPIFunctionClassifier::isGatherType( |
| const IdentifierInfo *IdentInfo) const { |
| return IdentInfo == IdentInfo_MPI_Gather || |
| IdentInfo == IdentInfo_MPI_Igather || |
| IdentInfo == IdentInfo_MPI_Allgather || |
| IdentInfo == IdentInfo_MPI_Iallgather; |
| } |
| |
| bool MPIFunctionClassifier::isAllgatherType( |
| const IdentifierInfo *IdentInfo) const { |
| return IdentInfo == IdentInfo_MPI_Allgather || |
| IdentInfo == IdentInfo_MPI_Iallgather; |
| } |
| |
| bool MPIFunctionClassifier::isAlltoallType( |
| const IdentifierInfo *IdentInfo) const { |
| return IdentInfo == IdentInfo_MPI_Alltoall || |
| IdentInfo == IdentInfo_MPI_Ialltoall; |
| } |
| |
| bool MPIFunctionClassifier::isBcastType(const IdentifierInfo *IdentInfo) const { |
| return IdentInfo == IdentInfo_MPI_Bcast || IdentInfo == IdentInfo_MPI_Ibcast; |
| } |
| |
| bool MPIFunctionClassifier::isReduceType( |
| const IdentifierInfo *IdentInfo) const { |
| return IdentInfo == IdentInfo_MPI_Reduce || |
| IdentInfo == IdentInfo_MPI_Ireduce || |
| IdentInfo == IdentInfo_MPI_Allreduce || |
| IdentInfo == IdentInfo_MPI_Iallreduce; |
| } |
| |
| // additional identifiers |
| bool MPIFunctionClassifier::isMPI_Wait(const IdentifierInfo *IdentInfo) const { |
| return IdentInfo == IdentInfo_MPI_Wait; |
| } |
| |
| bool MPIFunctionClassifier::isMPI_Waitall( |
| const IdentifierInfo *IdentInfo) const { |
| return IdentInfo == IdentInfo_MPI_Waitall; |
| } |
| |
| bool MPIFunctionClassifier::isWaitType(const IdentifierInfo *IdentInfo) const { |
| return IdentInfo == IdentInfo_MPI_Wait || IdentInfo == IdentInfo_MPI_Waitall; |
| } |
| |
| } // end of namespace: mpi |
| } // end of namespace: ento |
| } // end of namespace: clang |