@@ -24,11 +24,14 @@ namespace
24
24
bool runOnFunction (Function &Func) override
25
25
{
26
26
// Keep reference of value still left to find the ranges
27
- // 'from' is unknown, it depends on 'to', 'toValue', and 'toOps'
28
- // from = to toOps('+' or '-') toValue
27
+ // 'from' is unknown, it depends on 'to', 'toValue', and 'toOps' ('+' or '-')
28
+ // from = to toOps toValue (a = b + 1)
29
+ // from = toValue toOps to (a = 1 + b)
30
+ // from = to toOps to2 (a = b + c)
29
31
std::vector<Value *> from;
30
32
std::vector<Value *> to;
31
33
std::vector<int > toValue;
34
+ std::vector<Value *> to2;
32
35
std::vector<unsigned > toOps;
33
36
34
37
// Reference of variabiles for which range has been found
@@ -48,80 +51,85 @@ namespace
48
51
// Print instruction
49
52
errs () << I << " \n " ;
50
53
54
+ // When instruction is load, store reference to its variables
55
+ if (auto *loadInst = dyn_cast<LoadInst>(&I))
56
+ {
57
+ for (Use &U : loadInst->operands ())
58
+ {
59
+ Value *v = U.get ();
60
+ loadRef.push_back (v);
61
+ errs () << " -Load:" << v->getName () << " \n " ;
62
+ }
63
+ }
64
+
51
65
// 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
66
+ // Save operand0 (reference/constant) and operand1 (reference/constant)
56
67
if (auto *operInst = dyn_cast<BinaryOperator>(&I))
57
68
{
58
- // Value *oper0 = operInst->getOperand(0);
69
+ Value *oper0 = operInst->getOperand (0 );
59
70
Value *oper1 = operInst->getOperand (1 );
60
71
61
- // Store opcode ('+' or '-') to find real value range
62
- if (operInst->getOpcode () == Instruction::Add)
63
- {
64
- errs () << " -Stored(Add):" << operInst->getName () << " \n " ;
72
+ // Store reference of variable still to find range
73
+ from.push_back (operInst);
74
+ toOps.push_back (operInst->getOpcode ()); // '+' ot '-'
65
75
66
- // Store reference of variable still to find range
67
- from.push_back (operInst);
68
- to.push_back (loadRef.at (0 ));
69
- toOps.push_back (operInst->getOpcode ());
70
- if (ConstantInt *CI = dyn_cast<ConstantInt>(oper1))
71
- {
72
- toValue.push_back (CI->getZExtValue ());
73
- }
76
+ // Store constants/references
77
+ errs () << " -Stored:" << operInst->getName () << " \n " ;
74
78
75
- // Remove previous used load instruction value
79
+ // a = b + 1 (variable + constant)
80
+ // Get reference from previous load instruction
81
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(oper1))
82
+ {
83
+ toValue.push_back (CI->getZExtValue ());
84
+ to.push_back (loadRef.at (0 ));
76
85
loadRef.pop_back ();
77
86
}
78
- else if (operInst->getOpcode () == Instruction::Sub)
79
- {
80
- errs () << " -Stored(Sub):" << operInst->getName () << " \n " ;
81
87
82
- // Store reference of variable still to find range
83
- from.push_back (operInst);
88
+ // a = 1 + b (constant + variable)
89
+ // Get reference from previous load instruction
90
+ else if (ConstantInt *CI = dyn_cast<ConstantInt>(oper0))
91
+ {
92
+ toValue.push_back (CI->getZExtValue ());
84
93
to.push_back (loadRef.at (0 ));
85
- toOps.push_back (operInst->getOpcode ());
86
- if (ConstantInt *CI = dyn_cast<ConstantInt>(oper1))
87
- {
88
- toValue.push_back (CI->getZExtValue ());
89
- }
90
-
91
- // Remove previous used load instruction value
92
94
loadRef.pop_back ();
93
95
}
94
- }
95
96
96
- // When instruction is load, store reference to its variable
97
- if (auto *loadInst = dyn_cast<LoadInst>(&I))
98
- {
99
- for (Use &U : loadInst->operands ())
97
+ // a = b + c (variable + variable)
98
+ // Get reference from two previous load instructions
99
+ else
100
100
{
101
- Value *v = U.get ();
102
- loadRef.push_back (v);
101
+ // TODO: It may be that there are x2 'to', create a struct to handle them both
102
+ to.push_back (loadRef.at (0 ));
103
+ to.push_back (loadRef.at (1 ));
104
+
105
+ // Remove previous used load instruction value
106
+ loadRef.pop_back ();
107
+ loadRef.pop_back ();
103
108
}
104
109
}
105
110
106
111
// When instruction is store
107
112
if (auto *strInst = dyn_cast<StoreInst>(&I))
108
113
{
109
114
// Get operand0 (value) and operand1 (assigned)
115
+ // operand1 = operand0
110
116
Value *oper0 = strInst->getOperand (0 );
111
117
Value *oper1 = strInst->getOperand (1 );
112
118
113
119
// Store reference to variable still to find range
120
+ // a = b
114
121
if (oper0->hasName ())
115
122
{
116
123
errs () << " -Ref:" << oper0->getName () << " \n " ;
117
- from.push_back (oper1);
118
- to.push_back (oper0);
124
+ from.push_back (oper1); // a
125
+ to.push_back (oper0); // b
119
126
120
- toValue.push_back (0 );
121
- toOps.push_back (Instruction::Add);
127
+ toValue.push_back (0 ); // Placeholder
128
+ toOps.push_back (Instruction::Add); // Placeholder
122
129
}
123
130
124
- // Store constant range value
131
+ // Store constant range value (Value-Range Found!)
132
+ // a = 1
125
133
else
126
134
{
127
135
if (ConstantInt *CI = dyn_cast<ConstantInt>(oper0))
@@ -138,7 +146,7 @@ namespace
138
146
}
139
147
}
140
148
141
- // Print references
149
+ // Resolve references
142
150
errs () << " \n REFERENCES:\n " ;
143
151
for (unsigned i = 0 ; i < from.size (); ++i)
144
152
{
0 commit comments