Remove BPass* instructions

Esse commit está contido em:
aravind
2013-05-31 12:26:29 -07:00
commit de sgolemon
commit a686bd4ca1
11 arquivos alterados com 51 adições e 54 exclusões
+31 -7
Ver Arquivo
@@ -286,6 +286,7 @@ static int32_t countStackValues(const std::vector<uchar>& immVec) {
#define COUNT_R_LMANY() 0
#define COUNT_V_LMANY() 0
#define COUNT_FMANY 0
#define COUNT_CVMANY 0
#define COUNT_CMANY 0
#define ONE(t) \
@@ -338,6 +339,8 @@ static int32_t countStackValues(const std::vector<uchar>& immVec) {
getEmitterVisitor().popEvalStackLMany()
#define POP_FMANY \
getEmitterVisitor().popEvalStackMany(a1, StackSym::F)
#define POP_CVMANY \
getEmitterVisitor().popEvalStackCVMany(a1)
#define POP_CMANY \
getEmitterVisitor().popEvalStackMany(a1, StackSym::C)
@@ -562,6 +565,7 @@ static int32_t countStackValues(const std::vector<uchar>& immVec) {
#undef POP_FV
#undef POP_LREST
#undef POP_FMANY
#undef POP_CVMANY
#undef POP_CMANY
#undef POP_HA_ONE
#undef POP_HA_TWO
@@ -1314,6 +1318,32 @@ void EmitterVisitor::popEvalStackMany(int len, char symFlavor) {
}
}
void EmitterVisitor::popEvalStackCVMany(int len) {
for (int i = 0; i < len; i++) {
if (m_evalStack.size() == 0) {
InvariantViolation("Emitter emitted an instruction that tries to consume "
"a value from the stack when the stack is empty "
"(expected symbolic flavor C or V at offset %d)",
m_ue.bcPos());
return;
}
char sym = m_evalStack.top();
char actual = StackSym::GetSymFlavor(sym);
m_evalStack.pop();
if (actual != StackSym::C && actual != StackSym::V) {
InvariantViolation(
"Emitter emitted an instruction that tries to consume a "
"value from the stack when the top of the stack does not "
"match the symbolic flavor that the instruction expects "
"(expected symbolic flavor C or V, actual symbolic flavor \"%s\" "
"at offset %d)",
StackSym::ToString(actual).c_str(),
m_ue.bcPos());
}
}
}
void EmitterVisitor::pushEvalStack(char symFlavor) {
// Push a value from the evaluation stack with the specified
// symbolic flavor
@@ -4291,15 +4321,11 @@ void EmitterVisitor::emitBuiltinCallArg(Emitter& e,
int paramId,
bool byRef) {
visit(exp);
if (checkIfStackEmpty("BPass*")) return;
if (checkIfStackEmpty("Builtin arg*")) return;
if (byRef) {
emitVGet(e);
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
e.BPassV(paramId);
} else {
emitCGet(e);
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
e.BPassC(paramId);
}
return;
}
@@ -4344,8 +4370,6 @@ void EmitterVisitor::emitBuiltinDefaultArg(Emitter& e, Variant& v,
default:
not_reached();
}
m_metaInfo.add(m_ue.bcPos(), Unit::MetaInfo::NopOut, false, 0, 0);
e.BPassC(paramId);
}
void EmitterVisitor::emitFuncCallArg(Emitter& e,
+1
Ver Arquivo
@@ -343,6 +343,7 @@ public:
void popSymbolicLocal(Opcode opcode, int arg = -1, int pos = -1);
void popEvalStackLMany();
void popEvalStackMany(int len, char symFlavor);
void popEvalStackCVMany(int len);
void pushEvalStack(char symFlavor);
void peekEvalStack(char symFlavor, int depthActual);
void pokeEvalStack(char symFlavor, int depthActual);
+2 -14
Ver Arquivo
@@ -320,8 +320,8 @@ dispatcher to call the function.
Calls to builtin functions may be optimized to avoid pusing an entry on the FPI
stack if it is known that the builtin function does not need access to the call
stack. In this case, the arguments to the builtin are passed with the BPass*
instructions, and the builtin can be invoked with the FCallBuiltin instruction.
stack. In this case, the arguments to the builtin are pushed on stack as Cells
and Vars, and the builtin can be invoked with the FCallBuiltin instruction.
Unless otherwise noted, subsequent references to FCall* instructions should be
meant to refer to non-optimized FCall instructions, i.e. all FCall instructions
other than FCallBuiltin.
@@ -1806,18 +1806,6 @@ FCallArray [F] -> [R]
call the callee. When the callee returns, it will transfer the return value
onto the caller's evaluation stack using the R flavor.
BPassC <param id> [C] -> [F]
Pass parameter to builtin call. This opcode is expected to be emitted
only when parameter %1 is pass by value. The instruction pushes $1
onto the stack as a cell.
BPassV <param id> [V] -> [F]
Pass parameter to builtin call. This opcode is expected to be emitted
only when parameter %1 is pass by reference. The instruction pushes $1
onto the stack as a var.
FCallBuiltin <total params> <passed params> <litstr id> [F..F] -> [R]
Optimized builtin call without an ActRec. This instruction attempts to
+2
Ver Arquivo
@@ -1023,6 +1023,7 @@ OpcodeParserMap opcode_parsers;
#define NUM_POP_R_LMANY() (1 + vecImmStackValues)
#define NUM_POP_C_LMANY() (1 + vecImmStackValues)
#define NUM_POP_FMANY immIVA /* number of arguments */
#define NUM_POP_CVMANY immIVA /* number of arguments */
#define NUM_POP_CMANY immIVA /* number of arguments */
#define O(name, imm, pop, push, flags) \
@@ -1098,6 +1099,7 @@ OPCODES
#undef NUM_POP_R_LMANY
#undef NUM_POP_C_LMANY
#undef NUM_POP_FMANY
#undef NUM_POP_CVMANY
#undef NUM_POP_CMANY
void initialize_opcode_map() {
-10
Ver Arquivo
@@ -6030,16 +6030,6 @@ static inline ActRec* arFromInstr(TypedValue* sp, const Opcode* pc) {
return arFromSpOffset((ActRec*)sp, instrSpToArDelta(pc));
}
inline void OPTBLD_INLINE VMExecutionContext::iopBPassC(PC& pc) {
NEXT();
DECODE_IVA(paramId);
}
inline void OPTBLD_INLINE VMExecutionContext::iopBPassV(PC& pc) {
NEXT();
DECODE_IVA(paramId);
}
inline void OPTBLD_INLINE VMExecutionContext::iopFPassC(PC& pc) {
#ifdef DEBUG
ActRec* ar = arFromInstr(m_stack.top(), (Opcode*)pc);
+2
Ver Arquivo
@@ -366,6 +366,7 @@ int instrNumPops(const Opcode* opcode) {
#define V_LMANY(...) -2
#define R_LMANY(...) -2
#define FMANY -3
#define CVMANY -3
#define CMANY -3
#define O(name, imm, pop, push, flags) pop,
OPCODES
@@ -379,6 +380,7 @@ int instrNumPops(const Opcode* opcode) {
#undef V_LMANY
#undef R_LMANY
#undef FMANY
#undef CVMANY
#undef CMANY
#undef O
};
+3 -4
Ver Arquivo
@@ -74,6 +74,7 @@ enum FlavorDesc {
AV = 3, // Classref
RV = 4, // Return value (cell or var)
FV = 5, // Function parameter (cell or var)
CVV = 6, // Cell or Var argument
};
enum InstrFlags {
@@ -510,11 +511,9 @@ enum SetOpOp {
O(FPushCufF, ONE(IVA), ONE(CV), NOV, NF) \
O(FPushCufSafe, ONE(IVA), TWO(CV,CV), TWO(CV,CV), NF) \
O(FPassC, ONE(IVA), ONE(CV), ONE(FV), FF) \
O(BPassC, ONE(IVA), ONE(CV), ONE(FV), FF) \
O(FPassCW, ONE(IVA), ONE(CV), ONE(FV), FF) \
O(FPassCE, ONE(IVA), ONE(CV), ONE(FV), FF) \
O(FPassV, ONE(IVA), ONE(VV), ONE(FV), FF) \
O(BPassV, ONE(IVA), ONE(VV), ONE(FV), FF) \
O(FPassR, ONE(IVA), ONE(RV), ONE(FV), FF) \
O(FPassL, TWO(IVA,HA), NOV, ONE(FV), FF) \
O(FPassN, ONE(IVA), ONE(CV), ONE(FV), FF) \
@@ -523,7 +522,7 @@ enum SetOpOp {
O(FPassM, TWO(IVA,MA), LMANY(), ONE(FV), FF) \
O(FCall, ONE(IVA), FMANY, ONE(RV), CF_FF) \
O(FCallArray, NA, ONE(FV), ONE(RV), CF_FF) \
O(FCallBuiltin, THREE(IVA,IVA,SA),FMANY, ONE(RV), CF) \
O(FCallBuiltin, THREE(IVA,IVA,SA),CVMANY, ONE(RV), CF) \
O(CufSafeArray, NA, THREE(RV,CV,CV), ONE(CV), NF) \
O(CufSafeReturn, NA, THREE(RV,CV,CV), ONE(RV), NF) \
O(IterInit, THREE(IA,BA,HA), ONE(CV), NOV, CF) \
@@ -567,7 +566,7 @@ enum SetOpOp {
O(Parent, NA, NOV, ONE(AV), NF) \
O(LateBoundCls, NA, NOV, ONE(AV), NF) \
O(NativeImpl, NA, NOV, NOV, CF_TF) \
O(CreateCl, TWO(IVA,SA), FMANY, ONE(CV), NF) \
O(CreateCl, TWO(IVA,SA), CVMANY, ONE(CV), NF) \
O(CreateCont, TWO(IVA,SA), NOV, ONE(CV), NF) \
O(ContEnter, NA, NOV, NOV, CF) \
O(ContExit, NA, NOV, NOV, CF) \
@@ -1043,18 +1043,6 @@ TranslatorX64::irTranslateFPushFuncD(const Tracelet& t,
HHIR_EMIT(FPushFuncD, (i.imm[0].u_IVA), (i.imm[1].u_SA));
}
void
TranslatorX64::irTranslateBPassC(const Tracelet& t,
const NormalizedInstruction& i) {
// No-op
}
void
TranslatorX64::irTranslateBPassV(const Tracelet& t,
const NormalizedInstruction& i) {
// No-op
}
void
TranslatorX64::irTranslateFPassCOp(const Tracelet& t,
const NormalizedInstruction& i) {
@@ -445,8 +445,6 @@ private:
CASE(IterFree) \
CASE(FPassV) \
CASE(UnsetN) \
CASE(BPassC) \
CASE(BPassV) \
// These are instruction-like functions which cover more than one
// opcode.
-2
Ver Arquivo
@@ -1320,8 +1320,6 @@ static const struct {
{ OpFPassS, {StackTop2|FuncdRef,
Stack1, OutUnknown, -1 }},
{ OpFPassM, {MVector|FuncdRef, Stack1, OutUnknown, 1 }},
{ OpBPassC, {None, None, OutNull, 0 }},
{ OpBPassV, {None, None, OutNull, 0 }},
/*
* FCall is special. Like the Ret* instructions, its manipulation of the
* runtime stack are outside the boundaries of the tracelet abstraction.
+10 -3
Ver Arquivo
@@ -527,7 +527,8 @@ static char stkflav(FlavorDesc f) {
bool FuncChecker::checkSig(PC pc, int len, const FlavorDesc* args,
const FlavorDesc* sig) {
for (int i = 0; i < len; ++i) {
if (args[i] != (FlavorDesc)sig[i]) {
if (args[i] != (FlavorDesc)sig[i] &&
!((FlavorDesc)sig[i] == CVV && (args[i] == CV || args[i] == VV))) {
verify_error("flavor mismatch at %d, got %s expected %s\n",
offset(pc), stkToString(len, args).c_str(),
sigToString(len, sig).c_str());
@@ -575,6 +576,7 @@ const FlavorDesc* FuncChecker::sig(PC pc) {
static const FlavorDesc inputSigs[][3] = {
#define NOV { },
#define FMANY { },
#define CVMANY { },
#define CMANY { },
#define ONE(a) { a },
#define TWO(a,b) { b, a },
@@ -592,6 +594,7 @@ const FlavorDesc* FuncChecker::sig(PC pc) {
#undef R_LMANY
#undef LMANY
#undef FMANY
#undef CVMANY
#undef CMANY
#undef FOUR
#undef THREE
@@ -619,12 +622,16 @@ const FlavorDesc* FuncChecker::sig(PC pc) {
return vectorSig(pc, RV);
case OpFCall: // ONE(IVA), FMANY, ONE(RV)
case OpFCallArray:// NA, ONE(FV), ONE(RV)
case OpFCallBuiltin: //TWO(IVA, SA) FMANY, ONE(RV)
case OpCreateCl: // TWO(IVA,SA), FMANY, ONE(CV)
for (int i = 0, n = instrNumPops(pc); i < n; ++i) {
m_tmp_sig[i] = FV;
}
return m_tmp_sig;
case OpFCallBuiltin: //TWO(IVA, SA) CVMANY, ONE(RV)
case OpCreateCl: // TWO(IVA,SA), CVMANY, ONE(CV)
for (int i = 0, n = instrNumPops(pc); i < n; ++i) {
m_tmp_sig[i] = CVV;
}
return m_tmp_sig;
case OpNewTuple: // ONE(IVA), CMANY, ONE(CV)
for (int i = 0, n = instrNumPops(pc); i < n; ++i) {
m_tmp_sig[i] = CV;