From 181687037ee040b86682d13cec3f2fba1e4f1eef Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 12 Nov 2013 05:46:43 -0800 Subject: [PATCH] Bug 937121 - IonMonkey: Improved register allocation debug output. r=bhackett --- js/src/jit/BacktrackingAllocator.cpp | 46 ++++++++++++++++------------ js/src/jit/LIR.cpp | 11 ++++++- js/src/jit/LiveRangeAllocator.cpp | 4 +-- js/src/jit/RegisterAllocator.cpp | 14 +++++++-- 4 files changed, 50 insertions(+), 25 deletions(-) diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp index 4ee42a08803..e6c6897bd13 100644 --- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -113,12 +113,12 @@ BacktrackingAllocator::go() return false; IonSpew(IonSpew_RegAlloc, "Liveness analysis complete"); - if (IonSpewEnabled(IonSpew_RegAlloc)) - dumpLiveness(); - if (!init()) return false; + if (IonSpewEnabled(IonSpew_RegAlloc)) + dumpLiveness(); + if (!allocationQueue.reserve(graph.numVirtualRegisters() * 3 / 2)) return false; @@ -791,7 +791,7 @@ BacktrackingAllocator::split(LiveInterval *interval, const LiveIntervalVector &newIntervals) { 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)); for (size_t i = 0; i < newIntervals.length(); i++) IonSpew(IonSpew_RegAlloc, " %s", IntervalString(newIntervals[i])); @@ -1200,11 +1200,12 @@ BacktrackingAllocator::dumpLiveness() for (size_t i = 0; i < block->numPhis(); i++) { LPhi *phi = block->getPhi(i); - fprintf(stderr, "[%u,%u Phi v%u <-", - inputOf(phi).pos(), outputOf(phi).pos(), + // Don't print the inputOf for phi nodes, since it's never used. + fprintf(stderr, "[,%u Phi [def v%u] <-", + outputOf(phi).pos(), phi->getDef(0)->virtualRegister()); 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"); } @@ -1224,10 +1225,8 @@ BacktrackingAllocator::dumpLiveness() fprintf(stderr, " [def v%u]", def->virtualRegister()); } - for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next()) { - if (alloc->isUse()) - fprintf(stderr, " [use v%u]", alloc->toUse()->virtualRegister()); - } + for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next()) + fprintf(stderr, " [use %s]", alloc->toString()); fprintf(stderr, "\n"); } @@ -1236,9 +1235,11 @@ BacktrackingAllocator::dumpLiveness() fprintf(stderr, "\nLive Ranges:\n\n"); 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(i)); VirtualRegister &vreg = vregs[i]; for (size_t j = 0; j < vreg.numIntervals(); j++) { @@ -1259,9 +1260,13 @@ struct BacktrackingAllocator::PrintLiveIntervalRange void operator()(const AllocatedRange &item) { if (item.range == item.interval->getRange(0)) { - fprintf(stderr, " v%u: %s\n", - item.interval->hasVreg() ? item.interval->vreg() : 0, - IntervalString(item.interval)); + if (item.interval->hasVreg()) + fprintf(stderr, " v%u: %s\n", + item.interval->vreg(), + IntervalString(item.interval)); + else + fprintf(stderr, " fixed: %s\n", + IntervalString(item.interval)); } } }; @@ -1273,7 +1278,8 @@ BacktrackingAllocator::dumpAllocations() #ifdef DEBUG 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(i)); VirtualRegister &vreg = vregs[i]; for (size_t j = 0; j < vreg.numIntervals(); j++) { @@ -1288,8 +1294,10 @@ BacktrackingAllocator::dumpAllocations() fprintf(stderr, "\n"); for (size_t i = 0; i < AnyRegister::Total; i++) { - fprintf(stderr, "reg %s:\n", AnyRegister::FromCode(i).name()); - registers[i].allocations.forEach(PrintLiveIntervalRange()); + if (registers[i].allocatable) { + fprintf(stderr, "reg %s:\n", AnyRegister::FromCode(i).name()); + registers[i].allocations.forEach(PrintLiveIntervalRange()); + } } fprintf(stderr, "\n"); diff --git a/js/src/jit/LIR.cpp b/js/src/jit/LIR.cpp index 24b8059fba6..ee895f6d38b 100644 --- a/js/src/jit/LIR.cpp +++ b/js/src/jit/LIR.cpp @@ -236,8 +236,17 @@ PrintUse(char *buf, size_t size, const LUse *use) JS_snprintf(buf, size, "v%d:%s", use->virtualRegister(), Registers::GetName(Registers::Code(use->registerCode()))); 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()); + break; + case LUse::RECOVERED_INPUT: + JS_snprintf(buf, size, "v%d:**", use->virtualRegister()); + break; + default: + MOZ_ASSUME_UNREACHABLE("invalid use policy"); } } diff --git a/js/src/jit/LiveRangeAllocator.cpp b/js/src/jit/LiveRangeAllocator.cpp index 553cb9d7080..222bacf3c0a 100644 --- a/js/src/jit/LiveRangeAllocator.cpp +++ b/js/src/jit/LiveRangeAllocator.cpp @@ -420,7 +420,7 @@ LiveRangeAllocator::init() // Build virtual register objects 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; LBlock *block = graph.getBlock(i); @@ -498,7 +498,7 @@ LiveRangeAllocator::buildLivenessInfo() return false; 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; LBlock *block = graph.getBlock(i - 1); diff --git a/js/src/jit/RegisterAllocator.cpp b/js/src/jit/RegisterAllocator.cpp index dc58cafd9d3..46347a77757 100644 --- a/js/src/jit/RegisterAllocator.cpp +++ b/js/src/jit/RegisterAllocator.cpp @@ -374,11 +374,16 @@ AllocationIntegrityState::dump() for (size_t i = 0; i < block->numPhis(); i++) { InstructionInfo &info = blocks[blockIndex].phis[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++) fprintf(stderr, " %s", info.inputs[j].toString()); - fprintf(stderr, "\n"); + fprintf(stderr, "]\n"); } for (LInstructionIterator iter = block->begin(); iter != block->end(); iter++) { @@ -388,7 +393,10 @@ AllocationIntegrityState::dump() CodePosition input(ins->id(), CodePosition::INPUT); 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()) { LMoveGroup *group = ins->toMoveGroup();