summaryrefslogtreecommitdiffstats
path: root/js/src/jit/C1Spewer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/C1Spewer.cpp')
-rw-r--r--js/src/jit/C1Spewer.cpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/js/src/jit/C1Spewer.cpp b/js/src/jit/C1Spewer.cpp
new file mode 100644
index 000000000..f334345ba
--- /dev/null
+++ b/js/src/jit/C1Spewer.cpp
@@ -0,0 +1,194 @@
+/* -*- 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 \"wasm compilation\"\n");
+ out_.printf(" method \"wasm 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().get());
+ 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 */
+