Skip to content

Commit 1cb6845

Browse files
Completed operations of two variables
Support for a + b, a + 1, 1 + a, a - b, a - 1, 1 - a
1 parent 8a68918 commit 1cb6845

File tree

17 files changed

+494
-28
lines changed

17 files changed

+494
-28
lines changed

Hpps.cpp

Lines changed: 91 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ using namespace llvm;
1515

1616
namespace
1717
{
18+
1819
struct Hpps : public FunctionPass
1920
{
2021
static char ID;
@@ -23,15 +24,19 @@ namespace
2324
// Run over a single function
2425
bool runOnFunction(Function &Func) override
2526
{
27+
// Null Value reference
28+
LLVMContext &context = Func.getContext();
29+
Value *nullValue = ConstantInt::get(Type::getInt32Ty(context), -1);
30+
2631
// Keep reference of value still left to find the ranges
2732
// 'from' is unknown, it depends on 'to', 'toValue', and 'toOps' ('+' or '-')
2833
// from = to toOps toValue (a = b + 1)
2934
// from = toValue toOps to (a = 1 + b)
3035
// from = to toOps to2 (a = b + c)
3136
std::vector<Value *> from;
3237
std::vector<Value *> to;
33-
std::vector<int> toValue;
3438
std::vector<Value *> to2;
39+
std::vector<int> toValue;
3540
std::vector<unsigned> toOps;
3641

3742
// Reference of variabiles for which range has been found
@@ -58,30 +63,31 @@ namespace
5863
{
5964
Value *v = U.get();
6065
loadRef.push_back(v);
61-
errs() << " -Load:" << v->getName() << "\n";
66+
errs() << " -Load: " << v->getName() << "\n";
6267
}
6368
}
6469

65-
// When instruction is Add or Sub
70+
// When instruction is Add or Sub (a = a + c or a = b + 1 or a = 1 + b)
6671
// Save operand0 (reference/constant) and operand1 (reference/constant)
6772
if (auto *operInst = dyn_cast<BinaryOperator>(&I))
6873
{
6974
Value *oper0 = operInst->getOperand(0);
7075
Value *oper1 = operInst->getOperand(1);
7176

7277
// Store reference of variable still to find range
73-
from.push_back(operInst);
78+
from.push_back(operInst); // left-hand side of the operation
7479
toOps.push_back(operInst->getOpcode()); // '+' ot '-'
7580

7681
// Store constants/references
77-
errs() << " -Stored:" << operInst->getName() << "\n";
82+
errs() << " -Operation: " << operInst->getName() << "\n";
7883

7984
// a = b + 1 (variable + constant)
8085
// Get reference from previous load instruction
8186
if (ConstantInt *CI = dyn_cast<ConstantInt>(oper1))
8287
{
8388
toValue.push_back(CI->getZExtValue());
8489
to.push_back(loadRef.at(0));
90+
to2.push_back(nullValue);
8591
loadRef.pop_back();
8692
}
8793

@@ -90,25 +96,35 @@ namespace
9096
else if (ConstantInt *CI = dyn_cast<ConstantInt>(oper0))
9197
{
9298
toValue.push_back(CI->getZExtValue());
93-
to.push_back(loadRef.at(0));
99+
to.push_back(nullValue);
100+
to2.push_back(loadRef.at(0));
94101
loadRef.pop_back();
95102
}
96103

97104
// a = b + c (variable + variable)
98105
// Get reference from two previous load instructions
99106
else
100107
{
101-
// TODO: It may be that there are x2 'to', create a struct to handle them both
108+
// It may be that there are x2 'to'
109+
toValue.push_back(0);
102110
to.push_back(loadRef.at(0));
103-
to.push_back(loadRef.at(1));
111+
112+
// TODO: When a = a + b + 3, the IR creates two loads for a and b, then
113+
// it does the 'add' = a + b, and then uses 'add1' = 'add' + 3. The problem
114+
// is that 'add' is not in loadRef, so there is an error!
115+
//
116+
// Same with a = a + b + c, 'add' = a + b, then load of c and 'add1' = 'add' + c,
117+
// but since those are both variables, and loadRef contains only c, calling
118+
// loadRef.at(1) gives error!
119+
to2.push_back(loadRef.at(1));
104120

105121
// Remove previous used load instruction value
106122
loadRef.pop_back();
107123
loadRef.pop_back();
108124
}
109125
}
110126

111-
// When instruction is store
127+
// When instruction is store (a = b or a = 1)
112128
if (auto *strInst = dyn_cast<StoreInst>(&I))
113129
{
114130
// Get operand0 (value) and operand1 (assigned)
@@ -120,10 +136,11 @@ namespace
120136
// a = b
121137
if (oper0->hasName())
122138
{
123-
errs() << " -Ref:" << oper0->getName() << "\n";
139+
errs() << " -Ref: " << oper0->getName() << "\n";
124140
from.push_back(oper1); // a
125141
to.push_back(oper0); // b
126142

143+
to2.push_back(nullValue); // Placeholder
127144
toValue.push_back(0); // Placeholder
128145
toOps.push_back(Instruction::Add); // Placeholder
129146
}
@@ -134,7 +151,7 @@ namespace
134151
{
135152
if (ConstantInt *CI = dyn_cast<ConstantInt>(oper0))
136153
{
137-
errs() << " -Const:" << CI->getZExtValue() << "\n";
154+
errs() << " -Range found: " << CI->getZExtValue() << "\n";
138155
ranged.push_back(oper1);
139156
minRange.push_back(CI->getZExtValue());
140157
maxRange.push_back(CI->getZExtValue());
@@ -147,39 +164,85 @@ namespace
147164
}
148165

149166
// Resolve references
150-
errs() << "\nREFERENCES:\n";
167+
errs() << "\n--- REFERENCES ---\n";
151168
for (unsigned i = 0; i < from.size(); ++i)
152169
{
153-
errs() << to.at(i)->getName() << "+" << toValue.at(i) << "<-" << from.at(i)->getName() << "\n";
170+
// Print all dependencies
171+
errs() << from.at(i)->getName() << "(";
172+
if (to.at(i) == nullValue)
173+
{
174+
errs() << toValue.at(i) << ", ";
175+
}
176+
else
177+
{
178+
errs() << to.at(i)->getName() << ", ";
179+
}
180+
if (to2.at(i) == nullValue)
181+
{
182+
errs() << toValue.at(i) << ")\n";
183+
}
184+
else
185+
{
186+
errs() << to2.at(i)->getName() << ")\n";
187+
}
188+
189+
// Get value from ranged ranges
190+
int refValue1 = -1;
191+
int refValue2 = -1;
192+
193+
if (to.at(i) == nullValue)
194+
{
195+
refValue1 = toValue.at(i);
196+
// errs() << "- F(const):" << refValue1 << "\n";
197+
}
198+
199+
if (to2.at(i) == nullValue)
200+
{
201+
refValue2 = toValue.at(i);
202+
// errs() << "- F(const):" << refValue2 << "\n";
203+
}
154204

155205
// Search variable reference inside already found ranges
156206
for (unsigned v = 0; v < ranged.size(); ++v)
157207
{
158-
// When range found, add a new found range
208+
// When found value of 'to' in 'ranged'
159209
if (to.at(i) == ranged.at(v))
160210
{
161-
errs() << "-FOUND:" << ranged.at(v)->getName() << "\n";
162-
if (toOps.at(i) == Instruction::Add)
163-
{
164-
minRange.push_back(minRange.at(v) + toValue.at(i));
165-
maxRange.push_back(minRange.at(v) + toValue.at(i));
166-
}
167-
else if (toOps.at(i) == Instruction::Sub)
168-
{
169-
minRange.push_back(minRange.at(v) - toValue.at(i));
170-
maxRange.push_back(minRange.at(v) - toValue.at(i));
171-
}
211+
// When range found, add a new found range
212+
refValue1 = minRange.at(v);
213+
// errs() << "- F(to):" << ranged.at(v)->getName() << " (" << refValue1 << "\n\n";
214+
}
172215

173-
ranged.push_back(from.at(i));
216+
// When found value of 'to2' in 'ranged'
217+
if (to2.at(i) == ranged.at(v))
218+
{
219+
// When range found, add a new found range
220+
refValue2 = minRange.at(v);
221+
// errs() << "- F(to2):" << ranged.at(v)->getName() << " (" << refValue2 << "\n\n";
174222
}
175223
}
224+
225+
if (toOps.at(i) == Instruction::Add)
226+
{
227+
minRange.push_back(refValue1 + refValue2);
228+
maxRange.push_back(refValue1 + refValue2);
229+
ranged.push_back(from.at(i));
230+
errs() << " " << from.at(i)->getName() << " = " << refValue1 << " + " << refValue2 << " = " << (refValue1 + refValue2) << "\n\n";
231+
}
232+
else if (toOps.at(i) == Instruction::Sub)
233+
{
234+
minRange.push_back(refValue1 - refValue2);
235+
maxRange.push_back(refValue1 - refValue2);
236+
ranged.push_back(from.at(i));
237+
errs() << " " << from.at(i)->getName() << " = " << refValue1 << " - " << refValue2 << " = " << (refValue1 - refValue2) << "\n\n";
238+
}
176239
}
177240

178241
// Print value range computed
179-
errs() << "\nVALUE RANGES\n";
242+
errs() << "\n--- VALUE RANGES ---\n";
180243
for (unsigned i = 0; i < minRange.size(); ++i)
181244
{
182-
errs() << ranged.at(i)->getName() << "(" << minRange.at(i) << ", " << maxRange.at(i) << ")\n";
245+
errs() << " " << ranged.at(i)->getName() << "(" << minRange.at(i) << ", " << maxRange.at(i) << ")\n";
183246
}
184247

185248
return false;

IR/interm.ll

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
; ModuleID = '../../../code/interm.c'
2+
source_filename = "../../../code/interm.c"
3+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4+
target triple = "x86_64-unknown-linux-gnu"
5+
6+
; Function Attrs: noinline nounwind optnone uwtable
7+
define dso_local i32 @main() #0 {
8+
entry:
9+
%retval = alloca i32, align 4
10+
%a = alloca i32, align 4
11+
%b = alloca i32, align 4
12+
%c = alloca i32, align 4
13+
%d = alloca i32, align 4
14+
%e = alloca i32, align 4
15+
store i32 0, i32* %retval, align 4
16+
store i32 0, i32* %a, align 4
17+
store i32 10, i32* %b, align 4
18+
%0 = load i32, i32* %a, align 4
19+
%add = add nsw i32 3, %0
20+
store i32 %add, i32* %c, align 4
21+
%1 = load i32, i32* %b, align 4
22+
%2 = load i32, i32* %c, align 4
23+
%sub = sub nsw i32 %1, %2
24+
store i32 %sub, i32* %d, align 4
25+
%3 = load i32, i32* %d, align 4
26+
%add1 = add nsw i32 %3, 7
27+
store i32 %add1, i32* %e, align 4
28+
ret i32 0
29+
}
30+
31+
attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
32+
33+
!llvm.module.flags = !{!0}
34+
!llvm.ident = !{!1}
35+
36+
!0 = !{i32 1, !"wchar_size", i32 4}
37+
!1 = !{!"clang version 7.1.0 "}

IR/interm.txt

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
%retval = alloca i32, align 4
2+
%a = alloca i32, align 4
3+
%b = alloca i32, align 4
4+
%c = alloca i32, align 4
5+
%d = alloca i32, align 4
6+
%e = alloca i32, align 4
7+
store i32 0, i32* %retval, align 4 retval = 0 ranged = [ {retval, 0, 0} ]
8+
store i32 0, i32* %a, align 4 a = 0 ranged = [ {retval, 0, 0}, {a, 0, 0} ]
9+
store i32 10, i32* %b, align 4 b = 10 ranged = [ {retval, 0, 0}, {a, 0, 0}, {b, 10, 10} ]
10+
%0 = load i32, i32* %a, align 4 loadRef = [ a ]
11+
%add = add nsw i32 3, %0 add = 3 + a, loadRef = [] ref = [ {add, /, a, 3, + } ]
12+
store i32 %add, i32* %c, align 4 c = add ref = [ {add, /, a, 3, + }, {c, add, /, 0, +} ]
13+
%1 = load i32, i32* %b, align 4 loadRef = [ b ]
14+
%2 = load i32, i32* %c, align 4 loadRef = [ b, c ]
15+
%sub = sub nsw i32 %1, %2 sub = b - c, loadRef = [] ref = [ {add, /, a, 3, + }, {c, add, /, 0, +}, {sub, b, c, 0, -} ]
16+
store i32 %sub, i32* %d, align 4 d = sub ref = [ {add, /, a, 3, + }, {c, add, /, 0, +}, {sub, b, c, 0, -}, {d, sub, /, 0, -} ]
17+
%3 = load i32, i32* %d, align 4 loadRef = [ d ]
18+
%add1 = add nsw i32 %3, 7 add1 = d + 7, loadRef = [] ref = [ {add, /, a, 3, + }, {c, add, /, 0, +}, {sub, b, c, 0, -}, {d, sub, /, 0, -}, {add1, d, /, 7, +} ]
19+
store i32 %add1, i32* %e, align 4 e = add1 ref = [ {add, /, a, 3, + }, {c, add, /, 0, +}, {sub, b, c, 0, -}, {d, sub, /, 0, -}, {add1, d, /, 7, +}, {e, add1, /, 0, +} ]
20+
ret i32 0
21+
22+
ref = [
23+
{add, /, a, 3, + },
24+
{c, add, /, 0, +},
25+
{sub, b, c, 0, -},
26+
{d, sub, /, 0, -},
27+
{add1, d, /, 7, +},
28+
{e, add1, /, 0, +}
29+
]
30+
31+
ranged = [
32+
{retval, 0, 0},
33+
{a, 0, 0},
34+
{b, 10, 10}
35+
]
36+
37+
a = 0 -> add = a + 3 = 0 + 3 = 3
38+
ranged = [ {retval, 0, 0}, {a, 0, 0}, {b, 10, 10}, {add, 3, 3} ]
39+
40+
add = 3 -> c = add = 3
41+
ranged = [ {retval, 0, 0}, {a, 0, 0}, {b, 10, 10}, {add, 3, 3}, {c, 3, 3} ]
42+
43+
b = 10
44+
c = 3
45+
-> sub = b - c = 10 - 3 = 7
46+
ranged = [ {retval, 0, 0}, {a, 0, 0}, {b, 10, 10}, {add, 3, 3}, {c, 3, 3}, {sub, 7, 7} ]
47+
48+
d = 7 -> add1 = d + 7 = 14
49+
ranged = [ {retval, 0, 0}, {a, 0, 0}, {b, 10, 10}, {add, 3, 3}, {c, 3, 3}, {sub, 7, 7}, {add1, 14, 14} ]
50+
51+
add1 = 14 -> e = add1 = 14
52+
ranged = [ {retval, 0, 0}, {a, 0, 0}, {b, 10, 10}, {add, 3, 3}, {c, 3, 3}, {sub, 7, 7}, {add1, 14, 14}, {e, 14, 14} ]
53+
54+
ranged = [
55+
{retval, 0, 0},
56+
{a, 0, 0},
57+
{b, 10, 10},
58+
{add, 3, 3},
59+
{c, 3, 3},
60+
{sub, 7, 7},
61+
{add1, 14, 14},
62+
{e, 14, 14}
63+
]

simple.ll renamed to IR/simple.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,16 @@ entry:
1010
%a = alloca i32, align 4
1111
%b = alloca i32, align 4
1212
%c = alloca i32, align 4
13+
%d = alloca i32, align 4
1314
store i32 0, i32* %retval, align 4
1415
store i32 0, i32* %a, align 4
1516
store i32 10, i32* %b, align 4
1617
%0 = load i32, i32* %a, align 4
1718
%add = add nsw i32 %0, 3
1819
store i32 %add, i32* %c, align 4
20+
%1 = load i32, i32* %b, align 4
21+
%add1 = add nsw i32 %1, 10
22+
store i32 %add1, i32* %d, align 4
1923
ret i32 0
2024
}
2125

IR/simple2.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; ModuleID = '../../../code/simple2.c'
2+
source_filename = "../../../code/simple2.c"
3+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4+
target triple = "x86_64-unknown-linux-gnu"
5+
6+
; Function Attrs: noinline nounwind optnone uwtable
7+
define dso_local i32 @main() #0 {
8+
entry:
9+
%retval = alloca i32, align 4
10+
%a = alloca i32, align 4
11+
%b = alloca i32, align 4
12+
%c = alloca i32, align 4
13+
%d = alloca i32, align 4
14+
store i32 0, i32* %retval, align 4
15+
store i32 0, i32* %a, align 4
16+
store i32 10, i32* %b, align 4
17+
%0 = load i32, i32* %a, align 4
18+
%sub = sub nsw i32 %0, 3
19+
store i32 %sub, i32* %c, align 4
20+
%1 = load i32, i32* %b, align 4
21+
%sub1 = sub nsw i32 %1, 6
22+
store i32 %sub1, i32* %d, align 4
23+
ret i32 0
24+
}
25+
26+
attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
27+
28+
!llvm.module.flags = !{!0}
29+
!llvm.ident = !{!1}
30+
31+
!0 = !{i32 1, !"wchar_size", i32 4}
32+
!1 = !{!"clang version 7.1.0 "}

0 commit comments

Comments
 (0)