//===-- 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