-
Notifications
You must be signed in to change notification settings - Fork 2
/
InstLoc.cpp
119 lines (101 loc) · 2.66 KB
/
InstLoc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include "llvm/Analysis/CFG.h"
#include "llvm/Support/raw_ostream.h"
#include "InstLoc.h"
#include <algorithm>
using namespace llvm;
using namespace std;
Context::Context(Function *entry) : entry(entry)
{
}
bool Context::operator<(const Context &rhs) const
{
if (this->entry == rhs.entry)
{
return this->pairs < rhs.pairs;
}
else
{
return this->entry < rhs.entry;
}
}
Function *Context::getCurrentFunction() const
{
if (this->pairs.size() == 0)
{
return entry;
}
else
{
return this->pairs.back().second;
}
}
InstLoc Context::getCallerInstLoc() const
{
assert(this->pairs.size() >= 1);
CallInst *inst = this->pairs.back().first;
Context res(*this);
res.pairs.pop_back();
return InstLoc(res, inst);
}
uint32_t Context::getDepth() const
{
return this->pairs.size() + 1;
}
Context Context::add(CallInst *callInst, Function *calledFunc) const
{
Context res(*this);
res.pairs.push_back(std::pair<CallInst *, Function *>(callInst, calledFunc));
return res;
}
string Context::toString() const
{
string res;
res += entry->getName().str();
for (auto &pair : this->pairs)
{
// for simplicity, only print called function
res += ":";
res += pair.second->getName().str();
}
return res;
}
InstLoc::InstLoc(Context context, Instruction *inst) : context(context), inst(inst)
{
}
string InstLoc::toString() const
{
string res;
res += this->context.toString();
res += ":";
string tmp;
raw_string_ostream ss(tmp);
ss << *this->inst;
res += ss.str();
return res;
}
bool isReachable(InstLoc fromLoc, InstLoc toLoc)
{
// Different entries, unreachable
if (fromLoc.context.entry != toLoc.context.entry)
{
return false;
}
size_t minPairsSize = min(fromLoc.context.pairs.size(), toLoc.context.pairs.size());
for (size_t i = 0; i < minPairsSize; ++i)
{
if (fromLoc.context.pairs[i].first != toLoc.context.pairs[i].first)
{
return isPotentiallyReachable(fromLoc.context.pairs[i].first, toLoc.context.pairs[i].first);
}
else
{
if (fromLoc.context.pairs[i].second != toLoc.context.pairs[i].second)
{
return false; // same caller but different called functions, unreachable
}
}
}
Instruction *tmpFrom = (fromLoc.context.pairs.size() <= minPairsSize) ? fromLoc.inst : fromLoc.context.pairs[minPairsSize].first;
Instruction *tmpTo = (toLoc.context.pairs.size() <= minPairsSize) ? toLoc.inst : toLoc.context.pairs[minPairsSize].first;
return isPotentiallyReachable(tmpFrom, tmpTo);
}