From 3d2109011832afdc695110abc1555ce74473b25f Mon Sep 17 00:00:00 2001 From: Eric Caruso Date: Fri, 28 Jun 2013 18:02:21 -0700 Subject: [PATCH] Move type dispatch of ConvCellToDbl to simplifier As D867556, but with doubles. --- hphp/runtime/base/tv_helpers.cpp | 28 ++++++++++++++++++++++ hphp/runtime/base/tv_helpers.h | 1 + hphp/runtime/vm/jit/hhbctranslator.cpp | 21 ++-------------- hphp/runtime/vm/jit/ir.h | 6 ++--- hphp/runtime/vm/jit/simplifier.cpp | 16 +++++++++++++ hphp/runtime/vm/jit/simplifier.h | 1 + hphp/runtime/vm/jit/translator-runtime.cpp | 14 +---------- 7 files changed, 52 insertions(+), 35 deletions(-) diff --git a/hphp/runtime/base/tv_helpers.cpp b/hphp/runtime/base/tv_helpers.cpp index ea0756dc0..080bc558f 100644 --- a/hphp/runtime/base/tv_helpers.cpp +++ b/hphp/runtime/base/tv_helpers.cpp @@ -198,6 +198,34 @@ void tvCastToDoubleInPlace(TypedValue* tv) { tv->m_type = KindOfDouble; } +double tvCastToDouble(TypedValue* tv) { + if (tv->m_type == KindOfRef) { + tv = tv->m_data.pref->tv(); + } + + switch(tv->m_type) { + case KindOfUninit: + case KindOfNull: + return 0; + case KindOfBoolean: + assert(tv->m_data.num == 0LL || tv->m_data.num == 1LL); + // Fall through + case KindOfInt64: + return (double)(tv->m_data.num); + case KindOfDouble: + return tv->m_data.dbl; + case KindOfStaticString: + case KindOfString: + return tv->m_data.pstr->toDouble(); + case KindOfArray: + return tv->m_data.parr->empty() ? 0.0 : 1.0; + case KindOfObject: + return tv->m_data.pobj ? tv->m_data.pobj->o_toDouble() : 0.0; + default: + not_reached(); + } +} + const StaticString s_1("1"), s_Array("Array"); diff --git a/hphp/runtime/base/tv_helpers.h b/hphp/runtime/base/tv_helpers.h index 116aefb81..7a82c0530 100644 --- a/hphp/runtime/base/tv_helpers.h +++ b/hphp/runtime/base/tv_helpers.h @@ -456,6 +456,7 @@ void tvCastToBooleanInPlace(TypedValue* tv); void tvCastToInt64InPlace(TypedValue* tv, int base = 10); int64_t tvCastToInt64(TypedValue* tv, int base = 10); void tvCastToDoubleInPlace(TypedValue* tv); +double tvCastToDouble(TypedValue* tv); void tvCastToStringInPlace(TypedValue* tv); StringData* tvCastToString(TypedValue* tv); void tvCastToArrayInPlace(TypedValue* tv); diff --git a/hphp/runtime/vm/jit/hhbctranslator.cpp b/hphp/runtime/vm/jit/hhbctranslator.cpp index 0c65b7d30..f592b21d0 100644 --- a/hphp/runtime/vm/jit/hhbctranslator.cpp +++ b/hphp/runtime/vm/jit/hhbctranslator.cpp @@ -2852,25 +2852,8 @@ void HhbcTranslator::emitCastBool() { void HhbcTranslator::emitCastDouble() { IRTrace* catchTrace = getCatchTrace(); SSATmp* src = popC(); - Type fromType = src->type(); - if (fromType.isDbl()) { - push(src); - } else if (fromType.isNull()) { - push(cns(0.0)); - } else if (fromType.isArray()) { - push(gen(ConvArrToDbl, src)); - gen(DecRef, src); - } else if (fromType.isBool()) { - push(gen(ConvBoolToDbl, src)); - } else if (fromType.isInt()) { - push(gen(ConvIntToDbl, src)); - } else if (fromType.isString()) { - push(gen(ConvStrToDbl, src)); - } else if (fromType.isObj()) { - push(gen(ConvObjToDbl, catchTrace, src)); - } else { - push(gen(ConvCellToDbl, catchTrace, src)); - } + push(gen(ConvCellToDbl, catchTrace, src)); + gen(DecRef, src); } void HhbcTranslator::emitCastInt() { diff --git a/hphp/runtime/vm/jit/ir.h b/hphp/runtime/vm/jit/ir.h index 52a32df52..bfbead103 100644 --- a/hphp/runtime/vm/jit/ir.h +++ b/hphp/runtime/vm/jit/ir.h @@ -235,9 +235,9 @@ O(ConvCellToBool, D(Bool), S(Cell), N) \ O(ConvArrToDbl, D(Dbl), S(Arr), C|N) \ O(ConvBoolToDbl, D(Dbl), S(Bool), C) \ O(ConvIntToDbl, D(Dbl), S(Int), C) \ -O(ConvObjToDbl, D(Dbl), S(Obj), N|Er|CRc|K) \ -O(ConvStrToDbl, D(Dbl), S(Str), N|CRc|K) \ -O(ConvCellToDbl, D(Dbl), S(Cell), N|Er|CRc|K) \ +O(ConvObjToDbl, D(Dbl), S(Obj), N|Er|K) \ +O(ConvStrToDbl, D(Dbl), S(Str), N|K) \ +O(ConvCellToDbl, D(Dbl), S(Cell), N|Er|K) \ \ O(ConvArrToInt, D(Int), S(Arr), C|N) \ O(ConvBoolToInt, D(Int), S(Bool), C) \ diff --git a/hphp/runtime/vm/jit/simplifier.cpp b/hphp/runtime/vm/jit/simplifier.cpp index 07623cd4d..062bf6488 100644 --- a/hphp/runtime/vm/jit/simplifier.cpp +++ b/hphp/runtime/vm/jit/simplifier.cpp @@ -318,6 +318,7 @@ SSATmp* Simplifier::simplify(IRInstruction* inst) { case ConvIntToStr: return simplifyConvIntToStr(inst); case ConvCellToBool:return simplifyConvCellToBool(inst); case ConvCellToInt: return simplifyConvCellToInt(inst); + case ConvCellToDbl: return simplifyConvCellToDbl(inst); case Unbox: return simplifyUnbox(inst); case UnboxPtr: return simplifyUnboxPtr(inst); case IsType: @@ -1475,6 +1476,21 @@ SSATmp* Simplifier::simplifyConvCellToInt(IRInstruction* inst) { return nullptr; } +SSATmp* Simplifier::simplifyConvCellToDbl(IRInstruction* inst) { + auto const src = inst->src(0); + auto const srcType = src->type(); + + if (srcType.isDbl()) return src; + if (srcType.isNull()) return cns(0.0); + if (srcType.isArray()) return gen(ConvArrToDbl, src); + if (srcType.isBool()) return gen(ConvBoolToDbl, src); + if (srcType.isInt()) return gen(ConvIntToDbl, src); + if (srcType.isString()) return gen(ConvStrToDbl, src); + if (srcType.isObj()) return gen(ConvObjToDbl, inst->taken(), src); + + return nullptr; +} + SSATmp* Simplifier::simplifyLdClsPropAddr(IRInstruction* inst) { SSATmp* propName = inst->src(1); if (!propName->isConst()) return nullptr; diff --git a/hphp/runtime/vm/jit/simplifier.h b/hphp/runtime/vm/jit/simplifier.h index fce336365..697ce23d5 100644 --- a/hphp/runtime/vm/jit/simplifier.h +++ b/hphp/runtime/vm/jit/simplifier.h @@ -102,6 +102,7 @@ private: SSATmp* simplifyConvIntToStr(IRInstruction*); SSATmp* simplifyConvCellToBool(IRInstruction*); SSATmp* simplifyConvCellToInt(IRInstruction*); + SSATmp* simplifyConvCellToDbl(IRInstruction*); SSATmp* simplifyUnbox(IRInstruction*); SSATmp* simplifyUnboxPtr(IRInstruction*); SSATmp* simplifyCheckInit(IRInstruction* inst); diff --git a/hphp/runtime/vm/jit/translator-runtime.cpp b/hphp/runtime/vm/jit/translator-runtime.cpp index 87678fc9d..6b9663f36 100644 --- a/hphp/runtime/vm/jit/translator-runtime.cpp +++ b/hphp/runtime/vm/jit/translator-runtime.cpp @@ -140,19 +140,7 @@ int64_t convStrToDblHelper(const StringData* s) { } int64_t convCellToDblHelper(TypedValue tv) { - try { - tvCastToDoubleInPlace(&tv); // consumes a ref on counted values - // but not if an exception happens. (REVIEW) - return tv.m_data.num; - } catch (...) { - // spill tv back to stack. unwinder - // will take care of decreffing it. - VMRegAnchor _; - TypedValue* spillSlot = (TypedValue *)vmsp(); - spillSlot->m_data.num = tv.m_data.num; - spillSlot->m_type = tv.m_type; - throw; - } + return reinterpretDblAsInt(tvCastToDouble(&tv)); } int64_t convArrToIntHelper(ArrayData* a) {