Coverage Report

Created: 2023-10-30 17:15

/builds/2mk6rsew/0/parcoach/parcoach/src/aSSA/Utils.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "Utils.h"
2
#include "parcoach/Collectives.h"
3
4
#include <sys/time.h>
5
6
#include "llvm/IR/DebugInfo.h"
7
#include "llvm/IR/DebugLoc.h"
8
#include "llvm/IR/IRBuilder.h"
9
#include "llvm/IR/InstIterator.h"
10
#include "llvm/IR/IntrinsicInst.h"
11
#include "llvm/Support/raw_ostream.h"
12
13
#include <map>
14
15
#define DEBUG_TYPE "hello"
16
17
using namespace llvm;
18
19
376k
bool isCallSite(llvm::Instruction const *Inst) {
20
376k
  return llvm::isa<llvm::CallBase>(Inst);
21
376k
}
22
23
100
std::string getValueLabel(llvm::Value const *V) {
24
100
  assert(!isa<Function>(V) && "Use F->getName for functions");
25
26
100
  std::string Label;
27
100
  llvm::raw_string_ostream Rso(Label);
28
100
  V->print(Rso);
29
100
  size_t Pos = Label.find_first_of('=');
30
100
  if (Pos != std::string::npos) {
31
74
    Label = Label.substr(0, Pos);
32
74
  }
33
100
  return Label;
34
100
}
35
36
26
std::string getCallValueLabel(llvm::Value const *V) {
37
26
  std::string Label;
38
26
  llvm::raw_string_ostream Rso(Label);
39
26
  V->print(Rso);
40
26
  size_t Pos = Label.find_first_of('=');
41
26
  if (Pos != std::string::npos) {
42
20
    Label = Label.substr(Pos + 2);
43
20
  }
44
26
  return Label;
45
26
}
46
47
/*
48
 * POSTDOMINANCE
49
 */
50
51
static std::map<BasicBlock *, std::unique_ptr<std::set<BasicBlock *>>> PdfCache;
52
53
// PDF computation
54
std::vector<BasicBlock *> postdominanceFrontier(PostDominatorTree &PDT,
55
50.3k
                                                BasicBlock *BB) {
56
50.3k
  std::vector<BasicBlock *> PDF;
57
58
50.3k
  auto &Cache = PdfCache[BB];
59
50.3k
  if (Cache) {
60
35.3k
    for (BasicBlock *B : *Cache) {
61
7.75k
      PDF.push_back(B);
62
7.75k
    }
63
35.3k
    return PDF;
64
35.3k
  }
65
66
15.0k
  PDF.clear();
67
15.0k
  DomTreeNode *DomNode = PDT.getNode(BB);
68
69
33.7k
  for (auto It = pred_begin(BB), Et = pred_end(BB); It != Et; ++It) {
70
    // does BB immediately dominate this predecessor?
71
18.6k
    DomTreeNode *ID = PDT[*It]; //->getIDom();
72
18.6k
    if ((ID != nullptr) && ID->getIDom() != DomNode && *It != BB) {
73
7.01k
      PDF.push_back(*It);
74
7.01k
    }
75
18.6k
  }
76
15.0k
  for (DomTreeNode::const_iterator NI = DomNode->begin(), NE = DomNode->end();
77
28.2k
       NI != NE; ++NI) {
78
13.1k
    DomTreeNode *IDominee = *NI;
79
13.1k
    std::vector<BasicBlock *> ChildDF =
80
13.1k
        postdominanceFrontier(PDT, IDominee->getBlock());
81
13.1k
    std::vector<BasicBlock *>::const_iterator CDFI = ChildDF.begin();
82
13.1k
    std::vector<BasicBlock *>::const_iterator CDFE = ChildDF.end();
83
20.8k
    for (; CDFI != CDFE; ++CDFI) {
84
7.72k
      if (PDT[*CDFI]->getIDom() != DomNode && *CDFI != BB) {
85
781
        PDF.push_back(*CDFI);
86
781
      }
87
7.72k
    }
88
13.1k
  }
89
90
15.0k
  PdfCache[BB] = std::make_unique<std::set<BasicBlock *>>();
91
15.0k
  PdfCache[BB]->insert(PDF.begin(), PDF.end());
92
93
15.0k
  return PDF;
94
50.3k
}
95
96
static std::map<BasicBlock *, std::unique_ptr<std::set<BasicBlock *>>>
97
    IpdfCache;
98
99
// PDF+ computation
100
std::vector<BasicBlock *>
101
50.9k
iterated_postdominance_frontier(PostDominatorTree &PDT, BasicBlock *BB) {
102
50.9k
  std::vector<BasicBlock *> IPDF;
103
104
50.9k
  auto &Cache = IpdfCache[BB];
105
50.9k
  if (Cache) {
106
22.8k
    for (BasicBlock *B : *Cache) {
107
22.8k
      IPDF.push_back(B);
108
22.8k
    }
109
21.6k
    return IPDF;
110
21.6k
  }
111
112
29.3k
  IPDF = postdominanceFrontier(PDT, BB);
113
29.3k
  if (IPDF.empty()) {
114
22.0k
    return IPDF;
115
22.0k
  }
116
117
7.30k
  std::set<BasicBlock *> S;
118
7.30k
  S.insert(IPDF.begin(), IPDF.end());
119
120
7.30k
  std::set<BasicBlock *> ToCompute;
121
7.30k
  std::set<BasicBlock *> ToComputeTmp;
122
7.30k
  ToCompute.insert(IPDF.begin(), IPDF.end());
123
124
7.30k
  bool Changed = true;
125
15.1k
  while (Changed) {
126
7.79k
    Changed = false;
127
128
15.6k
    for (auto I = ToCompute.begin(), E = ToCompute.end(); I != E; ++I) {
129
7.80k
      std::vector<BasicBlock *> Tmp = postdominanceFrontier(PDT, *I);
130
8.31k
      for (auto J = Tmp.begin(), F = Tmp.end(); J != F; ++J) {
131
509
        if ((S.insert(*J)).second) {
132
494
          ToComputeTmp.insert(*J);
133
494
          Changed = true;
134
494
        }
135
509
      }
136
7.80k
    }
137
138
7.79k
    ToCompute = ToComputeTmp;
139
7.79k
    ToComputeTmp.clear();
140
7.79k
  }
141
142
7.30k
  IPDF.insert(IPDF.end(), S.begin(), S.end());
143
144
7.30k
  IpdfCache[BB] = std::make_unique<std::set<BasicBlock *>>();
145
7.30k
  IpdfCache[BB]->insert(IPDF.begin(), IPDF.end());
146
147
7.30k
  return IPDF;
148
29.3k
}
149
150
std::set<llvm::Value const *>
151
27.5k
computeIPDFPredicates(llvm::PostDominatorTree &PDT, llvm::BasicBlock *BB) {
152
27.5k
  std::set<llvm::Value const *> Preds;
153
154
  // Get IPDF
155
27.5k
  std::vector<BasicBlock *> IPDF = iterated_postdominance_frontier(PDT, BB);
156
157
42.3k
  for (unsigned N = 0; N < IPDF.size(); ++N) {
158
    // Push conditions of each BB in the IPDF
159
14.7k
    Instruction const *Term = IPDF[N]->getTerminator();
160
14.7k
    assert(Term);
161
162
14.7k
    if (isa<BranchInst>(Term)) {
163
14.7k
      BranchInst const *Bi = cast<BranchInst>(Term);
164
14.7k
      assert(Bi);
165
166
14.7k
      if (Bi->isUnconditional()) {
167
0
        continue;
168
0
      }
169
170
14.7k
      Value const *Cond = Bi->getCondition();
171
14.7k
      Preds.insert(Cond);
172
14.7k
    } else if (isa<SwitchInst>(Term)) {
173
10
      SwitchInst const *SI = cast<SwitchInst>(Term);
174
10
      assert(SI);
175
10
      Value const *Cond = SI->getCondition();
176
10
      Preds.insert(Cond);
177
10
    }
178
14.7k
  }
179
180
27.5k
  return Preds;
181
27.5k
}
182
183
2.57k
llvm::Value const *getBasicBlockCond(BasicBlock const *BB) {
184
2.57k
  Instruction const *Term = BB->getTerminator();
185
2.57k
  assert(Term);
186
187
2.57k
  if (isa<BranchInst>(Term)) {
188
2.57k
    BranchInst const *Bi = cast<BranchInst>(Term);
189
2.57k
    assert(Bi);
190
191
2.57k
    if (Bi->isUnconditional()) {
192
0
      return nullptr;
193
0
    }
194
195
2.57k
    return Bi->getCondition();
196
2.57k
  }
197
0
  if (isa<SwitchInst>(Term)) {
198
0
    SwitchInst const *SI = cast<SwitchInst>(Term);
199
0
    assert(SI);
200
0
    return SI->getCondition();
201
0
  }
202
203
0
  return nullptr;
204
0
}
205
206
0
llvm::Value const *getReturnValue(llvm::Function const *F) {
207
0
  Value const *Ret = NULL;
208
209
0
  for (auto I = inst_begin(F), E = inst_end(F); I != E; ++I) {
210
0
    Instruction const *Inst = &*I;
211
212
0
    if (ReturnInst const *RI = dyn_cast<ReturnInst>(Inst)) {
213
0
      assert(Ret == NULL && "There exists more than one return instruction");
214
215
0
      Ret = RI->getReturnValue();
216
0
    }
217
0
  }
218
219
0
  assert(Ret != NULL && "There is no return instruction");
220
221
0
  return Ret;
222
0
}
223
224
135k
bool isIntrinsicDbgFunction(llvm::Function const *F) {
225
135k
  return F != NULL && F->getName().startswith("llvm.dbg");
226
135k
}
227
228
107k
bool isIntrinsicDbgInst(llvm::Instruction const *I) {
229
107k
  return isa<DbgInfoIntrinsic>(I);
230
107k
}
231
232
1.82k
bool functionDoesNotRet(llvm::Function const *F) {
233
1.82k
  std::vector<BasicBlock const *> ToVisit;
234
1.82k
  std::set<BasicBlock const *> Visited;
235
236
1.82k
  ToVisit.push_back(&F->getEntryBlock());
237
238
9.12k
  while (!ToVisit.empty()) {
239
9.12k
    BasicBlock const *BB = ToVisit.back();
240
9.12k
    ToVisit.pop_back();
241
242
150k
    for (Instruction const &Inst : *BB) {
243
150k
      if (isa<ReturnInst>(Inst)) {
244
1.82k
        return false;
245
1.82k
      }
246
150k
    }
247
248
19.9k
    for (auto I = succ_begin(BB), E = succ_end(BB); I != E; ++I) {
249
12.6k
      BasicBlock const *Succ = *I;
250
12.6k
      if (Visited.find(Succ) == Visited.end()) {
251
12.5k
        ToVisit.push_back(Succ);
252
12.5k
        Visited.insert(Succ);
253
12.5k
      }
254
12.6k
    }
255
7.29k
  }
256
257
0
  return true;
258
1.82k
}
259
260
unsigned getBBSetIntersectionSize(const std::set<BasicBlock const *> S1,
261
0
                                  const std::set<BasicBlock const *> S2) {
262
0
  unsigned Ret = 0;
263
264
0
  for (BasicBlock const *BB : S1) {
265
0
    if (S2.find(BB) != S2.end()) {
266
0
      Ret++;
267
0
    }
268
0
  }
269
270
0
  return Ret;
271
0
}
272
273
unsigned getInstSetIntersectionSize(const std::set<Instruction const *> S1,
274
0
                                    const std::set<Instruction const *> S2) {
275
0
  unsigned Ret = 0;
276
277
0
  for (Instruction const *I : S1) {
278
0
    if (S2.find(I) != S2.end()) {
279
0
      Ret++;
280
0
    }
281
0
  }
282
283
0
  return Ret;
284
0
}