diff --git a/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp b/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp index fe9be5990..19afd848c 100644 --- a/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp +++ b/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp @@ -1219,7 +1219,7 @@ void HhbcTranslator::emitEmptyL(int32_t id) { } else { Trace* exitTrace = getExitTrace(); SSATmp* ld = m_tb->genLdLocAsCell(id, exitTrace); - push(m_tb->genNot(m_tb->genConvToBool(ld))); + push(m_tb->genNot(gen(ConvCellToBool, ld))); } } @@ -1300,7 +1300,7 @@ SSATmp* HhbcTranslator::emitJmpCondHelper(int32_t offset, } else { target = getExitTrace(offset); } - SSATmp* boolSrc = m_tb->genConvToBool(src); + auto const boolSrc = gen(ConvCellToBool, src); gen(DecRef, src); return gen(negate ? JmpZero : JmpNZero, target, boolSrc); } @@ -2451,8 +2451,8 @@ void HhbcTranslator::emitCastArray() { } void HhbcTranslator::emitCastBool() { - SSATmp* src = popC(); - push(m_tb->genConvToBool(src)); + auto const src = popC(); + push(gen(ConvCellToBool, src)); gen(DecRef, src); } @@ -2651,7 +2651,7 @@ void HhbcTranslator::emitIsset(const StringData* name, void HhbcTranslator::emitEmptyMem(SSATmp* ptr) { SSATmp* ld = gen(LdMem, Type::Cell, gen(UnboxPtr, ptr), cns(0)); - push(m_tb->genNot(m_tb->genConvToBool(ld))); + push(m_tb->genNot(gen(ConvCellToBool, ld))); } template @@ -2671,7 +2671,7 @@ void HhbcTranslator::emitEmpty(const StringData* name, gen(UnboxPtr, ptr), cns(0) ); - return m_tb->genNot(m_tb->genConvToBool(ld)); + return m_tb->genNot(gen(ConvCellToBool, ld)); }, [&] { // Taken return cns(true); @@ -2794,7 +2794,7 @@ void HhbcTranslator::emitBinaryArith(Opcode opc) { void HhbcTranslator::emitNot() { SSATmp* src = popC(); - push(m_tb->genNot(m_tb->genConvToBool(src))); + push(m_tb->genNot(gen(ConvCellToBool, src))); gen(DecRef, src); } @@ -2878,9 +2878,9 @@ void HhbcTranslator::emitBitNot() { void HhbcTranslator::emitXor() { SSATmp* btr = popC(); SSATmp* btl = popC(); - SSATmp* tr = m_tb->genConvToBool(btr); - SSATmp* tl = m_tb->genConvToBool(btl); - push(m_tb->genConvToBool(gen(OpXor, tl, tr))); + SSATmp* tr = gen(ConvCellToBool, btr); + SSATmp* tl = gen(ConvCellToBool, btl); + push(gen(ConvCellToBool, gen(OpXor, tl, tr))); gen(DecRef, btl); gen(DecRef, btr); } diff --git a/hphp/runtime/vm/translator/hopt/simplifier.cpp b/hphp/runtime/vm/translator/hopt/simplifier.cpp index 92051b0ff..42e667f2f 100644 --- a/hphp/runtime/vm/translator/hopt/simplifier.cpp +++ b/hphp/runtime/vm/translator/hopt/simplifier.cpp @@ -280,6 +280,7 @@ SSATmp* Simplifier::simplify(IRInstruction* inst) { case ConvBoolToStr: return simplifyConvBoolToStr(inst); case ConvDblToStr: return simplifyConvDblToStr(inst); case ConvIntToStr: return simplifyConvIntToStr(inst); + case ConvCellToBool:return simplifyConvCellToBool(inst); case Unbox: return simplifyUnbox(inst); case UnboxPtr: return simplifyUnboxPtr(inst); case IsType: @@ -580,7 +581,7 @@ SSATmp* Simplifier::simplifyNot(SSATmp* src) { case OpXor: { // !!X --> bool(X) if (isNotInst(inst->getSrc(0))) { - return m_tb->genConvToBool(inst->getSrc(0)); + return gen(ConvCellToBool, inst->getSrc(0)); } break; } @@ -1129,7 +1130,7 @@ SSATmp* Simplifier::simplifyCmp(Opcode opName, SSATmp* src1, SSATmp* src2) { } // Nothing fancy to do - perform juggling as normal. - return gen(opName, m_tb->genConvToBool(src1), src2); + return gen(opName, gen(ConvCellToBool, src1), src2); } // From here on, we must be careful of how Type::Obj gets dealt with, @@ -1401,6 +1402,25 @@ SSATmp* Simplifier::simplifyConvIntToStr(IRInstruction* inst) { return nullptr; } +SSATmp* Simplifier::simplifyConvCellToBool(IRInstruction* inst) { + auto const src = inst->getSrc(0); + auto const srcType = src->type(); + + if (srcType.isBool()) return src; + if (srcType.isNull()) return cns(false); + if (srcType.isArray()) return gen(ConvArrToBool, src); + if (srcType.isDbl()) return gen(ConvDblToBool, src); + if (srcType.isInt()) return gen(ConvIntToBool, src); + if (srcType.isString()) return gen(ConvStrToBool, src); + + if (srcType.isObj()) { + // If a value is known to be an object, it is known to be non null. + return cns(true); + } + + return nullptr; +} + SSATmp* Simplifier::simplifyLdClsPropAddr(IRInstruction* inst) { SSATmp* propName = inst->getSrc(1); if (!propName->isConst()) return nullptr; diff --git a/hphp/runtime/vm/translator/hopt/simplifier.h b/hphp/runtime/vm/translator/hopt/simplifier.h index 760cb6445..07dec0cd7 100644 --- a/hphp/runtime/vm/translator/hopt/simplifier.h +++ b/hphp/runtime/vm/translator/hopt/simplifier.h @@ -98,6 +98,7 @@ private: SSATmp* simplifyConvBoolToStr(IRInstruction*); SSATmp* simplifyConvDblToStr(IRInstruction*); SSATmp* simplifyConvIntToStr(IRInstruction*); + SSATmp* simplifyConvCellToBool(IRInstruction*); SSATmp* simplifyUnbox(IRInstruction*); SSATmp* simplifyUnboxPtr(IRInstruction*); SSATmp* simplifyCheckInit(IRInstruction* inst); diff --git a/hphp/runtime/vm/translator/hopt/tracebuilder.cpp b/hphp/runtime/vm/translator/hopt/tracebuilder.cpp index 952bd7edf..c505e92f9 100644 --- a/hphp/runtime/vm/translator/hopt/tracebuilder.cpp +++ b/hphp/runtime/vm/translator/hopt/tracebuilder.cpp @@ -204,7 +204,7 @@ Trace* TraceBuilder::genExitTrace(uint32_t bcOff, SSATmp* TraceBuilder::genNot(SSATmp* src) { assert(src->type() == Type::Bool); - return genConvToBool(gen(OpXor, src, cns(1))); + return gen(ConvCellToBool, gen(OpXor, src, cns(1))); } SSATmp* TraceBuilder::genDefUninit() { @@ -231,28 +231,6 @@ SSATmp* TraceBuilder::genDefNone() { return gen(DefConst, Type::None, ConstData(0)); } -SSATmp* TraceBuilder::genConvToBool(SSATmp* src) { - Type fromType = src->type(); - if (fromType.isBool()) { - return src; - } else if (fromType.isNull()) { - return cns(false); - } else if (fromType.isArray()) { - return gen(ConvArrToBool, src); - } else if (fromType.isDbl()) { - return gen(ConvDblToBool, src); - } else if (fromType.isInt()) { - return gen(ConvIntToBool, src); - } else if (fromType.isString()) { - return gen(ConvStrToBool, src); - } else if (fromType.isObj()) { - // If a value is known to be an object, it is known to be non null. - return cns(true); - } else { - return gen(ConvCellToBool, src); - } -} - SSATmp* TraceBuilder::genBoxLoc(uint32_t id) { SSATmp* prevValue = genLdLoc(id); Type prevType = prevValue->type(); diff --git a/hphp/runtime/vm/translator/hopt/tracebuilder.h b/hphp/runtime/vm/translator/hopt/tracebuilder.h index 67d835beb..be7fc9a71 100644 --- a/hphp/runtime/vm/translator/hopt/tracebuilder.h +++ b/hphp/runtime/vm/translator/hopt/tracebuilder.h @@ -232,8 +232,6 @@ struct TraceBuilder { // TODO(#2058865): we should have a real not opcode SSATmp* genNot(SSATmp* src); - SSATmp* genConvToBool(SSATmp* src); - ////////////////////////////////////////////////////////////////////// // control flow