Changeset 188747 in webkit


Ignore:
Timestamp:
Aug 20, 2015 8:59:33 PM (9 years ago)
Author:
fpizlo@apple.com
Message:

DFG should have a KnownBooleanUse for cases where we are required to know that the child is a boolean and it's not OK to speculate
https://bugs.webkit.org/show_bug.cgi?id=148286

Reviewed by Benjamin Poulain.

This enables us to ensure that the Branch or LogicalNot after an effectful CompareXYZ can
be marked as !mayExit(). I need that for https://bugs.webkit.org/show_bug.cgi?id=145204.

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::observeUseKindOnNode):

  • dfg/DFGSafeToExecute.h:

(JSC::DFG::SafeToExecuteEdge::operator()):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::speculate):

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitBranch):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitBranch):

  • dfg/DFGUseKind.cpp:

(WTF::printInternal):

  • dfg/DFGUseKind.h:

(JSC::DFG::typeFilterFor):
(JSC::DFG::shouldNotHaveTypeCheck):

  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::DFG::LowerDFGToLLVM::boolify):
(JSC::FTL::DFG::LowerDFGToLLVM::lowBoolean):

Location:
trunk/Source/JavaScriptCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r188720 r188747  
     12015-08-20  Filip Pizlo  <fpizlo@apple.com>
     2
     3        DFG should have a KnownBooleanUse for cases where we are required to know that the child is a boolean and it's not OK to speculate
     4        https://bugs.webkit.org/show_bug.cgi?id=148286
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        This enables us to ensure that the Branch or LogicalNot after an effectful CompareXYZ can
     9        be marked as !mayExit(). I need that for https://bugs.webkit.org/show_bug.cgi?id=145204.
     10
     11        * dfg/DFGFixupPhase.cpp:
     12        (JSC::DFG::FixupPhase::fixupNode):
     13        (JSC::DFG::FixupPhase::observeUseKindOnNode):
     14        * dfg/DFGSafeToExecute.h:
     15        (JSC::DFG::SafeToExecuteEdge::operator()):
     16        * dfg/DFGSpeculativeJIT.cpp:
     17        (JSC::DFG::SpeculativeJIT::speculate):
     18        * dfg/DFGSpeculativeJIT.h:
     19        (JSC::DFG::SpeculateBooleanOperand::SpeculateBooleanOperand):
     20        * dfg/DFGSpeculativeJIT32_64.cpp:
     21        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
     22        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
     23        (JSC::DFG::SpeculativeJIT::emitBranch):
     24        * dfg/DFGSpeculativeJIT64.cpp:
     25        (JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
     26        (JSC::DFG::SpeculativeJIT::compileLogicalNot):
     27        (JSC::DFG::SpeculativeJIT::emitBranch):
     28        * dfg/DFGUseKind.cpp:
     29        (WTF::printInternal):
     30        * dfg/DFGUseKind.h:
     31        (JSC::DFG::typeFilterFor):
     32        (JSC::DFG::shouldNotHaveTypeCheck):
     33        * ftl/FTLCapabilities.cpp:
     34        (JSC::FTL::canCompile):
     35        * ftl/FTLLowerDFGToLLVM.cpp:
     36        (JSC::FTL::DFG::LowerDFGToLLVM::boolify):
     37        (JSC::FTL::DFG::LowerDFGToLLVM::lowBoolean):
     38
    1392015-08-20  Filip Pizlo  <fpizlo@apple.com>
    240
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r188624 r188747  
    357357           
    358358        case LogicalNot: {
    359             if (node->child1()->shouldSpeculateBoolean())
    360                 fixEdge<BooleanUse>(node->child1());
    361             else if (node->child1()->shouldSpeculateObjectOrOther())
     359            if (node->child1()->shouldSpeculateBoolean()) {
     360                if (node->child1()->result() == NodeResultBoolean) {
     361                    // This is necessary in case we have a bytecode instruction implemented by:
     362                    //
     363                    // a: CompareEq(...)
     364                    // b: LogicalNot(@a)
     365                    //
     366                    // In that case, CompareEq might have a side-effect. Then, we need to make
     367                    // sure that we know that Branch does not exit.
     368                    fixEdge<KnownBooleanUse>(node->child1());
     369                } else
     370                    fixEdge<BooleanUse>(node->child1());
     371            } else if (node->child1()->shouldSpeculateObjectOrOther())
    362372                fixEdge<ObjectOrOtherUse>(node->child1());
    363373            else if (node->child1()->shouldSpeculateInt32OrBoolean())
     
    820830           
    821831        case Branch: {
    822             if (node->child1()->shouldSpeculateBoolean())
    823                 fixEdge<BooleanUse>(node->child1());
    824             else if (node->child1()->shouldSpeculateObjectOrOther())
     832            if (node->child1()->shouldSpeculateBoolean()) {
     833                if (node->child1()->result() == NodeResultBoolean) {
     834                    // This is necessary in case we have a bytecode instruction implemented by:
     835                    //
     836                    // a: CompareEq(...)
     837                    // b: Branch(@a)
     838                    //
     839                    // In that case, CompareEq might have a side-effect. Then, we need to make
     840                    // sure that we know that Branch does not exit.
     841                    fixEdge<KnownBooleanUse>(node->child1());
     842                } else
     843                    fixEdge<BooleanUse>(node->child1());
     844            } else if (node->child1()->shouldSpeculateObjectOrOther())
    825845                fixEdge<ObjectOrOtherUse>(node->child1());
    826846            else if (node->child1()->shouldSpeculateInt32OrBoolean())
     
    17781798        switch (useKind) {
    17791799        case Int32Use:
     1800        case KnownInt32Use:
    17801801            if (alwaysUnboxSimplePrimitives()
    17811802                || isInt32Speculation(variable->prediction()))
     
    17901811            break;
    17911812        case BooleanUse:
     1813        case KnownBooleanUse:
    17921814            if (alwaysUnboxSimplePrimitives()
    17931815                || isBooleanSpeculation(variable->prediction()))
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r188624 r188747  
    7373        case KnownInt32Use:
    7474            if (m_state.forNode(edge).m_type & ~SpecInt32)
     75                m_result = false;
     76            return;
     77
     78        case KnownBooleanUse:
     79            if (m_state.forNode(edge).m_type & ~SpecBoolean)
    7580                m_result = false;
    7681            return;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r188624 r188747  
    59095909        speculateBoolean(edge);
    59105910        break;
     5911    case KnownBooleanUse:
     5912        ASSERT(!needsTypeCheck(edge, SpecBoolean));
     5913        break;
    59115914    case CellUse:
    59125915        speculateCell(edge);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r188624 r188747  
    32463246    {
    32473247        ASSERT(m_jit);
    3248         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
     3248        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse || edge.useKind() == KnownBooleanUse);
    32493249        if (jit->isFilled(node()))
    32503250            gpr();
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r188649 r188747  
    10341034    AbstractValue& value = m_state.forNode(edge);
    10351035    SpeculatedType type = value.m_type;
     1036    ASSERT(edge.useKind() != KnownBooleanUse || !(value.m_type & ~SpecBoolean));
    10361037
    10371038    m_interpreter.filter(value, SpecBoolean);
     
    14641465{
    14651466    switch (node->child1().useKind()) {
    1466     case BooleanUse: {
     1467    case BooleanUse:
     1468    case KnownBooleanUse: {
    14671469        SpeculateBooleanOperand value(this, node->child1());
    14681470        GPRTemporary result(this, Reuse, value);
     
    15831585
    15841586    switch (node->child1().useKind()) {
    1585     case BooleanUse: {
     1587    case BooleanUse:
     1588    case KnownBooleanUse: {
    15861589        SpeculateBooleanOperand value(this, node->child1());
    15871590        MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r188649 r188747  
    11401140    AbstractValue& value = m_state.forNode(edge);
    11411141    SpeculatedType type = value.m_type;
     1142    ASSERT(edge.useKind() != KnownBooleanUse || !(value.m_type & ~SpecBoolean));
    11421143
    11431144    m_interpreter.filter(value, SpecBoolean);
     
    16181619    }
    16191620   
    1620     case BooleanUse: {
     1621    case BooleanUse:
     1622    case KnownBooleanUse: {
    16211623        if (!needsTypeCheck(node->child1(), SpecBoolean)) {
    16221624            SpeculateBooleanOperand value(this, node->child1());
     
    17701772
    17711773    case UntypedUse:
    1772     case BooleanUse: {
     1774    case BooleanUse:
     1775    case KnownBooleanUse: {
    17731776        JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
    17741777        GPRReg valueGPR = value.gpr();
    17751778       
    1776         if (node->child1().useKind() == BooleanUse) {
     1779        if (node->child1().useKind() == BooleanUse || node->child1().useKind() == KnownBooleanUse) {
    17771780            if (!needsTypeCheck(node->child1(), SpecBoolean)) {
    17781781                MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp

    r188299 r188747  
    7171        out.print("Boolean");
    7272        return;
     73    case KnownBooleanUse:
     74        out.print("KnownBoolean");
     75        return;
    7376    case CellUse:
    7477        out.print("Cell");
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.h

    r188299 r188747  
    4949    RealNumberUse,
    5050    BooleanUse,
     51    KnownBooleanUse,
    5152    CellUse,
    5253    KnownCellUse,
     
    102103        return SpecInt52AsDouble;
    103104    case BooleanUse:
     105    case KnownBooleanUse:
    104106        return SpecBoolean;
    105107    case CellUse:
     
    146148    case KnownCellUse:
    147149    case KnownStringUse:
     150    case KnownBooleanUse:
    148151    case Int52RepUse:
    149152    case DoubleRepUse:
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r188649 r188747  
    413413                case DoubleRepRealUse:
    414414                case BooleanUse:
     415                case KnownBooleanUse:
    415416                case CellUse:
    416417                case KnownCellUse:
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r188649 r188747  
    61316131        switch (edge.useKind()) {
    61326132        case BooleanUse:
     6133        case KnownBooleanUse:
    61336134            return lowBoolean(edge);
    61346135        case Int32Use:
     
    71217122    LValue lowBoolean(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
    71227123    {
    7123         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
     7124        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse || edge.useKind() == KnownBooleanUse);
    71247125       
    71257126        if (edge->hasConstant()) {
Note: See TracChangeset for help on using the changeset viewer.