Ignore:
Timestamp:
Mar 9, 2013, 2:48:09 PM (12 years ago)
Author:
[email protected]
Message:

Unreviewed, rolling out r145299.
http://trac.webkit.org/changeset/145299
https://bugs.webkit.org/show_bug.cgi?id=111928

compilation failure with recent clang
(DFGBackwardsPropagationPhase.cpp:132:35: error: comparison of
constant 10 with expression of type 'bool' is always false)
(Requested by thorton on #webkit).

Patch by Sheriff Bot <[email protected]> on 2013-03-09

Source/JavaScriptCore:

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Target.pri:
  • dfg/DFGArrayMode.cpp:

(JSC::DFG::ArrayMode::refine):

  • dfg/DFGBackwardsPropagationPhase.cpp: Removed.
  • dfg/DFGBackwardsPropagationPhase.h: Removed.
  • dfg/DFGCPSRethreadingPhase.cpp:

(JSC::DFG::CPSRethreadingPhase::run):
(CPSRethreadingPhase):
(JSC::DFG::CPSRethreadingPhase::canonicalizeGetLocalFor):
(JSC::DFG::CPSRethreadingPhase::canonicalizeFlushOrPhantomLocalFor):

  • dfg/DFGDriver.cpp:

(JSC::DFG::compile):

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::dump):

  • dfg/DFGNodeFlags.cpp:

(JSC::DFG::nodeFlagsAsString):
(DFG):

  • dfg/DFGNodeFlags.h:

(DFG):

  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::isNotNegZero):
(PredictionPropagationPhase):
(JSC::DFG::PredictionPropagationPhase::isNotZero):
(JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoForConstant):
(JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwoNonRecursive):
(JSC::DFG::PredictionPropagationPhase::isWithinPowerOfTwo):
(JSC::DFG::PredictionPropagationPhase::propagate):
(JSC::DFG::PredictionPropagationPhase::mergeDefaultFlags):

  • dfg/DFGUnificationPhase.cpp:

(JSC::DFG::UnificationPhase::run):

  • dfg/DFGVariableAccessData.h:

(JSC::DFG::VariableAccessData::VariableAccessData):
(VariableAccessData):

LayoutTests:

  • fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int-expected.txt: Removed.
  • fast/js/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.html: Removed.
  • fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers-expected.txt: Removed.
  • fast/js/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.html: Removed.
  • fast/js/jsc-test-list:
  • fast/js/script-tests/dfg-arith-add-overflow-check-elimination-predicted-but-not-proven-int.js: Removed.
  • fast/js/script-tests/dfg-arith-add-overflow-check-elimination-tower-of-large-numbers.js: Removed.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r145299 r145323  
    107107    }
    108108   
     109    bool isNotNegZero(Node* node)
     110    {
     111        if (!m_graph.isNumberConstant(node))
     112            return false;
     113        double value = m_graph.valueOfNumberConstant(node);
     114        return !value && 1.0 / value < 0.0;
     115    }
     116   
     117    bool isNotZero(Node* node)
     118    {
     119        if (!m_graph.isNumberConstant(node))
     120            return false;
     121        return !!m_graph.valueOfNumberConstant(node);
     122    }
     123   
     124    bool isWithinPowerOfTwoForConstant(Node* node, int power)
     125    {
     126        JSValue immediateValue = node->valueOfJSConstant(codeBlock());
     127        if (!immediateValue.isInt32())
     128            return false;
     129        int32_t intImmediate = immediateValue.asInt32();
     130        return intImmediate > -(1 << power) && intImmediate < (1 << power);
     131    }
     132   
     133    bool isWithinPowerOfTwoNonRecursive(Node* node, int power)
     134    {
     135        if (node->op() != JSConstant)
     136            return false;
     137        return isWithinPowerOfTwoForConstant(node, power);
     138    }
     139   
     140    bool isWithinPowerOfTwo(Node* node, int power)
     141    {
     142        switch (node->op()) {
     143        case JSConstant: {
     144            return isWithinPowerOfTwoForConstant(node, power);
     145        }
     146           
     147        case BitAnd: {
     148            return isWithinPowerOfTwoNonRecursive(node->child1().node(), power)
     149                || isWithinPowerOfTwoNonRecursive(node->child2().node(), power);
     150        }
     151           
     152        case BitRShift:
     153        case BitURShift: {
     154            Node* shiftAmount = node->child2().node();
     155            if (shiftAmount->op() != JSConstant)
     156                return false;
     157            JSValue immediateValue = shiftAmount->valueOfJSConstant(codeBlock());
     158            if (!immediateValue.isInt32())
     159                return false;
     160            return immediateValue > 32 - power;
     161        }
     162           
     163        default:
     164            return false;
     165        }
     166    }
     167
    109168    SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
    110169    {
     
    124183    {
    125184        NodeType op = node->op();
     185        NodeFlags flags = node->flags() & NodeBackPropMask;
    126186
    127187#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
    128         dataLog("   ", Graph::opName(op), " ", m_currentNode, ": ", NodeFlagsDump(node->flags()), " ");
     188        dataLog("   ", Graph::opName(op), " ", m_currentNode, ": ", nodeFlagsAsString(flags), " ");
    129189#endif
    130190       
     
    143203            if (prediction)
    144204                changed |= mergePrediction(prediction);
     205           
     206            // Assume conservatively that a SetLocal implies that the value may flow through a loop,
     207            // and so we would have overflow leading to the program "observing" numbers even if all
     208            // users of the value are doing toInt32. It might be worthwhile to revisit this at some
     209            // point and actually check if the data flow involves loops, but right now I don't think
     210            // we have evidence that this would be beneficial for benchmarks.
     211           
     212            changed |= variableAccessData->mergeFlags((flags & ~NodeUsedAsIntLocally) | NodeUsedAsNumber);
    145213            break;
    146214        }
     
    149217            VariableAccessData* variableAccessData = node->variableAccessData();
    150218            changed |= variableAccessData->predict(node->child1()->prediction());
     219
     220            changed |= node->child1()->mergeFlags(variableAccessData->flags());
     221            break;
     222        }
     223           
     224        case Flush: {
     225            // Make sure that the analysis knows that flushed locals escape.
     226            VariableAccessData* variableAccessData = node->variableAccessData();
     227            changed |= variableAccessData->mergeFlags(NodeUsedAsValue);
    151228            break;
    152229        }
     
    159236        case BitURShift: {
    160237            changed |= setPrediction(SpecInt32);
     238            flags |= NodeUsedAsInt | NodeUsedAsIntLocally;
     239            flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther);
     240            changed |= node->child1()->mergeFlags(flags);
     241            changed |= node->child2()->mergeFlags(flags);
    161242            break;
    162243        }
     
    164245        case ValueToInt32: {
    165246            changed |= setPrediction(SpecInt32);
    166             break;
    167         }
    168            
    169         case ArrayPop:
    170         case ArrayPush:
     247            flags |= NodeUsedAsInt | NodeUsedAsIntLocally;
     248            flags &= ~(NodeUsedAsNumber | NodeNeedsNegZero | NodeUsedAsOther);
     249            changed |= node->child1()->mergeFlags(flags);
     250            break;
     251        }
     252           
     253        case ArrayPop: {
     254            changed |= mergePrediction(node->getHeapPrediction());
     255            changed |= mergeDefaultFlags(node);
     256            break;
     257        }
     258
     259        case ArrayPush: {
     260            changed |= mergePrediction(node->getHeapPrediction());
     261            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     262            changed |= node->child2()->mergeFlags(NodeUsedAsValue);
     263            break;
     264        }
     265
    171266        case RegExpExec:
    172         case RegExpTest:
    173         case GetById:
    174         case GetByIdFlush:
    175         case GetMyArgumentByValSafe:
    176         case GetByOffset:
    177         case Call:
    178         case Construct:
    179         case GetGlobalVar:
    180         case GetScopedVar:
    181         case Resolve:
    182         case ResolveBase:
    183         case ResolveBaseStrictPut:
    184         case ResolveGlobal: {
    185             changed |= setPrediction(node->getHeapPrediction());
     267        case RegExpTest: {
     268            changed |= mergePrediction(node->getHeapPrediction());
     269            changed |= mergeDefaultFlags(node);
    186270            break;
    187271        }
    188272
    189273        case StringCharCodeAt: {
    190             changed |= setPrediction(SpecInt32);
     274            changed |= mergePrediction(SpecInt32);
     275            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     276            changed |= node->child2()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally);
    191277            break;
    192278        }
     
    197283            else
    198284                changed |= mergePrediction(SpecNumber);
     285           
     286            changed |= node->child1()->mergeFlags(flags);
    199287            break;
    200288        }
     
    204292            SpeculatedType right = node->child2()->prediction();
    205293           
     294            AddSpeculationMode mode = DontSpeculateInteger;
     295           
    206296            if (left && right) {
    207297                if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)) {
    208                     if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
     298                    if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
    209299                        changed |= mergePrediction(SpecInt32);
    210300                    else
     
    216306                    changed |= mergePrediction(SpecString | SpecInt32 | SpecDouble);
    217307            }
     308           
     309            if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node()))
     310                flags &= ~NodeNeedsNegZero;
     311            if (node->child1()->hasNumberResult() || node->child2()->hasNumberResult())
     312                flags &= ~NodeUsedAsOther;
     313           
     314            if (mode != SpeculateInteger)
     315                flags |= NodeUsedAsNumber;
     316           
     317            changed |= node->child1()->mergeFlags(flags);
     318            changed |= node->child2()->mergeFlags(flags);
    218319            break;
    219320        }
     
    223324            SpeculatedType right = node->child2()->prediction();
    224325           
     326            AddSpeculationMode mode = DontSpeculateInteger;
     327           
    225328            if (left && right) {
    226                 if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
     329                if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
    227330                    changed |= mergePrediction(SpecInt32);
    228331                else
    229332                    changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
    230333            }
     334           
     335            if (isNotNegZero(node->child1().node()) || isNotNegZero(node->child2().node()))
     336                flags &= ~NodeNeedsNegZero;
     337            flags &= ~NodeUsedAsOther;
     338           
     339            if (mode != SpeculateInteger)
     340                flags |= NodeUsedAsNumber;
     341           
     342            changed |= node->child1()->mergeFlags(flags);
     343            changed |= node->child2()->mergeFlags(flags);
    231344            break;
    232345        }
     
    236349            SpeculatedType right = node->child2()->prediction();
    237350           
     351            AddSpeculationMode mode = DontSpeculateInteger;
     352           
    238353            if (left && right) {
    239                 if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
     354                if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
    240355                    changed |= mergePrediction(SpecInt32);
    241356                else
    242357                    changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
    243358            }
     359
     360            if (isNotZero(node->child1().node()) || isNotZero(node->child2().node()))
     361                flags &= ~NodeNeedsNegZero;
     362            flags &= ~NodeUsedAsOther;
     363           
     364            if (mode != SpeculateInteger)
     365                flags |= NodeUsedAsNumber;
     366           
     367            changed |= node->child1()->mergeFlags(flags);
     368            changed |= node->child2()->mergeFlags(flags);
    244369            break;
    245370        }
     
    252377                    changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
    253378            }
     379
     380            flags &= ~NodeUsedAsOther;
     381
     382            changed |= node->child1()->mergeFlags(flags);
    254383            break;
    255384           
     
    266395                    changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
    267396            }
     397
     398            flags |= NodeUsedAsNumber;
     399            flags &= ~NodeUsedAsOther;
     400
     401            changed |= node->child1()->mergeFlags(flags);
     402            changed |= node->child2()->mergeFlags(flags);
    268403            break;
    269404        }
     
    279414                    changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
    280415            }
     416
     417            // As soon as a multiply happens, we can easily end up in the part
     418            // of the double domain where the point at which you do truncation
     419            // can change the outcome. So, ArithMul always forces its inputs to
     420            // check for overflow. Additionally, it will have to check for overflow
     421            // itself unless we can prove that there is no way for the values
     422            // produced to cause double rounding.
     423           
     424            if (!isWithinPowerOfTwo(node->child1().node(), 22)
     425                && !isWithinPowerOfTwo(node->child2().node(), 22))
     426                flags |= NodeUsedAsNumber;
     427           
     428            changed |= node->mergeFlags(flags);
     429           
     430            flags |= NodeUsedAsNumber | NodeNeedsNegZero;
     431            flags &= ~NodeUsedAsOther;
     432
     433            changed |= node->child1()->mergeFlags(flags);
     434            changed |= node->child2()->mergeFlags(flags);
    281435            break;
    282436        }
     
    293447                    changed |= mergePrediction(SpecDouble);
    294448            }
     449
     450            // As soon as a multiply happens, we can easily end up in the part
     451            // of the double domain where the point at which you do truncation
     452            // can change the outcome. So, ArithDiv always checks for overflow
     453            // no matter what, and always forces its inputs to check as well.
     454           
     455            flags |= NodeUsedAsNumber | NodeNeedsNegZero;
     456            flags &= ~NodeUsedAsOther;
     457
     458            changed |= node->child1()->mergeFlags(flags);
     459            changed |= node->child2()->mergeFlags(flags);
    295460            break;
    296461        }
     
    307472                    changed |= mergePrediction(SpecDouble);
    308473            }
     474           
     475            flags |= NodeUsedAsNumber | NodeNeedsNegZero;
     476            flags &= ~NodeUsedAsOther;
     477
     478            changed |= node->child1()->mergeFlags(flags);
     479            changed |= node->child2()->mergeFlags(flags);
    309480            break;
    310481        }
     
    312483        case ArithSqrt: {
    313484            changed |= setPrediction(SpecDouble);
     485            flags |= NodeUsedAsNumber | NodeNeedsNegZero;
     486            flags &= ~NodeUsedAsOther;
     487            changed |= node->child1()->mergeFlags(flags);
    314488            break;
    315489        }
     
    322496            else
    323497                changed |= mergePrediction(speculatedDoubleTypeForPrediction(child));
     498
     499            changed |= node->child1()->mergeFlags(flags);
    324500            break;
    325501        }
     
    342518        case IsFunction: {
    343519            changed |= setPrediction(SpecBoolean);
     520            changed |= mergeDefaultFlags(node);
    344521            break;
    345522        }
     
    347524        case TypeOf: {
    348525            changed |= setPrediction(SpecString);
    349             break;
    350         }
    351 
     526            changed |= mergeDefaultFlags(node);
     527            break;
     528        }
     529
     530        case GetById: {
     531            changed |= mergePrediction(node->getHeapPrediction());
     532            changed |= mergeDefaultFlags(node);
     533            break;
     534        }
     535           
     536        case GetByIdFlush:
     537            changed |= mergePrediction(node->getHeapPrediction());
     538            changed |= mergeDefaultFlags(node);
     539            break;
     540           
    352541        case GetByVal: {
    353542            if (node->child1()->shouldSpeculateFloat32Array()
     
    356545            else
    357546                changed |= mergePrediction(node->getHeapPrediction());
     547
     548            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     549            changed |= node->child2()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally);
     550            break;
     551        }
     552           
     553        case GetMyArgumentByValSafe: {
     554            changed |= mergePrediction(node->getHeapPrediction());
     555            changed |= node->child1()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally);
    358556            break;
    359557        }
     
    370568        case ReallocatePropertyStorage: {
    371569            changed |= setPrediction(SpecOther);
    372             break;
    373         }
    374 
     570            changed |= mergeDefaultFlags(node);
     571            break;
     572        }
     573
     574        case GetByOffset: {
     575            changed |= mergePrediction(node->getHeapPrediction());
     576            changed |= mergeDefaultFlags(node);
     577            break;
     578        }
     579           
     580        case Call:
     581        case Construct: {
     582            changed |= mergePrediction(node->getHeapPrediction());
     583            for (unsigned childIdx = node->firstChild();
     584                childIdx < node->firstChild() + node->numChildren();
     585                ++childIdx)
     586                changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsValue);
     587            break;
     588        }
     589           
    375590        case ConvertThis: {
    376591            SpeculatedType prediction = node->child1()->prediction();
     
    382597                changed |= mergePrediction(prediction);
    383598            }
     599            changed |= mergeDefaultFlags(node);
     600            break;
     601        }
     602           
     603        case GetGlobalVar: {
     604            changed |= mergePrediction(node->getHeapPrediction());
     605            break;
     606        }
     607           
     608        case PutGlobalVar:
     609        case PutGlobalVarCheck: {
     610            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     611            break;
     612        }
     613           
     614        case GetScopedVar:
     615        case Resolve:
     616        case ResolveBase:
     617        case ResolveBaseStrictPut:
     618        case ResolveGlobal: {
     619            SpeculatedType prediction = node->getHeapPrediction();
     620            changed |= mergePrediction(prediction);
    384621            break;
    385622        }
     
    400637        case NewObject: {
    401638            changed |= setPrediction(SpecFinalObject);
    402             break;
    403         }
    404            
    405         case NewArray:
    406         case NewArrayWithSize:
     639            changed |= mergeDefaultFlags(node);
     640            break;
     641        }
     642           
     643        case NewArray: {
     644            changed |= setPrediction(SpecArray);
     645            for (unsigned childIdx = node->firstChild();
     646                childIdx < node->firstChild() + node->numChildren();
     647                ++childIdx)
     648                changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsValue);
     649            break;
     650        }
     651           
     652        case NewArrayWithSize: {
     653            changed |= setPrediction(SpecArray);
     654            changed |= node->child1()->mergeFlags(NodeUsedAsValue | NodeUsedAsInt | NodeUsedAsIntLocally);
     655            break;
     656        }
     657           
    407658        case NewArrayBuffer: {
    408659            changed |= setPrediction(SpecArray);
     
    410661        }
    411662           
    412         case NewRegexp:
    413         case CreateActivation: {
     663        case NewRegexp: {
    414664            changed |= setPrediction(SpecObjectOther);
    415665            break;
    416666        }
    417667       
    418         case StringCharAt:
     668        case StringCharAt: {
     669            changed |= setPrediction(SpecString);
     670            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     671            changed |= node->child2()->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally);
     672            break;
     673        }
     674           
    419675        case StrCat: {
    420676            changed |= setPrediction(SpecString);
     677            for (unsigned childIdx = node->firstChild();
     678                childIdx < node->firstChild() + node->numChildren();
     679                ++childIdx)
     680                changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther);
    421681            break;
    422682        }
     
    440700                    changed |= mergePrediction(child);
    441701            }
     702            changed |= node->child1()->mergeFlags(flags);
     703            break;
     704        }
     705           
     706        case CreateActivation: {
     707            changed |= setPrediction(SpecObjectOther);
    442708            break;
    443709        }
     
    478744        }
    479745       
     746        case PutByVal:
     747            changed |= m_graph.varArgChild(node, 0)->mergeFlags(NodeUsedAsValue);
     748            changed |= m_graph.varArgChild(node, 1)->mergeFlags(NodeUsedAsNumber | NodeUsedAsOther | NodeUsedAsInt | NodeUsedAsIntLocally);
     749            changed |= m_graph.varArgChild(node, 2)->mergeFlags(NodeUsedAsValue);
     750            break;
     751
     752        case PutScopedVar:
     753            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     754            changed |= node->child3()->mergeFlags(NodeUsedAsValue);
     755            break;
     756           
     757        case Return:
     758        case Throw:
     759            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     760            break;
     761
     762        case PutById:
     763        case PutByIdDirect:
     764            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     765            changed |= node->child2()->mergeFlags(NodeUsedAsValue);
     766            break;
     767
     768        case PutByOffset:
     769            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     770            changed |= node->child3()->mergeFlags(NodeUsedAsValue);
     771            break;
     772           
    480773        case Phi:
    481774            // Phis should not be visible here since we're iterating the all-but-Phi's
     
    484777            break;
    485778
     779        case SetCallee:
     780        case SetMyScope:
     781            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     782            break;
     783           
    486784        case GetScope:
     785            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
    487786            changed |= setPrediction(SpecCellOther);
    488787            break;
     
    490789#ifndef NDEBUG
    491790        // These get ignored because they don't return anything.
    492         case PutByVal:
    493         case PutScopedVar:
    494         case Return:
    495         case Throw:
    496         case PutById:
    497         case PutByIdDirect:
    498         case PutByOffset:
    499         case SetCallee:
    500         case SetMyScope:
    501791        case DFG::Jump:
    502792        case Branch:
     
    520810        case AllocationProfileWatchpoint:
    521811        case Phantom:
    522         case PutGlobalVar:
    523         case PutGlobalVarCheck:
     812            changed |= mergeDefaultFlags(node);
    524813            break;
    525814           
     
    529818        case CountExecution:
    530819        case PhantomLocal:
    531         case Flush:
    532820            break;
    533821           
     
    537825#else
    538826        default:
     827            changed |= mergeDefaultFlags(node);
    539828            break;
    540829#endif
     
    548837    }
    549838       
     839    bool mergeDefaultFlags(Node* node)
     840    {
     841        bool changed = false;
     842        if (node->flags() & NodeHasVarArgs) {
     843            for (unsigned childIdx = node->firstChild();
     844                childIdx < node->firstChild() + node->numChildren();
     845                childIdx++) {
     846                if (!!m_graph.m_varArgChildren[childIdx])
     847                    changed |= m_graph.m_varArgChildren[childIdx]->mergeFlags(NodeUsedAsValue);
     848            }
     849        } else {
     850            if (!node->child1())
     851                return changed;
     852            changed |= node->child1()->mergeFlags(NodeUsedAsValue);
     853            if (!node->child2())
     854                return changed;
     855            changed |= node->child2()->mergeFlags(NodeUsedAsValue);
     856            if (!node->child3())
     857                return changed;
     858            changed |= node->child3()->mergeFlags(NodeUsedAsValue);
     859        }
     860        return changed;
     861    }
     862   
    550863    void propagateForward()
    551864    {
Note: See TracChangeset for help on using the changeset viewer.