Skip to content

Commit 8ad50a1

Browse files
authored
Merge branch 'development' into f-FixIDEEdgeFunctions
2 parents 04419a1 + b361364 commit 8ad50a1

9 files changed

Lines changed: 904 additions & 215 deletions

File tree

include/phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/IDEInstInteractionAnalysis.h

Lines changed: 337 additions & 58 deletions
Large diffs are not rendered by default.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/******************************************************************************
2+
* Copyright (c) 2019 Philipp Schubert, Richard Leer, and Florian Sattler.
3+
* All rights reserved. This program and the accompanying materials are made
4+
* available under the terms of LICENSE.txt.
5+
*
6+
* Contributors:
7+
* Philipp Schubert and others
8+
*****************************************************************************/
9+
10+
#include "phasar/PhasarLLVM/DataFlowSolver/IfdsIde/Problems/IDEInstInteractionAnalysis.h"
11+
12+
#include "llvm/IR/Instruction.h"
13+
#include "llvm/IR/Instructions.h"
14+
#include "llvm/IR/Value.h"
15+
#include "llvm/Support/Casting.h"
16+
#include "llvm/Support/ErrorHandling.h"
17+
18+
#include <algorithm>
19+
#include <memory>
20+
#include <tuple>
21+
22+
using namespace psr;
23+
24+
IDEIIAFlowFact::IDEIIAFlowFact(const llvm::Value *BaseVal) : BaseVal(BaseVal) {}
25+
26+
IDEIIAFlowFact::IDEIIAFlowFact(
27+
const llvm::Value *BaseVal,
28+
llvm::SmallVector<const llvm::GetElementPtrInst *, KLimit> FieldDesc)
29+
: BaseVal(BaseVal), FieldDesc(std::move(FieldDesc)) {
30+
assert(FieldDesc.size() <= getKLimit() &&
31+
"Field descriptor exceeds k-limit!");
32+
}
33+
34+
IDEIIAFlowFact IDEIIAFlowFact::create(const llvm::Value *BaseVal) {
35+
if (const auto *Alloca = llvm::dyn_cast<llvm::AllocaInst>(BaseVal)) {
36+
return {BaseVal};
37+
}
38+
if (const auto *Gep = llvm::dyn_cast<llvm::GetElementPtrInst>(BaseVal)) {
39+
// Construct field descriptor
40+
llvm::SmallVector<const llvm::GetElementPtrInst *, KLimit> FieldDesc;
41+
FieldDesc.push_back(Gep);
42+
const auto *NextGep = Gep->getPointerOperand();
43+
while (llvm::isa_and_nonnull<llvm::GetElementPtrInst>(NextGep)) {
44+
Gep = llvm::dyn_cast<llvm::GetElementPtrInst>(NextGep);
45+
if (FieldDesc.size() >= KLimit) {
46+
// do a left shift to make space
47+
if (FieldDesc.size() == 1) {
48+
FieldDesc.pop_back();
49+
} else {
50+
for (size_t Idx = 0; Idx < FieldDesc.size() - 1; ++Idx) {
51+
FieldDesc[Idx] = FieldDesc[Idx + 1];
52+
}
53+
FieldDesc.pop_back();
54+
}
55+
}
56+
FieldDesc.push_back(Gep);
57+
NextGep = Gep->getPointerOperand();
58+
}
59+
std::reverse(FieldDesc.begin(), FieldDesc.end());
60+
// Get base variable
61+
if (llvm::isa_and_nonnull<llvm::AllocaInst>(NextGep)) {
62+
BaseVal = NextGep;
63+
}
64+
assert(BaseVal && "BaseVal cannot be nullptr!");
65+
if (KLimit == 0) {
66+
return {BaseVal};
67+
}
68+
return {BaseVal, FieldDesc};
69+
}
70+
llvm::report_fatal_error("Unexpected instruction!");
71+
}
72+
73+
bool IDEIIAFlowFact::flowFactEqual(const IDEIIAFlowFact &Other) const {
74+
return *this == Other;
75+
}
76+
77+
void IDEIIAFlowFact::print(llvm::raw_ostream &OS,
78+
[[maybe_unused]] bool IsForDebug) const {
79+
OS << "IDEIIAFlowFact { ";
80+
if (!BaseVal) {
81+
OS << "nullptr";
82+
} else {
83+
OS << *BaseVal;
84+
}
85+
if (FieldDesc.empty()) {
86+
OS << " }";
87+
} else {
88+
OS << ",\n\t[\n\t\t";
89+
for (const auto *Gep : FieldDesc) {
90+
OS << *Gep;
91+
if (Gep != FieldDesc.back()) {
92+
OS << ",\n\t\t";
93+
}
94+
}
95+
OS << "\n\t]\n}";
96+
}
97+
}
98+
99+
bool IDEIIAFlowFact::operator==(const IDEIIAFlowFact &Other) const {
100+
if (BaseVal != Other.BaseVal) {
101+
return false;
102+
}
103+
if (FieldDesc.size() != Other.FieldDesc.size()) {
104+
return false;
105+
}
106+
auto EqualGEPDescriptor = [](const llvm::GetElementPtrInst *Lhs,
107+
const llvm::GetElementPtrInst *Rhs) {
108+
const auto *LhsI = llvm::dyn_cast<llvm::Instruction>(Lhs);
109+
const auto *RhsI = llvm::dyn_cast<llvm::Instruction>(Rhs);
110+
return LhsI->isSameOperationAs(RhsI);
111+
};
112+
for (unsigned Idx = 0; Idx < FieldDesc.size(); ++Idx) {
113+
if (!EqualGEPDescriptor(FieldDesc[Idx], Other.FieldDesc[Idx])) {
114+
return false;
115+
}
116+
}
117+
return true;
118+
}
119+
120+
bool IDEIIAFlowFact::operator!=(const IDEIIAFlowFact &Other) const {
121+
return !(*this == Other);
122+
}
123+
124+
bool IDEIIAFlowFact::operator<(const IDEIIAFlowFact &Other) const {
125+
return std::tie(BaseVal, FieldDesc) <
126+
std::tie(Other.BaseVal, Other.FieldDesc);
127+
}
128+
129+
bool IDEIIAFlowFact::operator==(const llvm::Value *V) const {
130+
return BaseVal == V && FieldDesc.empty();
131+
}

test/llvm_test_code/inst_interaction/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
set(Sources
2+
array_01.cpp
3+
array_02.cpp
4+
array_03.cpp
25
basic_01.cpp
36
basic_02.cpp
47
basic_03.cpp
@@ -24,6 +27,7 @@ set(Sources
2427
return_01.cpp
2528
rvo_01.cpp
2629
struct_01.cpp
30+
struct_02.cpp
2731
)
2832

2933
set(SourcesOpt
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
int main() {
2+
int i = 13;
3+
int j = 42;
4+
int buffer[16] = {0};
5+
buffer[0] = i;
6+
buffer[10] = j;
7+
int x = buffer[0];
8+
int y = buffer[10];
9+
int z = buffer[1];
10+
return 0;
11+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
int main() {
2+
int buffer[10][10];
3+
buffer[0][0] = 1;
4+
int i = buffer[0][0];
5+
return i;
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
int main() {
2+
int buffer[3][3][3];
3+
buffer[1][1][1] = 42;
4+
int i = buffer[1][1][1];
5+
return i;
6+
}
Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1-
2-
struct X {
3-
int i;
4-
int j;
5-
X(int i, int j) : i(i), j(j) {}
1+
struct S {
2+
int a;
3+
int b;
4+
int c;
65
};
76

87
int main() {
9-
X x(10, 20);
10-
int a = x.i;
11-
return a;
8+
int i = 1;
9+
int j = 2;
10+
int k = 3;
11+
S l;
12+
l.a = i;
13+
l.b = j;
14+
l.c = k;
15+
int x = l.a;
16+
int y = l.b;
17+
int z = l.c;
18+
return 0;
1219
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
struct X {
3+
int i;
4+
};
5+
6+
struct Y {
7+
X x;
8+
int j;
9+
};
10+
11+
int main() {
12+
Y b;
13+
b.x.i = 1000;
14+
b.j = 2000;
15+
int k = b.x.i;
16+
int l = b.j;
17+
return 0;
18+
}

0 commit comments

Comments
 (0)