Kill runtime options related to turning off the IR
Esse commit está contido em:
@@ -413,9 +413,7 @@ public:
|
||||
F(bool, ThreadingJit, false) \
|
||||
F(bool, JitTransCounters, false) \
|
||||
F(bool, JitMGeneric, true) \
|
||||
F(bool, JitUseIR, true) \
|
||||
F(double, JitCompareHHIR, 0) \
|
||||
F(bool, IRPuntDontInterp, false) \
|
||||
F(bool, HHIRGenericDtorHelper, true) \
|
||||
F(bool, HHIRCse, true) \
|
||||
F(bool, HHIRSimplification, true) \
|
||||
@@ -435,8 +433,7 @@ public:
|
||||
F(bool, HHIRAllocXMMRegs, true) \
|
||||
F(bool, HHIRGenerateAsserts, debug) \
|
||||
F(bool, HHIRDirectExit, true) \
|
||||
F(bool, HHIRDisableTx64, true) \
|
||||
F(uint64_t, MaxHHIRTrans, -1) \
|
||||
F(uint64_t, MaxTrans, -1) \
|
||||
F(bool, HHIRDeadCodeElim, true) \
|
||||
/* DumpBytecode =1 dumps user php, =2 dumps systemlib & user php */ \
|
||||
F(int32_t, DumpBytecode, 0) \
|
||||
|
||||
@@ -245,11 +245,8 @@ const int kNumServiceReqArgRegs =
|
||||
REQ(STACK_OVERFLOW) \
|
||||
\
|
||||
/*
|
||||
* When HHIR is in use, this requests a retranslation that does not use HHIR.
|
||||
* This is only used when HHIR is turned on.
|
||||
*
|
||||
* Note that, when EvalJitUseIR is enabled, RETRANSLATE requests will attempt
|
||||
* to use HHIR.
|
||||
* This requests a retranslation that does not use HHIR, meaning it
|
||||
* will be an INTERPRET service request.
|
||||
*/ \
|
||||
REQ(RETRANSLATE_NO_IR) \
|
||||
\
|
||||
|
||||
@@ -2993,14 +2993,7 @@ void HhbcTranslator::emitInterpOneCF(int numPopped) {
|
||||
|
||||
void HhbcTranslator::emitInterpOneOrPunt(Type type, int numPopped,
|
||||
int numExtraPushed) {
|
||||
if (RuntimeOption::EvalIRPuntDontInterp) {
|
||||
Op op = *(Op*)(getCurUnit()->entry() + bcOff());
|
||||
const char* name = StringData::GetStaticString(
|
||||
std::string("PuntDontInterp-") + opcodeToName(op))->data();
|
||||
SPUNT(name);
|
||||
} else {
|
||||
emitInterpOne(type, numPopped, numExtraPushed);
|
||||
}
|
||||
emitInterpOne(type, numPopped, numExtraPushed);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -76,11 +76,6 @@ class FailedIRGen : public std::exception {
|
||||
throw FailedIRGen(__FILE__, __LINE__, instr); \
|
||||
} while(0)
|
||||
#define PUNT(instr) SPUNT(#instr)
|
||||
#define PUNT_WITH_TX64(instr) do { \
|
||||
if (!RuntimeOption::EvalHHIRDisableTx64) { \
|
||||
PUNT(inst); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -1798,14 +1798,13 @@ TranslatorX64::irTranslateTracelet(Tracelet& t,
|
||||
} catch (JIT::FailedIRGen& fcg) {
|
||||
// If we haven't tried interpreting ni yet, flag it to be interpreted
|
||||
// and retry
|
||||
if (RuntimeOption::EvalHHIRDisableTx64 && !ni->interp &&
|
||||
supportedInterpOne(ni)) {
|
||||
if (!ni->interp && supportedInterpOne(ni)) {
|
||||
ni->interp = true;
|
||||
transResult = Retry;
|
||||
break;
|
||||
}
|
||||
if (!RuntimeOption::EvalHHIRDisableTx64 || !ni->prev) {
|
||||
// Let tx64 handle the entire tracelet.
|
||||
if (!ni->prev) {
|
||||
// Let the interpreter handle the entire tracelet.
|
||||
throw;
|
||||
}
|
||||
// We've made forward progress. Proceed with the partial tracelet,
|
||||
|
||||
@@ -1444,15 +1444,16 @@ TranslatorX64::lookupTranslation(SrcKey sk) const {
|
||||
|
||||
TCA
|
||||
TranslatorX64::translate(SrcKey sk, bool align, bool allowIR) {
|
||||
bool useHHIR = allowIR && RuntimeOption::EvalJitUseIR;
|
||||
bool useHHIR = allowIR;
|
||||
INC_TPC(translate);
|
||||
assert(((uintptr_t)vmsp() & (sizeof(Cell) - 1)) == 0);
|
||||
assert(((uintptr_t)vmfp() & (sizeof(Cell) - 1)) == 0);
|
||||
|
||||
if (useHHIR) {
|
||||
if (m_numHHIRTrans == RuntimeOption::EvalMaxHHIRTrans) {
|
||||
if (m_numHHIRTrans == RuntimeOption::EvalMaxTrans) {
|
||||
useHHIR = m_useHHIR = false;
|
||||
RuntimeOption::EvalJitUseIR = false;
|
||||
RuntimeOption::EvalJit = false;
|
||||
ThreadInfo::s_threadInfo->m_reqInjectionData.updateJit();
|
||||
} else {
|
||||
m_useHHIR = true;
|
||||
}
|
||||
@@ -1468,7 +1469,7 @@ TranslatorX64::translate(SrcKey sk, bool align, bool allowIR) {
|
||||
|
||||
TCA start = a.code.frontier;
|
||||
m_lastHHIRPunt.clear();
|
||||
translateTracelet(sk, m_useHHIR || RuntimeOption::EvalHHIRDisableTx64);
|
||||
translateTracelet(sk, true);
|
||||
|
||||
SKTRACE(1, sk, "translate moved head from %p to %p\n",
|
||||
getTopTranslation(sk), start);
|
||||
@@ -10878,10 +10879,6 @@ TranslatorX64::emitPredictionGuards(const NormalizedInstruction& i) {
|
||||
Stats::emitInc(a, Stats::TC_TypePredHit);
|
||||
}
|
||||
|
||||
static void failedTypePred() {
|
||||
raise_error("A type prediction was incorrect");
|
||||
}
|
||||
|
||||
void
|
||||
TranslatorX64::translateInstrWork(const Tracelet& t,
|
||||
const NormalizedInstruction& i) {
|
||||
@@ -10904,146 +10901,7 @@ TranslatorX64::translateInstrWork(const Tracelet& t,
|
||||
void
|
||||
TranslatorX64::translateInstr(const Tracelet& t,
|
||||
const NormalizedInstruction& i) {
|
||||
/**
|
||||
* translateInstr() translates an individual instruction in a tracelet,
|
||||
* either by directly emitting machine code for that instruction or by
|
||||
* emitting a call to the interpreter.
|
||||
*
|
||||
* If the instruction ends the current tracelet, we must emit machine code
|
||||
* to transfer control to some target that will continue to make forward
|
||||
* progress. This target may be the beginning of another tracelet, or it may
|
||||
* be a translator service request. Before transferring control, a tracelet
|
||||
* must ensure the following invariants hold:
|
||||
* 1) The machine registers rVmFp and rVmSp are in sync with vmfp()
|
||||
* and vmsp().
|
||||
* 2) All "dirty" values are synced in memory. This includes the
|
||||
* evaluation stack, locals, globals, statics, and any other program
|
||||
* accessible locations. This also means that all refcounts must be
|
||||
* up to date.
|
||||
*/
|
||||
assert(!m_useHHIR);
|
||||
assert(!(RuntimeOption::EvalJitUseIR && RuntimeOption::EvalHHIRDisableTx64));
|
||||
assert(!i.outStack || i.outStack->isStack());
|
||||
assert(!i.outLocal || i.outLocal->isLocal());
|
||||
const char *opNames[] = {
|
||||
#define O(name, imm, push, pop, flags) \
|
||||
#name,
|
||||
OPCODES
|
||||
#undef O
|
||||
};
|
||||
SpaceRecorder sr(opNames[i.op()], a);
|
||||
SKTRACE(1, i.source, "translate %#lx\n", long(a.code.frontier));
|
||||
const Opcode op = i.op();
|
||||
|
||||
TCA start = a.code.frontier;
|
||||
TCA astart = astubs.code.frontier;
|
||||
|
||||
m_regMap.bumpEpoch();
|
||||
// Allocate the input regs upfront unless instructed otherwise
|
||||
// or the instruction is interpreted
|
||||
if (!i.manuallyAllocInputs && i.m_txFlags) {
|
||||
m_regMap.allocInputRegs(i);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
for (unsigned j = 0; j < i.inputs.size(); j++) {
|
||||
if (i.inputWasInferred(j)) {
|
||||
DynLocation* dl = i.inputs[j];
|
||||
assert(dl->rtt.isValue() &&
|
||||
!dl->rtt.isVagueValue() &&
|
||||
dl->outerType() != KindOfInvalid);
|
||||
PhysReg base;
|
||||
int disp;
|
||||
locToRegDisp(dl->location, &base, &disp);
|
||||
DataType type = dl->rtt.typeCheckValue();
|
||||
emitTypeCheck(a, type, base, disp);
|
||||
ConditionCode cc = IS_STRING_TYPE(type) ? CC_Z : CC_NZ;
|
||||
{
|
||||
UnlikelyIfBlock typePredFailed(cc, a, astubs);
|
||||
EMIT_CALL(astubs, failedTypePred);
|
||||
recordReentrantStubCall(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!i.grouped) {
|
||||
emitVariantGuards(t, i);
|
||||
const NormalizedInstruction* n = &i;
|
||||
while (n->next && n->next->grouped) {
|
||||
n = n->next;
|
||||
emitVariantGuards(t, *n);
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate the input regs upfront unless instructed otherwise
|
||||
// or the instruction is interpreted
|
||||
if (!i.manuallyAllocInputs && i.m_txFlags) {
|
||||
m_regMap.allocInputRegs(i);
|
||||
}
|
||||
|
||||
if (i.m_txFlags == Interp || RuntimeOption::EvalThreadingJit) {
|
||||
// If the problem is local to this instruction, just call out to
|
||||
// the interpreter. emitInterpOne will perform end-of-tracelet duties
|
||||
// if this instruction ends the tracelet.
|
||||
SKTRACE(1, i.source, "Interp\n");
|
||||
emitInterpOne(t, i);
|
||||
} else {
|
||||
// Actually translate the instruction's body.
|
||||
Stats::emitIncTranslOp(a, op, RuntimeOption::EnableInstructionCounts);
|
||||
translateInstrWork(t, i);
|
||||
}
|
||||
|
||||
// Invalidate locations that are no longer live
|
||||
for (unsigned k = 0; k < i.deadLocs.size(); ++k) {
|
||||
const Location& l = i.deadLocs[k];
|
||||
m_regMap.invalidate(l);
|
||||
}
|
||||
|
||||
// Kill any live regs that won't be of further use in this trace.
|
||||
RegSet live = m_regMap.getRegsLike(RegInfo::DIRTY) |
|
||||
m_regMap.getRegsLike(RegInfo::CLEAN);
|
||||
PhysReg pr;
|
||||
while (live.findFirst(pr)) {
|
||||
live.remove(pr);
|
||||
const RegInfo* ri = m_regMap.getInfo(pr);
|
||||
assert(ri->m_state == RegInfo::CLEAN || ri->m_state == RegInfo::DIRTY);
|
||||
bool dirty = ri->m_state == RegInfo::DIRTY;
|
||||
if (ri->m_cont.m_kind != RegContent::Loc) continue;
|
||||
const Location loc = ri->m_cont.m_loc;
|
||||
// These heuristics do poorly on stack slots, which are more like
|
||||
// ephemeral temps.
|
||||
if (loc.space != Location::Local) continue;
|
||||
if (false && dirty && !t.isWrittenAfterInstr(loc, i)) {
|
||||
// This seems plausible enough: the intuition is that carrying aroud
|
||||
// a register we'll read, but not write, in a dirty state, has a cost
|
||||
// because any control-flow diamonds will have to spill it and then
|
||||
// refill it. It appears to hurt performance today, though.
|
||||
m_regMap.cleanLoc(loc);
|
||||
}
|
||||
if (t.isLiveAfterInstr(loc, i)) continue;
|
||||
SKTRACE(1, i.source, "killing %s reg %d for (%s, %d)\n",
|
||||
dirty ? "dirty" : "clean", (int)pr, loc.spaceName(), loc.offset);
|
||||
if (dirty) {
|
||||
m_regMap.cleanLoc(loc);
|
||||
}
|
||||
assert(ri->m_state == RegInfo::CLEAN);
|
||||
m_regMap.smashLoc(loc);
|
||||
}
|
||||
|
||||
emitPredictionGuards(i);
|
||||
recordBCInstr(op, a, start);
|
||||
recordBCInstr(op + Op_count, astubs, astart);
|
||||
|
||||
if (i.breaksTracelet && !i.changesPC) {
|
||||
// If this instruction's opcode always ends the tracelet then the
|
||||
// instruction case is responsible for performing end-of-tracelet
|
||||
// duties. Otherwise, we handle ending the tracelet here.
|
||||
syncOutputs(t);
|
||||
emitBindJmp(t.m_nextSk);
|
||||
}
|
||||
|
||||
m_regMap.assertNoScratch();
|
||||
not_reached();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -11218,9 +11076,7 @@ TranslatorX64::translateTracelet(SrcKey sk, bool considerHHIR/*=true*/,
|
||||
// with more aggressive assumptions, or fall back to the
|
||||
// interpreter.
|
||||
if (considerHHIR) {
|
||||
if (RuntimeOption::EvalHHIRDisableTx64) {
|
||||
punt();
|
||||
}
|
||||
punt();
|
||||
// Recur. We need to re-analyze. Since m_useHHIR is clear, we
|
||||
// won't go down this path again.
|
||||
return translateTracelet(sk, false);
|
||||
|
||||
+1
-3
@@ -215,9 +215,7 @@ function mode_arg($options) {
|
||||
switch ($mode) {
|
||||
case '':
|
||||
case 'jit':
|
||||
return "$jit_args -vEval.JitUseIR=0 -vEval.HHIRDisableTx64=0";
|
||||
case 'hhir':
|
||||
return "$jit_args -vEval.JitUseIR=1 -vEval.HHIRDisableTx64=1";
|
||||
return "$jit_args";
|
||||
case 'interp':
|
||||
return "$repo_args -vEval.Jit=0";
|
||||
default:
|
||||
|
||||
@@ -156,17 +156,12 @@ static bool verify_result(const char *input, const char *output, bool perfMode,
|
||||
|
||||
string jitarg = string("-vEval.Jit=") +
|
||||
(RuntimeOption::EvalJit ? "true" : "false");
|
||||
string jit_use_ir = string("-vEval.JitUseIR=") +
|
||||
(RuntimeOption::EvalJitUseIR ? "true" : "false");
|
||||
string jit_rename = string("-vEval.JitEnableRenameFunction=") +
|
||||
(RuntimeOption::EvalJit ? "true" : "false");
|
||||
const char *argv[] = {"", filearg.c_str(),
|
||||
"--config=test/slow/config.hdf",
|
||||
repoarg.c_str(),
|
||||
jitarg.c_str(),
|
||||
jit_use_ir.c_str(),
|
||||
// Next arg only takes effect if JitUseIR=true also
|
||||
"-vEval.HHIRDisableTx64=true",
|
||||
jit_rename.c_str(),
|
||||
nullptr};
|
||||
Process::Exec(HHVM_PATH, argv, nullptr, actual, &err);
|
||||
|
||||
@@ -376,9 +376,6 @@ void TestDebugger::runServer() {
|
||||
boost::lexical_cast<string>(m_debugPort);
|
||||
string jitConfig = "-vEval.Jit=" +
|
||||
boost::lexical_cast<string>(RuntimeOption::EvalJit);
|
||||
string jitUseIRConfig = "-vEval.JitUseIR=" +
|
||||
boost::lexical_cast<string>(
|
||||
RuntimeOption::EvalJitUseIR);
|
||||
|
||||
// To emulate sandbox setup, let home to be "hphp/test", and user name to be
|
||||
// "debugger_tests", so that it can find the sandbox_conf there
|
||||
@@ -395,7 +392,6 @@ void TestDebugger::runServer() {
|
||||
adminPortConfig.c_str(),
|
||||
debugPortConfig.c_str(),
|
||||
jitConfig.c_str(),
|
||||
jitUseIRConfig.c_str(),
|
||||
nullptr};
|
||||
printf("Running server with arguments:\n");
|
||||
for (unsigned i = 1; i < array_size(argv) - 1; ++i) {
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário