Skip to content

Commit c3407f4

Browse files
Bill Nellmemfrob
authored andcommitted
[BOLT] Add ability to specify custom printers for annotations.
Summary: This will give us the ability to print annotations in a more meaningful way. Especially annotations that could be interpreted in multiple ways. I've added one register name printer for liveness analysis. We can update the other dataflow annotations as needed. I also noticed that BitVector annotations were leaking since they contain heap allocated memory. I made removeAnnotation call the annotation destructor explicitly to mitigate this but it won't fix the problem when annotations are just dropped en masse. (cherry picked from FBD6105999)
1 parent fad1a24 commit c3407f4

File tree

3 files changed

+54
-20
lines changed

3 files changed

+54
-20
lines changed

bolt/Passes/DataflowAnalysis.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
#include "DataflowAnalysis.h"
22

33
namespace llvm {
4+
5+
raw_ostream &operator<<(raw_ostream &OS, const BitVector &Val) {
6+
OS << "BitVector";
7+
return OS;
8+
}
9+
410
namespace bolt {
511

612
void doForAllPreds(const BinaryContext &BC, const BinaryBasicBlock &BB,
@@ -30,11 +36,11 @@ void doForAllSuccs(const BinaryBasicBlock &BB,
3036
}
3137
}
3238

39+
void RegStatePrinter::print(raw_ostream &OS, const BitVector &State) const {
40+
for (auto I = State.find_first(); I != -1; I = State.find_next(I)) {
41+
OS << BC.MRI->getName(I) << " ";
42+
}
43+
}
44+
3345
} // namespace bolt
3446
} // namespace llvm
35-
36-
llvm::raw_ostream &llvm::operator<<(llvm::raw_ostream &OS,
37-
const BitVector &Val) {
38-
OS << "BitVector";
39-
return OS;
40-
}

bolt/Passes/DataflowAnalysis.h

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,25 @@ void doForAllPreds(const BinaryContext &BC, const BinaryBasicBlock &BB,
105105
void doForAllSuccs(const BinaryBasicBlock &BB,
106106
std::function<void(ProgramPoint)> Task);
107107

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+
108127
/// Base class for dataflow analyses. Depends on the type of whatever object is
109128
/// stored as the state (StateTy) at each program point. The dataflow then
110129
/// updates the state at each program point depending on the instruction being
@@ -132,7 +151,10 @@ void doForAllSuccs(const BinaryBasicBlock &BB,
132151
/// Confluence operator = union (if a reg is alive in any succ, it is alive
133152
/// in the current block).
134153
///
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>>
136158
class DataflowAnalysis {
137159
/// CRTP convenience methods
138160
Derived &derived() {
@@ -212,7 +234,7 @@ class DataflowAnalysis {
212234

213235
StateTy &getOrCreateStateAt(MCInst &Point) {
214236
return BC.MIA->getOrCreateAnnotationAs<StateTy>(
215-
BC.Ctx.get(), Point, derived().getAnnotationName());
237+
BC.Ctx.get(), Point, derived().getAnnotationName(), StatePrinterTy(BC));
216238
}
217239

218240
StateTy &getOrCreateStateAt(ProgramPoint Point) {
@@ -272,7 +294,7 @@ class DataflowAnalysis {
272294
return getStateAt(PrevPoint[&Point]);
273295
}
274296

275-
ErrorOr<const StateTy &>getStateBefore(ProgramPoint Point) {
297+
ErrorOr<const StateTy &> getStateBefore(ProgramPoint Point) {
276298
if (Point.isBB())
277299
return getStateAt(*Point.getBB());
278300
return getStateAt(PrevPoint[Point.getInst()]);
@@ -462,9 +484,11 @@ class ExprIterator
462484

463485
/// Specialization of DataflowAnalysis whose state specifically stores
464486
/// a set of instructions.
465-
template <typename Derived, bool Backward = false>
487+
template <typename Derived,
488+
bool Backward = false,
489+
typename StatePrinterTy = StatePrinter<BitVector>>
466490
class InstrsDataflowAnalysis
467-
: public DataflowAnalysis<Derived, BitVector, Backward> {
491+
: public DataflowAnalysis<Derived, BitVector, Backward, StatePrinterTy> {
468492
public:
469493
/// These iterator functions offer access to the set of pointers to
470494
/// instructions in a given program point
@@ -512,7 +536,7 @@ class InstrsDataflowAnalysis
512536
}
513537

514538
InstrsDataflowAnalysis(const BinaryContext &BC, BinaryFunction &BF)
515-
: DataflowAnalysis<Derived, BitVector, Backward>(BC, BF) {}
539+
: DataflowAnalysis<Derived, BitVector, Backward, StatePrinterTy>(BC, BF) {}
516540
virtual ~InstrsDataflowAnalysis() {}
517541
};
518542

@@ -541,8 +565,7 @@ template<> struct DenseMapInfo<bolt::ProgramPoint> {
541565
}
542566
};
543567

544-
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
545-
const BitVector &Val);
568+
raw_ostream &operator<<(raw_ostream &OS, const BitVector &Val);
546569

547570
} // namespace llvm
548571

bolt/Passes/LivenessAnalysis.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,20 @@ namespace llvm {
2626
namespace bolt {
2727

2828
class LivenessAnalysis
29-
: public DataflowAnalysis<LivenessAnalysis, BitVector, true> {
30-
friend class DataflowAnalysis<LivenessAnalysis, BitVector, true>;
29+
: public DataflowAnalysis<LivenessAnalysis, BitVector, true, RegStatePrinter> {
30+
using Parent = DataflowAnalysis<LivenessAnalysis,
31+
BitVector,
32+
true,
33+
RegStatePrinter>;
34+
friend class DataflowAnalysis<LivenessAnalysis,
35+
BitVector,
36+
true,
37+
RegStatePrinter>;
3138

3239
public:
3340
LivenessAnalysis(const RegAnalysis &RA, const BinaryContext &BC,
3441
BinaryFunction &BF)
35-
: DataflowAnalysis<LivenessAnalysis, BitVector, true>(BC, BF), RA(RA),
36-
NumRegs(BC.MRI->getNumRegs()) {}
42+
: Parent(BC, BF), RA(RA), NumRegs(BC.MRI->getNumRegs()) {}
3743
virtual ~LivenessAnalysis();
3844

3945
bool isAlive(ProgramPoint PP, MCPhysReg Reg) const {
@@ -45,7 +51,7 @@ class LivenessAnalysis
4551

4652
void run() {
4753
NamedRegionTimer T1("LA", "Dataflow", opts::TimeOpts);
48-
DataflowAnalysis<LivenessAnalysis, BitVector, true>::run();
54+
Parent::run();
4955
}
5056

5157
// Return a usable general-purpose reg after point P. Return 0 if no reg is
@@ -122,5 +128,4 @@ class LivenessAnalysis
122128
} // end namespace bolt
123129
} // end namespace llvm
124130

125-
126131
#endif

0 commit comments

Comments
 (0)