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 () << " \n REFERENCES:\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
0 commit comments