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 = ®alloc->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 +