When working on the register allocator, I often need to introspect the various components of the model - e.g. InstructionSequence, Instruction, LiveRange, etc. A pretty printer would help. While we have a suite of operator<< defined for these types, turns out that using them at debug time is close to impossible - gdb has poor (or convoluted) support for instantiating structures (e.g. OFStream, PrintableInstructionSequence, etc), and calling operator<< with pass-by-reference semantics.

I explored gdb macros, but hit an issue quite early with instantiating and initializing an OFStream - "virtual baseclass botch".

Currently, I have a side-file that I include (and then remove before publishing CLs), which defines wrappers to the above operator<< APIs, but this is becoming quite awkward, and I believe the functionality to be quite useful to anyone working in this (regalloc) area, so it's worth having something better than local side-files. The gdb path seems overly-twisted for the problem at hand, and I've noticed elsewhere (e.g. Object) the presence of Print APIs - hence this change.

BUG=

Review URL: https://codereview.chromium.org/1280483002

Cr-Commit-Position: refs/heads/master@{#30039}
This commit is contained in:
mtrofin 2015-08-05 23:15:18 -07:00 committed by Commit bot
parent b7726c447a
commit ee005fbb81
2 changed files with 57 additions and 0 deletions

View File

@ -1087,6 +1087,57 @@ bool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const {
}
void RegisterAllocationData::Print(
const InstructionSequence* instructionSequence) {
OFStream os(stdout);
PrintableInstructionSequence wrapper;
wrapper.register_configuration_ = config();
wrapper.sequence_ = instructionSequence;
os << wrapper << std::endl;
}
void RegisterAllocationData::Print(const Instruction* instruction) {
OFStream os(stdout);
PrintableInstruction wrapper;
wrapper.instr_ = instruction;
wrapper.register_configuration_ = config();
os << wrapper << std::endl;
}
void RegisterAllocationData::Print(const LiveRange* range, bool with_children) {
OFStream os(stdout);
PrintableLiveRange wrapper;
wrapper.register_configuration_ = config();
for (const LiveRange* i = range; i != nullptr; i = i->next()) {
wrapper.range_ = i;
os << wrapper << std::endl;
if (!with_children) break;
}
}
void RegisterAllocationData::Print(const InstructionOperand& op) {
OFStream os(stdout);
PrintableInstructionOperand wrapper;
wrapper.register_configuration_ = config();
wrapper.op_ = op;
os << wrapper << std::endl;
}
void RegisterAllocationData::Print(const MoveOperands* move) {
OFStream os(stdout);
PrintableInstructionOperand wrapper;
wrapper.register_configuration_ = config();
wrapper.op_ = move->destination();
os << wrapper << " = ";
wrapper.op_ = move->source();
os << wrapper << std::endl;
}
ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data)
: data_(data) {}

View File

@ -630,6 +630,12 @@ class RegisterAllocationData final : public ZoneObject {
PhiMapValue* GetPhiMapValueFor(int virtual_register);
bool IsBlockBoundary(LifetimePosition pos) const;
void Print(const InstructionSequence* instructionSequence);
void Print(const Instruction* instruction);
void Print(const LiveRange* range, bool with_children = false);
void Print(const InstructionOperand& op);
void Print(const MoveOperands* move);
private:
Zone* const allocation_zone_;
Frame* const frame_;