void printDst(std::ostream& os, const IRInstruction* inst, const RegAllocInfo* regs, const LifetimeInfo* lifetime) { if (inst->numDsts() == 0) return; const char* sep = ""; for (const SSATmp& dst : inst->dsts()) { os << punc(sep); print(os, &dst, regs, lifetime, true); sep = ", "; } os << punc(" = "); }
void print(std::ostream& ostream, const IRInstruction* inst, const RegAllocInfo* regs, const LifetimeInfo* lifetime) { if (inst->op() == Marker) { auto* marker = inst->getExtra<Marker>(); ostream << color(ANSI_COLOR_BLUE) << folly::format("--- bc {}, spOff {} ({})", marker->bcOff, marker->stackOff, marker->func->fullName()->data()) << color(ANSI_COLOR_END); return; } if (!inst->isTransient()) { ostream << color(ANSI_COLOR_YELLOW); if (!lifetime || !lifetime->linear[inst]) { ostream << folly::format("({:02d}) ", inst->getId()); } else { ostream << folly::format("({:02d}@{:02d}) ", inst->getId(), lifetime->linear[inst]); } ostream << color(ANSI_COLOR_END); } printDst(ostream, inst, regs, lifetime); printOpcode(ostream, inst); printSrcs(ostream, inst, regs, lifetime); if (Block* taken = inst->getTaken()) { ostream << punc(" -> "); printLabel(ostream, taken); } if (TCA tca = inst->getTCA()) { ostream << punc(", "); if (tca == kIRDirectJccJmpActive) { ostream << "JccJmp_Exit "; } else if (tca == kIRDirectJccActive) { ostream << "Jcc_Exit "; } else if (tca == kIRDirectGuardActive) { ostream << "Guard_Exit "; } else { ostream << (void*)tca; } } }
void printInstr(std::ostream& ostream, const IRInstruction* inst, const RegAllocInfo* regs, const GuardConstraints* guards) { printDsts(ostream, inst, regs); if (inst->numDsts()) ostream << punc(" = "); printOpcode(ostream, inst, guards); printSrcs(ostream, inst, regs); }
void print(std::ostream& ostream, const IRInstruction* inst, const RegAllocInfo* regs, const LifetimeInfo* lifetime) { if (inst->op() == Marker) { auto* marker = inst->extra<Marker>(); ostream << color(ANSI_COLOR_BLUE) << marker->show() << color(ANSI_COLOR_END); return; } if (!inst->isTransient()) { ostream << color(ANSI_COLOR_YELLOW); if (!lifetime || !lifetime->linear[inst]) { ostream << folly::format("({:02d}) ", inst->id()); } else { ostream << folly::format("({:02d}@{:02d}) ", inst->id(), lifetime->linear[inst]); } ostream << color(ANSI_COLOR_END); } printDst(ostream, inst, regs, lifetime); printOpcode(ostream, inst); printSrcs(ostream, inst, regs, lifetime); if (Block* taken = inst->taken()) { ostream << punc(" -> "); printLabel(ostream, taken); } }
void printDsts(std::ostream& os, const IRInstruction* inst) { const char* sep = ""; for (unsigned i = 0, n = inst->numDsts(); i < n; i++) { os << punc(sep); print(os, inst->dst(i)); sep = ", "; } }
void printDsts(std::ostream& os, const IRInstruction* inst, const RegAllocInfo* regs) { const char* sep = ""; for (unsigned i = 0, n = inst->numDsts(); i < n; i++) { os << punc(sep); print(os, inst->dst(i), dstLoc(regs, inst, i)); sep = ", "; } }
void printOpcode(std::ostream& os, const IRInstruction* inst, const GuardConstraints* guards) { os << color(ANSI_COLOR_CYAN) << opcodeName(inst->op()) << color(ANSI_COLOR_END) ; auto const typeParam = inst->typeParam(); auto const hasTypeParam = !typeParam.equals(Type::None); auto const hasExtra = inst->hasExtra(); auto const isGuard = guards && !inst->isTransient() && isGuardOp(inst->op()); if (!hasTypeParam && !hasExtra && !isGuard) return; os << color(ANSI_COLOR_LIGHT_BLUE) << '<' << color(ANSI_COLOR_END); if (hasTypeParam) { os << color(ANSI_COLOR_GREEN) << typeParam.toString() << color(ANSI_COLOR_END) ; if (hasExtra || isGuard) os << punc(","); } if (inst->op() == LdConst) { os << constToString(inst->typeParam(), inst->extra<LdConst>()); } else { if (hasExtra) { os << color(ANSI_COLOR_GREEN) << showExtra(inst->op(), inst->rawExtra()) << color(ANSI_COLOR_END); if (isGuard) os << punc(","); } } if (isGuard) { auto it = guards->find(inst); os << (it == guards->end() ? "unused" : it->second.toString()); } os << color(ANSI_COLOR_LIGHT_BLUE) << '>' << color(ANSI_COLOR_END); }
/* * IRInstruction */ void printOpcode(std::ostream& os, const IRInstruction* inst, const GuardConstraints* constraints) { os << color(ANSI_COLOR_CYAN) << opcodeName(inst->op()) << color(ANSI_COLOR_END) ; auto const hasTypeParam = inst->hasTypeParam(); auto const hasExtra = inst->hasExtra(); auto const isGuard = constraints && !inst->isTransient() && isGuardOp(inst->op()); if (!hasTypeParam && !hasExtra && !isGuard) return; os << color(ANSI_COLOR_LIGHT_BLUE) << '<' << color(ANSI_COLOR_END); if (hasTypeParam) { os << color(ANSI_COLOR_GREEN) << inst->typeParam().toString() << color(ANSI_COLOR_END) ; if (hasExtra || isGuard) os << punc(","); } if (hasExtra) { os << color(ANSI_COLOR_GREEN) << showExtra(inst->op(), inst->rawExtra()) << color(ANSI_COLOR_END); if (isGuard) os << punc(","); } if (isGuard) { auto it = constraints->guards.find(inst); os << (it == constraints->guards.end() ? "unused" : it->second.toString()); } os << color(ANSI_COLOR_LIGHT_BLUE) << '>' << color(ANSI_COLOR_END); }
void print(std::ostream& ostream, const IRInstruction* inst, const RegAllocInfo* regs, const GuardConstraints* guards) { if (!inst->isTransient()) { ostream << color(ANSI_COLOR_YELLOW); ostream << folly::format("({:02d}) ", inst->id()); ostream << color(ANSI_COLOR_END); } printInstr(ostream, inst, regs, guards); if (Block* taken = inst->taken()) { ostream << punc(" -> "); printLabel(ostream, taken); } }
void print(std::ostream& os, const SSATmp* tmp) { if (tmp->inst()->is(DefConst)) { os << constToString(tmp->type()); return; } os << color(ANSI_COLOR_WHITE); os << "t" << tmp->id(); os << color(ANSI_COLOR_END); os << punc(":") << color(ANSI_COLOR_GREEN) << tmp->type().toString() << color(ANSI_COLOR_END) ; }
void printSrcs(std::ostream& os, const IRInstruction* inst) { bool first = true; if (inst->op() == IncStat) { os << " " << Stats::g_counterNames[inst->src(0)->intVal()] << ", " << inst->src(1)->intVal(); return; } for (uint32_t i = 0, n = inst->numSrcs(); i < n; i++) { if (!first) { os << punc(", "); } else { os << " "; first = false; } printSrc(os, inst, i); } }
void printSrcs(std::ostream& os, const IRInstruction* inst, const RegAllocInfo* regs, const LifetimeInfo* lifetime) { bool first = true; if (inst->op() == IncStat) { os << " " << Stats::g_counterNames[inst->src(0)->getValInt()] << ", " << inst->src(1)->getValInt(); return; } for (uint32_t i = 0, n = inst->numSrcs(); i < n; i++) { if (!first) { os << punc(", "); } else { os << " "; first = false; } printSrc(os, inst, i, regs, lifetime); } }
void PuncFilter::parsePuncInputFile( QString fileName ) { file = new QFile(fileName); doc = new QTextDocument; if (file->open(QFile::Text|QFile::ReadOnly) == false) return; doc->setPlainText(file->readAll()); file->close(); QRegExp punc("^\\S+"); QRegExp desc("\\w+"); QList<lineCell*> data; for (int i = 0; i < doc->lineCount(); i++) { QString line = doc->findBlockByLineNumber(i).text(); int pos1 = punc.indexIn(line, 0); lineCell* lc = new lineCell; lc->pattern = line.mid(pos1, punc.matchedLength()); int pos2 = desc.indexIn(line, 0); lc->description = line.mid(pos2, desc.matchedLength()); data.append(lc); } int maxLen = 0; foreach(lineCell* lc, data) { maxLen = lc->description.length() > maxLen ? lc ->description.length() : maxLen; } //generate punctuation codes foreach(lineCell* lc, data) { int spaceNum = maxLen - lc->description.length(); QString space; for (int i = 0; i < spaceNum; i++) space.append(" "); codes << QString("addTokenType ( \"_%1\", %2\"%3\",\t\t\"_punctuation\" );\n").arg(lc->description).arg(space).arg(lc->pattern); }
void print(std::ostream& os, const Block* block, const RegAllocInfo* regs, const AsmInfo* asmInfo, const GuardConstraints* guards, BCMarker* markerPtr) { BCMarker dummy; BCMarker& curMarker = markerPtr ? *markerPtr : dummy; TcaRange blockRange = asmInfo ? asmInfo->asmRanges[block] : TcaRange(nullptr, nullptr); os << '\n' << std::string(kIndent - 3, ' '); printLabel(os, block); os << punc(":"); auto& preds = block->preds(); if (!preds.empty()) { os << " (preds"; for (auto const& edge : preds) { os << " B" << edge.from()->id(); } os << ')'; } os << "\n"; if (block->empty()) { os << std::string(kIndent, ' ') << "empty block\n"; return; } const char* markerEndl = ""; for (auto it = block->begin(); it != block->end();) { auto& inst = *it; ++it; if (inst.marker() != curMarker) { std::ostringstream mStr; auto const& newMarker = inst.marker(); if (!newMarker.hasFunc()) { os << color(ANSI_COLOR_BLUE) << std::string(kIndent, ' ') << "--- invalid marker" << color(ANSI_COLOR_END) << '\n'; } else { auto func = newMarker.func(); if (!curMarker.hasFunc() || func != curMarker.func()) { func->prettyPrint(mStr, Func::PrintOpts().noFpi()); } mStr << std::string(kIndent, ' ') << newMarker.show() << '\n'; auto bcOffset = newMarker.bcOff(); func->unit()->prettyPrint( mStr, Unit::PrintOpts() .range(bcOffset, bcOffset+1) .noLineNumbers() .noFuncs() .indent(0)); std::vector<std::string> vec; folly::split('\n', mStr.str(), vec); os << markerEndl; markerEndl = "\n"; for (auto& s : vec) { if (s.empty()) continue; os << color(ANSI_COLOR_BLUE) << s << color(ANSI_COLOR_END) << '\n'; } } curMarker = newMarker; } if (inst.op() == DefLabel) { // print phi pseudo-instructions for (unsigned i = 0, n = inst.numDsts(); i < n; ++i) { os << std::string(kIndent + folly::format("({}) ", inst.id()).str().size(), ' '); auto dst = inst.dst(i); jit::print(os, dst, dstLoc(regs, &inst, i)); os << punc(" = ") << color(ANSI_COLOR_CYAN) << "phi " << color(ANSI_COLOR_END); bool first = true; inst.block()->forEachSrc(i, [&](IRInstruction* jmp, SSATmp*) { if (!first) os << punc(", "); first = false; printSrc(os, jmp, i, regs); os << punc("@"); printLabel(os, jmp->block()); }); os << '\n'; } } os << std::string(kIndent, ' '); jit::print(os, &inst, regs, guards); os << '\n'; if (asmInfo) { TcaRange instRange = asmInfo->instRanges[inst]; if (!instRange.empty()) { disasmRange(os, instRange.begin(), instRange.end()); os << '\n'; assert(instRange.end() >= blockRange.start() && instRange.end() <= blockRange.end()); blockRange = TcaRange(instRange.end(), blockRange.end()); } } } if (asmInfo) { // print code associated with this block that isn't tied to any // instruction. This includes code after the last isntruction (e.g. // jmp to next block), and ACold or AFrozen code. if (!blockRange.empty()) { os << std::string(kIndent, ' ') << punc("A:") << "\n"; disasmRange(os, blockRange.start(), blockRange.end()); } auto acoldRange = asmInfo->acoldRanges[block]; if (!acoldRange.empty()) { os << std::string(kIndent, ' ') << punc("ACold:") << "\n"; disasmRange(os, acoldRange.start(), acoldRange.end()); } auto afrozenRange = asmInfo->afrozenRanges[block]; if (!afrozenRange.empty()) { os << std::string(kIndent, ' ') << punc("AFrozen:") << "\n"; disasmRange(os, afrozenRange.start(), afrozenRange.end()); } if (!blockRange.empty() || !acoldRange.empty() || !afrozenRange.empty()) { os << '\n'; } } os << std::string(kIndent - 2, ' '); auto next = block->empty() ? nullptr : block->next(); if (next) { os << punc("-> "); printLabel(os, next); os << '\n'; } else { os << "no fallthrough\n"; } }
void print(std::ostream& os, const Block* block, AreaIndex area, const AsmInfo* asmInfo, const GuardConstraints* guards, BCMarker* markerPtr) { BCMarker dummy; BCMarker& curMarker = markerPtr ? *markerPtr : dummy; TcaRange blockRange = asmInfo ? asmInfo->blockRangesForArea(area)[block] : TcaRange { nullptr, nullptr }; os << '\n' << std::string(kIndent - 3, ' '); printLabel(os, block); os << punc(":"); auto& preds = block->preds(); if (!preds.empty()) { os << " (preds"; for (auto const& edge : preds) { os << " B" << edge.from()->id(); } os << ')'; } os << "\n"; if (block->empty()) { os << std::string(kIndent, ' ') << "empty block\n"; return; } const char* markerEndl = ""; for (auto it = block->begin(); it != block->end();) { auto& inst = *it; ++it; if (inst.marker() != curMarker) { std::ostringstream mStr; auto const& newMarker = inst.marker(); if (!newMarker.hasFunc()) { os << color(ANSI_COLOR_BLUE) << std::string(kIndent, ' ') << "--- invalid marker" << color(ANSI_COLOR_END) << '\n'; } else { auto func = newMarker.func(); if (!curMarker.hasFunc() || func != curMarker.func()) { func->prettyPrint(mStr, Func::PrintOpts().noFpi()); } mStr << std::string(kIndent, ' ') << newMarker.show() << '\n'; auto bcOffset = newMarker.bcOff(); func->unit()->prettyPrint( mStr, Unit::PrintOpts() .range(bcOffset, bcOffset+1) .noLineNumbers() .noFuncs() .indent(0)); std::vector<std::string> vec; folly::split('\n', mStr.str(), vec); os << markerEndl; markerEndl = "\n"; for (auto& s : vec) { if (s.empty()) continue; os << color(ANSI_COLOR_BLUE) << s << color(ANSI_COLOR_END) << '\n'; } } curMarker = newMarker; } if (inst.op() == DefLabel) { // print phi pseudo-instructions for (unsigned i = 0, n = inst.numDsts(); i < n; ++i) { os << std::string(kIndent + folly::format("({}) ", inst.id()).str().size(), ' '); auto dst = inst.dst(i); jit::print(os, dst); os << punc(" = ") << color(ANSI_COLOR_CYAN) << "phi " << color(ANSI_COLOR_END); bool first = true; inst.block()->forEachSrc(i, [&](IRInstruction* jmp, SSATmp*) { if (!first) os << punc(", "); first = false; printSrc(os, jmp, i); os << punc("@"); printLabel(os, jmp->block()); }); os << '\n'; } } os << std::string(kIndent, ' '); jit::print(os, &inst, guards); os << '\n'; if (asmInfo) { // There can be asm ranges in areas other than the one this blocks claims // to be in so we have to iterate all the areas to be sure to get // everything. for (auto i = 0; i < kNumAreas; ++i) { AreaIndex currentArea = static_cast<AreaIndex>(i); TcaRange instRange = asmInfo->instRangesForArea(currentArea)[inst]; if (!instRange.empty()) { os << std::string(kIndent + 4, ' ') << areaAsString(currentArea); os << ":\n"; disasmRange(os, instRange.begin(), instRange.end()); os << '\n'; if (currentArea == area) { // FIXME: this used to be an assertion auto things_are_ok = instRange.end() >= blockRange.start() && instRange.end() <= blockRange.end(); if (things_are_ok) { blockRange = TcaRange(instRange.end(), blockRange.end()); } else { // Don't crash; do something broken instead. os << "<note: print range is probably incorrect right now>\n"; } } } } } } if (asmInfo) { // Print code associated with the block that isn't tied to any instruction. if (!blockRange.empty()) { os << std::string(kIndent, ' ') << punc("A:") << "\n"; disasmRange(os, blockRange.start(), blockRange.end()); os << '\n'; } } os << std::string(kIndent - 2, ' '); auto next = block->empty() ? nullptr : block->next(); if (next) { os << punc("-> "); printLabel(os, next); os << '\n'; } else { os << "no fallthrough\n"; } }