interpOne instructions that fail at code-gen
This avoids running to whole tracelet with a backup, slower engine (interpreter or Tx64). This will also help with the ARM port: we can initially CG_PUNT on all IR instructions, and add support for them incrementally (without sending the whole tracelet to the interpreter).
Esse commit está contido em:
@@ -85,14 +85,15 @@ int64_t spillSlotsToSize(int n) {
|
||||
return n * sizeof(int64_t);
|
||||
}
|
||||
|
||||
void cgPunt(const char* file, int line, const char* func) {
|
||||
void cgPunt(const char* file, int line, const char* func, uint32_t bcOff) {
|
||||
if (dumpIREnabled()) {
|
||||
HPHP::Trace::trace("--------- CG_PUNT %s %d %s\n", file, line, func);
|
||||
HPHP::Trace::trace("--------- CG_PUNT %s %d %s bcOff: %d \n",
|
||||
file, line, func, bcOff);
|
||||
}
|
||||
throw FailedCodeGen(file, line, func);
|
||||
throw FailedCodeGen(file, line, func, bcOff);
|
||||
}
|
||||
|
||||
#define CG_PUNT(instr) cgPunt(__FILE__, __LINE__, #instr)
|
||||
#define CG_PUNT(instr) cgPunt(__FILE__, __LINE__, #instr, m_curBcOff)
|
||||
|
||||
struct CycleInfo {
|
||||
int node;
|
||||
@@ -304,7 +305,6 @@ PUNT_OPCODE(DefCls)
|
||||
NOOP_OPCODE(DefConst)
|
||||
NOOP_OPCODE(DefFP)
|
||||
NOOP_OPCODE(DefSP)
|
||||
NOOP_OPCODE(Marker)
|
||||
NOOP_OPCODE(AssertLoc)
|
||||
NOOP_OPCODE(OverrideLoc)
|
||||
NOOP_OPCODE(AssertStk)
|
||||
@@ -909,6 +909,14 @@ void CodeGenerator::cgCallHelper(Asm& a,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This doesn't really produce any code; it just keeps track of the current
|
||||
* bytecode offset.
|
||||
*/
|
||||
void CodeGenerator::cgMarker(IRInstruction* inst) {
|
||||
m_curBcOff = inst->getExtra<MarkerData>()->bcOff;
|
||||
}
|
||||
|
||||
void CodeGenerator::cgMov(IRInstruction* inst) {
|
||||
assert(!m_regs[inst->getSrc(0)].hasReg(1));//TODO: t2082361: handle Gen & Cell
|
||||
SSATmp* dst = inst->getDst();
|
||||
|
||||
@@ -31,11 +31,13 @@ namespace JIT {
|
||||
|
||||
class FailedCodeGen : public std::exception {
|
||||
public:
|
||||
const char* file;
|
||||
const int line;
|
||||
const char* func;
|
||||
FailedCodeGen(const char* _file, int _line, const char* _func) :
|
||||
file(_file), line(_line), func(_func) { }
|
||||
const char* file;
|
||||
const int line;
|
||||
const char* func;
|
||||
const uint32_t bcOff;
|
||||
FailedCodeGen(const char* _file, int _line, const char* _func,
|
||||
uint32_t _bcOff) :
|
||||
file(_file), line(_line), func(_func), bcOff(_bcOff) { }
|
||||
};
|
||||
|
||||
struct ArgGroup;
|
||||
@@ -117,7 +119,8 @@ struct CodeGenerator {
|
||||
CodeGenerator(Trace* trace, Asm& as, Asm& astubs, Transl::TranslatorX64* tx64,
|
||||
CodegenState& state)
|
||||
: m_as(as), m_astubs(astubs), m_tx64(tx64), m_state(state),
|
||||
m_regs(state.regs), m_curInst(nullptr), m_curTrace(trace) {
|
||||
m_regs(state.regs), m_curInst(nullptr), m_curTrace(trace),
|
||||
m_curBcOff(-1){
|
||||
}
|
||||
|
||||
void cgBlock(Block* block, vector<TransBCMapping>* bcMap);
|
||||
@@ -354,13 +357,15 @@ private:
|
||||
void print() const;
|
||||
|
||||
private:
|
||||
Asm& m_as; // current "main" assembler
|
||||
Asm& m_astubs; // assembler for stubs and other cold code.
|
||||
TranslatorX64* m_tx64;
|
||||
CodegenState& m_state;
|
||||
Asm& m_as; // current "main" assembler
|
||||
Asm& m_astubs; // assembler for stubs and other cold code.
|
||||
TranslatorX64* m_tx64;
|
||||
CodegenState& m_state;
|
||||
const RegAllocInfo& m_regs;
|
||||
IRInstruction* m_curInst; // current instruction being generated
|
||||
Trace* m_curTrace;
|
||||
IRInstruction* m_curInst; // current instruction being generated
|
||||
Trace* m_curTrace;
|
||||
uint32_t m_curBcOff; // offset of bytecode instr that produced
|
||||
// m_curInst
|
||||
};
|
||||
|
||||
class ArgDesc {
|
||||
|
||||
@@ -1827,11 +1827,30 @@ TranslatorX64::irTranslateTracelet(Tracelet& t,
|
||||
|
||||
hhirTraceEnd(t.m_nextSk.offset());
|
||||
if (transResult != Retry) {
|
||||
transResult = Success;
|
||||
hhirTraceCodeGen(bcMap);
|
||||
|
||||
TRACE(1, "HHIR: SUCCEEDED to generate code for Translation %d\n\n\n",
|
||||
getCurrentTransID());
|
||||
try {
|
||||
transResult = Success;
|
||||
hhirTraceCodeGen(bcMap);
|
||||
} catch (JIT::FailedCodeGen& fcg) {
|
||||
// Code-gen failed. Search for the bytecode instruction that caused the
|
||||
// problem, flag it to be interpreted, and retranslate the tracelet.
|
||||
NormalizedInstruction *ni;
|
||||
for (ni = t.m_instrStream.first; ni; ni = ni->next) {
|
||||
if (ni->source.offset() == fcg.bcOff) break;
|
||||
}
|
||||
if (ni && !ni->interp) {
|
||||
ni->interp = true;
|
||||
transResult = Retry;
|
||||
TRACE(1, "HHIR: RETRY Translation %d: will interpOne BC instr %s "
|
||||
"after failing to code-gen \n\n",
|
||||
getCurrentTransID(), ni->toString().c_str());
|
||||
} else {
|
||||
throw fcg;
|
||||
}
|
||||
}
|
||||
if (transResult == Success) {
|
||||
TRACE(1, "HHIR: SUCCEEDED to generate code for Translation %d\n\n\n",
|
||||
getCurrentTransID());
|
||||
}
|
||||
}
|
||||
} catch (JIT::FailedCodeGen& fcg) {
|
||||
transResult = Failure;
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário