js/src/jit/C1Spewer.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/src/jit/C1Spewer.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,222 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99:
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifdef DEBUG
    1.11 +
    1.12 +#include "jit/C1Spewer.h"
    1.13 +
    1.14 +#include <time.h>
    1.15 +
    1.16 +#include "jit/LinearScan.h"
    1.17 +#include "jit/LIR.h"
    1.18 +#include "jit/MIRGraph.h"
    1.19 +
    1.20 +using namespace js;
    1.21 +using namespace js::jit;
    1.22 +
    1.23 +bool
    1.24 +C1Spewer::init(const char *path)
    1.25 +{
    1.26 +    spewout_ = fopen(path, "w");
    1.27 +    return spewout_ != nullptr;
    1.28 +}
    1.29 +
    1.30 +void
    1.31 +C1Spewer::beginFunction(MIRGraph *graph, HandleScript script)
    1.32 +{
    1.33 +    if (!spewout_)
    1.34 +        return;
    1.35 +
    1.36 +    this->graph  = graph;
    1.37 +    this->script.repoint(script);
    1.38 +
    1.39 +    fprintf(spewout_, "begin_compilation\n");
    1.40 +    if (script) {
    1.41 +        fprintf(spewout_, "  name \"%s:%d\"\n", script->filename(), (int)script->lineno());
    1.42 +        fprintf(spewout_, "  method \"%s:%d\"\n", script->filename(), (int)script->lineno());
    1.43 +    } else {
    1.44 +        fprintf(spewout_, "  name \"asm.js compilation\"\n");
    1.45 +        fprintf(spewout_, "  method \"asm.js compilation\"\n");
    1.46 +    }
    1.47 +    fprintf(spewout_, "  date %d\n", (int)time(nullptr));
    1.48 +    fprintf(spewout_, "end_compilation\n");
    1.49 +}
    1.50 +
    1.51 +void
    1.52 +C1Spewer::spewPass(const char *pass)
    1.53 +{
    1.54 +    if (!spewout_)
    1.55 +        return;
    1.56 +
    1.57 +    fprintf(spewout_, "begin_cfg\n");
    1.58 +    fprintf(spewout_, "  name \"%s\"\n", pass);
    1.59 +
    1.60 +    for (MBasicBlockIterator block(graph->begin()); block != graph->end(); block++)
    1.61 +        spewPass(spewout_, *block);
    1.62 +
    1.63 +    fprintf(spewout_, "end_cfg\n");
    1.64 +    fflush(spewout_);
    1.65 +}
    1.66 +
    1.67 +void
    1.68 +C1Spewer::spewIntervals(const char *pass, LinearScanAllocator *regalloc)
    1.69 +{
    1.70 +    if (!spewout_)
    1.71 +        return;
    1.72 +
    1.73 +    fprintf(spewout_, "begin_intervals\n");
    1.74 +    fprintf(spewout_, " name \"%s\"\n", pass);
    1.75 +
    1.76 +    size_t nextId = 0x4000;
    1.77 +    for (MBasicBlockIterator block(graph->begin()); block != graph->end(); block++)
    1.78 +        spewIntervals(spewout_, *block, regalloc, nextId);
    1.79 +
    1.80 +    fprintf(spewout_, "end_intervals\n");
    1.81 +    fflush(spewout_);
    1.82 +}
    1.83 +
    1.84 +void
    1.85 +C1Spewer::endFunction()
    1.86 +{
    1.87 +}
    1.88 +
    1.89 +void
    1.90 +C1Spewer::finish()
    1.91 +{
    1.92 +    if (spewout_)
    1.93 +        fclose(spewout_);
    1.94 +}
    1.95 +
    1.96 +static void
    1.97 +DumpDefinition(FILE *fp, MDefinition *def)
    1.98 +{
    1.99 +    fprintf(fp, "      ");
   1.100 +    fprintf(fp, "%u %u ", def->id(), unsigned(def->useCount()));
   1.101 +    def->printName(fp);
   1.102 +    fprintf(fp, " ");
   1.103 +    def->printOpcode(fp);
   1.104 +    fprintf(fp, " <|@\n");
   1.105 +}
   1.106 +
   1.107 +static void
   1.108 +DumpLIR(FILE *fp, LInstruction *ins)
   1.109 +{
   1.110 +    fprintf(fp, "      ");
   1.111 +    fprintf(fp, "%d ", ins->id());
   1.112 +    ins->dump(fp);
   1.113 +    fprintf(fp, " <|@\n");
   1.114 +}
   1.115 +
   1.116 +void
   1.117 +C1Spewer::spewIntervals(FILE *fp, LinearScanAllocator *regalloc, LInstruction *ins, size_t &nextId)
   1.118 +{
   1.119 +    for (size_t k = 0; k < ins->numDefs(); k++) {
   1.120 +        uint32_t id = ins->getDef(k)->virtualRegister();
   1.121 +        VirtualRegister *vreg = &regalloc->vregs[id];
   1.122 +
   1.123 +        for (size_t i = 0; i < vreg->numIntervals(); i++) {
   1.124 +            LiveInterval *live = vreg->getInterval(i);
   1.125 +            if (live->numRanges()) {
   1.126 +                fprintf(fp, "%d object \"", (i == 0) ? id : int32_t(nextId++));
   1.127 +                fprintf(fp, "%s", live->getAllocation()->toString());
   1.128 +                fprintf(fp, "\" %d -1", id);
   1.129 +                for (size_t j = 0; j < live->numRanges(); j++) {
   1.130 +                    fprintf(fp, " [%d, %d[", live->getRange(j)->from.pos(),
   1.131 +                            live->getRange(j)->to.pos());
   1.132 +                }
   1.133 +                for (UsePositionIterator usePos(live->usesBegin()); usePos != live->usesEnd(); usePos++)
   1.134 +                    fprintf(fp, " %d M", usePos->pos.pos());
   1.135 +                fprintf(fp, " \"\"\n");
   1.136 +            }
   1.137 +        }
   1.138 +    }
   1.139 +}
   1.140 +
   1.141 +void
   1.142 +C1Spewer::spewIntervals(FILE *fp, MBasicBlock *block, LinearScanAllocator *regalloc, size_t &nextId)
   1.143 +{
   1.144 +    LBlock *lir = block->lir();
   1.145 +    if (!lir)
   1.146 +        return;
   1.147 +
   1.148 +    for (size_t i = 0; i < lir->numPhis(); i++)
   1.149 +        spewIntervals(fp, regalloc, lir->getPhi(i), nextId);
   1.150 +
   1.151 +    for (LInstructionIterator ins = lir->begin(); ins != lir->end(); ins++)
   1.152 +        spewIntervals(fp, regalloc, *ins, nextId);
   1.153 +}
   1.154 +
   1.155 +void
   1.156 +C1Spewer::spewPass(FILE *fp, MBasicBlock *block)
   1.157 +{
   1.158 +    fprintf(fp, "  begin_block\n");
   1.159 +    fprintf(fp, "    name \"B%d\"\n", block->id());
   1.160 +    fprintf(fp, "    from_bci -1\n");
   1.161 +    fprintf(fp, "    to_bci -1\n");
   1.162 +
   1.163 +    fprintf(fp, "    predecessors");
   1.164 +    for (uint32_t i = 0; i < block->numPredecessors(); i++) {
   1.165 +        MBasicBlock *pred = block->getPredecessor(i);
   1.166 +        fprintf(fp, " \"B%d\"", pred->id());
   1.167 +    }
   1.168 +    fprintf(fp, "\n");
   1.169 +
   1.170 +    fprintf(fp, "    successors");
   1.171 +    for (uint32_t i = 0; i < block->numSuccessors(); i++) {
   1.172 +        MBasicBlock *successor = block->getSuccessor(i);
   1.173 +        fprintf(fp, " \"B%d\"", successor->id());
   1.174 +    }
   1.175 +    fprintf(fp, "\n");
   1.176 +
   1.177 +    fprintf(fp, "    xhandlers\n");
   1.178 +    fprintf(fp, "    flags\n");
   1.179 +
   1.180 +    if (block->lir() && block->lir()->begin() != block->lir()->end()) {
   1.181 +        fprintf(fp, "    first_lir_id %d\n", block->lir()->firstId());
   1.182 +        fprintf(fp, "    last_lir_id %d\n", block->lir()->lastId());
   1.183 +    }
   1.184 +
   1.185 +    fprintf(fp, "    begin_states\n");
   1.186 +
   1.187 +    if (block->entryResumePoint()) {
   1.188 +        fprintf(fp, "      begin_locals\n");
   1.189 +        fprintf(fp, "        size %d\n", (int)block->numEntrySlots());
   1.190 +        fprintf(fp, "        method \"None\"\n");
   1.191 +        for (uint32_t i = 0; i < block->numEntrySlots(); i++) {
   1.192 +            MDefinition *ins = block->getEntrySlot(i);
   1.193 +            fprintf(fp, "        ");
   1.194 +            fprintf(fp, "%d ", i);
   1.195 +            if (ins->isUnused())
   1.196 +                fprintf(fp, "unused");
   1.197 +            else
   1.198 +                ins->printName(fp);
   1.199 +            fprintf(fp, "\n");
   1.200 +        }
   1.201 +        fprintf(fp, "      end_locals\n");
   1.202 +    }
   1.203 +    fprintf(fp, "    end_states\n");
   1.204 +
   1.205 +    fprintf(fp, "    begin_HIR\n");
   1.206 +    for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); phi++)
   1.207 +        DumpDefinition(fp, *phi);
   1.208 +    for (MInstructionIterator i(block->begin()); i != block->end(); i++)
   1.209 +        DumpDefinition(fp, *i);
   1.210 +    fprintf(fp, "    end_HIR\n");
   1.211 +
   1.212 +    if (block->lir()) {
   1.213 +        fprintf(fp, "    begin_LIR\n");
   1.214 +        for (size_t i = 0; i < block->lir()->numPhis(); i++)
   1.215 +            DumpLIR(fp, block->lir()->getPhi(i));
   1.216 +        for (LInstructionIterator i(block->lir()->begin()); i != block->lir()->end(); i++)
   1.217 +            DumpLIR(fp, *i);
   1.218 +        fprintf(fp, "    end_LIR\n");
   1.219 +    }
   1.220 +
   1.221 +    fprintf(fp, "  end_block\n");
   1.222 +}
   1.223 +
   1.224 +#endif /* DEBUG */
   1.225 +

mercurial