blob: f1df190ca224d36213d9e2623ed20843e4ac8f81 [file] [log] [blame]
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef JS_JITSPEW
#include "jit/C1Spewer.h"
#include "mozilla/SizePrintfMacros.h"
#include <time.h>
#include "jit/BacktrackingAllocator.h"
#include "jit/LIR.h"
#include "jit/MIRGraph.h"
#include "vm/Printer.h"
using namespace js;
using namespace js::jit;
void
C1Spewer::beginFunction(MIRGraph* graph, JSScript* script)
{
this->graph = graph;
out_.printf("begin_compilation\n");
if (script) {
out_.printf(" name \"%s:%" PRIuSIZE "\"\n", script->filename(), script->lineno());
out_.printf(" method \"%s:%" PRIuSIZE "\"\n", script->filename(), script->lineno());
} else {
out_.printf(" name \"asm.js compilation\"\n");
out_.printf(" method \"asm.js compilation\"\n");
}
out_.printf(" date %d\n", (int)time(nullptr));
out_.printf("end_compilation\n");
}
void
C1Spewer::spewPass(const char* pass)
{
out_.printf("begin_cfg\n");
out_.printf(" name \"%s\"\n", pass);
for (MBasicBlockIterator block(graph->begin()); block != graph->end(); block++)
spewPass(out_, *block);
out_.printf("end_cfg\n");
}
void
C1Spewer::spewRanges(const char* pass, BacktrackingAllocator* regalloc)
{
out_.printf("begin_ranges\n");
out_.printf(" name \"%s\"\n", pass);
for (MBasicBlockIterator block(graph->begin()); block != graph->end(); block++)
spewRanges(out_, *block, regalloc);
out_.printf("end_ranges\n");
}
void
C1Spewer::endFunction()
{
}
static void
DumpDefinition(GenericPrinter& out, MDefinition* def)
{
out.printf(" ");
out.printf("%u %u ", def->id(), unsigned(def->useCount()));
def->printName(out);
out.printf(" ");
def->printOpcode(out);
out.printf(" <|@\n");
}
static void
DumpLIR(GenericPrinter& out, LNode* ins)
{
out.printf(" ");
out.printf("%d ", ins->id());
ins->dump(out);
out.printf(" <|@\n");
}
void
C1Spewer::spewRanges(GenericPrinter& out, BacktrackingAllocator* regalloc, LNode* ins)
{
for (size_t k = 0; k < ins->numDefs(); k++) {
uint32_t id = ins->getDef(k)->virtualRegister();
VirtualRegister* vreg = &regalloc->vregs[id];
for (LiveRange::RegisterLinkIterator iter = vreg->rangesBegin(); iter; iter++) {
LiveRange* range = LiveRange::get(*iter);
out.printf("%d object \"", id);
out.printf("%s", range->bundle()->allocation().toString());
out.printf("\" %d -1", id);
out.printf(" [%u, %u[", range->from().bits(), range->to().bits());
for (UsePositionIterator usePos(range->usesBegin()); usePos; usePos++)
out.printf(" %u M", usePos->pos.bits());
out.printf(" \"\"\n");
}
}
}
void
C1Spewer::spewRanges(GenericPrinter& out, MBasicBlock* block, BacktrackingAllocator* regalloc)
{
LBlock* lir = block->lir();
if (!lir)
return;
for (size_t i = 0; i < lir->numPhis(); i++)
spewRanges(out, regalloc, lir->getPhi(i));
for (LInstructionIterator ins = lir->begin(); ins != lir->end(); ins++)
spewRanges(out, regalloc, *ins);
}
void
C1Spewer::spewPass(GenericPrinter& out, MBasicBlock* block)
{
out.printf(" begin_block\n");
out.printf(" name \"B%d\"\n", block->id());
out.printf(" from_bci -1\n");
out.printf(" to_bci -1\n");
out.printf(" predecessors");
for (uint32_t i = 0; i < block->numPredecessors(); i++) {
MBasicBlock* pred = block->getPredecessor(i);
out.printf(" \"B%d\"", pred->id());
}
out.printf("\n");
out.printf(" successors");
for (uint32_t i = 0; i < block->numSuccessors(); i++) {
MBasicBlock* successor = block->getSuccessor(i);
out.printf(" \"B%d\"", successor->id());
}
out.printf("\n");
out.printf(" xhandlers\n");
out.printf(" flags\n");
if (block->lir() && block->lir()->begin() != block->lir()->end()) {
out.printf(" first_lir_id %d\n", block->lir()->firstId());
out.printf(" last_lir_id %d\n", block->lir()->lastId());
}
out.printf(" begin_states\n");
if (block->entryResumePoint()) {
out.printf(" begin_locals\n");
out.printf(" size %d\n", (int)block->numEntrySlots());
out.printf(" method \"None\"\n");
for (uint32_t i = 0; i < block->numEntrySlots(); i++) {
MDefinition* ins = block->getEntrySlot(i);
out.printf(" ");
out.printf("%d ", i);
if (ins->isUnused())
out.printf("unused");
else
ins->printName(out);
out.printf("\n");
}
out.printf(" end_locals\n");
}
out.printf(" end_states\n");
out.printf(" begin_HIR\n");
for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); phi++)
DumpDefinition(out, *phi);
for (MInstructionIterator i(block->begin()); i != block->end(); i++)
DumpDefinition(out, *i);
out.printf(" end_HIR\n");
if (block->lir()) {
out.printf(" begin_LIR\n");
for (size_t i = 0; i < block->lir()->numPhis(); i++)
DumpLIR(out, block->lir()->getPhi(i));
for (LInstructionIterator i(block->lir()->begin()); i != block->lir()->end(); i++)
DumpLIR(out, *i);
out.printf(" end_LIR\n");
}
out.printf(" end_block\n");
}
#endif /* JS_JITSPEW */