Coverage Report

Created: 2023-10-30 17:15

/builds/2mk6rsew/0/parcoach/parcoach/src/aSSA/MemoryRegion.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "parcoach/MemoryRegion.h"
2
#include "Utils.h"
3
#include "parcoach/Options.h"
4
#include "parcoach/andersen/Andersen.h"
5
6
#include "llvm/IR/GlobalValue.h"
7
#include "llvm/Support/raw_ostream.h"
8
9
#include <set>
10
11
#define DEBUG_TYPE "memreg"
12
13
using namespace llvm;
14
using namespace parcoach;
15
16
namespace {
17
cl::opt<bool> OptDumpRegions("dump-regions",
18
                             cl::desc("Dump the regions found by the "
19
                                      "Andersen PTA"),
20
                             cl::cat(ParcoachCategory));
21
cl::opt<bool>
22
    OptWithRegName("with-reg-name",
23
                   cl::desc("Compute human readable names of regions"),
24
                   cl::cat(ParcoachCategory));
25
26
} // namespace
27
28
llvm::ValueMap<llvm::Function const *, std::set<llvm::Value const *>>
29
    MemReg::func2SharedOmpVar;
30
31
42.3k
unsigned MemRegEntry::generateId() {
32
42.3k
  static unsigned Count{};
33
42.3k
  return Count++;
34
42.3k
}
35
36
MemRegEntry::MemRegEntry(Value const *V)
37
42.3k
    : id_(generateId()), cudaShared_(false), Val(V) {
38
#ifdef PARCOACH_ENABLE_CUDA
39
  // Cuda shared region
40
  if (Options::get().isActivated(Paradigm::CUDA)) {
41
    GlobalValue const *GV = dyn_cast<GlobalValue>(V);
42
    if (GV && GV->getType()->getPointerAddressSpace() == 3) {
43
      cudaShared_ = true;
44
      // FIXME
45
      // sharedCudaRegions.insert(this);
46
    }
47
  }
48
#endif
49
50
42.3k
  if (!OptWithRegName) {
51
42.3k
    name_ = std::to_string(id_);
52
42.3k
    return;
53
42.3k
  }
54
55
0
  name_ = getValueLabel(V);
56
0
  if (auto const *I = dyn_cast<Instruction>(V)) {
57
0
    name_.append(I->getFunction()->getName());
58
0
  }
59
0
}
60
61
1.76k
MemReg::MemReg(Module &M, Andersen const &AA) {
62
1.76k
  TimeTraceScope TTS("MemRegAnalysis");
63
  // Create regions from allocation sites.
64
1.76k
  std::vector<Value const *> Regions;
65
1.76k
  AA.getAllAllocationSites(Regions);
66
67
1.76k
  LLVM_DEBUG(dbgs() << Regions.size() << " regions\n");
68
42.3k
  for (Value const *R : Regions) {
69
42.3k
    createRegion(R);
70
42.3k
  }
71
72
1.76k
  LLVM_DEBUG({
73
1.76k
    if (OptDumpRegions)
74
1.76k
      dumpRegions();
75
1.76k
    dbgs() << "* Regions creation done\n";
76
1.76k
  });
77
78
1.76k
#ifdef PARCOACH_ENABLE_OPENMP
79
  // Compute shared regions for each OMP function.
80
1.76k
  if (Options::get().isActivated(Paradigm::OMP)) {
81
15
    FunctionToMemRegSetMap Func2SharedOmpReg;
82
15
    for (auto I : func2SharedOmpVar) {
83
8
      Function const *F = I.first;
84
85
9
      for (Value const *V : I.second) {
86
9
        std::vector<Value const *> PtsSet;
87
9
        if (AA.getPointsToSet(V, PtsSet)) {
88
9
          MemRegVector Regs;
89
9
          getValuesRegion(PtsSet, Regs);
90
9
          setOmpSharedRegions(F, Regs);
91
9
        }
92
9
      }
93
8
    }
94
15
  }
95
1.76k
#endif
96
1.76k
}
97
98
42.3k
void MemReg::createRegion(llvm::Value const *V) {
99
42.3k
  auto [ItEntry, _] =
100
42.3k
      valueToRegMap.insert({V, std::make_unique<MemRegEntry>(V)});
101
42.3k
  auto &Entry = ItEntry->second;
102
42.3k
  if (Entry->isCudaShared()) {
103
0
    sharedCudaRegions.insert(Entry.get());
104
0
  }
105
42.3k
}
106
107
9
void MemReg::setOmpSharedRegions(Function const *F, MemRegVector &Regs) {
108
9
  func2SharedOmpRegs[F].insert(Regs.begin(), Regs.end());
109
9
}
110
111
#ifndef NDEBUG
112
void MemReg::dumpRegions() const {
113
  dbgs() << valueToRegMap.size() << " regions :\n";
114
  for (auto I : valueToRegMap) {
115
    dbgs() << *I.second->Val
116
           << (I.second->isCudaShared() ? " (shared)\n" : "\n");
117
  }
118
}
119
#endif
120
121
283k
MemRegEntry *MemReg::getValueRegion(llvm::Value const *V) const {
122
283k
  auto I = valueToRegMap.find(V);
123
283k
  if (I == valueToRegMap.end()) {
124
0
    return NULL;
125
0
  }
126
127
283k
  return I->second.get();
128
283k
}
129
130
void MemReg::getValuesRegion(std::vector<Value const *> &PtsSet,
131
256k
                             MemRegVector &Regs) const {
132
256k
  MemRegSet Regions;
133
256k
  for (Value const *V : PtsSet) {
134
255k
    MemRegEntry *R = getValueRegion(V);
135
136
255k
    if (R) {
137
255k
      Regions.insert(R);
138
255k
    }
139
255k
  }
140
141
256k
  Regs.insert(Regs.begin(), Regions.begin(), Regions.end());
142
256k
}
143
144
0
MemRegSet const &MemReg::getCudaSharedRegions() const {
145
0
  return sharedCudaRegions;
146
0
}
147
148
42
FunctionToMemRegSetMap const &MemReg::getOmpSharedRegions() const {
149
42
  return func2SharedOmpRegs;
150
42
}
151
152
AnalysisKey MemRegAnalysis::Key;
153
154
MemRegAnalysis::Result MemRegAnalysis::run(llvm::Module &M,
155
1.76k
                                           llvm::ModuleAnalysisManager &AM) {
156
1.76k
  TimeTraceScope TTS("MemRegAnalysisPass");
157
1.76k
  Andersen const &AA = AM.getResult<AndersenAA>(M);
158
1.76k
  return std::make_unique<MemReg>(M, AA);
159
1.76k
}