Simplifier gets gen()/cns(), replace genDefConst with cns outside tracebuilder

Also removes simplifier's genDef{Bool,Dbl,Int}.
Esse commit está contido em:
Jordan DeLong
2013-04-24 18:43:51 -07:00
commit de Sara Golemon
commit 406eb59593
5 arquivos alterados com 292 adições e 299 exclusões
+48 -54
Ver Arquivo
@@ -334,7 +334,7 @@ void HhbcTranslator::emitPrint() {
if (op != Nop) {
gen(op, cell);
}
push(m_tb->genDefConst<int64_t>(1));
push(cns(1));
} else {
emitInterpOne(Type::Int, 1);
}
@@ -388,14 +388,12 @@ void HhbcTranslator::emitBareThis(int notice) {
}
void HhbcTranslator::emitArray(int arrayId) {
ArrayData* ad = lookupArrayId(arrayId);
push(m_tb->genDefConst(ad));
push(cns(lookupArrayId(arrayId)));
}
void HhbcTranslator::emitNewArray(int capacity) {
if (capacity == 0) {
ArrayData* ad = HphpArray::GetStaticEmptyArray();
push(m_tb->genDefConst(ad));
push(cns(HphpArray::GetStaticEmptyArray()));
} else {
push(gen(NewArray, cns(capacity)));
}
@@ -556,7 +554,7 @@ void HhbcTranslator::emitSelf() {
if (clss == nullptr) {
emitInterpOne(Type::Cls, 0);
} else {
push(m_tb->genDefConst(clss));
push(cns(clss));
}
}
@@ -565,20 +563,20 @@ void HhbcTranslator::emitParent() {
if (clss == nullptr || clss->parent() == nullptr) {
emitInterpOne(Type::Cls, 0);
} else {
push(m_tb->genDefConst(clss->parent()));
push(cns(clss->parent()));
}
}
void HhbcTranslator::emitString(int strId) {
push(m_tb->genDefConst(lookupStringId(strId)));
push(cns(lookupStringId(strId)));
}
void HhbcTranslator::emitInt(int64_t val) {
push(m_tb->genDefConst(val));
push(cns(val));
}
void HhbcTranslator::emitDouble(double val) {
push(m_tb->genDefConst(val));
push(cns(val));
}
void HhbcTranslator::emitNullUninit() {
@@ -590,11 +588,11 @@ void HhbcTranslator::emitNull() {
}
void HhbcTranslator::emitTrue() {
push(m_tb->genDefConst(true));
push(cns(true));
}
void HhbcTranslator::emitFalse() {
push(m_tb->genDefConst(false));
push(cns(false));
}
void HhbcTranslator::emitInitThisLoc(int32_t id) {
@@ -677,8 +675,7 @@ void HhbcTranslator::emitIncDecL(bool pre, bool inc, uint32_t id) {
// only handles integer or double inc/dec
SSATmp* HhbcTranslator::emitIncDec(bool pre, bool inc, SSATmp* src) {
assert(src->isA(Type::Int) || src->isA(Type::Dbl));
SSATmp* one = src->isA(Type::Int) ? m_tb->genDefConst(1)
: m_tb->genDefConst(1.0);
SSATmp* one = src->isA(Type::Int) ? cns(1) : cns(1.0);
SSATmp* res = inc ? m_tb->genAdd(src, one) : m_tb->genSub(src, one);
// no incref necessary on push since result is an int
push(pre ? res : src);
@@ -1043,7 +1040,7 @@ void HhbcTranslator::emitContCurrent() {
assert(getCurClass());
SSATmp* cont = gen(LdThis, m_tb->getFp());
gen(ContStartedCheck, getExitSlowTrace(), cont);
SSATmp* offset = m_tb->genDefConst<int64_t>(CONTOFF(m_value));
SSATmp* offset = cns(CONTOFF(m_value));
SSATmp* value = gen(LdProp, Type::Cell, cont, offset);
value = gen(IncRef, value);
push(value);
@@ -1068,14 +1065,14 @@ void HhbcTranslator::emitStrlen() {
SSATmp* input = popC();
if (input->isConst()) {
// static string; fold its strlen operation
push(m_tb->genDefConst<int64_t>(input->getValStr()->size()));
push(cns(input->getValStr()->size()));
} else {
push(gen(LdRaw, Type::Int, input, cns(RawMemSlot::StrLen)));
m_tb->genDecRef(input);
}
} else if (inType.isNull()) {
popC();
push(m_tb->genDefConst<int64_t>(0));
push(cns(0));
} else if (inType == Type::Bool) {
// strlen(true) == 1, strlen(false) == 0.
push(gen(ConvBoolToInt, popC()));
@@ -1101,7 +1098,7 @@ SSATmp* HhbcTranslator::getStrName(const StringData* knownName) {
if (knownName) {
// The SSATmp on the evaluation stack was not a string constant,
// but the bytecode translator somehow knew the name statically.
name = m_tb->genDefConst(knownName);
name = cns(knownName);
}
} else {
assert(!knownName || knownName->same(name->getValStr()));
@@ -1119,7 +1116,7 @@ SSATmp* HhbcTranslator::emitLdClsPropAddrOrExit(const StringData* propName,
block,
clsTmp,
prop,
m_tb->genDefConst(getCurClass()));
cns(getCurClass()));
m_tb->genDecRef(prop); // safe to do early because prop is a string
return addr;
}
@@ -1176,7 +1173,7 @@ void HhbcTranslator::emitIssetL(int32_t id) {
// guards should ensure we have type info at this point
assert(trackedType != Type::None);
if (trackedType.subtypeOf(Type::Uninit)) {
push(m_tb->genDefConst(false));
push(cns(false));
} else {
Trace* exitTrace = getExitTrace();
SSATmp* ld = m_tb->genLdLocAsCell(id, exitTrace);
@@ -1200,7 +1197,7 @@ void HhbcTranslator::emitEmptyL(int32_t id) {
Type trackedType = m_tb->getLocalType(id);
assert(trackedType != Type::None);
if (trackedType == Type::Uninit) {
push(m_tb->genDefConst(true));
push(cns(true));
} else {
Trace* exitTrace = getExitTrace();
SSATmp* ld = m_tb->genLdLocAsCell(id, exitTrace);
@@ -1317,8 +1314,8 @@ void HhbcTranslator::emitClsCnsD(int32_t cnsNameStrId, int32_t clsNameStrId) {
// and can throw a fatal error.
const StringData* cnsNameStr = lookupStringId(cnsNameStrId);
const StringData* clsNameStr = lookupStringId(clsNameStrId);
SSATmp* cnsNameTmp = m_tb->genDefConst(cnsNameStr);
SSATmp* clsNameTmp = m_tb->genDefConst(clsNameStr);
SSATmp* cnsNameTmp = cns(cnsNameStr);
SSATmp* clsNameTmp = cns(clsNameStr);
if (0) {
// TODO: 2068502 pick one of these two implementations and remove the other.
Trace* exitTrace = getExitSlowTrace();
@@ -1550,7 +1547,7 @@ void HhbcTranslator::emitFPushFuncD(int32_t numParams, int32_t funcId) {
const Func* func = Unit::lookupFunc(nep.second, name);
if (!func) {
// function lookup failed so just do the same as FPushFunc
emitFPushFunc(numParams, m_tb->genDefConst(name));
emitFPushFunc(numParams, cns(name));
return;
}
func->validate();
@@ -1560,8 +1557,8 @@ void HhbcTranslator::emitFPushFuncD(int32_t numParams, int32_t funcId) {
if (!immutable) {
exceptionBarrier(); // LdFuncCached can reenter
}
SSATmp* ssaFunc = immutable ? m_tb->genDefConst(func)
: gen(LdFuncCached, m_tb->genDefConst(name));
SSATmp* ssaFunc = immutable ? cns(func)
: gen(LdFuncCached, cns(name));
emitFPushActRec(ssaFunc,
m_tb->genDefInitNull(),
numParams,
@@ -1645,9 +1642,9 @@ void HhbcTranslator::emitFPushObjMethodD(int32_t numParams,
// the obj won't be in the actrec and thus MethodCache::lookup won't
// decref it
m_tb->genDecRef(obj);
objOrCls = m_tb->genDefConst(baseClass);
objOrCls = cns(baseClass);
}
emitFPushActRec(m_tb->genDefConst(func),
emitFPushActRec(cns(func),
objOrCls,
numParams,
magicCall ? methodName : nullptr);
@@ -1706,7 +1703,7 @@ void HhbcTranslator::emitFPushClsMethodD(int32_t numParams,
true);
if (func) {
SSATmp* objOrCls = getClsMethodCtx(func, baseClass);
emitFPushActRec(m_tb->genDefConst(func),
emitFPushActRec(cns(func),
objOrCls,
numParams,
func && magicCall ? methodName : nullptr);
@@ -1743,7 +1740,7 @@ void HhbcTranslator::emitFPushClsMethodF(int32_t numParams,
true /* staticLookup */);
SSATmp* curCtxTmp = gen(LdCtx, m_tb->getFp(), cns(getCurFunc()));
if (func) {
SSATmp* funcTmp = m_tb->genDefConst(func);
SSATmp* funcTmp = cns(func);
SSATmp* newCtxTmp = gen(GetCtxFwdCall, curCtxTmp, funcTmp);
emitFPushActRec(funcTmp, newCtxTmp, numParams,
@@ -1751,8 +1748,8 @@ void HhbcTranslator::emitFPushClsMethodF(int32_t numParams,
} else {
SSATmp* funcCtxTmp = gen(LdClsMethodFCache, exitBlock,
m_tb->genDefConst(cls),
m_tb->genDefConst(methName),
cns(cls),
cns(methName),
curCtxTmp);
emitFPushActRec(funcCtxTmp,
m_tb->genDefInitNull(),
@@ -1835,7 +1832,7 @@ void HhbcTranslator::emitFCallBuiltin(uint32_t numArgs,
}
}
// generate call and set return type
SSATmp* func = m_tb->genDefConst<const Func*>(callee);
SSATmp* func = cns(callee);
Type type = Type::fromDataTypeWithRef(callee->returnType(),
(callee->attrs() & ClassInfo::IsReference));
SSATmp* ret = m_tb->genCallBuiltin(func, type, numArgs, args);
@@ -1976,8 +1973,8 @@ void HhbcTranslator::emitSwitch(const ImmVector& iv,
assert(IMPLIES(!type.equals(Type::Int), bounded));
assert(IMPLIES(bounded, iv.size() > 2));
SSATmp* index;
SSATmp* ssabase = m_tb->genDefConst(base);
SSATmp* ssatargets = m_tb->genDefConst(nTargets);
SSATmp* ssabase = cns(base);
SSATmp* ssatargets = cns(nTargets);
Offset defaultOff = bcOff() + iv.vec32()[iv.size() - 1];
Offset zeroOff = 0;
@@ -2345,13 +2342,13 @@ void HhbcTranslator::emitInstanceOfD(int classNameStrId) {
PUNT(InstanceOfD_MaybeObj);
}
if (!src->isA(Type::Obj)) {
push(m_tb->genDefConst(false));
push(cns(false));
m_tb->genDecRef(src);
return;
}
SSATmp* objClass = gen(LdObjClass, src);
SSATmp* ssaClassName = m_tb->genDefConst(className);
SSATmp* ssaClassName = cns(className);
Class::initInstanceBits();
const bool haveBit = Class::haveInstanceBit(className);
@@ -2371,7 +2368,7 @@ void HhbcTranslator::emitInstanceOfD(int classNameStrId) {
SSATmp* checkClass =
isUnique || (maybeCls && getCurClass() &&
getCurClass()->classof(maybeCls))
? m_tb->genDefConst(maybeCls)
? cns(maybeCls)
: gen(LdClsCachedSafe, ssaClassName);
push(
@@ -2384,7 +2381,7 @@ void HhbcTranslator::emitInstanceOfD(int classNameStrId) {
gen(InstanceOf,
objClass,
checkClass,
m_tb->genDefConst(maybeCls && !isNormalClass))
cns(maybeCls && !isNormalClass))
);
m_tb->genDecRef(src);
}
@@ -2409,7 +2406,7 @@ void HhbcTranslator::emitCastArray() {
if (fromType.isArray()) {
push(src);
} else if (fromType.isNull()) {
push(m_tb->genDefConst(HphpArray::GetStaticEmptyArray()));
push(cns(HphpArray::GetStaticEmptyArray()));
} else if (fromType.isBool()) {
push(gen(ConvBoolToArr, src));
} else if (fromType.isDbl()) {
@@ -2437,7 +2434,7 @@ void HhbcTranslator::emitCastDouble() {
if (fromType.isDbl()) {
push(src);
} else if (fromType.isNull()) {
push(m_tb->genDefConst(0.0));
push(cns(0.0));
} else if (fromType.isArray()) {
push(gen(ConvArrToDbl, src));
m_tb->genDecRef(src);
@@ -2462,7 +2459,7 @@ void HhbcTranslator::emitCastInt() {
if (fromType.isInt()) {
push(src);
} else if (fromType.isNull()) {
push(m_tb->genDefConst(0));
push(cns(0));
} else if (fromType.isArray()) {
push(gen(ConvArrToInt, src));
m_tb->genDecRef(src);
@@ -2498,9 +2495,9 @@ void HhbcTranslator::emitCastString() {
if (fromType.isString()) {
push(src);
} else if (fromType.isNull()) {
push(m_tb->genDefConst(StringData::GetStaticString("")));
push(cns(StringData::GetStaticString("")));
} else if (fromType.isArray()) {
push(m_tb->genDefConst(StringData::GetStaticString("Array")));
push(cns(StringData::GetStaticString("Array")));
m_tb->genDecRef(src);
} else if (fromType.isBool()) {
push(gen(ConvBoolToStr, src));
@@ -2524,13 +2521,11 @@ bool isSupportedAGet(SSATmp* classSrc, const StringData* clsName) {
void HhbcTranslator::emitAGet(SSATmp* classSrc, const StringData* clsName) {
if (classSrc->isA(Type::Str)) {
push(gen(LdCls, classSrc, m_tb->genDefConst(getCurClass())));
push(gen(LdCls, classSrc, cns(getCurClass())));
} else if (classSrc->isA(Type::Obj)) {
push(gen(LdObjClass, classSrc));
} else if (clsName) {
push(gen(LdCls,
m_tb->genDefConst(clsName),
m_tb->genDefConst(getCurClass())));
push(gen(LdCls, cns(clsName), cns(getCurClass())));
} else {
not_reached();
}
@@ -2620,7 +2615,7 @@ void HhbcTranslator::emitIsset(const StringData* name,
gen(UnboxPtr, ptr));
},
[&] { // Taken
return m_tb->genDefConst(false);
return cns(false);
}
);
push(result);
@@ -2651,7 +2646,7 @@ void HhbcTranslator::emitEmpty(const StringData* name,
return m_tb->genNot(m_tb->genConvToBool(ld));
},
[&] { // Taken
return m_tb->genDefConst(true);
return cns(true);
}
);
push(result);
@@ -2810,7 +2805,7 @@ void HhbcTranslator::emitMod() {
SSATmp* l = popC();
// Exit path spills an additional false
auto exitSpillValues = getSpillValues();
exitSpillValues.push_back(m_tb->genDefConst(false));
exitSpillValues.push_back(cns(false));
// Generate an exit for the rare case that r is zero
auto exit =
m_tb->ifThenExit(
@@ -2836,7 +2831,7 @@ void HhbcTranslator::emitBitNot() {
Type srcType = topC()->type();
if (srcType == Type::Int) {
SSATmp* src = popC();
SSATmp* ones = m_tb->genDefConst<int64_t>(~0);
SSATmp* ones = cns(~uint64_t(0));
push(m_tb->genXor(src, ones));
} else if (srcType.subtypeOf(Type::Null | Type::Bool | Type::Arr | Type::Obj)) {
// raise fatal
@@ -2893,8 +2888,7 @@ void HhbcTranslator::emitInterpOneCF(int numPopped) {
// discard the top elements of the stack, which are consumed by this instr
discard(numPopped);
assert(numPopped == m_stackDeficit);
gen(InterpOneCF, m_tb->getFp(), m_tb->getSp(),
m_tb->genDefConst(bcOff()));
gen(InterpOneCF, m_tb->getFp(), m_tb->getSp(), cns(bcOff()));
m_stackDeficit = 0;
m_hasExit = true;
}
+236 -238
Ver Arquivo
@@ -56,6 +56,18 @@ void copyProp(IRInstruction* inst) {
}
}
//////////////////////////////////////////////////////////////////////
template<class T> SSATmp* Simplifier::cns(T cns) {
return m_tb->genDefConst(cns);
}
template<class... Args> SSATmp* Simplifier::gen(Args&&... args) {
return m_tb->gen(std::forward<Args>(args)...);
}
//////////////////////////////////////////////////////////////////////
static bool isNotInst(SSATmp *src1, SSATmp *src2) {
// right operand should be 1
if (!src2->isConst() || src2->type() != Type::Int ||
@@ -292,7 +304,7 @@ SSATmp* Simplifier::simplifyLdCtx(IRInstruction* inst) {
if (func->isStatic()) {
// ActRec->m_cls of a static function is always a valid class pointer with
// the bottom bit set
return m_tb->gen(LdCctx, inst->getSrc(0));
return gen(LdCctx, inst->getSrc(0));
}
return nullptr;
}
@@ -302,10 +314,10 @@ SSATmp* Simplifier::simplifyLdClsCtx(IRInstruction* inst) {
Type ctxType = ctx->type();
if (ctxType.equals(Type::Obj)) {
// this pointer... load its class ptr
return m_tb->gen(LdObjClass, ctx);
return gen(LdObjClass, ctx);
}
if (ctxType.equals(Type::Cctx)) {
return m_tb->gen(LdClsCctx, ctx);
return gen(LdClsCctx, ctx);
}
return nullptr;
}
@@ -325,17 +337,17 @@ SSATmp* Simplifier::simplifyLdCls(IRInstruction* inst) {
if (cls) {
if (Transl::TargetCache::isPersistentHandle(cls->m_cachedOffset)) {
// the class is always defined
return m_tb->genDefConst(cls);
return cns(cls);
}
const Class* ctx = inst->getSrc(1)->getValClass();
if (ctx && ctx->classof(cls)) {
// the class of the current function being compiled is the
// same as or derived from cls, so cls must be defined and
// cannot change the next time we execute this same code
return m_tb->genDefConst(cls);
return cns(cls);
}
}
return m_tb->gen(LdClsCached, clsName);
return gen(LdClsCached, clsName);
}
return nullptr;
}
@@ -450,7 +462,7 @@ SSATmp* Simplifier::simplifyNot(SSATmp* src) {
case NInstanceOfBitmask:
// TODO: combine this with the above check and use isQueryOp or
// add an isNegatable.
return m_tb->gen(
return gen(
negateQueryOp(op),
std::make_pair(inst->getNumSrcs(), inst->getSrcs().begin())
);
@@ -461,161 +473,161 @@ SSATmp* Simplifier::simplifyNot(SSATmp* src) {
return nullptr;
}
#define SIMPLIFY_CONST(OP) do { \
/* don't canonicalize to the right, OP might not be commutative */ \
if (src1->isConst() && src2->isConst()) { \
if (src1->type().isNull()) { \
/* Null op Null */ \
if (src2->type().isNull()) { \
return genDefInt(0 OP 0); \
} \
/* Null op ConstInt */ \
if (src2->type() == Type::Int) { \
return genDefInt(0 OP src2->getValInt()); \
} \
/* Null op ConstBool */ \
if (src2->type() == Type::Bool) { \
return genDefInt(0 OP src2->getValBool()); \
} \
/* Null op StaticStr */ \
if (src2->type() == Type::StaticStr) { \
const StringData* str = src2->getValStr(); \
if (str->isInteger()) { \
return genDefInt(0 OP str->toInt64()); \
} \
return genDefInt(0 OP 0); \
} \
} \
if (src1->type() == Type::Int) { \
/* ConstInt op Null */ \
if (src2->type().isNull()) { \
return genDefInt(src1->getValInt() OP 0); \
} \
/* ConstInt op ConstInt */ \
if (src2->type() == Type::Int) { \
return genDefInt(src1->getValInt() OP \
src2->getValInt()); \
} \
/* ConstInt op ConstBool */ \
if (src2->type() == Type::Bool) { \
return genDefInt(src1->getValInt() OP \
int(src2->getValBool())); \
} \
/* ConstInt op StaticStr */ \
if (src2->type() == Type::StaticStr) { \
const StringData* str = src2->getValStr(); \
if (str->isInteger()) { \
return genDefInt(src1->getValInt() OP str->toInt64()); \
} \
return genDefInt(src1->getValInt() OP 0); \
} \
} \
if (src1->type() == Type::Bool) { \
/* ConstBool op Null */ \
if (src2->type().isNull()) { \
return genDefInt(src1->getValBool() OP 0); \
} \
/* ConstBool op ConstInt */ \
if (src2->type() == Type::Int) { \
return genDefInt(int(src1->getValBool()) OP \
src2->getValInt()); \
} \
/* ConstBool op ConstBool */ \
if (src2->type() == Type::Bool) { \
return genDefInt(src1->getValBool() OP \
src2->getValBool()); \
} \
/* ConstBool op StaticStr */ \
if (src2->type() == Type::StaticStr) { \
const StringData* str = src2->getValStr(); \
if (str->isInteger()) { \
return genDefInt(int(src1->getValBool()) OP str->toInt64()); \
} \
return genDefInt(int(src1->getValBool()) OP 0); \
} \
} \
if (src1->type() == Type::StaticStr) { \
const StringData* str = src1->getValStr(); \
int64_t strInt = 0; \
if (str->isInteger()) { \
strInt = str->toInt64(); \
} \
/* StaticStr op Null */ \
if (src2->type().isNull()) { \
return genDefInt(strInt OP 0); \
} \
/* StaticStr op ConstInt */ \
if (src2->type() == Type::Int) { \
return genDefInt(strInt OP src2->getValInt()); \
} \
/* StaticStr op ConstBool */ \
if (src2->type() == Type::Bool) { \
return genDefInt(strInt OP int(src2->getValBool())); \
} \
/* StaticStr op StaticStr */ \
if (src2->type() == Type::StaticStr) { \
const StringData* str2 = src2->getValStr(); \
if (str2->isInteger()) { \
return genDefInt(strInt OP str2->toInt64()); \
} \
return genDefInt(strInt OP 0); \
} \
} \
} \
#define SIMPLIFY_CONST(OP) do { \
/* don't canonicalize to the right, OP might not be commutative */ \
if (src1->isConst() && src2->isConst()) { \
if (src1->type().isNull()) { \
/* Null op Null */ \
if (src2->type().isNull()) { \
return cns(int64_t(0 OP 0)); \
} \
/* Null op ConstInt */ \
if (src2->type() == Type::Int) { \
return cns(int64_t(0 OP src2->getValInt())); \
} \
/* Null op ConstBool */ \
if (src2->type() == Type::Bool) { \
return cns(int64_t(0 OP src2->getValBool())); \
} \
/* Null op StaticStr */ \
if (src2->type() == Type::StaticStr) { \
const StringData* str = src2->getValStr(); \
if (str->isInteger()) { \
return cns(int64_t(0 OP str->toInt64())); \
} \
return cns(int64_t(0 OP 0)); \
} \
} \
if (src1->type() == Type::Int) { \
/* ConstInt op Null */ \
if (src2->type().isNull()) { \
return cns(int64_t(src1->getValInt()) OP 0); \
} \
/* ConstInt op ConstInt */ \
if (src2->type() == Type::Int) { \
return cns(int64_t(src1->getValInt() OP \
src2->getValInt())); \
} \
/* ConstInt op ConstBool */ \
if (src2->type() == Type::Bool) { \
return cns(int64_t(src1->getValInt() OP \
int(src2->getValBool()))); \
} \
/* ConstInt op StaticStr */ \
if (src2->type() == Type::StaticStr) { \
const StringData* str = src2->getValStr(); \
if (str->isInteger()) { \
return cns(int64_t(src1->getValInt() OP str->toInt64())); \
} \
return cns(int64_t(src1->getValInt() OP 0)); \
} \
} \
if (src1->type() == Type::Bool) { \
/* ConstBool op Null */ \
if (src2->type().isNull()) { \
return cns(int64_t(src1->getValBool() OP 0)); \
} \
/* ConstBool op ConstInt */ \
if (src2->type() == Type::Int) { \
return cns(int64_t(int(src1->getValBool()) OP \
src2->getValInt())); \
} \
/* ConstBool op ConstBool */ \
if (src2->type() == Type::Bool) { \
return cns(int64_t(src1->getValBool() OP \
src2->getValBool())); \
} \
/* ConstBool op StaticStr */ \
if (src2->type() == Type::StaticStr) { \
const StringData* str = src2->getValStr(); \
if (str->isInteger()) { \
return cns(int64_t(int(src1->getValBool()) OP str->toInt64())); \
} \
return cns(int64_t(int(src1->getValBool()) OP 0)); \
} \
} \
if (src1->type() == Type::StaticStr) { \
const StringData* str = src1->getValStr(); \
int64_t strInt = 0; \
if (str->isInteger()) { \
strInt = str->toInt64(); \
} \
/* StaticStr op Null */ \
if (src2->type().isNull()) { \
return cns(int64_t(strInt OP 0)); \
} \
/* StaticStr op ConstInt */ \
if (src2->type() == Type::Int) { \
return cns(int64_t(strInt OP src2->getValInt())); \
} \
/* StaticStr op ConstBool */ \
if (src2->type() == Type::Bool) { \
return cns(int64_t(strInt OP int(src2->getValBool()))); \
} \
/* StaticStr op StaticStr */ \
if (src2->type() == Type::StaticStr) { \
const StringData* str2 = src2->getValStr(); \
if (str2->isInteger()) { \
return cns(int64_t(strInt OP str2->toInt64())); \
} \
return cns(int64_t(strInt OP 0)); \
} \
} \
} \
} while (0)
#define SIMPLIFY_COMMUTATIVE(OP, NAME) do { \
SIMPLIFY_CONST(OP); \
if (src1->isConst() && !src2->isConst()) { \
return m_tb->gen##NAME(src2, src1); \
} \
if (src1->isA(Type::Int) && src2->isA(Type::Int)) { \
IRInstruction* inst1 = src1->inst(); \
IRInstruction* inst2 = src2->inst(); \
if (inst1->op() == Op##NAME && inst1->getSrc(1)->isConst()) { \
/* (X + C1) + C2 --> X + C3 */ \
if (src2->isConst()) { \
int64_t right = inst1->getSrc(1)->getValInt(); \
right OP##= src2->getValInt(); \
return m_tb->gen##NAME(inst1->getSrc(0), genDefInt(right)); \
} \
/* (X + C1) + (Y + C2) --> X + Y + C3 */ \
if (inst2->op() == Op##NAME && inst2->getSrc(1)->isConst()) { \
int64_t right = inst1->getSrc(1)->getValInt(); \
right OP##= inst2->getSrc(1)->getValInt(); \
#define SIMPLIFY_COMMUTATIVE(OP, NAME) do { \
SIMPLIFY_CONST(OP); \
if (src1->isConst() && !src2->isConst()) { \
return m_tb->gen##NAME(src2, src1); \
} \
if (src1->isA(Type::Int) && src2->isA(Type::Int)) { \
IRInstruction* inst1 = src1->inst(); \
IRInstruction* inst2 = src2->inst(); \
if (inst1->op() == Op##NAME && inst1->getSrc(1)->isConst()) { \
/* (X + C1) + C2 --> X + C3 */ \
if (src2->isConst()) { \
int64_t right = inst1->getSrc(1)->getValInt(); \
right OP##= src2->getValInt(); \
return m_tb->gen##NAME(inst1->getSrc(0), cns(right)); \
} \
/* (X + C1) + (Y + C2) --> X + Y + C3 */ \
if (inst2->op() == Op##NAME && inst2->getSrc(1)->isConst()) { \
int64_t right = inst1->getSrc(1)->getValInt(); \
right OP##= inst2->getSrc(1)->getValInt(); \
SSATmp* left = m_tb->gen##NAME(inst1->getSrc(0), inst2->getSrc(0)); \
return m_tb->gen##NAME(left, genDefInt(right)); \
} \
} \
} \
return m_tb->gen##NAME(left, cns(right)); \
} \
} \
} \
} while (0)
#define SIMPLIFY_DISTRIBUTIVE(OUTOP, INOP, OUTNAME, INNAME) do { \
/* assumes that OUTOP is commutative, don't use with subtract! */ \
SIMPLIFY_COMMUTATIVE(OUTOP, OUTNAME); \
IRInstruction* inst1 = src1->inst(); \
IRInstruction* inst2 = src2->inst(); \
Opcode op1 = inst1->op(); \
Opcode op2 = inst2->op(); \
/* all combinations of X * Y + X * Z --> X * (Y + Z) */ \
if (op1 == Op##INNAME && op2 == Op##INNAME) { \
if (inst1->getSrc(0) == inst2->getSrc(0)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(1), inst2->getSrc(1)); \
return m_tb->gen##INNAME(inst1->getSrc(0), fold); \
} \
if (inst1->getSrc(0) == inst2->getSrc(1)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(1), inst2->getSrc(0)); \
return m_tb->gen##INNAME(inst1->getSrc(0), fold); \
} \
if (inst1->getSrc(1) == inst2->getSrc(0)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(0), inst2->getSrc(1)); \
return m_tb->gen##INNAME(inst1->getSrc(1), fold); \
} \
if (inst1->getSrc(1) == inst2->getSrc(1)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(0), inst2->getSrc(0)); \
return m_tb->gen##INNAME(inst1->getSrc(1), fold); \
} \
} \
#define SIMPLIFY_DISTRIBUTIVE(OUTOP, INOP, OUTNAME, INNAME) do { \
/* assumes that OUTOP is commutative, don't use with subtract! */ \
SIMPLIFY_COMMUTATIVE(OUTOP, OUTNAME); \
IRInstruction* inst1 = src1->inst(); \
IRInstruction* inst2 = src2->inst(); \
Opcode op1 = inst1->op(); \
Opcode op2 = inst2->op(); \
/* all combinations of X * Y + X * Z --> X * (Y + Z) */ \
if (op1 == Op##INNAME && op2 == Op##INNAME) { \
if (inst1->getSrc(0) == inst2->getSrc(0)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(1), inst2->getSrc(1)); \
return m_tb->gen##INNAME(inst1->getSrc(0), fold); \
} \
if (inst1->getSrc(0) == inst2->getSrc(1)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(1), inst2->getSrc(0)); \
return m_tb->gen##INNAME(inst1->getSrc(0), fold); \
} \
if (inst1->getSrc(1) == inst2->getSrc(0)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(0), inst2->getSrc(1)); \
return m_tb->gen##INNAME(inst1->getSrc(1), fold); \
} \
if (inst1->getSrc(1) == inst2->getSrc(1)) { \
SSATmp* fold = m_tb->gen##OUTNAME(inst1->getSrc(0), inst2->getSrc(0)); \
return m_tb->gen##INNAME(inst1->getSrc(1), fold); \
} \
} \
} while (0)
SSATmp* Simplifier::simplifyAdd(SSATmp* src1, SSATmp* src2) {
@@ -625,13 +637,13 @@ SSATmp* Simplifier::simplifyAdd(SSATmp* src1, SSATmp* src2) {
// X + 0 --> X
if (src2Val == 0) {
if (src1->type() == Type::Bool) {
return m_tb->gen(ConvBoolToInt, src1);
return gen(ConvBoolToInt, src1);
}
return src1;
}
// X + -C --> X - C
if (src2Val < 0) {
return m_tb->genSub(src1, genDefInt(-src2Val));
return m_tb->genSub(src1, cns(-src2Val));
}
}
// X + (0 - Y) --> X - Y
@@ -651,20 +663,20 @@ SSATmp* Simplifier::simplifySub(SSATmp* src1, SSATmp* src2) {
SIMPLIFY_CONST(-);
// X - X --> 0
if (src1 == src2) {
return genDefInt(0);
return cns(0);
}
if (src2->isConst() && src2->type() == Type::Int) {
int64_t src2Val = src2->getValInt();
// X - 0 --> X
if (src2Val == 0) {
if (src1->type() == Type::Bool) {
return m_tb->gen(ConvBoolToInt, src1);
return gen(ConvBoolToInt, src1);
}
return src1;
}
// X - -C --> X + C
if (src2Val < 0 && src2Val > std::numeric_limits<int64_t>::min()) {
return m_tb->genAdd(src1, genDefInt(-src2Val));
return m_tb->genAdd(src1, cns(-src2Val));
}
}
// X - (0 - Y) --> X + Y
@@ -689,16 +701,16 @@ SSATmp* Simplifier::simplifyMul(SSATmp* src1, SSATmp* src2) {
if (src2->isConst() && src2->type() == Type::Int) {
// X * (-1) --> -X
if (src2->getValInt() == -1) {
return m_tb->genSub(genDefInt(0), src1);
return m_tb->genSub(cns(0), src1);
}
// X * 0 --> 0
if (src2->getValInt() == 0) {
return genDefInt(0);
return cns(0);
}
// X * 1 --> X
if (src2->getValInt() == 1) {
if (src1->type() == Type::Bool) {
return m_tb->gen(ConvBoolToInt, src1);
return gen(ConvBoolToInt, src1);
}
return src1;
}
@@ -722,7 +734,7 @@ SSATmp* Simplifier::simplifyAnd(SSATmp* src1, SSATmp* src2) {
if (src2->isConst() && src2->type() == Type::Int) {
// X & 0 --> 0
if (src2->getValInt() == 0) {
return genDefInt(0);
return cns(0);
}
// X & (~0) --> X
if (src2->getValInt() == ~0L) {
@@ -743,8 +755,8 @@ SSATmp* Simplifier::simplifyOr(SSATmp* src1, SSATmp* src2) {
return src1;
}
// X | (~0) --> ~0
if (src2->getValInt() == ~0L) {
return genDefInt(~0L);
if (src2->getValInt() == ~uint64_t(0)) {
return cns(~uint64_t(0));
}
}
return nullptr;
@@ -753,7 +765,7 @@ SSATmp* Simplifier::simplifyXor(SSATmp* src1, SSATmp* src2) {
SIMPLIFY_COMMUTATIVE(^, Xor);
// X ^ X --> 0
if (src1 == src2)
return genDefInt(0);
return cns(0);
// X ^ 0 --> X
if (src2->isConst() && src2->type() == Type::Int) {
if (src2->getValInt() == 0) {
@@ -798,7 +810,7 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
if ((src1 == src2 || chaseIncRefs(src1) == chaseIncRefs(src2)) &&
src1->type() != Type::Dbl) {
// (val1 == val1) does not simplify to true when val1 is a NaN
return genDefBool(cmpOp(opName, 0, 0));
return cns(bool(cmpOp(opName, 0, 0)));
}
// need both types to be unboxed and known to simplify
@@ -815,7 +827,7 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
// OpSame and OpNSame do not perform type juggling
if (src1->type() != src2->type()) {
if (!(src1->type().isString() && src2->type().isString())) {
return genDefBool(opName == OpNSame);
return cns(opName == OpNSame);
}
}
@@ -828,7 +840,7 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
auto str1 = src1->getValStr();
auto str2 = src2->getValStr();
bool same = str1->same(str2);
return genDefBool(cmpOp(opName, same, 1));
return cns(bool(cmpOp(opName, same, 1)));
} else {
return nullptr;
}
@@ -853,7 +865,7 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
// Null cmp Null
if (src1->type().isNull() && src2->type().isNull()) {
return genDefBool(cmpOp(opName, 0, 0));
return cns(bool(cmpOp(opName, 0, 0)));
}
// const cmp const
// TODO this list is incomplete - feel free to add more
@@ -863,17 +875,17 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
if (src1->type() == Type::StaticStr &&
src2->type() == Type::StaticStr) {
int cmp = src1->getValStr()->compare(src2->getValStr());
return genDefBool(cmpOp(opName, cmp, 0));
return cns(bool(cmpOp(opName, cmp, 0)));
}
// ConstInt cmp ConstInt
if (src1->type() == Type::Int && src2->type() == Type::Int) {
return genDefBool(
cmpOp(opName, src1->getValInt(), src2->getValInt()));
return cns(bool(
cmpOp(opName, src1->getValInt(), src2->getValInt())));
}
// ConstBool cmp ConstBool
if (src1->type() == Type::Bool && src2->type() == Type::Bool) {
return genDefBool(
cmpOp(opName, src1->getValBool(), src2->getValBool()));
return cns(bool(
cmpOp(opName, src1->getValBool(), src2->getValBool())));
}
}
@@ -892,7 +904,7 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
// (0 or 1), but `0 > true` and `1 > true` are both false, so we can
// simplify to false immediately.
if (cmpOp(opName, false, b) == cmpOp(opName, true, b)) {
return genDefBool(cmpOp(opName, false, b));
return cns(bool(cmpOp(opName, false, b)));
}
// There are only two distinct booleans - false and true (0 and 1).
@@ -904,9 +916,9 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
// E.g. `some-int > false` is equivalent to `some-int == true`
if (opName != OpEq) {
if (cmpOp(opName, false, b)) {
return m_tb->genCmp(OpEq, src1, genDefBool(false));
return m_tb->genCmp(OpEq, src1, cns(false));
} else {
return m_tb->genCmp(OpEq, src1, genDefBool(true));
return m_tb->genCmp(OpEq, src1, cns(true));
}
}
}
@@ -937,12 +949,12 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
// case 1: null cmp string. Convert null to ""
if (src1->type().isString() && src2->type().isNull()) {
return m_tb->genCmp(opName, src1,
m_tb->genDefConst(StringData::GetStaticString("")));
cns(StringData::GetStaticString("")));
}
// case 2a: null cmp anything. Convert null to false
if (src2->type().isNull()) {
return m_tb->genCmp(opName, src1, genDefBool(false));
return m_tb->genCmp(opName, src1, cns(false));
}
// bools get canonicalized to the right
@@ -954,10 +966,10 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
if (src2->type() == Type::Bool) {
if (src1->isConst()) {
if (src1->type() == Type::Int) {
return m_tb->genCmp(opName, genDefBool(src1->getValInt()), src2);
return m_tb->genCmp(opName, cns(bool(src1->getValInt())), src2);
} else if (src1->type().isString()) {
auto str = src1->getValStr();
return m_tb->genCmp(opName, genDefBool(str->toBoolean()), src2);
return m_tb->genCmp(opName, cns(str->toBoolean()), src2);
}
}
@@ -967,9 +979,9 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
always_assert(opName == OpEq);
if (src2->getValBool()) {
return m_tb->genCmp(OpNeq, src1, m_tb->genDefConst<int64_t>(0));
return m_tb->genCmp(OpNeq, src1, cns(0));
} else {
return m_tb->genCmp(OpEq, src1, m_tb->genDefConst<int64_t>(0));
return m_tb->genCmp(OpEq, src1, cns(0));
}
}
@@ -1004,12 +1016,12 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
int64_t si; double sd;
auto st = str->isNumericWithVal(si, sd, true /* allow errors */);
if (st == KindOfDouble) {
return m_tb->genCmp(opName, m_tb->genDefConst<double>(sd), src2);
return m_tb->genCmp(opName, cns(sd), src2);
}
if (st == KindOfNull) {
si = 0;
}
return m_tb->genCmp(opName, m_tb->genDefConst<int64_t>(si), src2);
return m_tb->genCmp(opName, cns(si), src2);
}
// case 5: array cmp array. No juggling to do
@@ -1017,10 +1029,10 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) {
// case 6: array cmp anything. Array is greater
if (src1->isArray()) {
return genDefBool(cmpOp(opName, 1, 0));
return cns(bool(cmpOp(opName, 1, 0)));
}
if (src2->isArray()) {
return genDefBool(cmpOp(opName, 0, 1));
return cns(bool(cmpOp(opName, 0, 1)));
}
// case 7: object cmp anything. Object is greater
@@ -1037,7 +1049,7 @@ SSATmp* Simplifier::simplifyJmpIsType(IRInstruction* inst) {
assert(res->isConst());
if (res->getValBool()) {
// Taken jump
return m_tb->gen(Jmp_, inst->getTaken());
return gen(Jmp_, inst->getTaken());
} else {
// Not taken jump; turn jump into a nop
inst->convertToNop();
@@ -1057,17 +1069,17 @@ SSATmp* Simplifier::simplifyIsType(IRInstruction* inst) {
assert(type.isKnownUnboxedDataType() && type != Type::StaticStr);
if (type != Type::Obj) {
if (srcType.subtypeOf(type) || (type.isString() && srcType.isString())) {
return genDefBool(trueSense);
return cns(trueSense);
}
if (srcType != Type::Cell) {
return genDefBool(!trueSense);
return cns(!trueSense);
}
}
if (srcType != Type::Obj) {
// Note: for IsObject*, we need to emit a call to ObjectData::isResource
// (or equivalent), so we can't fold away the case where we know we are
// checking an object.
return genDefBool(!trueSense);
return cns(!trueSense);
}
return nullptr;
}
@@ -1078,7 +1090,7 @@ SSATmp* Simplifier::simplifyConcat(SSATmp* src1, SSATmp* src2) {
StringData* str1 = const_cast<StringData *>(src1->getValStr());
StringData* str2 = const_cast<StringData *>(src2->getValStr());
StringData* merge = StringData::GetStaticString(concat_ss(str1, str2));
return m_tb->genDefConst(merge);
return cns(merge);
}
return nullptr;
}
@@ -1087,7 +1099,7 @@ SSATmp* Simplifier::simplifyConvToArr(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
Array arr = Array::Create(src->getValVariant());
return m_tb->genDefConst(ArrayData::GetScalarArray(arr.get()));
return cns(ArrayData::GetScalarArray(arr.get()));
}
return nullptr;
}
@@ -1096,9 +1108,9 @@ SSATmp* Simplifier::simplifyConvArrToBool(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
if (src->getValArr()->empty()) {
return genDefBool(false);
return cns(false);
}
return genDefBool(true);
return cns(true);
}
return nullptr;
}
@@ -1106,7 +1118,7 @@ SSATmp* Simplifier::simplifyConvArrToBool(IRInstruction* inst) {
SSATmp* Simplifier::simplifyConvDblToBool(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
return genDefBool(bool(src->getValDbl()));
return cns(bool(src->getValDbl()));
}
return nullptr;
}
@@ -1114,7 +1126,7 @@ SSATmp* Simplifier::simplifyConvDblToBool(IRInstruction* inst) {
SSATmp* Simplifier::simplifyConvIntToBool(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
return genDefBool(bool(src->getValInt()));
return cns(bool(src->getValInt()));
}
return nullptr;
}
@@ -1125,7 +1137,7 @@ SSATmp* Simplifier::simplifyConvStrToBool(IRInstruction* inst) {
// only the strings "", and "0" convert to false, all other strings
// are converted to true
const StringData* str = src->getValStr();
return genDefBool(!str->empty() && !str->isZero());
return cns(!str->empty() && !str->isZero());
}
return nullptr;
}
@@ -1134,7 +1146,7 @@ SSATmp* Simplifier::simplifyConvArrToDbl(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
if (src->getValArr()->empty()) {
return genDefDbl(0.0);
return cns(0.0);
}
}
return nullptr;
@@ -1143,7 +1155,7 @@ SSATmp* Simplifier::simplifyConvArrToDbl(IRInstruction* inst) {
SSATmp* Simplifier::simplifyConvBoolToDbl(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
return genDefDbl(double(src->getValBool()));
return cns(double(src->getValBool()));
}
return nullptr;
}
@@ -1151,7 +1163,7 @@ SSATmp* Simplifier::simplifyConvBoolToDbl(IRInstruction* inst) {
SSATmp* Simplifier::simplifyConvIntToDbl(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
return genDefDbl(double(src->getValInt()));
return cns(double(src->getValInt()));
}
return nullptr;
}
@@ -1168,7 +1180,7 @@ SSATmp* Simplifier::simplifyConvStrToDbl(IRInstruction* inst) {
} else if (ret != KindOfDouble) {
dval = 0.0;
}
return genDefDbl(dval);
return cns(dval);
}
return nullptr;
}
@@ -1177,9 +1189,9 @@ SSATmp* Simplifier::simplifyConvArrToInt(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
if (src->getValArr()->empty()) {
return genDefInt(0);
return cns(0);
}
return genDefInt(1);
return cns(1);
}
return nullptr;
}
@@ -1187,7 +1199,7 @@ SSATmp* Simplifier::simplifyConvArrToInt(IRInstruction* inst) {
SSATmp* Simplifier::simplifyConvBoolToInt(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
return genDefInt(int(src->getValBool()));
return cns(int(src->getValBool()));
}
return nullptr;
}
@@ -1195,7 +1207,7 @@ SSATmp* Simplifier::simplifyConvBoolToInt(IRInstruction* inst) {
SSATmp* Simplifier::simplifyConvDblToInt(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
return genDefInt(toInt64(src->getValDbl()));
return cns(toInt64(src->getValDbl()));
}
return nullptr;
}
@@ -1212,7 +1224,7 @@ SSATmp* Simplifier::simplifyConvStrToInt(IRInstruction* inst) {
} else if (ret != KindOfInt64) {
lval = 0;
}
return genDefInt(lval);
return cns(lval);
}
return nullptr;
}
@@ -1221,9 +1233,9 @@ SSATmp* Simplifier::simplifyConvBoolToStr(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
if (src->getValBool()) {
return m_tb->genDefConst(StringData::GetStaticString("1"));
return cns(StringData::GetStaticString("1"));
}
return m_tb->genDefConst(StringData::GetStaticString(""));
return cns(StringData::GetStaticString(""));
}
return nullptr;
}
@@ -1231,7 +1243,7 @@ SSATmp* Simplifier::simplifyConvBoolToStr(IRInstruction* inst) {
SSATmp* Simplifier::simplifyConvDblToStr(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
return m_tb->genDefConst(
return cns(
StringData::convert_double_helper(src->getValDbl()));
}
return nullptr;
@@ -1240,7 +1252,7 @@ SSATmp* Simplifier::simplifyConvDblToStr(IRInstruction* inst) {
SSATmp* Simplifier::simplifyConvIntToStr(IRInstruction* inst) {
SSATmp* src = inst->getSrc(0);
if (src->isConst()) {
return m_tb->genDefConst(
return cns(
StringData::convert_integer_helper(src->getValInt()));
}
return nullptr;
@@ -1276,11 +1288,11 @@ SSATmp* Simplifier::simplifyLdClsPropAddr(IRInstruction* inst) {
return nullptr;
}
return m_tb->gen(LdClsPropAddrCached,
return gen(LdClsPropAddrCached,
inst->getTaken(),
cls,
propName,
m_tb->genDefConst(clsNameString),
cns(clsNameString),
inst->getSrc(2));
}
@@ -1316,7 +1328,7 @@ SSATmp* Simplifier::simplifyUnbox(IRInstruction* inst) {
if (srcType.isBoxed()) {
srcType = srcType.innerType();
assert(type.equals(srcType));
return m_tb->gen(LdRef, type, inst->getTaken()->getTrace(), src);
return gen(LdRef, type, inst->getTaken()->getTrace(), src);
}
return nullptr;
}
@@ -1362,18 +1374,6 @@ SSATmp* Simplifier::simplifyIncRef(IRInstruction* inst) {
return nullptr;
}
SSATmp* Simplifier::genDefInt(int64_t val) {
return m_tb->genDefConst<int64_t>(val);
}
SSATmp* Simplifier::genDefDbl(double val) {
return m_tb->genDefConst<double>(val);
}
SSATmp* Simplifier::genDefBool(bool val) {
return m_tb->genDefConst<bool>(val);
}
SSATmp* Simplifier::simplifyCondJmp(IRInstruction* inst) {
SSATmp* const src = inst->getSrc(0);
IRInstruction* const srcInst = src->inst();
@@ -1392,7 +1392,7 @@ SSATmp* Simplifier::simplifyCondJmp(IRInstruction* inst) {
val = !val;
}
if (val) {
return m_tb->gen(Jmp_, inst->getTaken());
return gen(Jmp_, inst->getTaken());
}
inst->convertToNop();
return nullptr;
@@ -1400,9 +1400,9 @@ SSATmp* Simplifier::simplifyCondJmp(IRInstruction* inst) {
// Pull negations into the jump.
if (isNotInst(src)) {
return m_tb->gen(inst->op() == JmpZero ? JmpNZero : JmpZero,
inst->getTaken(),
srcInst->getSrc(0));
return gen(inst->op() == JmpZero ? JmpNZero : JmpZero,
inst->getTaken(),
srcInst->getSrc(0));
}
/*
@@ -1418,15 +1418,13 @@ SSATmp* Simplifier::simplifyCondJmp(IRInstruction* inst) {
// If the source is conversion of an int or pointer to boolean, we
// can test the int/ptr value directly.
if (isConvIntOrPtrToBool(srcInst)) {
return m_tb->gen(inst->op(),
inst->getTaken(),
srcInst->getSrc(0));
return gen(inst->op(), inst->getTaken(), srcInst->getSrc(0));
}
// Fuse jumps with query operators.
if (isQueryOp(srcOpcode) && !disableBranchFusion(srcOpcode)) {
SrcRange ssas = srcInst->getSrcs();
return m_tb->gen(
return gen(
queryToJmpOp(
inst->op() == JmpZero
? negateQueryOp(srcOpcode)
+4 -3
Ver Arquivo
@@ -93,14 +93,15 @@ private:
SSATmp* simplifyGetCtxFwdCall(IRInstruction* inst);
SSATmp* simplifySpillStack(IRInstruction* inst);
SSATmp* simplifyCall(IRInstruction* inst);
SSATmp* genDefInt(int64_t val);
SSATmp* genDefDbl(double val);
SSATmp* genDefBool(bool val);
SSATmp* simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2);
SSATmp* simplifyCondJmp(IRInstruction*);
SSATmp* simplifyQueryJmp(IRInstruction*);
SSATmp* simplifyExitOnVarEnv(IRInstruction*);
private: // tracebuilder forwarders
template<class T> SSATmp* cns(T);
template<class... Args> SSATmp* gen(Args&&...);
private:
TraceBuilder* const m_tb;
};
@@ -25,7 +25,7 @@
namespace HPHP { namespace VM { namespace JIT {
#define CTX() m_tb.genDefConst(contextClass())
#define CTX() cns(contextClass())
static const MInstrAttr Warn = MIA_warn;
static const MInstrAttr Unset = MIA_unset;
@@ -692,9 +692,9 @@ void HhbcTranslator::VectorTranslator::emitBaseG() {
SSATmp* gblName = getBase();
m_ht.exceptionBarrier();
m_base = gen(BaseG,
m_tb.genDefConst((TCA)opFunc),
gblName,
genMisPtr());
cns(reinterpret_cast<TCA>(opFunc)),
gblName,
genMisPtr());
}
void HhbcTranslator::VectorTranslator::emitBaseS() {