Skip to content

Commit ffc8203

Browse files
Complete v1.0 range analysis
1 parent 85e832b commit ffc8203

File tree

3 files changed

+129
-39
lines changed

3 files changed

+129
-39
lines changed

Hpps.cpp

Lines changed: 77 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "llvm/IR/Instructions.h"
77
#include "llvm/Pass.h"
88
#include "llvm/Support/raw_ostream.h"
9+
#include "llvm/IR/InstrTypes.h"
910

1011
#include "llvm/IR/LegacyPassManager.h"
1112
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
@@ -22,51 +23,91 @@ namespace
2223
// Run over a single function
2324
bool runOnFunction(Function &Func) override
2425
{
25-
// Reference to unroll
26-
std::vector<Value *> from; // Value that depend on
27-
std::vector<Value *> to; // Value that depend to
28-
29-
// Found range
30-
std::vector<Value *> ranged; // Reference to the value found
31-
std::vector<int> minRange;
32-
std::vector<int> maxRange;
26+
// Keep reference of value still left to find the ranges
27+
// 'from' is unknown, it depends on 'to' and 'toValue'
28+
// from = to + toValue
29+
std::vector<Value *> from;
30+
std::vector<Value *> to;
31+
std::vector<int> toValue;
32+
std::vector<unsigned> toOps;
33+
34+
// Reference of variabiles for which range has been found
35+
std::vector<Value *> ranged; // Reference to the variable
36+
std::vector<int> minRange; // Min range of variable
37+
std::vector<int> maxRange; // Max range of variable
38+
39+
// Keep reference of variables in load instructions
40+
std::vector<Value *> loadRef;
3341

3442
// Run over all basic blocks in the function
3543
for (BasicBlock &BB : Func)
3644
{
3745
// Run over all instructions in the basic block
3846
for (Instruction &I : BB)
3947
{
40-
// The next statement works since operator<<(ostream&,...)
41-
// is overloaded for Instruction&
48+
// Print instruction
4249
errs() << I << "\n";
4350

44-
// if (auto *operInst = dyn_cast<BinaryOperator>(&I))
45-
// {
46-
// errs() << "Operand" << operInst->getName() << "\n";
47-
// }
51+
// When instruction is Add or Sub
52+
// Save operand0 (variable) and operand1 (int)
53+
// 'to' -> Previous load instruction value
54+
// 'from' -> Current assigned variable value
55+
// 'toValue' -> Operand1 int value
56+
if (auto *operInst = dyn_cast<BinaryOperator>(&I))
57+
{
58+
Value *oper0 = operInst->getOperand(0);
59+
Value *oper1 = operInst->getOperand(1);
60+
61+
if (operInst->getOpcode() == Instruction::Add)
62+
{
63+
errs() << " -Stored:" << operInst->getName() << "\n";
64+
65+
// Store reference of variable still to find range
66+
from.push_back(operInst);
67+
to.push_back(loadRef.at(0));
68+
toOps.push_back(operInst->getOpcode());
69+
if (ConstantInt *CI = dyn_cast<ConstantInt>(oper1))
70+
{
71+
toValue.push_back(CI->getZExtValue());
72+
}
4873

49-
// if (auto *loadInst = dyn_cast<LoadInst>(&I))
50-
// {
51-
// errs() << "Load" << loadInst->getPointerOperand()->getName() << "\n";
52-
// }
74+
// Remove previous used load instruction value
75+
loadRef.pop_back();
76+
}
77+
else if (operInst->getOpcode() == Instruction::Sub)
78+
{
79+
}
80+
}
5381

54-
// STORE INSTRUCTION (Check all store in first cycle)
82+
// When instruction is load, store reference to its variable
83+
if (auto *loadInst = dyn_cast<LoadInst>(&I))
84+
{
85+
for (Use &U : loadInst->operands())
86+
{
87+
Value *v = U.get();
88+
loadRef.push_back(v);
89+
}
90+
}
91+
92+
// When instruction is store
5593
if (auto *strInst = dyn_cast<StoreInst>(&I))
56-
{
94+
{
5795
// Get operand0 (value) and operand1 (assigned)
5896
Value *oper0 = strInst->getOperand(0);
5997
Value *oper1 = strInst->getOperand(1);
6098

61-
// Oper0 is reference
99+
// Store reference to variable still to find range
62100
if (oper0->hasName())
63101
{
64102
errs() << " -Ref:" << oper0->getName() << "\n";
65103
from.push_back(oper1);
66104
to.push_back(oper0);
105+
106+
toValue.push_back(0);
107+
toOps.push_back(Instruction::Add);
67108
}
68109

69-
// Oper0 is constant
110+
// Store constant range value
70111
else
71112
{
72113
if (ConstantInt *CI = dyn_cast<ConstantInt>(oper0))
@@ -77,20 +118,6 @@ namespace
77118
maxRange.push_back(CI->getZExtValue());
78119
}
79120
}
80-
81-
// for (User *U : oper1->users())
82-
// {
83-
// if (Instruction *Inst = dyn_cast<Instruction>(U))
84-
// {
85-
// errs() << "-USED:" << *Inst << "\n";
86-
87-
// for (Use &U : Inst->operands())
88-
// {
89-
// Value *v = U.get();
90-
// errs() << "-DEF:" << v->getName() << "\n";
91-
// }
92-
// }
93-
// }
94121
}
95122

96123
errs() << "\n";
@@ -101,7 +128,20 @@ namespace
101128
errs() << "\nREFERENCES:\n";
102129
for (auto i = 0; i < from.size(); ++i)
103130
{
104-
errs() << to.at(i)->getName() << "(" << to.at(i) << ") <-" << from.at(i)->getName() << "\n";
131+
errs() << to.at(i)->getName() << "+" << toValue.at(i) << "<-" << from.at(i)->getName() << "\n";
132+
133+
// Search variable reference inside already found ranges
134+
for (int v = 0; v < ranged.size(); ++v)
135+
{
136+
// When range found, add a new found range
137+
if (to.at(i) == ranged.at(v))
138+
{
139+
errs() << "-FOUND:" << ranged.at(v)->getName() << "\n";
140+
minRange.push_back(minRange.at(v) + toValue.at(i));
141+
maxRange.push_back(minRange.at(v) + toValue.at(i));
142+
ranged.push_back(from.at(i));
143+
}
144+
}
105145
}
106146

107147
// Print value range computed

result.txt

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
discovered a new reachable node %entry
12
%retval = alloca i32, align 4
23

34
%a = alloca i32, align 4
@@ -6,6 +7,8 @@
67

78
%c = alloca i32, align 4
89

10+
%d = alloca i32, align 4
11+
912
store i32 0, i32* %retval, align 4
1013
-Const:0
1114

@@ -18,18 +21,56 @@
1821
%0 = load i32, i32* %a, align 4
1922

2023
%add = add nsw i32 %0, 3
24+
-Reg:add-a
2125

2226
store i32 %add, i32* %c, align 4
2327
-Ref:add
2428

29+
%1 = load i32, i32* %b, align 4
30+
31+
%add1 = add nsw i32 %1, 10
32+
-Reg:add1-b
33+
34+
store i32 %add1, i32* %d, align 4
35+
-Ref:add1
36+
2537
ret i32 0
2638

2739

2840
REFERENCES:
29-
add(0x83ef100) <-c
41+
a+3<-add
42+
-NOT_FOUND
43+
-FOUND:a
44+
-NOT_FOUND
45+
-NOT_FOUND
46+
add+0<-c
47+
-NOT_FOUND
48+
-NOT_FOUND
49+
-NOT_FOUND
50+
-FOUND:add
51+
-NOT_FOUND
52+
b+10<-add1
53+
-NOT_FOUND
54+
-NOT_FOUND
55+
-FOUND:b
56+
-NOT_FOUND
57+
-NOT_FOUND
58+
-NOT_FOUND
59+
add1+0<-d
60+
-NOT_FOUND
61+
-NOT_FOUND
62+
-NOT_FOUND
63+
-NOT_FOUND
64+
-NOT_FOUND
65+
-FOUND:add1
66+
-NOT_FOUND
3067

3168
VALUE RANGES:
3269
retval(0, 0)
3370
a(0, 0)
3471
b(10, 10)
35-
72+
add(3, 3)
73+
c(3, 3)
74+
add1(20, 20)
75+
d(20, 20)
76+
discovered a new reachable node %entry

simple.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <stdio.h>
2+
3+
int main() {
4+
int a = 0;
5+
int b = 10;
6+
int c = a + 3;
7+
int d = b + 10;
8+
return 0;
9+
}

0 commit comments

Comments
 (0)