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