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:
parent
b7726c447a
commit
ee005fbb81
@ -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) {}
|
||||
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user