Coverage Report

Created: 2023-10-30 17:15

/builds/2mk6rsew/0/parcoach/parcoach/src/aSSA/CollectiveList.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "parcoach/CollectiveList.h"
2
3
#include "PTACallGraph.h"
4
#include "Utils.h"
5
6
#include "llvm/IR/BasicBlock.h"
7
#include "llvm/Support/raw_ostream.h"
8
9
#include <sstream>
10
11
using namespace llvm;
12
namespace parcoach {
13
namespace {
14
// Little helper to tell us if we should ignore the collective.
15
// We basically ignore the collective if the Communicator is not null and if
16
// it matches the communicator in the call instruction.
17
7.08k
bool shouldIgnore(CallInst const &CI, Collective const &Coll, Value *Comm) {
18
7.08k
  if (!isa<MPICollective>(Coll) || !Comm) {
19
    // If it's not an mpi collective, or if we don't have a communicator,
20
    // we definitely shouldn't ignore it!
21
247
    return false;
22
247
  }
23
6.83k
  MPICollective const &MPIColl = cast<MPICollective>(Coll);
24
6.83k
  Value *CommForCollective = MPIColl.getCommunicator(CI);
25
6.83k
  return CommForCollective != nullptr && CommForCollective != Comm;
26
7.08k
}
27
} // namespace
28
29
4.97k
bool CollectiveList::navs() const {
30
4.97k
  if (List_.empty()) {
31
1
    return false;
32
1
  }
33
4.97k
  return List_.front()->navs();
34
4.97k
}
35
36
CollectiveList::CollectiveList(CollectiveList const &From)
37
2.94k
    : LoopHeader_(From.LoopHeader_) {
38
2.94k
  for (auto const &Elem : From.List_) {
39
162
    List_.emplace_back(Elem->copy());
40
162
  }
41
2.94k
}
42
43
CollectiveList::CollectiveList(BasicBlock *Header,
44
                               CollectiveList const &LoopList)
45
468
    : CollectiveList(LoopList) {
46
  // Override the loop header after copy construction.
47
468
  LoopHeader_ = Header;
48
468
}
49
50
void CollectiveList::add(CollectiveList const &Other,
51
13.4k
                         std::insert_iterator<ListTy> Inserter) {
52
13.4k
  if (!Other.List_.empty()) {
53
12.0k
    if (Other.LoopHeader_) {
54
15
      Inserter = std::make_unique<CollListElement>(Other);
55
12.0k
    } else {
56
17.1k
      for (auto const &ListElem : Other.List_) {
57
17.1k
        Inserter = ListElem->copy();
58
17.1k
      }
59
12.0k
    }
60
12.0k
  }
61
13.4k
}
62
63
12.5k
void CollectiveList::extendWith(CollectiveList const &Other) {
64
12.5k
  add(Other, std::inserter(List_, List_.end()));
65
12.5k
}
66
67
963
void CollectiveList::prependWith(CollectiveList const &Other) {
68
963
  add(Other, std::inserter(List_, List_.begin()));
69
963
}
70
71
10.5k
std::string CollectiveList::toString() const {
72
10.5k
  std::string Ret;
73
10.5k
  raw_string_ostream Err(Ret);
74
10.5k
  if (LoopHeader_) {
75
18
    Err << "*";
76
18
    LoopHeader_.value()->printAsOperand(Err, false);
77
18
  }
78
10.5k
  Err << "(";
79
10.5k
  bool First = true;
80
18.4k
  for (auto const &Elem : List_) {
81
18.4k
    if (!First) {
82
7.91k
      Err << ", ";
83
7.91k
    }
84
18.4k
    Err << Elem->toString();
85
18.4k
    First = false;
86
18.4k
  }
87
10.5k
  Err << ")";
88
10.5k
  return Ret;
89
10.5k
}
90
91
CollectiveList CollectiveList::CreateFromBB(BBToCollListMap const &CollLists,
92
                                            PTACallGraph const &PTACG,
93
                                            bool NeighborsAreNAVS,
94
                                            llvm::BasicBlock &BB,
95
15.2k
                                            llvm::Value *Comm) {
96
15.2k
  CollectiveList Current;
97
15.2k
  if (NeighborsAreNAVS) {
98
798
    Current.extendWith<NavsElement>();
99
798
    return Current;
100
798
  }
101
102
50.3k
  auto ActOnFunction = [&](CallInst &CI, Function const &F) {
103
50.3k
    if (auto const *Coll = Collective::find(F)) {
104
7.08k
      if (!shouldIgnore(CI, *Coll, Comm)) {
105
6.93k
        Current.extendWith<CollElement>(*Coll);
106
6.93k
      }
107
43.3k
    } else if (CollLists.count(&F.getEntryBlock()) != 0) {
108
62
      auto const &ListForFunc = CollLists.find(&F.getEntryBlock())->second;
109
62
      Current.extendWith(ListForFunc);
110
62
    }
111
50.3k
  };
112
178k
  auto IsCI = [](Instruction &I) { return isa<CallInst>(I); };
113
50.3k
  for (auto &I : make_filter_range(BB, IsCI)) {
114
50.3k
    CallInst &CI = cast<CallInst>(I);
115
50.3k
    if (!CI.getCalledFunction()) {
116
      // Iterate over functions which may be called
117
3
      auto Found = PTACG.getIndirectCallMap().find(&CI);
118
3
      if (Found == PTACG.getIndirectCallMap().end()) {
119
0
        continue;
120
0
      }
121
6
      for (Function const *MayCall : Found->second) {
122
6
        if (isIntrinsicDbgFunction(MayCall)) {
123
0
          continue;
124
0
        }
125
        // FIXME: think about that: currently it pushes *all* the possible
126
        // collective called by *all* the may call functions.
127
6
        ActOnFunction(CI, *MayCall);
128
6
      }
129
50.3k
    } else {
130
50.3k
      ActOnFunction(CI, *CI.getCalledFunction());
131
50.3k
    }
132
50.3k
  }
133
14.4k
  return Current;
134
15.2k
}
135
136
} // namespace parcoach