6
6
#include " llvm/IR/Instructions.h"
7
7
#include " llvm/Pass.h"
8
8
#include " llvm/Support/raw_ostream.h"
9
+ #include " llvm/IR/InstrTypes.h"
9
10
10
11
#include " llvm/IR/LegacyPassManager.h"
11
12
#include " llvm/Transforms/IPO/PassManagerBuilder.h"
@@ -22,51 +23,91 @@ namespace
22
23
// Run over a single function
23
24
bool runOnFunction (Function &Func) override
24
25
{
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;
33
41
34
42
// Run over all basic blocks in the function
35
43
for (BasicBlock &BB : Func)
36
44
{
37
45
// Run over all instructions in the basic block
38
46
for (Instruction &I : BB)
39
47
{
40
- // The next statement works since operator<<(ostream&,...)
41
- // is overloaded for Instruction&
48
+ // Print instruction
42
49
errs () << I << " \n " ;
43
50
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
+ }
48
73
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
+ }
53
81
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
55
93
if (auto *strInst = dyn_cast<StoreInst>(&I))
56
- {
94
+ {
57
95
// Get operand0 (value) and operand1 (assigned)
58
96
Value *oper0 = strInst->getOperand (0 );
59
97
Value *oper1 = strInst->getOperand (1 );
60
98
61
- // Oper0 is reference
99
+ // Store reference to variable still to find range
62
100
if (oper0->hasName ())
63
101
{
64
102
errs () << " -Ref:" << oper0->getName () << " \n " ;
65
103
from.push_back (oper1);
66
104
to.push_back (oper0);
105
+
106
+ toValue.push_back (0 );
107
+ toOps.push_back (Instruction::Add);
67
108
}
68
109
69
- // Oper0 is constant
110
+ // Store constant range value
70
111
else
71
112
{
72
113
if (ConstantInt *CI = dyn_cast<ConstantInt>(oper0))
@@ -77,20 +118,6 @@ namespace
77
118
maxRange.push_back (CI->getZExtValue ());
78
119
}
79
120
}
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
- // }
94
121
}
95
122
96
123
errs () << " \n " ;
@@ -101,7 +128,20 @@ namespace
101
128
errs () << " \n REFERENCES:\n " ;
102
129
for (auto i = 0 ; i < from.size (); ++i)
103
130
{
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
+ }
105
145
}
106
146
107
147
// Print value range computed
0 commit comments