Do away with DumpIR.

DumpIR inconsistently interacted with the trace facility.
Move it to the hhir trace module. Compress a bunch of copy-pasta.
Esse commit está contido em:
kma
2013-04-01 17:26:50 -07:00
commit de Sara Golemon
commit 68ac3730f4
8 arquivos alterados com 90 adições e 112 exclusões
-1
Ver Arquivo
@@ -433,7 +433,6 @@ public:
F(uint64_t, MaxHHIRTrans, -1) \
F(bool, HHIRDeadCodeElim, true) \
F(bool, DumpBytecode, false) \
F(uint32_t, DumpIR, 0) \
F(bool, DumpTC, false) \
F(bool, DumpAst, false) \
F(bool, MapTCHuge, true) \
+2 -2
Ver Arquivo
@@ -75,7 +75,7 @@ int64_t spillSlotsToSize(int n) {
}
void cgPunt(const char* file, int line, const char* func) {
if (RuntimeOption::EvalDumpIR) {
if (dumpIREnabled()) {
HPHP::Trace::trace("--------- CG_PUNT %s %d %s\n", file, line, func);
}
throw FailedCodeGen(file, line, func);
@@ -3656,7 +3656,7 @@ void CodeGenerator::emitGuardOrFwdJcc(IRInstruction* inst, ConditionCode cc) {
if (cc == CC_None) return;
Block* label = inst->getTaken();
if (inst && inst->getTCA() == kIRDirectGuardActive) {
if (RuntimeOption::EvalDumpIR) {
if (dumpIREnabled()) {
m_tx64->prepareForSmash(m_as, TranslatorX64::kJmpccLen);
inst->setTCA(m_as.code.frontier);
}
+29 -1
Ver Arquivo
@@ -1072,7 +1072,7 @@ void Trace::print() const {
void Trace::print(std::ostream& os, const AsmInfo* asmInfo) const {
static const int kIndent = 4;
Disasm disasm(Disasm::Options().indent(kIndent + 4)
.printEncoding(RuntimeOption::EvalDumpIR > 5));
.printEncoding(dumpIREnabled(6)));
// Print unlikely blocks at the end
BlockList blocks, unlikely;
@@ -1371,5 +1371,33 @@ bool hasInternalFlow(Trace* trace) {
return false;
}
void dumpTraceImpl(const Trace* trace, std::ostream& out,
const AsmInfo* asmInfo) {
auto func = trace->getFunc();
auto unitName = func->unit()->filepath()->empty()
? "<systemlib>"
: func->unit()->filepath()->data();
out << folly::format("{}() @{} ({})\n",
func->fullName()->data(),
trace->getBcOff(),
unitName);
trace->print(out, asmInfo);
}
// Suggested captions: "before jiffy removal", "after goat saturation",
// etc.
void dumpTrace(int level, const Trace* trace, const char* caption,
AsmInfo* ai) {
if (dumpIREnabled(level)) {
std::ostringstream str;
auto bannerFmt = "{:-^40}\n";
str << folly::format(bannerFmt, caption);
dumpTraceImpl(trace, str, ai);
trace->print(str);
str << folly::format(bannerFmt, "");
HPHP::Trace::traceRelease("%s", str.str().c_str());
}
}
}}}
+25 -1
Ver Arquivo
@@ -30,6 +30,7 @@
#include <boost/checked_delete.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include "util/asm-x64.h"
#include "util/trace.h"
#include "runtime/ext/ext_continuation.h"
#include "runtime/vm/translator/physreg.h"
#include "runtime/vm/translator/abi-x64.h"
@@ -2207,6 +2208,8 @@ public:
std::list<Block*>& getBlocks() { return m_blocks; }
Block* front() { return *m_blocks.begin(); }
Block* back() { auto it = m_blocks.end(); return *(--it); }
const Block* front() const { return *m_blocks.begin(); }
const Block* back() const { auto it = m_blocks.end(); return *(--it); }
Block* push_back(Block* b) {
b->setTrace(this);
@@ -2214,7 +2217,15 @@ public:
return b;
}
uint32_t getBcOff() { return m_bcOff; }
const Func* getFunc() const {
return front()->getFunc();
}
const Unit* getUnit() const {
return getFunc()->unit();
}
uint32_t getBcOff() const { return m_bcOff; }
Trace* addExitTrace(Trace* exit) {
m_exitTraces.push_back(exit);
exit->setMain(this);
@@ -2382,6 +2393,19 @@ void forEachTraceInst(Trace* main, Body body) {
});
}
/*
* Some utilities related to dumping. Rather than file-by-file control, we control
* most IR logging via the hhir trace module.
*/
static inline bool dumpIREnabled(int level = 1) {
return HPHP::Trace::moduleEnabledRelease(HPHP::Trace::hhir, level);
}
void dumpTraceImpl(const Trace* trace, std::ostream& out,
const AsmInfo* asmInfo = nullptr);
void dumpTrace(int level, const Trace* trace, const char* caption,
AsmInfo* ai = nullptr);
}}}
namespace std {
+9 -45
Ver Arquivo
@@ -1588,63 +1588,27 @@ void TranslatorX64::hhirTraceCodeGen(vector<TransBCMapping>* bcMap) {
assert(m_useHHIR);
JIT::Trace* trace = m_hhbcTrans->getTrace();
auto traceTraceImpl = [&](std::ostream& out,
const JIT::AsmInfo* asmInfo = nullptr) {
auto unitName = curUnit()->filepath()->empty()
? "<systemlib>"
: curUnit()->filepath()->data();
out << folly::format("{}() @{} ({})\n",
curFunc()->fullName()->data(),
trace->getBcOff(),
unitName);
trace->print(out, asmInfo);
auto finishPass = [&](const char* msg) {
dumpTrace(1, trace, msg);
assert(JIT::checkCfg(trace, *m_irFactory));
};
auto traceTrace = [&] (const char* banner,
const JIT::AsmInfo* asmInfo = nullptr) {
std::ostringstream str;
str << folly::format("{:-^40}\n", banner);
traceTraceImpl(str, asmInfo);
str << folly::format("{:-^40}\n", "");
if (Trace::moduleEnabled(TRACEMOD, 1)) {
// If tracing is enabled, print using the trace facility so IR dumps
// interleave properly with traced output.
FTRACE(1, "{}", str.str());
} else {
std::cout << str.str();
}
};
if (RuntimeOption::EvalDumpIR) {
traceTrace(" HHIR after initial translation ");
}
assert(JIT::checkCfg(trace, *m_irFactory));
finishPass(" after initial translation ");
JIT::optimizeTrace(trace, m_hhbcTrans->getTraceBuilder());
if (RuntimeOption::EvalDumpIR > 1) {
traceTrace(" HHIR after optimizing ");
}
assert(JIT::checkCfg(trace, *m_irFactory));
finishPass(" after optimizing ");
JIT::allocRegsForTrace(trace, m_irFactory.get());
if (RuntimeOption::EvalDumpIR) {
traceTrace(" HHIR after reg alloc ");
}
assert(JIT::checkCfg(trace, *m_irFactory));
finishPass(" after reg alloc ");
auto* factory = m_irFactory.get();
if (RuntimeOption::EvalDumpIR || RuntimeOption::EvalJitCompareHHIR) {
if (JIT::dumpIREnabled() || RuntimeOption::EvalJitCompareHHIR) {
JIT::AsmInfo ai(factory);
JIT::genCodeForTrace(trace, a, astubs, factory, bcMap, this, &ai);
if (RuntimeOption::EvalJitCompareHHIR) {
std::ostringstream out;
traceTraceImpl(out, &ai);
dumpTraceImpl(trace, out, &ai);
m_lastHHIRDump = out.str();
} else {
traceTrace(" HHIR after code gen ", &ai);
dumpTrace(1, trace, " after code gen ", &ai);
}
} else {
JIT::genCodeForTrace(trace, a, astubs, factory, bcMap, this);
+14 -25
Ver Arquivo
@@ -236,13 +236,18 @@ void LinearScan::computeLiveRegs() {
}
}
template<typename Inner, int DumpVal=4>
static inline void dumpIR(const Inner* in, const char* msg) {
if (dumpIREnabled(DumpVal)) {
std::ostringstream str;
in->print(str);
HPHP::Trace::traceRelease("--- %s: %s\n", msg, str.str().c_str());
}
}
void LinearScan::allocRegToInstruction(InstructionList::iterator it) {
IRInstruction* inst = &*it;
if (RuntimeOption::EvalDumpIR > 3) {
std::cout << "--- allocating to instruction: ";
inst->print(std::cout);
std::cout << std::endl;
}
dumpIR<IRInstruction, 4>(inst, "allocating to instruction");
// Reload all source operands if necessary.
// Mark registers as unpinned.
@@ -293,11 +298,7 @@ void LinearScan::allocRegToInstruction(InstructionList::iterator it) {
}
// Remember this reload tmp in case we can reuse it in later blocks.
m_slots[slotId].m_latestReload = reloadTmp;
if (RuntimeOption::EvalDumpIR > 4) {
std::cout << "--- created reload: ";
reload->print(std::cout);
std::cout << std::endl;
}
dumpIR<IRInstruction, 5>(reload, "created reload");
}
}
@@ -792,11 +793,7 @@ void LinearScan::allocRegs(Trace* trace) {
if (RuntimeOption::EvalHHIREnableRematerialization && m_slots.size() > 0) {
// Don't bother rematerializing the trace if it has no Spill/Reload.
if (RuntimeOption::EvalDumpIR > 5) {
std::cout << "--------- HHIR before rematerialization ---------\n";
trace->print(std::cout);
std::cout << "-------------------------------------------------\n";
}
dumpTrace(6, trace, "before rematerialization");
rematerialize();
}
@@ -843,11 +840,7 @@ void LinearScan::allocRegsToTrace() {
}
for (auto it = block->begin(), end = block->end(); it != end; ++it) {
allocRegToInstruction(it);
if (RuntimeOption::EvalDumpIR > 3) {
std::cout << "--- allocated to instruction: ";
it->print(std::cout);
std::cout << "\n";
}
dumpIR<IRInstruction, 4>(&*it, "allocated to instruction");
}
}
@@ -1143,11 +1136,7 @@ LinearScan::RegState* LinearScan::popFreeReg(std::list<RegState*>& freeList) {
}
void LinearScan::spill(SSATmp* tmp) {
if (RuntimeOption::EvalDumpIR > 4) {
std::cout << "--- spilling ";
tmp->print(std::cout);
std::cout << "\n";
}
dumpIR<SSATmp, 5>(tmp, "spilling");
// If we're spilling, we better actually have registers allocated.
assert(tmp->numAllocatedRegs() > 0);
assert(tmp->numAllocatedRegs() == tmp->numNeededRegs());
+10 -36
Ver Arquivo
@@ -99,64 +99,38 @@ static void insertAsserts(Trace* trace, IRFactory* factory) {
void optimizeTrace(Trace* trace, TraceBuilder* traceBuilder) {
IRFactory* irFactory = traceBuilder->getIrFactory();
auto finishPass = [&](const char* msg) {
dumpTrace(6, trace, msg);
assert(JIT::checkCfg(trace, *irFactory));
};
if (RuntimeOption::EvalHHIRMemOpt) {
optimizeMemoryAccesses(trace, irFactory);
if (RuntimeOption::EvalDumpIR > 5) {
std::cout << "----- HHIR after MemElim -----\n";
trace->print(std::cout);
std::cout << "---------------------------\n";
}
assert(JIT::checkCfg(trace, *irFactory));
finishPass("after MemeLim");
}
if (RuntimeOption::EvalHHIRDeadCodeElim) {
eliminateDeadCode(trace, irFactory);
if (RuntimeOption::EvalDumpIR > 5) {
std::cout << "----- HHIR after DCE -----\n";
trace->print(std::cout);
std::cout << "---------------------------\n";
}
assert(JIT::checkCfg(trace, *irFactory));
finishPass("after DCE");
}
if (RuntimeOption::EvalHHIRExtraOptPass
&& (RuntimeOption::EvalHHIRCse
|| RuntimeOption::EvalHHIRSimplification)) {
traceBuilder->optimizeTrace();
if (RuntimeOption::EvalDumpIR > 5) {
std::cout << "----- HHIR after CSE/Simplification -----\n";
trace->print(std::cout);
std::cout << "---------------------------\n";
}
assert(JIT::checkCfg(trace, *irFactory));
finishPass("after CSE/Simplification");
// Cleanup any dead code left around by CSE/Simplification
// Ideally, this would be controlled by a flag returned
// by optimzeTrace indicating whether DCE is necessary
if (RuntimeOption::EvalHHIRDeadCodeElim) {
eliminateDeadCode(trace, irFactory);
if (RuntimeOption::EvalDumpIR > 5) {
std::cout << "----- HHIR after DCE -----\n";
trace->print(std::cout);
std::cout << "---------------------------\n";
}
assert(JIT::checkCfg(trace, *irFactory));
finishPass("after DCE");
}
}
if (RuntimeOption::EvalHHIRJumpOpts) {
optimizeJumps(trace, irFactory);
if (RuntimeOption::EvalDumpIR > 5) {
std::cout << "----- HHIR after jump opts -----\n";
trace->print(std::cout);
std::cout << "---------------------------\n";
}
assert(JIT::checkCfg(trace, *irFactory));
finishPass("jump opts");
}
if (RuntimeOption::EvalHHIRGenerateAsserts) {
insertAsserts(trace, irFactory);
if (RuntimeOption::EvalDumpIR > 5) {
std::cout << "----- HHIR after inserting RefCnt asserts -----\n";
trace->print(std::cout);
std::cout << "---------------------------\n";
}
assert(JIT::checkCfg(trace, *irFactory));
finishPass("RefCnt asserts");
}
}
+1 -1
Ver Arquivo
@@ -51,7 +51,7 @@ const char *tokNames[] = {
class Init {
Module name2mod(const char *name) {
for (int i = 0; i < NumModules; i++) {
if (!strcmp(tokNames[i], name)) {
if (!strcasecmp(tokNames[i], name)) {
return (Module)i;
}
}