Coverage Report

Created: 2023-10-30 17:15

/builds/2mk6rsew/0/parcoach/parcoach/src/aSSA/andersen/Andersen.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "parcoach/andersen/Andersen.h"
2
3
#include "llvm/ADT/Statistic.h"
4
#include "llvm/IR/Module.h"
5
#include "llvm/Support/CommandLine.h"
6
#include "llvm/Support/raw_ostream.h"
7
#define DEBUG_TYPE "andersen"
8
9
using namespace llvm;
10
11
#ifndef NDEBUG
12
cl::opt<bool> DumpDebugInfo("dump-debug",
13
                            cl::desc("Dump debug info into stderr"),
14
                            cl::init(false), cl::Hidden);
15
cl::opt<bool> DumpResultInfo("dump-result",
16
                             cl::desc("Dump result info into stderr"),
17
                             cl::init(false), cl::Hidden);
18
cl::opt<bool> DumpConstraintInfo("dump-cons",
19
                                 cl::desc("Dump constraint info into stderr"),
20
                                 cl::init(false), cl::Hidden);
21
#endif
22
23
AnalysisKey AndersenAA::Key;
24
25
1.76k
Andersen AndersenAA::run(Module &M, ModuleAnalysisManager &) {
26
1.76k
  TimeTraceScope TTS("parcoach::Andersen");
27
1.76k
  Andersen AA;
28
1.76k
  LLVM_DEBUG(dbgs() << "Running Andersen\n");
29
1.76k
  AA.runOnModule(M);
30
1.76k
  return AA;
31
1.76k
}
32
33
void Andersen::getAllAllocationSites(
34
3.52k
    std::vector<llvm::Value const *> &allocSites) const {
35
3.52k
  nodeFactory.getAllocSites(allocSites);
36
3.52k
}
37
38
bool Andersen::getPointsToSet(llvm::Value const *v,
39
256k
                              std::vector<llvm::Value const *> &ptsSet) const {
40
256k
  NodeIndex ptrIndex = nodeFactory.getValueNodeFor(v);
41
  // We have no idea what v is...
42
256k
  if (ptrIndex == AndersNodeFactory::InvalidIndex ||
43
256k
      ptrIndex == nodeFactory.getUniversalPtrNode())
44
0
    return false;
45
46
256k
  NodeIndex ptrTgt = nodeFactory.getMergeTarget(ptrIndex);
47
256k
  ptsSet.clear();
48
49
256k
  auto ptsItr = ptsGraph.find(ptrTgt);
50
256k
  if (ptsItr == ptsGraph.end()) {
51
    // Can't find ptrTgt. The reason might be that ptrTgt is an undefined
52
    // pointer. Dereferencing it is undefined behavior anyway, so we might just
53
    // want to treat it as a nullptr pointer
54
10
    return true;
55
10
  }
56
394k
  for (auto v : ptsItr->second) {
57
394k
    if (v == nodeFactory.getNullObjectNode())
58
562
      continue;
59
60
394k
    llvm::Value const *val = nodeFactory.getValueForNode(v);
61
394k
    if (val != nullptr)
62
255k
      ptsSet.push_back(val);
63
394k
  }
64
256k
  return true;
65
256k
}
66
67
1.76k
bool Andersen::runOnModule(Module const &M) {
68
1.76k
  collectConstraints(M);
69
70
#ifndef NDEBUG
71
  if (DumpDebugInfo)
72
    dumpConstraintsPlainVanilla();
73
#endif
74
75
#ifdef ANDERSEN_ENABLE_OPTIMIZATIONS
76
  optimizeConstraints();
77
#endif
78
79
#ifndef NDEBUG
80
  if (DumpConstraintInfo)
81
    dumpConstraints();
82
#endif
83
84
1.76k
  solveConstraints();
85
86
#ifndef NDEBUG
87
  if (DumpDebugInfo) {
88
    errs() << "\n";
89
    dumpPtsGraphPlainVanilla();
90
  }
91
92
  if (DumpResultInfo) {
93
    nodeFactory.dumpNodeInfo();
94
    errs() << "\n";
95
    dumpPtsGraphPlainVanilla();
96
  }
97
#endif
98
99
1.76k
  return false;
100
1.76k
}
101
102
#ifndef NDEBUG
103
void Andersen::dumpConstraint(AndersConstraint const &item) const {
104
  NodeIndex dest = item.getDest();
105
  NodeIndex src = item.getSrc();
106
107
  switch (item.getType()) {
108
  case AndersConstraint::COPY: {
109
    nodeFactory.dumpNode(dest);
110
    errs() << " = ";
111
    nodeFactory.dumpNode(src);
112
    break;
113
  }
114
  case AndersConstraint::LOAD: {
115
    nodeFactory.dumpNode(dest);
116
    errs() << " = *";
117
    nodeFactory.dumpNode(src);
118
    break;
119
  }
120
  case AndersConstraint::STORE: {
121
    errs() << "*";
122
    nodeFactory.dumpNode(dest);
123
    errs() << " = ";
124
    nodeFactory.dumpNode(src);
125
    break;
126
  }
127
  case AndersConstraint::ADDR_OF: {
128
    nodeFactory.dumpNode(dest);
129
    errs() << " = &";
130
    nodeFactory.dumpNode(src);
131
  }
132
  }
133
134
  errs() << "\n";
135
}
136
137
void Andersen::dumpConstraints() const {
138
  errs() << "\n----- Constraints -----\n";
139
  for (auto const &item : constraints)
140
    dumpConstraint(item);
141
  errs() << "----- End of Print -----\n";
142
}
143
144
void Andersen::dumpConstraintsPlainVanilla() const {
145
  for (auto const &item : constraints) {
146
    errs() << item.getType() << " " << item.getDest() << " " << item.getSrc()
147
           << " 0\n";
148
  }
149
}
150
151
void Andersen::dumpPtsGraphPlainVanilla() const {
152
  for (unsigned i = 0, e = nodeFactory.getNumNodes(); i < e; ++i) {
153
    NodeIndex rep = nodeFactory.getMergeTarget(i);
154
    auto ptsItr = ptsGraph.find(rep);
155
    if (ptsItr != ptsGraph.end()) {
156
      errs() << i << " ";
157
      for (auto v : ptsItr->second)
158
        errs() << v << " ";
159
      errs() << "\n";
160
    }
161
  }
162
}
163
#endif