Bug 937121 - IonMonkey: Improved register allocation debug output. r=bhackett

This commit is contained in:
Dan Gohman 2013-11-12 05:46:43 -08:00
parent fb3df87d49
commit 181687037e
4 changed files with 50 additions and 25 deletions

View File

@ -113,12 +113,12 @@ BacktrackingAllocator::go()
return false; return false;
IonSpew(IonSpew_RegAlloc, "Liveness analysis complete"); IonSpew(IonSpew_RegAlloc, "Liveness analysis complete");
if (IonSpewEnabled(IonSpew_RegAlloc))
dumpLiveness();
if (!init()) if (!init())
return false; return false;
if (IonSpewEnabled(IonSpew_RegAlloc))
dumpLiveness();
if (!allocationQueue.reserve(graph.numVirtualRegisters() * 3 / 2)) if (!allocationQueue.reserve(graph.numVirtualRegisters() * 3 / 2))
return false; return false;
@ -791,7 +791,7 @@ BacktrackingAllocator::split(LiveInterval *interval,
const LiveIntervalVector &newIntervals) const LiveIntervalVector &newIntervals)
{ {
if (IonSpewEnabled(IonSpew_RegAlloc)) { if (IonSpewEnabled(IonSpew_RegAlloc)) {
IonSpew(IonSpew_RegAlloc, "splitting interval v%u %s:", IonSpew(IonSpew_RegAlloc, "splitting interval v%u %s into:",
interval->vreg(), IntervalString(interval)); interval->vreg(), IntervalString(interval));
for (size_t i = 0; i < newIntervals.length(); i++) for (size_t i = 0; i < newIntervals.length(); i++)
IonSpew(IonSpew_RegAlloc, " %s", IntervalString(newIntervals[i])); IonSpew(IonSpew_RegAlloc, " %s", IntervalString(newIntervals[i]));
@ -1200,11 +1200,12 @@ BacktrackingAllocator::dumpLiveness()
for (size_t i = 0; i < block->numPhis(); i++) { for (size_t i = 0; i < block->numPhis(); i++) {
LPhi *phi = block->getPhi(i); LPhi *phi = block->getPhi(i);
fprintf(stderr, "[%u,%u Phi v%u <-", // Don't print the inputOf for phi nodes, since it's never used.
inputOf(phi).pos(), outputOf(phi).pos(), fprintf(stderr, "[,%u Phi [def v%u] <-",
outputOf(phi).pos(),
phi->getDef(0)->virtualRegister()); phi->getDef(0)->virtualRegister());
for (size_t j = 0; j < phi->numOperands(); j++) for (size_t j = 0; j < phi->numOperands(); j++)
fprintf(stderr, " v%u", phi->getOperand(j)->toUse()->virtualRegister()); fprintf(stderr, " %s", phi->getOperand(j)->toString());
fprintf(stderr, "]\n"); fprintf(stderr, "]\n");
} }
@ -1224,10 +1225,8 @@ BacktrackingAllocator::dumpLiveness()
fprintf(stderr, " [def v%u]", def->virtualRegister()); fprintf(stderr, " [def v%u]", def->virtualRegister());
} }
for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next()) { for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next())
if (alloc->isUse()) fprintf(stderr, " [use %s]", alloc->toString());
fprintf(stderr, " [use v%u]", alloc->toUse()->virtualRegister());
}
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
@ -1236,9 +1235,11 @@ BacktrackingAllocator::dumpLiveness()
fprintf(stderr, "\nLive Ranges:\n\n"); fprintf(stderr, "\nLive Ranges:\n\n");
for (size_t i = 0; i < AnyRegister::Total; i++) for (size_t i = 0; i < AnyRegister::Total; i++)
fprintf(stderr, "reg %s: %s\n", AnyRegister::FromCode(i).name(), IntervalString(fixedIntervals[i])); if (registers[i].allocatable)
fprintf(stderr, "reg %s: %s\n", AnyRegister::FromCode(i).name(), IntervalString(fixedIntervals[i]));
for (size_t i = 0; i < graph.numVirtualRegisters(); i++) { // Virtual register number 0 is unused.
for (size_t i = 1; i < graph.numVirtualRegisters(); i++) {
fprintf(stderr, "v%lu:", static_cast<unsigned long>(i)); fprintf(stderr, "v%lu:", static_cast<unsigned long>(i));
VirtualRegister &vreg = vregs[i]; VirtualRegister &vreg = vregs[i];
for (size_t j = 0; j < vreg.numIntervals(); j++) { for (size_t j = 0; j < vreg.numIntervals(); j++) {
@ -1259,9 +1260,13 @@ struct BacktrackingAllocator::PrintLiveIntervalRange
void operator()(const AllocatedRange &item) void operator()(const AllocatedRange &item)
{ {
if (item.range == item.interval->getRange(0)) { if (item.range == item.interval->getRange(0)) {
fprintf(stderr, " v%u: %s\n", if (item.interval->hasVreg())
item.interval->hasVreg() ? item.interval->vreg() : 0, fprintf(stderr, " v%u: %s\n",
IntervalString(item.interval)); item.interval->vreg(),
IntervalString(item.interval));
else
fprintf(stderr, " fixed: %s\n",
IntervalString(item.interval));
} }
} }
}; };
@ -1273,7 +1278,8 @@ BacktrackingAllocator::dumpAllocations()
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Allocations:\n"); fprintf(stderr, "Allocations:\n");
for (size_t i = 0; i < graph.numVirtualRegisters(); i++) { // Virtual register number 0 is unused.
for (size_t i = 1; i < graph.numVirtualRegisters(); i++) {
fprintf(stderr, "v%lu:", static_cast<unsigned long>(i)); fprintf(stderr, "v%lu:", static_cast<unsigned long>(i));
VirtualRegister &vreg = vregs[i]; VirtualRegister &vreg = vregs[i];
for (size_t j = 0; j < vreg.numIntervals(); j++) { for (size_t j = 0; j < vreg.numIntervals(); j++) {
@ -1288,8 +1294,10 @@ BacktrackingAllocator::dumpAllocations()
fprintf(stderr, "\n"); fprintf(stderr, "\n");
for (size_t i = 0; i < AnyRegister::Total; i++) { for (size_t i = 0; i < AnyRegister::Total; i++) {
fprintf(stderr, "reg %s:\n", AnyRegister::FromCode(i).name()); if (registers[i].allocatable) {
registers[i].allocations.forEach(PrintLiveIntervalRange()); fprintf(stderr, "reg %s:\n", AnyRegister::FromCode(i).name());
registers[i].allocations.forEach(PrintLiveIntervalRange());
}
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");

View File

@ -236,8 +236,17 @@ PrintUse(char *buf, size_t size, const LUse *use)
JS_snprintf(buf, size, "v%d:%s", use->virtualRegister(), JS_snprintf(buf, size, "v%d:%s", use->virtualRegister(),
Registers::GetName(Registers::Code(use->registerCode()))); Registers::GetName(Registers::Code(use->registerCode())));
break; break;
default: case LUse::ANY:
JS_snprintf(buf, size, "v%d:r?", use->virtualRegister());
break;
case LUse::KEEPALIVE:
JS_snprintf(buf, size, "v%d:*", use->virtualRegister()); JS_snprintf(buf, size, "v%d:*", use->virtualRegister());
break;
case LUse::RECOVERED_INPUT:
JS_snprintf(buf, size, "v%d:**", use->virtualRegister());
break;
default:
MOZ_ASSUME_UNREACHABLE("invalid use policy");
} }
} }

View File

@ -420,7 +420,7 @@ LiveRangeAllocator<VREG>::init()
// Build virtual register objects // Build virtual register objects
for (size_t i = 0; i < graph.numBlocks(); i++) { for (size_t i = 0; i < graph.numBlocks(); i++) {
if (mir->shouldCancel("LSRA create data structures (main loop)")) if (mir->shouldCancel("Create data structures (main loop)"))
return false; return false;
LBlock *block = graph.getBlock(i); LBlock *block = graph.getBlock(i);
@ -498,7 +498,7 @@ LiveRangeAllocator<VREG>::buildLivenessInfo()
return false; return false;
for (size_t i = graph.numBlocks(); i > 0; i--) { for (size_t i = graph.numBlocks(); i > 0; i--) {
if (mir->shouldCancel("LSRA Build Liveness Info (main loop)")) if (mir->shouldCancel("Build Liveness Info (main loop)"))
return false; return false;
LBlock *block = graph.getBlock(i - 1); LBlock *block = graph.getBlock(i - 1);

View File

@ -374,11 +374,16 @@ AllocationIntegrityState::dump()
for (size_t i = 0; i < block->numPhis(); i++) { for (size_t i = 0; i < block->numPhis(); i++) {
InstructionInfo &info = blocks[blockIndex].phis[i]; InstructionInfo &info = blocks[blockIndex].phis[i];
LPhi *phi = block->getPhi(i); LPhi *phi = block->getPhi(i);
CodePosition output(phi->id(), CodePosition::OUTPUT);
fprintf(stderr, "Phi v%u <-", info.outputs[0].virtualRegister()); // Don't print the inputOf for phi nodes, since it's never used.
fprintf(stderr, "[,%u Phi [def v%u %s] <-",
output.pos(),
info.outputs[0].virtualRegister(),
phi->getDef(0)->output()->toString());
for (size_t j = 0; j < phi->numOperands(); j++) for (size_t j = 0; j < phi->numOperands(); j++)
fprintf(stderr, " %s", info.inputs[j].toString()); fprintf(stderr, " %s", info.inputs[j].toString());
fprintf(stderr, "\n"); fprintf(stderr, "]\n");
} }
for (LInstructionIterator iter = block->begin(); iter != block->end(); iter++) { for (LInstructionIterator iter = block->begin(); iter != block->end(); iter++) {
@ -388,7 +393,10 @@ AllocationIntegrityState::dump()
CodePosition input(ins->id(), CodePosition::INPUT); CodePosition input(ins->id(), CodePosition::INPUT);
CodePosition output(ins->id(), CodePosition::OUTPUT); CodePosition output(ins->id(), CodePosition::OUTPUT);
fprintf(stderr, "[%u,%u %s]", input.pos(), output.pos(), ins->opName()); fprintf(stderr, "[");
if (input != CodePosition::MIN)
fprintf(stderr, "%u,%u ", input.pos(), output.pos());
fprintf(stderr, "%s]", ins->opName());
if (ins->isMoveGroup()) { if (ins->isMoveGroup()) {
LMoveGroup *group = ins->toMoveGroup(); LMoveGroup *group = ins->toMoveGroup();