1*9880d681SAndroid Build Coastguard Worker //===--- BitTracker.h -----------------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #ifndef BITTRACKER_H
11*9880d681SAndroid Build Coastguard Worker #define BITTRACKER_H
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SetVector.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Worker #include <map>
18*9880d681SAndroid Build Coastguard Worker #include <queue>
19*9880d681SAndroid Build Coastguard Worker #include <set>
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker namespace llvm {
22*9880d681SAndroid Build Coastguard Worker class ConstantInt;
23*9880d681SAndroid Build Coastguard Worker class MachineRegisterInfo;
24*9880d681SAndroid Build Coastguard Worker class MachineBasicBlock;
25*9880d681SAndroid Build Coastguard Worker class MachineInstr;
26*9880d681SAndroid Build Coastguard Worker class MachineOperand;
27*9880d681SAndroid Build Coastguard Worker class raw_ostream;
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard Worker struct BitTracker {
30*9880d681SAndroid Build Coastguard Worker struct BitRef;
31*9880d681SAndroid Build Coastguard Worker struct RegisterRef;
32*9880d681SAndroid Build Coastguard Worker struct BitValue;
33*9880d681SAndroid Build Coastguard Worker struct BitMask;
34*9880d681SAndroid Build Coastguard Worker struct RegisterCell;
35*9880d681SAndroid Build Coastguard Worker struct MachineEvaluator;
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker typedef SetVector<const MachineBasicBlock *> BranchTargetList;
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker typedef std::map<unsigned, RegisterCell> CellMapType;
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker BitTracker(const MachineEvaluator &E, MachineFunction &F);
42*9880d681SAndroid Build Coastguard Worker ~BitTracker();
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker void run();
45*9880d681SAndroid Build Coastguard Worker void trace(bool On = false) { Trace = On; }
46*9880d681SAndroid Build Coastguard Worker bool has(unsigned Reg) const;
47*9880d681SAndroid Build Coastguard Worker const RegisterCell &lookup(unsigned Reg) const;
48*9880d681SAndroid Build Coastguard Worker RegisterCell get(RegisterRef RR) const;
49*9880d681SAndroid Build Coastguard Worker void put(RegisterRef RR, const RegisterCell &RC);
50*9880d681SAndroid Build Coastguard Worker void subst(RegisterRef OldRR, RegisterRef NewRR);
51*9880d681SAndroid Build Coastguard Worker bool reached(const MachineBasicBlock *B) const;
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker private:
54*9880d681SAndroid Build Coastguard Worker void visitPHI(const MachineInstr &PI);
55*9880d681SAndroid Build Coastguard Worker void visitNonBranch(const MachineInstr &MI);
56*9880d681SAndroid Build Coastguard Worker void visitBranchesFrom(const MachineInstr &BI);
57*9880d681SAndroid Build Coastguard Worker void visitUsesOf(unsigned Reg);
58*9880d681SAndroid Build Coastguard Worker void reset();
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker typedef std::pair<int,int> CFGEdge;
61*9880d681SAndroid Build Coastguard Worker typedef std::set<CFGEdge> EdgeSetType;
62*9880d681SAndroid Build Coastguard Worker typedef std::set<const MachineInstr *> InstrSetType;
63*9880d681SAndroid Build Coastguard Worker typedef std::queue<CFGEdge> EdgeQueueType;
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker EdgeSetType EdgeExec; // Executable flow graph edges.
66*9880d681SAndroid Build Coastguard Worker InstrSetType InstrExec; // Executable instructions.
67*9880d681SAndroid Build Coastguard Worker EdgeQueueType FlowQ; // Work queue of CFG edges.
68*9880d681SAndroid Build Coastguard Worker bool Trace; // Enable tracing for debugging.
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker const MachineEvaluator &ME;
71*9880d681SAndroid Build Coastguard Worker MachineFunction &MF;
72*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo &MRI;
73*9880d681SAndroid Build Coastguard Worker CellMapType ⤅
74*9880d681SAndroid Build Coastguard Worker };
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker // Abstraction of a reference to bit at position Pos from a register Reg.
78*9880d681SAndroid Build Coastguard Worker struct BitTracker::BitRef {
RegBitRef79*9880d681SAndroid Build Coastguard Worker BitRef(unsigned R = 0, uint16_t P = 0) : Reg(R), Pos(P) {}
80*9880d681SAndroid Build Coastguard Worker bool operator== (const BitRef &BR) const {
81*9880d681SAndroid Build Coastguard Worker // If Reg is 0, disregard Pos.
82*9880d681SAndroid Build Coastguard Worker return Reg == BR.Reg && (Reg == 0 || Pos == BR.Pos);
83*9880d681SAndroid Build Coastguard Worker }
84*9880d681SAndroid Build Coastguard Worker unsigned Reg;
85*9880d681SAndroid Build Coastguard Worker uint16_t Pos;
86*9880d681SAndroid Build Coastguard Worker };
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker
89*9880d681SAndroid Build Coastguard Worker // Abstraction of a register reference in MachineOperand. It contains the
90*9880d681SAndroid Build Coastguard Worker // register number and the subregister index.
91*9880d681SAndroid Build Coastguard Worker struct BitTracker::RegisterRef {
92*9880d681SAndroid Build Coastguard Worker RegisterRef(unsigned R = 0, unsigned S = 0)
RegRegisterRef93*9880d681SAndroid Build Coastguard Worker : Reg(R), Sub(S) {}
RegisterRefRegisterRef94*9880d681SAndroid Build Coastguard Worker RegisterRef(const MachineOperand &MO)
95*9880d681SAndroid Build Coastguard Worker : Reg(MO.getReg()), Sub(MO.getSubReg()) {}
96*9880d681SAndroid Build Coastguard Worker unsigned Reg, Sub;
97*9880d681SAndroid Build Coastguard Worker };
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Worker // Value that a single bit can take. This is outside of the context of
101*9880d681SAndroid Build Coastguard Worker // any register, it is more of an abstraction of the two-element set of
102*9880d681SAndroid Build Coastguard Worker // possible bit values. One extension here is the "Ref" type, which
103*9880d681SAndroid Build Coastguard Worker // indicates that this bit takes the same value as the bit described by
104*9880d681SAndroid Build Coastguard Worker // RefInfo.
105*9880d681SAndroid Build Coastguard Worker struct BitTracker::BitValue {
106*9880d681SAndroid Build Coastguard Worker enum ValueType {
107*9880d681SAndroid Build Coastguard Worker Top, // Bit not yet defined.
108*9880d681SAndroid Build Coastguard Worker Zero, // Bit = 0.
109*9880d681SAndroid Build Coastguard Worker One, // Bit = 1.
110*9880d681SAndroid Build Coastguard Worker Ref // Bit value same as the one described in RefI.
111*9880d681SAndroid Build Coastguard Worker // Conceptually, there is no explicit "bottom" value: the lattice's
112*9880d681SAndroid Build Coastguard Worker // bottom will be expressed as a "ref to itself", which, in the context
113*9880d681SAndroid Build Coastguard Worker // of registers, could be read as "this value of this bit is defined by
114*9880d681SAndroid Build Coastguard Worker // this bit".
115*9880d681SAndroid Build Coastguard Worker // The ordering is:
116*9880d681SAndroid Build Coastguard Worker // x <= Top,
117*9880d681SAndroid Build Coastguard Worker // Self <= x, where "Self" is "ref to itself".
118*9880d681SAndroid Build Coastguard Worker // This makes the value lattice different for each virtual register
119*9880d681SAndroid Build Coastguard Worker // (even for each bit in the same virtual register), since the "bottom"
120*9880d681SAndroid Build Coastguard Worker // for one register will be a simple "ref" for another register.
121*9880d681SAndroid Build Coastguard Worker // Since we do not store the "Self" bit and register number, the meet
122*9880d681SAndroid Build Coastguard Worker // operation will need to take it as a parameter.
123*9880d681SAndroid Build Coastguard Worker //
124*9880d681SAndroid Build Coastguard Worker // In practice there is a special case for values that are not associa-
125*9880d681SAndroid Build Coastguard Worker // ted with any specific virtual register. An example would be a value
126*9880d681SAndroid Build Coastguard Worker // corresponding to a bit of a physical register, or an intermediate
127*9880d681SAndroid Build Coastguard Worker // value obtained in some computation (such as instruction evaluation).
128*9880d681SAndroid Build Coastguard Worker // Such cases are identical to the usual Ref type, but the register
129*9880d681SAndroid Build Coastguard Worker // number is 0. In such case the Pos field of the reference is ignored.
130*9880d681SAndroid Build Coastguard Worker //
131*9880d681SAndroid Build Coastguard Worker // What is worthy of notice is that in value V (that is a "ref"), as long
132*9880d681SAndroid Build Coastguard Worker // as the RefI.Reg is not 0, it may actually be the same register as the
133*9880d681SAndroid Build Coastguard Worker // one in which V will be contained. If the RefI.Pos refers to the posi-
134*9880d681SAndroid Build Coastguard Worker // tion of V, then V is assumed to be "bottom" (as a "ref to itself"),
135*9880d681SAndroid Build Coastguard Worker // otherwise V is taken to be identical to the referenced bit of the
136*9880d681SAndroid Build Coastguard Worker // same register.
137*9880d681SAndroid Build Coastguard Worker // If RefI.Reg is 0, however, such a reference to the same register is
138*9880d681SAndroid Build Coastguard Worker // not possible. Any value V that is a "ref", and whose RefI.Reg is 0
139*9880d681SAndroid Build Coastguard Worker // is treated as "bottom".
140*9880d681SAndroid Build Coastguard Worker };
141*9880d681SAndroid Build Coastguard Worker ValueType Type;
142*9880d681SAndroid Build Coastguard Worker BitRef RefI;
143*9880d681SAndroid Build Coastguard Worker
TypeBitValue144*9880d681SAndroid Build Coastguard Worker BitValue(ValueType T = Top) : Type(T) {}
BitValueBitValue145*9880d681SAndroid Build Coastguard Worker BitValue(bool B) : Type(B ? One : Zero) {}
BitValueBitValue146*9880d681SAndroid Build Coastguard Worker BitValue(unsigned Reg, uint16_t Pos) : Type(Ref), RefI(Reg, Pos) {}
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker bool operator== (const BitValue &V) const {
149*9880d681SAndroid Build Coastguard Worker if (Type != V.Type)
150*9880d681SAndroid Build Coastguard Worker return false;
151*9880d681SAndroid Build Coastguard Worker if (Type == Ref && !(RefI == V.RefI))
152*9880d681SAndroid Build Coastguard Worker return false;
153*9880d681SAndroid Build Coastguard Worker return true;
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker bool operator!= (const BitValue &V) const {
156*9880d681SAndroid Build Coastguard Worker return !operator==(V);
157*9880d681SAndroid Build Coastguard Worker }
isBitValue158*9880d681SAndroid Build Coastguard Worker bool is(unsigned T) const {
159*9880d681SAndroid Build Coastguard Worker assert(T == 0 || T == 1);
160*9880d681SAndroid Build Coastguard Worker return T == 0 ? Type == Zero
161*9880d681SAndroid Build Coastguard Worker : (T == 1 ? Type == One : false);
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker // The "meet" operation is the "." operation in a semilattice (L, ., T, B):
165*9880d681SAndroid Build Coastguard Worker // (1) x.x = x
166*9880d681SAndroid Build Coastguard Worker // (2) x.y = y.x
167*9880d681SAndroid Build Coastguard Worker // (3) x.(y.z) = (x.y).z
168*9880d681SAndroid Build Coastguard Worker // (4) x.T = x (i.e. T = "top")
169*9880d681SAndroid Build Coastguard Worker // (5) x.B = B (i.e. B = "bottom")
170*9880d681SAndroid Build Coastguard Worker //
171*9880d681SAndroid Build Coastguard Worker // This "meet" function will update the value of the "*this" object with
172*9880d681SAndroid Build Coastguard Worker // the newly calculated one, and return "true" if the value of *this has
173*9880d681SAndroid Build Coastguard Worker // changed, and "false" otherwise.
174*9880d681SAndroid Build Coastguard Worker // To prove that it satisfies the conditions (1)-(5), it is sufficient
175*9880d681SAndroid Build Coastguard Worker // to show that a relation
176*9880d681SAndroid Build Coastguard Worker // x <= y <=> x.y = x
177*9880d681SAndroid Build Coastguard Worker // defines a partial order (i.e. that "meet" is same as "infimum").
meetBitValue178*9880d681SAndroid Build Coastguard Worker bool meet(const BitValue &V, const BitRef &Self) {
179*9880d681SAndroid Build Coastguard Worker // First, check the cases where there is nothing to be done.
180*9880d681SAndroid Build Coastguard Worker if (Type == Ref && RefI == Self) // Bottom.meet(V) = Bottom (i.e. This)
181*9880d681SAndroid Build Coastguard Worker return false;
182*9880d681SAndroid Build Coastguard Worker if (V.Type == Top) // This.meet(Top) = This
183*9880d681SAndroid Build Coastguard Worker return false;
184*9880d681SAndroid Build Coastguard Worker if (*this == V) // This.meet(This) = This
185*9880d681SAndroid Build Coastguard Worker return false;
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker // At this point, we know that the value of "this" will change.
188*9880d681SAndroid Build Coastguard Worker // If it is Top, it will become the same as V, otherwise it will
189*9880d681SAndroid Build Coastguard Worker // become "bottom" (i.e. Self).
190*9880d681SAndroid Build Coastguard Worker if (Type == Top) {
191*9880d681SAndroid Build Coastguard Worker Type = V.Type;
192*9880d681SAndroid Build Coastguard Worker RefI = V.RefI; // This may be irrelevant, but copy anyway.
193*9880d681SAndroid Build Coastguard Worker return true;
194*9880d681SAndroid Build Coastguard Worker }
195*9880d681SAndroid Build Coastguard Worker // Become "bottom".
196*9880d681SAndroid Build Coastguard Worker Type = Ref;
197*9880d681SAndroid Build Coastguard Worker RefI = Self;
198*9880d681SAndroid Build Coastguard Worker return true;
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker // Create a reference to the bit value V.
202*9880d681SAndroid Build Coastguard Worker static BitValue ref(const BitValue &V);
203*9880d681SAndroid Build Coastguard Worker // Create a "self".
204*9880d681SAndroid Build Coastguard Worker static BitValue self(const BitRef &Self = BitRef());
205*9880d681SAndroid Build Coastguard Worker
numBitValue206*9880d681SAndroid Build Coastguard Worker bool num() const {
207*9880d681SAndroid Build Coastguard Worker return Type == Zero || Type == One;
208*9880d681SAndroid Build Coastguard Worker }
209*9880d681SAndroid Build Coastguard Worker operator bool() const {
210*9880d681SAndroid Build Coastguard Worker assert(Type == Zero || Type == One);
211*9880d681SAndroid Build Coastguard Worker return Type == One;
212*9880d681SAndroid Build Coastguard Worker }
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker friend raw_ostream &operator<<(raw_ostream &OS, const BitValue &BV);
215*9880d681SAndroid Build Coastguard Worker };
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker // This operation must be idempotent, i.e. ref(ref(V)) == ref(V).
219*9880d681SAndroid Build Coastguard Worker inline BitTracker::BitValue
ref(const BitValue & V)220*9880d681SAndroid Build Coastguard Worker BitTracker::BitValue::ref(const BitValue &V) {
221*9880d681SAndroid Build Coastguard Worker if (V.Type != Ref)
222*9880d681SAndroid Build Coastguard Worker return BitValue(V.Type);
223*9880d681SAndroid Build Coastguard Worker if (V.RefI.Reg != 0)
224*9880d681SAndroid Build Coastguard Worker return BitValue(V.RefI.Reg, V.RefI.Pos);
225*9880d681SAndroid Build Coastguard Worker return self();
226*9880d681SAndroid Build Coastguard Worker }
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Worker inline BitTracker::BitValue
self(const BitRef & Self)230*9880d681SAndroid Build Coastguard Worker BitTracker::BitValue::self(const BitRef &Self) {
231*9880d681SAndroid Build Coastguard Worker return BitValue(Self.Reg, Self.Pos);
232*9880d681SAndroid Build Coastguard Worker }
233*9880d681SAndroid Build Coastguard Worker
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Worker // A sequence of bits starting from index B up to and including index E.
236*9880d681SAndroid Build Coastguard Worker // If E < B, the mask represents two sections: [0..E] and [B..W) where
237*9880d681SAndroid Build Coastguard Worker // W is the width of the register.
238*9880d681SAndroid Build Coastguard Worker struct BitTracker::BitMask {
BitMaskBitMask239*9880d681SAndroid Build Coastguard Worker BitMask() : B(0), E(0) {}
BitMaskBitMask240*9880d681SAndroid Build Coastguard Worker BitMask(uint16_t b, uint16_t e) : B(b), E(e) {}
firstBitMask241*9880d681SAndroid Build Coastguard Worker uint16_t first() const { return B; }
lastBitMask242*9880d681SAndroid Build Coastguard Worker uint16_t last() const { return E; }
243*9880d681SAndroid Build Coastguard Worker private:
244*9880d681SAndroid Build Coastguard Worker uint16_t B, E;
245*9880d681SAndroid Build Coastguard Worker };
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Worker // Representation of a register: a list of BitValues.
249*9880d681SAndroid Build Coastguard Worker struct BitTracker::RegisterCell {
BitsRegisterCell250*9880d681SAndroid Build Coastguard Worker RegisterCell(uint16_t Width = DefaultBitN) : Bits(Width) {}
251*9880d681SAndroid Build Coastguard Worker
widthRegisterCell252*9880d681SAndroid Build Coastguard Worker uint16_t width() const {
253*9880d681SAndroid Build Coastguard Worker return Bits.size();
254*9880d681SAndroid Build Coastguard Worker }
255*9880d681SAndroid Build Coastguard Worker const BitValue &operator[](uint16_t BitN) const {
256*9880d681SAndroid Build Coastguard Worker assert(BitN < Bits.size());
257*9880d681SAndroid Build Coastguard Worker return Bits[BitN];
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker BitValue &operator[](uint16_t BitN) {
260*9880d681SAndroid Build Coastguard Worker assert(BitN < Bits.size());
261*9880d681SAndroid Build Coastguard Worker return Bits[BitN];
262*9880d681SAndroid Build Coastguard Worker }
263*9880d681SAndroid Build Coastguard Worker
264*9880d681SAndroid Build Coastguard Worker bool meet(const RegisterCell &RC, unsigned SelfR);
265*9880d681SAndroid Build Coastguard Worker RegisterCell &insert(const RegisterCell &RC, const BitMask &M);
266*9880d681SAndroid Build Coastguard Worker RegisterCell extract(const BitMask &M) const; // Returns a new cell.
267*9880d681SAndroid Build Coastguard Worker RegisterCell &rol(uint16_t Sh); // Rotate left.
268*9880d681SAndroid Build Coastguard Worker RegisterCell &fill(uint16_t B, uint16_t E, const BitValue &V);
269*9880d681SAndroid Build Coastguard Worker RegisterCell &cat(const RegisterCell &RC); // Concatenate.
270*9880d681SAndroid Build Coastguard Worker uint16_t cl(bool B) const;
271*9880d681SAndroid Build Coastguard Worker uint16_t ct(bool B) const;
272*9880d681SAndroid Build Coastguard Worker
273*9880d681SAndroid Build Coastguard Worker bool operator== (const RegisterCell &RC) const;
274*9880d681SAndroid Build Coastguard Worker bool operator!= (const RegisterCell &RC) const {
275*9880d681SAndroid Build Coastguard Worker return !operator==(RC);
276*9880d681SAndroid Build Coastguard Worker }
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker // Generate a "ref" cell for the corresponding register. In the resulting
279*9880d681SAndroid Build Coastguard Worker // cell each bit will be described as being the same as the corresponding
280*9880d681SAndroid Build Coastguard Worker // bit in register Reg (i.e. the cell is "defined" by register Reg).
281*9880d681SAndroid Build Coastguard Worker static RegisterCell self(unsigned Reg, uint16_t Width);
282*9880d681SAndroid Build Coastguard Worker // Generate a "top" cell of given size.
283*9880d681SAndroid Build Coastguard Worker static RegisterCell top(uint16_t Width);
284*9880d681SAndroid Build Coastguard Worker // Generate a cell that is a "ref" to another cell.
285*9880d681SAndroid Build Coastguard Worker static RegisterCell ref(const RegisterCell &C);
286*9880d681SAndroid Build Coastguard Worker
287*9880d681SAndroid Build Coastguard Worker private:
288*9880d681SAndroid Build Coastguard Worker // The DefaultBitN is here only to avoid frequent reallocation of the
289*9880d681SAndroid Build Coastguard Worker // memory in the vector.
290*9880d681SAndroid Build Coastguard Worker static const unsigned DefaultBitN = 32;
291*9880d681SAndroid Build Coastguard Worker typedef SmallVector<BitValue, DefaultBitN> BitValueList;
292*9880d681SAndroid Build Coastguard Worker BitValueList Bits;
293*9880d681SAndroid Build Coastguard Worker
294*9880d681SAndroid Build Coastguard Worker friend raw_ostream &operator<<(raw_ostream &OS, const RegisterCell &RC);
295*9880d681SAndroid Build Coastguard Worker };
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker
has(unsigned Reg)298*9880d681SAndroid Build Coastguard Worker inline bool BitTracker::has(unsigned Reg) const {
299*9880d681SAndroid Build Coastguard Worker return Map.find(Reg) != Map.end();
300*9880d681SAndroid Build Coastguard Worker }
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker
303*9880d681SAndroid Build Coastguard Worker inline const BitTracker::RegisterCell&
lookup(unsigned Reg)304*9880d681SAndroid Build Coastguard Worker BitTracker::lookup(unsigned Reg) const {
305*9880d681SAndroid Build Coastguard Worker CellMapType::const_iterator F = Map.find(Reg);
306*9880d681SAndroid Build Coastguard Worker assert(F != Map.end());
307*9880d681SAndroid Build Coastguard Worker return F->second;
308*9880d681SAndroid Build Coastguard Worker }
309*9880d681SAndroid Build Coastguard Worker
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker inline BitTracker::RegisterCell
self(unsigned Reg,uint16_t Width)312*9880d681SAndroid Build Coastguard Worker BitTracker::RegisterCell::self(unsigned Reg, uint16_t Width) {
313*9880d681SAndroid Build Coastguard Worker RegisterCell RC(Width);
314*9880d681SAndroid Build Coastguard Worker for (uint16_t i = 0; i < Width; ++i)
315*9880d681SAndroid Build Coastguard Worker RC.Bits[i] = BitValue::self(BitRef(Reg, i));
316*9880d681SAndroid Build Coastguard Worker return RC;
317*9880d681SAndroid Build Coastguard Worker }
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Worker inline BitTracker::RegisterCell
top(uint16_t Width)321*9880d681SAndroid Build Coastguard Worker BitTracker::RegisterCell::top(uint16_t Width) {
322*9880d681SAndroid Build Coastguard Worker RegisterCell RC(Width);
323*9880d681SAndroid Build Coastguard Worker for (uint16_t i = 0; i < Width; ++i)
324*9880d681SAndroid Build Coastguard Worker RC.Bits[i] = BitValue(BitValue::Top);
325*9880d681SAndroid Build Coastguard Worker return RC;
326*9880d681SAndroid Build Coastguard Worker }
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker inline BitTracker::RegisterCell
ref(const RegisterCell & C)330*9880d681SAndroid Build Coastguard Worker BitTracker::RegisterCell::ref(const RegisterCell &C) {
331*9880d681SAndroid Build Coastguard Worker uint16_t W = C.width();
332*9880d681SAndroid Build Coastguard Worker RegisterCell RC(W);
333*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i < W; ++i)
334*9880d681SAndroid Build Coastguard Worker RC[i] = BitValue::ref(C[i]);
335*9880d681SAndroid Build Coastguard Worker return RC;
336*9880d681SAndroid Build Coastguard Worker }
337*9880d681SAndroid Build Coastguard Worker
338*9880d681SAndroid Build Coastguard Worker // A class to evaluate target's instructions and update the cell maps.
339*9880d681SAndroid Build Coastguard Worker // This is used internally by the bit tracker. A target that wants to
340*9880d681SAndroid Build Coastguard Worker // utilize this should implement the evaluation functions (noted below)
341*9880d681SAndroid Build Coastguard Worker // in a subclass of this class.
342*9880d681SAndroid Build Coastguard Worker struct BitTracker::MachineEvaluator {
MachineEvaluatorMachineEvaluator343*9880d681SAndroid Build Coastguard Worker MachineEvaluator(const TargetRegisterInfo &T, MachineRegisterInfo &M)
344*9880d681SAndroid Build Coastguard Worker : TRI(T), MRI(M) {}
~MachineEvaluatorMachineEvaluator345*9880d681SAndroid Build Coastguard Worker virtual ~MachineEvaluator() {}
346*9880d681SAndroid Build Coastguard Worker
347*9880d681SAndroid Build Coastguard Worker uint16_t getRegBitWidth(const RegisterRef &RR) const;
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker RegisterCell getCell(const RegisterRef &RR, const CellMapType &M) const;
350*9880d681SAndroid Build Coastguard Worker void putCell(const RegisterRef &RR, RegisterCell RC, CellMapType &M) const;
351*9880d681SAndroid Build Coastguard Worker // A result of any operation should use refs to the source cells, not
352*9880d681SAndroid Build Coastguard Worker // the cells directly. This function is a convenience wrapper to quickly
353*9880d681SAndroid Build Coastguard Worker // generate a ref for a cell corresponding to a register reference.
getRefMachineEvaluator354*9880d681SAndroid Build Coastguard Worker RegisterCell getRef(const RegisterRef &RR, const CellMapType &M) const {
355*9880d681SAndroid Build Coastguard Worker RegisterCell RC = getCell(RR, M);
356*9880d681SAndroid Build Coastguard Worker return RegisterCell::ref(RC);
357*9880d681SAndroid Build Coastguard Worker }
358*9880d681SAndroid Build Coastguard Worker
359*9880d681SAndroid Build Coastguard Worker // Helper functions.
360*9880d681SAndroid Build Coastguard Worker // Check if a cell is an immediate value (i.e. all bits are either 0 or 1).
361*9880d681SAndroid Build Coastguard Worker bool isInt(const RegisterCell &A) const;
362*9880d681SAndroid Build Coastguard Worker // Convert cell to an immediate value.
363*9880d681SAndroid Build Coastguard Worker uint64_t toInt(const RegisterCell &A) const;
364*9880d681SAndroid Build Coastguard Worker
365*9880d681SAndroid Build Coastguard Worker // Generate cell from an immediate value.
366*9880d681SAndroid Build Coastguard Worker RegisterCell eIMM(int64_t V, uint16_t W) const;
367*9880d681SAndroid Build Coastguard Worker RegisterCell eIMM(const ConstantInt *CI) const;
368*9880d681SAndroid Build Coastguard Worker
369*9880d681SAndroid Build Coastguard Worker // Arithmetic.
370*9880d681SAndroid Build Coastguard Worker RegisterCell eADD(const RegisterCell &A1, const RegisterCell &A2) const;
371*9880d681SAndroid Build Coastguard Worker RegisterCell eSUB(const RegisterCell &A1, const RegisterCell &A2) const;
372*9880d681SAndroid Build Coastguard Worker RegisterCell eMLS(const RegisterCell &A1, const RegisterCell &A2) const;
373*9880d681SAndroid Build Coastguard Worker RegisterCell eMLU(const RegisterCell &A1, const RegisterCell &A2) const;
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker // Shifts.
376*9880d681SAndroid Build Coastguard Worker RegisterCell eASL(const RegisterCell &A1, uint16_t Sh) const;
377*9880d681SAndroid Build Coastguard Worker RegisterCell eLSR(const RegisterCell &A1, uint16_t Sh) const;
378*9880d681SAndroid Build Coastguard Worker RegisterCell eASR(const RegisterCell &A1, uint16_t Sh) const;
379*9880d681SAndroid Build Coastguard Worker
380*9880d681SAndroid Build Coastguard Worker // Logical.
381*9880d681SAndroid Build Coastguard Worker RegisterCell eAND(const RegisterCell &A1, const RegisterCell &A2) const;
382*9880d681SAndroid Build Coastguard Worker RegisterCell eORL(const RegisterCell &A1, const RegisterCell &A2) const;
383*9880d681SAndroid Build Coastguard Worker RegisterCell eXOR(const RegisterCell &A1, const RegisterCell &A2) const;
384*9880d681SAndroid Build Coastguard Worker RegisterCell eNOT(const RegisterCell &A1) const;
385*9880d681SAndroid Build Coastguard Worker
386*9880d681SAndroid Build Coastguard Worker // Set bit, clear bit.
387*9880d681SAndroid Build Coastguard Worker RegisterCell eSET(const RegisterCell &A1, uint16_t BitN) const;
388*9880d681SAndroid Build Coastguard Worker RegisterCell eCLR(const RegisterCell &A1, uint16_t BitN) const;
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker // Count leading/trailing bits (zeros/ones).
391*9880d681SAndroid Build Coastguard Worker RegisterCell eCLB(const RegisterCell &A1, bool B, uint16_t W) const;
392*9880d681SAndroid Build Coastguard Worker RegisterCell eCTB(const RegisterCell &A1, bool B, uint16_t W) const;
393*9880d681SAndroid Build Coastguard Worker
394*9880d681SAndroid Build Coastguard Worker // Sign/zero extension.
395*9880d681SAndroid Build Coastguard Worker RegisterCell eSXT(const RegisterCell &A1, uint16_t FromN) const;
396*9880d681SAndroid Build Coastguard Worker RegisterCell eZXT(const RegisterCell &A1, uint16_t FromN) const;
397*9880d681SAndroid Build Coastguard Worker
398*9880d681SAndroid Build Coastguard Worker // Extract/insert
399*9880d681SAndroid Build Coastguard Worker // XTR R,b,e: extract bits from A1 starting at bit b, ending at e-1.
400*9880d681SAndroid Build Coastguard Worker // INS R,S,b: take R and replace bits starting from b with S.
401*9880d681SAndroid Build Coastguard Worker RegisterCell eXTR(const RegisterCell &A1, uint16_t B, uint16_t E) const;
402*9880d681SAndroid Build Coastguard Worker RegisterCell eINS(const RegisterCell &A1, const RegisterCell &A2,
403*9880d681SAndroid Build Coastguard Worker uint16_t AtN) const;
404*9880d681SAndroid Build Coastguard Worker
405*9880d681SAndroid Build Coastguard Worker // User-provided functions for individual targets:
406*9880d681SAndroid Build Coastguard Worker
407*9880d681SAndroid Build Coastguard Worker // Return a sub-register mask that indicates which bits in Reg belong
408*9880d681SAndroid Build Coastguard Worker // to the subregister Sub. These bits are assumed to be contiguous in
409*9880d681SAndroid Build Coastguard Worker // the super-register, and have the same ordering in the sub-register
410*9880d681SAndroid Build Coastguard Worker // as in the super-register. It is valid to call this function with
411*9880d681SAndroid Build Coastguard Worker // Sub == 0, in this case, the function should return a mask that spans
412*9880d681SAndroid Build Coastguard Worker // the entire register Reg (which is what the default implementation
413*9880d681SAndroid Build Coastguard Worker // does).
414*9880d681SAndroid Build Coastguard Worker virtual BitMask mask(unsigned Reg, unsigned Sub) const;
415*9880d681SAndroid Build Coastguard Worker // Indicate whether a given register class should be tracked.
trackMachineEvaluator416*9880d681SAndroid Build Coastguard Worker virtual bool track(const TargetRegisterClass *RC) const { return true; }
417*9880d681SAndroid Build Coastguard Worker // Evaluate a non-branching machine instruction, given the cell map with
418*9880d681SAndroid Build Coastguard Worker // the input values. Place the results in the Outputs map. Return "true"
419*9880d681SAndroid Build Coastguard Worker // if evaluation succeeded, "false" otherwise.
420*9880d681SAndroid Build Coastguard Worker virtual bool evaluate(const MachineInstr &MI, const CellMapType &Inputs,
421*9880d681SAndroid Build Coastguard Worker CellMapType &Outputs) const;
422*9880d681SAndroid Build Coastguard Worker // Evaluate a branch, given the cell map with the input values. Fill out
423*9880d681SAndroid Build Coastguard Worker // a list of all possible branch targets and indicate (through a flag)
424*9880d681SAndroid Build Coastguard Worker // whether the branch could fall-through. Return "true" if this information
425*9880d681SAndroid Build Coastguard Worker // has been successfully computed, "false" otherwise.
426*9880d681SAndroid Build Coastguard Worker virtual bool evaluate(const MachineInstr &BI, const CellMapType &Inputs,
427*9880d681SAndroid Build Coastguard Worker BranchTargetList &Targets, bool &FallsThru) const = 0;
428*9880d681SAndroid Build Coastguard Worker
429*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo &TRI;
430*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo &MRI;
431*9880d681SAndroid Build Coastguard Worker };
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
434*9880d681SAndroid Build Coastguard Worker
435*9880d681SAndroid Build Coastguard Worker #endif
436