LLVM 22.0.0git
BitTracker.h
Go to the documentation of this file.
1//===- BitTracker.h ---------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_TARGET_HEXAGON_BITTRACKER_H
10#define LLVM_LIB_TARGET_HEXAGON_BITTRACKER_H
11
12#include "llvm/ADT/DenseSet.h"
13#include "llvm/ADT/SetVector.h"
17#include <map>
18#include <queue>
19#include <set>
20
21namespace llvm {
22
23class BitVector;
24class ConstantInt;
25class MachineRegisterInfo;
26class MachineBasicBlock;
27class MachineFunction;
28class raw_ostream;
29class TargetRegisterClass;
30class TargetRegisterInfo;
31
32struct BitTracker {
33 struct BitRef;
34 struct RegisterRef;
35 struct BitValue;
36 struct BitMask;
37 struct RegisterCell;
38 struct MachineEvaluator;
39
41 using CellMapType = std::map<unsigned, RegisterCell>;
42
45
46 void run();
47 void trace(bool On = false) { Trace = On; }
48 bool has(unsigned Reg) const;
49 const RegisterCell &lookup(unsigned Reg) const;
50 RegisterCell get(RegisterRef RR) const;
51 void put(RegisterRef RR, const RegisterCell &RC);
52 void subst(RegisterRef OldRR, RegisterRef NewRR);
53 bool reached(const MachineBasicBlock *B) const;
54 void visit(const MachineInstr &MI);
55
56 void print_cells(raw_ostream &OS) const;
57
58private:
59 void visitPHI(const MachineInstr &PI);
60 void visitNonBranch(const MachineInstr &MI);
61 void visitBranchesFrom(const MachineInstr &BI);
62 void visitUsesOf(Register Reg);
63
64 using CFGEdge = std::pair<int, int>;
65 using EdgeSetType = std::set<CFGEdge>;
66 using InstrSetType = std::set<const MachineInstr *>;
67 using EdgeQueueType = std::queue<CFGEdge>;
68
69 // Priority queue of instructions using modified registers, ordered by
70 // their relative position in a basic block.
71 struct UseQueueType {
72 UseQueueType() : Uses(Dist) {}
73
74 unsigned size() const {
75 return Uses.size();
76 }
77 bool empty() const {
78 return size() == 0;
79 }
80 MachineInstr *front() const {
81 return Uses.top();
82 }
83 void push(MachineInstr *MI) {
84 if (Set.insert(MI).second)
85 Uses.push(MI);
86 }
87 void pop() {
88 Set.erase(front());
89 Uses.pop();
90 }
91 void reset() {
92 Dist.clear();
93 }
94 private:
95 struct Cmp {
96 Cmp(DenseMap<const MachineInstr*,unsigned> &Map) : Dist(Map) {}
97 bool operator()(const MachineInstr *MI, const MachineInstr *MJ) const;
98 DenseMap<const MachineInstr*,unsigned> &Dist;
99 };
100 DenseSet<const MachineInstr*> Set; // Set to avoid adding duplicate entries.
101 DenseMap<const MachineInstr*,unsigned> Dist;
102 std::priority_queue<MachineInstr *, std::vector<MachineInstr *>, Cmp> Uses;
103 };
104
105 void reset();
106 void runEdgeQueue(BitVector &BlockScanned);
107 void runUseQueue();
108
109 const MachineEvaluator &ME;
110 MachineFunction &MF;
111 MachineRegisterInfo &MRI;
112 CellMapType &Map;
113
114 EdgeSetType EdgeExec; // Executable flow graph edges.
115 InstrSetType InstrExec; // Executable instructions.
116 UseQueueType UseQ; // Work queue of register uses.
117 EdgeQueueType FlowQ; // Work queue of CFG edges.
118 DenseSet<unsigned> ReachedBB; // Cache of reached blocks.
119 bool Trace; // Enable tracing for debugging.
120};
121
122// Abstraction of a reference to bit at position Pos from a register Reg.
124 BitRef(unsigned R = 0, uint16_t P = 0) : Reg(R), Pos(P) {}
125
126 bool operator== (const BitRef &BR) const {
127 // If Reg is 0, disregard Pos.
128 return Reg == BR.Reg && (Reg == 0 || Pos == BR.Pos);
129 }
130
133};
134
135// Abstraction of a register reference in MachineOperand. It contains the
136// register number and the subregister index.
137// FIXME: Consolidate duplicate definitions of RegisterRef
139 RegisterRef(Register R = 0, unsigned S = 0) : Reg(R), Sub(S) {}
141 : Reg(MO.getReg()), Sub(MO.getSubReg()) {}
142
144 unsigned Sub;
145};
146
147// Value that a single bit can take. This is outside of the context of
148// any register, it is more of an abstraction of the two-element set of
149// possible bit values. One extension here is the "Ref" type, which
150// indicates that this bit takes the same value as the bit described by
151// RefInfo.
154 Top, // Bit not yet defined.
155 Zero, // Bit = 0.
156 One, // Bit = 1.
157 Ref // Bit value same as the one described in RefI.
158 // Conceptually, there is no explicit "bottom" value: the lattice's
159 // bottom will be expressed as a "ref to itself", which, in the context
160 // of registers, could be read as "this value of this bit is defined by
161 // this bit".
162 // The ordering is:
163 // x <= Top,
164 // Self <= x, where "Self" is "ref to itself".
165 // This makes the value lattice different for each virtual register
166 // (even for each bit in the same virtual register), since the "bottom"
167 // for one register will be a simple "ref" for another register.
168 // Since we do not store the "Self" bit and register number, the meet
169 // operation will need to take it as a parameter.
170 //
171 // In practice there is a special case for values that are not associa-
172 // ted with any specific virtual register. An example would be a value
173 // corresponding to a bit of a physical register, or an intermediate
174 // value obtained in some computation (such as instruction evaluation).
175 // Such cases are identical to the usual Ref type, but the register
176 // number is 0. In such case the Pos field of the reference is ignored.
177 //
178 // What is worthy of notice is that in value V (that is a "ref"), as long
179 // as the RefI.Reg is not 0, it may actually be the same register as the
180 // one in which V will be contained. If the RefI.Pos refers to the posi-
181 // tion of V, then V is assumed to be "bottom" (as a "ref to itself"),
182 // otherwise V is taken to be identical to the referenced bit of the
183 // same register.
184 // If RefI.Reg is 0, however, such a reference to the same register is
185 // not possible. Any value V that is a "ref", and whose RefI.Reg is 0
186 // is treated as "bottom".
187 };
190
192 BitValue(bool B) : Type(B ? One : Zero) {}
193 BitValue(unsigned Reg, uint16_t Pos) : Type(Ref), RefI(Reg, Pos) {}
194
195 bool operator== (const BitValue &V) const {
196 if (Type != V.Type)
197 return false;
198 if (Type == Ref && !(RefI == V.RefI))
199 return false;
200 return true;
201 }
202 bool operator!= (const BitValue &V) const {
203 return !operator==(V);
204 }
205
206 bool is(unsigned T) const {
207 assert(T == 0 || T == 1);
208 return T == 0 ? Type == Zero
209 : (T == 1 ? Type == One : false);
210 }
211
212 // The "meet" operation is the "." operation in a semilattice (L, ., T, B):
213 // (1) x.x = x
214 // (2) x.y = y.x
215 // (3) x.(y.z) = (x.y).z
216 // (4) x.T = x (i.e. T = "top")
217 // (5) x.B = B (i.e. B = "bottom")
218 //
219 // This "meet" function will update the value of the "*this" object with
220 // the newly calculated one, and return "true" if the value of *this has
221 // changed, and "false" otherwise.
222 // To prove that it satisfies the conditions (1)-(5), it is sufficient
223 // to show that a relation
224 // x <= y <=> x.y = x
225 // defines a partial order (i.e. that "meet" is same as "infimum").
226 bool meet(const BitValue &V, const BitRef &Self) {
227 // First, check the cases where there is nothing to be done.
228 if (Type == Ref && RefI == Self) // Bottom.meet(V) = Bottom (i.e. This)
229 return false;
230 if (V.Type == Top) // This.meet(Top) = This
231 return false;
232 if (*this == V) // This.meet(This) = This
233 return false;
234
235 // At this point, we know that the value of "this" will change.
236 // If it is Top, it will become the same as V, otherwise it will
237 // become "bottom" (i.e. Self).
238 if (Type == Top) {
239 Type = V.Type;
240 RefI = V.RefI; // This may be irrelevant, but copy anyway.
241 return true;
242 }
243 // Become "bottom".
244 Type = Ref;
245 RefI = Self;
246 return true;
247 }
248
249 // Create a reference to the bit value V.
250 static BitValue ref(const BitValue &V);
251 // Create a "self".
252 static BitValue self(const BitRef &Self = BitRef());
253
254 bool num() const {
255 return Type == Zero || Type == One;
256 }
257
258 operator bool() const {
259 assert(Type == Zero || Type == One);
260 return Type == One;
261 }
262
263 friend raw_ostream &operator<<(raw_ostream &OS, const BitValue &BV);
264};
265
266// This operation must be idempotent, i.e. ref(ref(V)) == ref(V).
269 if (V.Type != Ref)
270 return BitValue(V.Type);
271 if (V.RefI.Reg != 0)
272 return BitValue(V.RefI.Reg, V.RefI.Pos);
273 return self();
274}
275
278 return BitValue(Self.Reg, Self.Pos);
279}
280
281// A sequence of bits starting from index B up to and including index E.
282// If E < B, the mask represents two sections: [0..E] and [B..W) where
283// W is the width of the register.
285 BitMask() = default;
286 BitMask(uint16_t b, uint16_t e) : B(b), E(e) {}
287
288 uint16_t first() const { return B; }
289 uint16_t last() const { return E; }
290
291private:
292 uint16_t B = 0;
293 uint16_t E = 0;
294};
295
296// Representation of a register: a list of BitValues.
298 RegisterCell(uint16_t Width = DefaultBitN) : Bits(Width) {}
299
300 uint16_t width() const {
301 return Bits.size();
302 }
303
304 const BitValue &operator[](uint16_t BitN) const {
305 assert(BitN < Bits.size());
306 return Bits[BitN];
307 }
309 assert(BitN < Bits.size());
310 return Bits[BitN];
311 }
312
313 bool meet(const RegisterCell &RC, Register SelfR);
314 RegisterCell &insert(const RegisterCell &RC, const BitMask &M);
315 RegisterCell extract(const BitMask &M) const; // Returns a new cell.
316 RegisterCell &rol(uint16_t Sh); // Rotate left.
318 RegisterCell &cat(const RegisterCell &RC); // Concatenate.
319 uint16_t cl(bool B) const;
320 uint16_t ct(bool B) const;
321
322 bool operator== (const RegisterCell &RC) const;
323 bool operator!= (const RegisterCell &RC) const {
324 return !operator==(RC);
325 }
326
327 // Replace the ref-to-reg-0 bit values with the given register.
328 RegisterCell &regify(unsigned R);
329
330 // Generate a "ref" cell for the corresponding register. In the resulting
331 // cell each bit will be described as being the same as the corresponding
332 // bit in register Reg (i.e. the cell is "defined" by register Reg).
333 static RegisterCell self(unsigned Reg, uint16_t Width);
334 // Generate a "top" cell of given size.
335 static RegisterCell top(uint16_t Width);
336 // Generate a cell that is a "ref" to another cell.
337 static RegisterCell ref(const RegisterCell &C);
338
339private:
340 // The DefaultBitN is here only to avoid frequent reallocation of the
341 // memory in the vector.
342 static const unsigned DefaultBitN = 32;
343 using BitValueList = SmallVector<BitValue, DefaultBitN>;
344 BitValueList Bits;
345
346 friend raw_ostream &operator<<(raw_ostream &OS, const RegisterCell &RC);
347};
348
349inline bool BitTracker::has(unsigned Reg) const {
350 return Map.find(Reg) != Map.end();
351}
352
353inline const BitTracker::RegisterCell&
354BitTracker::lookup(unsigned Reg) const {
355 CellMapType::const_iterator F = Map.find(Reg);
356 assert(F != Map.end());
357 return F->second;
358}
359
362 RegisterCell RC(Width);
363 for (uint16_t i = 0; i < Width; ++i)
364 RC.Bits[i] = BitValue::self(BitRef(Reg, i));
365 return RC;
366}
367
370 RegisterCell RC(Width);
371 for (uint16_t i = 0; i < Width; ++i)
372 RC.Bits[i] = BitValue(BitValue::Top);
373 return RC;
374}
375
378 uint16_t W = C.width();
379 RegisterCell RC(W);
380 for (unsigned i = 0; i < W; ++i)
381 RC[i] = BitValue::ref(C[i]);
382 return RC;
383}
384
385// A class to evaluate target's instructions and update the cell maps.
386// This is used internally by the bit tracker. A target that wants to
387// utilize this should implement the evaluation functions (noted below)
388// in a subclass of this class.
391 : TRI(T), MRI(M) {}
392 virtual ~MachineEvaluator() = default;
393
394 uint16_t getRegBitWidth(const RegisterRef &RR) const;
395
396 RegisterCell getCell(const RegisterRef &RR, const CellMapType &M) const;
397 void putCell(const RegisterRef &RR, RegisterCell RC, CellMapType &M) const;
398
399 // A result of any operation should use refs to the source cells, not
400 // the cells directly. This function is a convenience wrapper to quickly
401 // generate a ref for a cell corresponding to a register reference.
402 RegisterCell getRef(const RegisterRef &RR, const CellMapType &M) const {
403 RegisterCell RC = getCell(RR, M);
404 return RegisterCell::ref(RC);
405 }
406
407 // Helper functions.
408 // Check if a cell is an immediate value (i.e. all bits are either 0 or 1).
409 bool isInt(const RegisterCell &A) const;
410 // Convert cell to an immediate value.
411 uint64_t toInt(const RegisterCell &A) const;
412
413 // Generate cell from an immediate value.
414 RegisterCell eIMM(int64_t V, uint16_t W) const;
415 RegisterCell eIMM(const ConstantInt *CI) const;
416
417 // Arithmetic.
418 RegisterCell eADD(const RegisterCell &A1, const RegisterCell &A2) const;
419 RegisterCell eSUB(const RegisterCell &A1, const RegisterCell &A2) const;
420 RegisterCell eMLS(const RegisterCell &A1, const RegisterCell &A2) const;
421 RegisterCell eMLU(const RegisterCell &A1, const RegisterCell &A2) const;
422
423 // Shifts.
424 RegisterCell eASL(const RegisterCell &A1, uint16_t Sh) const;
425 RegisterCell eLSR(const RegisterCell &A1, uint16_t Sh) const;
426 RegisterCell eASR(const RegisterCell &A1, uint16_t Sh) const;
427
428 // Logical.
429 RegisterCell eAND(const RegisterCell &A1, const RegisterCell &A2) const;
430 RegisterCell eORL(const RegisterCell &A1, const RegisterCell &A2) const;
431 RegisterCell eXOR(const RegisterCell &A1, const RegisterCell &A2) const;
432 RegisterCell eNOT(const RegisterCell &A1) const;
433
434 // Set bit, clear bit.
435 RegisterCell eSET(const RegisterCell &A1, uint16_t BitN) const;
436 RegisterCell eCLR(const RegisterCell &A1, uint16_t BitN) const;
437
438 // Count leading/trailing bits (zeros/ones).
439 RegisterCell eCLB(const RegisterCell &A1, bool B, uint16_t W) const;
440 RegisterCell eCTB(const RegisterCell &A1, bool B, uint16_t W) const;
441
442 // Sign/zero extension.
443 RegisterCell eSXT(const RegisterCell &A1, uint16_t FromN) const;
444 RegisterCell eZXT(const RegisterCell &A1, uint16_t FromN) const;
445
446 // Extract/insert
447 // XTR R,b,e: extract bits from A1 starting at bit b, ending at e-1.
448 // INS R,S,b: take R and replace bits starting from b with S.
449 RegisterCell eXTR(const RegisterCell &A1, uint16_t B, uint16_t E) const;
450 RegisterCell eINS(const RegisterCell &A1, const RegisterCell &A2,
451 uint16_t AtN) const;
452
453 // User-provided functions for individual targets:
454
455 // Return a sub-register mask that indicates which bits in Reg belong
456 // to the subregister Sub. These bits are assumed to be contiguous in
457 // the super-register, and have the same ordering in the sub-register
458 // as in the super-register. It is valid to call this function with
459 // Sub == 0, in this case, the function should return a mask that spans
460 // the entire register Reg (which is what the default implementation
461 // does).
462 virtual BitMask mask(Register Reg, unsigned Sub) const;
463 // Indicate whether a given register class should be tracked.
464 virtual bool track(const TargetRegisterClass *RC) const { return true; }
465 // Evaluate a non-branching machine instruction, given the cell map with
466 // the input values. Place the results in the Outputs map. Return "true"
467 // if evaluation succeeded, "false" otherwise.
468 virtual bool evaluate(const MachineInstr &MI, const CellMapType &Inputs,
469 CellMapType &Outputs) const;
470 // Evaluate a branch, given the cell map with the input values. Fill out
471 // a list of all possible branch targets and indicate (through a flag)
472 // whether the branch could fall-through. Return "true" if this information
473 // has been successfully computed, "false" otherwise.
474 virtual bool evaluate(const MachineInstr &BI, const CellMapType &Inputs,
475 BranchTargetList &Targets, bool &FallsThru) const = 0;
476 // Given a register class RC, return a register class that should be assumed
477 // when a register from class RC is used with a subregister of index Idx.
478 virtual const TargetRegisterClass&
479 composeWithSubRegIndex(const TargetRegisterClass &RC, unsigned Idx) const {
480 if (Idx == 0)
481 return RC;
482 llvm_unreachable("Unimplemented composeWithSubRegIndex");
483 }
484 // Return the size in bits of the physical register Reg.
485 virtual uint16_t getPhysRegBitWidth(MCRegister Reg) const;
486
489};
490
491} // end namespace llvm
492
493#endif // LLVM_LIB_TARGET_HEXAGON_BITTRACKER_H
unsigned const MachineRegisterInfo * MRI
static bool evaluate(const MCSpecifierExpr &Expr, MCValue &Res, const MCAssembler *Asm)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
raw_ostream & operator<<(raw_ostream &OS, const binary_le_impl< value_type > &BLE)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseSet and SmallDenseSet classes.
IRTranslator LLVM IR MI
loop extract
#define F(x, y, z)
Definition: MD5.cpp:55
Register Reg
Register const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define P(N)
Remove Loads Into Fake Uses
static uint32_t rol(uint32_t Number, int Bits)
Definition: SHA1.cpp:26
raw_pwrite_stream & OS
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Representation of each machine instruction.
Definition: MachineInstr.h:72
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
A vector that has set insertion semantics.
Definition: SetVector.h:59
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void fill(R &&Range, T &&Value)
Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1764
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1702
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition: MathExtras.h:174
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
uint16_t first() const
Definition: BitTracker.h:288
BitMask(uint16_t b, uint16_t e)
Definition: BitTracker.h:286
uint16_t last() const
Definition: BitTracker.h:289
BitRef(unsigned R=0, uint16_t P=0)
Definition: BitTracker.h:124
bool operator!=(const BitValue &V) const
Definition: BitTracker.h:202
static BitValue ref(const BitValue &V)
Definition: BitTracker.h:268
bool operator==(const BitValue &V) const
Definition: BitTracker.h:195
BitValue(unsigned Reg, uint16_t Pos)
Definition: BitTracker.h:193
bool is(unsigned T) const
Definition: BitTracker.h:206
static BitValue self(const BitRef &Self=BitRef())
Definition: BitTracker.h:277
friend raw_ostream & operator<<(raw_ostream &OS, const BitValue &BV)
Definition: BitTracker.cpp:92
BitValue(ValueType T=Top)
Definition: BitTracker.h:191
bool meet(const BitValue &V, const BitRef &Self)
Definition: BitTracker.h:226
RegisterCell getRef(const RegisterRef &RR, const CellMapType &M) const
Definition: BitTracker.h:402
virtual bool evaluate(const MachineInstr &BI, const CellMapType &Inputs, BranchTargetList &Targets, bool &FallsThru) const =0
MachineEvaluator(const TargetRegisterInfo &T, MachineRegisterInfo &M)
Definition: BitTracker.h:390
const TargetRegisterInfo & TRI
Definition: BitTracker.h:487
MachineRegisterInfo & MRI
Definition: BitTracker.h:488
virtual const TargetRegisterClass & composeWithSubRegIndex(const TargetRegisterClass &RC, unsigned Idx) const
Definition: BitTracker.h:479
virtual bool track(const TargetRegisterClass *RC) const
Definition: BitTracker.h:464
BitValue & operator[](uint16_t BitN)
Definition: BitTracker.h:308
static RegisterCell self(unsigned Reg, uint16_t Width)
Definition: BitTracker.h:361
static RegisterCell ref(const RegisterCell &C)
Definition: BitTracker.h:377
const BitValue & operator[](uint16_t BitN) const
Definition: BitTracker.h:304
static RegisterCell top(uint16_t Width)
Definition: BitTracker.h:369
RegisterCell(uint16_t Width=DefaultBitN)
Definition: BitTracker.h:298
RegisterRef(Register R=0, unsigned S=0)
Definition: BitTracker.h:139
RegisterRef(const MachineOperand &MO)
Definition: BitTracker.h:140
bool has(unsigned Reg) const
Definition: BitTracker.h:349
const RegisterCell & lookup(unsigned Reg) const
Definition: BitTracker.h:354
bool reached(const MachineBasicBlock *B) const
void trace(bool On=false)
Definition: BitTracker.h:47
void subst(RegisterRef OldRR, RegisterRef NewRR)
Definition: BitTracker.cpp:994
void print_cells(raw_ostream &OS) const
Definition: BitTracker.cpp:177
std::map< unsigned, RegisterCell > CellMapType
Definition: BitTracker.h:41
void put(RegisterRef RR, const RegisterCell &RC)
Definition: BitTracker.cpp:988
void visit(const MachineInstr &MI)
RegisterCell get(RegisterRef RR) const
Definition: BitTracker.cpp:984