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:
@@ -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) \
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário