@@ -105,6 +105,25 @@ void doForAllPreds(const BinaryContext &BC, const BinaryBasicBlock &BB,
105
105
void doForAllSuccs (const BinaryBasicBlock &BB,
106
106
std::function<void (ProgramPoint)> Task);
107
107
108
+ // / Default printer for State data.
109
+ template <typename StateTy>
110
+ class StatePrinter {
111
+ public:
112
+ void print (raw_ostream &OS, const StateTy &State) const {
113
+ OS << State;
114
+ }
115
+ explicit StatePrinter (const BinaryContext &) { }
116
+ };
117
+
118
+ // / Printer for State data that is a BitVector of registers.
119
+ class RegStatePrinter {
120
+ public:
121
+ void print (raw_ostream &OS, const BitVector &State) const ;
122
+ explicit RegStatePrinter (const BinaryContext &BC) : BC(BC) { }
123
+ private:
124
+ const BinaryContext &BC;
125
+ };
126
+
108
127
// / Base class for dataflow analyses. Depends on the type of whatever object is
109
128
// / stored as the state (StateTy) at each program point. The dataflow then
110
129
// / updates the state at each program point depending on the instruction being
@@ -132,7 +151,10 @@ void doForAllSuccs(const BinaryBasicBlock &BB,
132
151
// / Confluence operator = union (if a reg is alive in any succ, it is alive
133
152
// / in the current block).
134
153
// /
135
- template <typename Derived, typename StateTy, bool Backward=false >
154
+ template <typename Derived,
155
+ typename StateTy,
156
+ bool Backward = false ,
157
+ typename StatePrinterTy = StatePrinter<StateTy>>
136
158
class DataflowAnalysis {
137
159
// / CRTP convenience methods
138
160
Derived &derived () {
@@ -212,7 +234,7 @@ class DataflowAnalysis {
212
234
213
235
StateTy &getOrCreateStateAt (MCInst &Point) {
214
236
return BC.MIA ->getOrCreateAnnotationAs <StateTy>(
215
- BC.Ctx .get (), Point, derived ().getAnnotationName ());
237
+ BC.Ctx .get (), Point, derived ().getAnnotationName (), StatePrinterTy (BC) );
216
238
}
217
239
218
240
StateTy &getOrCreateStateAt (ProgramPoint Point) {
@@ -272,7 +294,7 @@ class DataflowAnalysis {
272
294
return getStateAt (PrevPoint[&Point]);
273
295
}
274
296
275
- ErrorOr<const StateTy &>getStateBefore (ProgramPoint Point) {
297
+ ErrorOr<const StateTy &> getStateBefore (ProgramPoint Point) {
276
298
if (Point.isBB ())
277
299
return getStateAt (*Point.getBB ());
278
300
return getStateAt (PrevPoint[Point.getInst ()]);
@@ -462,9 +484,11 @@ class ExprIterator
462
484
463
485
// / Specialization of DataflowAnalysis whose state specifically stores
464
486
// / a set of instructions.
465
- template <typename Derived, bool Backward = false >
487
+ template <typename Derived,
488
+ bool Backward = false ,
489
+ typename StatePrinterTy = StatePrinter<BitVector>>
466
490
class InstrsDataflowAnalysis
467
- : public DataflowAnalysis<Derived, BitVector, Backward> {
491
+ : public DataflowAnalysis<Derived, BitVector, Backward, StatePrinterTy > {
468
492
public:
469
493
// / These iterator functions offer access to the set of pointers to
470
494
// / instructions in a given program point
@@ -512,7 +536,7 @@ class InstrsDataflowAnalysis
512
536
}
513
537
514
538
InstrsDataflowAnalysis (const BinaryContext &BC, BinaryFunction &BF)
515
- : DataflowAnalysis<Derived, BitVector, Backward>(BC, BF) {}
539
+ : DataflowAnalysis<Derived, BitVector, Backward, StatePrinterTy >(BC, BF) {}
516
540
virtual ~InstrsDataflowAnalysis () {}
517
541
};
518
542
@@ -541,8 +565,7 @@ template<> struct DenseMapInfo<bolt::ProgramPoint> {
541
565
}
542
566
};
543
567
544
- llvm::raw_ostream &operator <<(llvm::raw_ostream &OS,
545
- const BitVector &Val);
568
+ raw_ostream &operator <<(raw_ostream &OS, const BitVector &Val);
546
569
547
570
} // namespace llvm
548
571
0 commit comments