Coverage Report

Created: 2023-10-30 17:15

/builds/2mk6rsew/0/parcoach/parcoach/src/aSSA/Collectives.cpp
Line
Count
Source
1
#include "parcoach/Collectives.h"
2
#include "parcoach/Options.h"
3
4
#include "llvm/ADT/StringMap.h"
5
#include "llvm/IR/Function.h"
6
#include "llvm/IR/Instructions.h"
7
8
namespace parcoach {
9
using namespace llvm;
10
namespace {
11
12
struct Registry {
13
425k
  static auto const &get() {
14
425k
    static Registry Instance;
15
425k
    return Instance.Data;
16
425k
  }
17
18
1.76k
  ~Registry() {
19
70.4k
    for (auto const &ItC : Data) {
20
70.4k
      delete ItC.second;
21
70.4k
    }
22
1.76k
  }
23
24
private:
25
  // NOTE: we must use dynamically allocated memory here, storing a Collective
26
  // would not allocate enough space for derived types.
27
  // We unfortunately can't use a unique_ptr as initializer lists don't have
28
  // a move semantic.
29
  // Therefore we use this trick of having a singleton instance with a custom
30
  // destructor.
31
1.76k
  Registry() = default;
32
  StringMap<Collective const *> const Data{
33
#define MPI_COLLECTIVE(Name, CommArgId)                                        \
34
  {#Name, new MPICollective(Collective::Kind::C_##Name, #Name, CommArgId)},
35
#include "parcoach/MPIRegistry.def"
36
#define COLLECTIVE(Name, FunctionName, Type)                                   \
37
  {#Name, new Type##Collective(Collective::Kind::C_##Name, #FunctionName)},
38
#ifdef PARCOACH_ENABLE_OPENMP
39
#define OMP_COLLECTIVE(Name) COLLECTIVE(Name, Name, OMP)
40
#include "parcoach/OMPRegistry.def"
41
#endif
42
#ifdef PARCOACH_ENABLE_UPC
43
#define UPC_COLLECTIVE(Name) COLLECTIVE(Name, Name, UPC)
44
#include "parcoach/UPCRegistry.def"
45
#endif
46
#ifdef PARCOACH_ENABLE_CUDA
47
#define CUDA_COLLECTIVE(Name, FunctionName) COLLECTIVE(Name, FunctionName, Cuda)
48
#include "parcoach/CUDARegistry.def"
49
#endif
50
#undef COLLECTIVE
51
  };
52
};
53
54
} // namespace
55
56
39.0k
bool Collective::enabled() const { return Options::get().isActivated(P_); }
57
58
212k
Collective const *Collective::find(Function const &F) {
59
212k
  auto It = Registry::get().find(F.getName());
60
212k
  if (It != Registry::get().end() && It->second->enabled()) {
61
39.0k
    return It->second;
62
39.0k
  }
63
173k
  return {};
64
212k
}
65
66
53.8k
bool Collective::isCollective(Function const &F) {
67
53.8k
  return Collective::find(F) != nullptr;
68
53.8k
}
69
70
18.8k
Value *MPICollective::getCommunicator(CallInst const &CI) const {
71
  // NOTE: we expect CI to actually call "this" collective, but we don't assert
72
  // for it since it may be an indirect call.
73
18.8k
  if (CommArgId < 0) {
74
3.35k
    return nullptr;
75
3.35k
  }
76
15.4k
  Value *Comm = CI.getArgOperand(CommArgId);
77
  // This is flaky, we should do a better job at tracking communicator aliases.
78
30.1k
  while (auto *PtrToComm = dyn_cast<LoadInst>(Comm)) {
79
14.7k
    Comm = PtrToComm->getPointerOperand();
80
14.7k
  }
81
15.4k
  return Comm;
82
18.8k
}
83
} // namespace parcoach