Ignore:
Timestamp:
Apr 15, 2014, 1:26:16 PM (11 years ago)
Author:
[email protected]
Message:

DFG IR should keep the data flow of doubles and int52's separate from the data flow of JSValue's
https://bugs.webkit.org/show_bug.cgi?id=131423

Reviewed by Geoffrey Garen.

This introduces more static typing into DFG IR. Previously we just had the notion of
JSValues and Storage. This was weird because doubles weren't always convertible to
JSValues, and Int52s weren't always convertible to either doubles or JSValues. We would
sort of insert explicit conversion nodes just for the places where we knew that an
implicit conversion wouldn't have been possible -- but there was no hard and fast rule so
we'd get bugs from forgetting to do the right conversion.

This patch introduces a hard and fast rule: doubles can never be implicitly converted to
anything but doubles, and likewise Int52's can never be implicitly converted. Conversion
nodes are used for all of the conversions. Int52Rep, DoubleRep, and ValueRep are the
conversions. They are like Identity but return the same value using a different
representation. Likewise, constants may now be represented using either JSConstant,
Int52Constant, or DoubleConstant. UseKinds have been adjusted accordingly, as well.
Int52RepUse and DoubleRepUse are node uses that mean "the node must be of Int52 (or
Double) type". They don't imply checks. There is also DoubleRepRealUse, which means that
we speculate DoubleReal and expect Double representation.

In addition to simplifying a bunch of rules in the IR and making the IR more verifiable,
this also makes it easier to introduce optimizations in the future. It's now possible for
AI to model when/how conversion take place. For example if doing a conversion results in
NaN sanitization, then AI can model this and can allow us to sink sanitizations. That's
what https://bugs.webkit.org/show_bug.cgi?id=131419 will be all about.

This was a big change, so I had to do some interesting things, like finally get rid of
the DFG's weird variadic template macro hacks and use real C++11 variadic templates. Also
the ByteCodeParser no longer emits Identity nodes since that was always pointless.

No performance change because this mostly just rationalizes preexisting behavior.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/MacroAssemblerX86.h:
  • bytecode/CodeBlock.cpp:
  • bytecode/CodeBlock.h:
  • dfg/DFGAbstractInterpreter.h:

(JSC::DFG::AbstractInterpreter::setBuiltInConstant):
(JSC::DFG::AbstractInterpreter::setConstant):

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGAbstractValue.cpp:

(JSC::DFG::AbstractValue::set):
(JSC::DFG::AbstractValue::fixTypeForRepresentation):
(JSC::DFG::AbstractValue::checkConsistency):

  • dfg/DFGAbstractValue.h:
  • dfg/DFGBackwardsPropagationPhase.cpp:

(JSC::DFG::BackwardsPropagationPhase::propagate):

  • dfg/DFGBasicBlock.h:
  • dfg/DFGBasicBlockInlines.h:

(JSC::DFG::BasicBlock::appendNode):
(JSC::DFG::BasicBlock::appendNonTerminal):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • dfg/DFGCSEPhase.cpp:

(JSC::DFG::CSEPhase::constantCSE):
(JSC::DFG::CSEPhase::performNodeCSE):
(JSC::DFG::CSEPhase::int32ToDoubleCSE): Deleted.

  • dfg/DFGCapabilities.h:
  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGConstantFoldingPhase.cpp:

(JSC::DFG::ConstantFoldingPhase::foldConstants):

  • dfg/DFGDCEPhase.cpp:

(JSC::DFG::DCEPhase::fixupBlock):

  • dfg/DFGEdge.h:

(JSC::DFG::Edge::willNotHaveCheck):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::run):
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::fixupGetAndSetLocalsInBlock):
(JSC::DFG::FixupPhase::observeUseKindOnNode):
(JSC::DFG::FixupPhase::fixIntEdge):
(JSC::DFG::FixupPhase::attemptToMakeIntegerAdd):
(JSC::DFG::FixupPhase::injectTypeConversionsInBlock):
(JSC::DFG::FixupPhase::tryToRelaxRepresentation):
(JSC::DFG::FixupPhase::fixEdgeRepresentation):
(JSC::DFG::FixupPhase::injectTypeConversionsForEdge):
(JSC::DFG::FixupPhase::addRequiredPhantom):
(JSC::DFG::FixupPhase::addPhantomsIfNecessary):
(JSC::DFG::FixupPhase::clearPhantomsAtEnd):
(JSC::DFG::FixupPhase::fixupSetLocalsInBlock): Deleted.

  • dfg/DFGFlushFormat.h:

(JSC::DFG::resultFor):
(JSC::DFG::useKindFor):

  • dfg/DFGGraph.cpp:

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

  • dfg/DFGGraph.h:

(JSC::DFG::Graph::addNode):

  • dfg/DFGInPlaceAbstractState.cpp:

(JSC::DFG::InPlaceAbstractState::initialize):

  • dfg/DFGInsertionSet.h:

(JSC::DFG::InsertionSet::insertNode):
(JSC::DFG::InsertionSet::insertConstant):
(JSC::DFG::InsertionSet::insertConstantForUse):

  • dfg/DFGIntegerCheckCombiningPhase.cpp:

(JSC::DFG::IntegerCheckCombiningPhase::insertAdd):
(JSC::DFG::IntegerCheckCombiningPhase::insertMustAdd):

  • dfg/DFGNode.cpp:

(JSC::DFG::Node::convertToIdentity):
(WTF::printInternal):

  • dfg/DFGNode.h:

(JSC::DFG::Node::Node):
(JSC::DFG::Node::setResult):
(JSC::DFG::Node::result):
(JSC::DFG::Node::isConstant):
(JSC::DFG::Node::hasConstant):
(JSC::DFG::Node::convertToConstant):
(JSC::DFG::Node::valueOfJSConstant):
(JSC::DFG::Node::hasResult):
(JSC::DFG::Node::hasInt32Result):
(JSC::DFG::Node::hasInt52Result):
(JSC::DFG::Node::hasNumberResult):
(JSC::DFG::Node::hasDoubleResult):
(JSC::DFG::Node::hasJSResult):
(JSC::DFG::Node::hasBooleanResult):
(JSC::DFG::Node::hasStorageResult):
(JSC::DFG::Node::defaultUseKind):
(JSC::DFG::Node::defaultEdge):
(JSC::DFG::Node::convertToIdentity): Deleted.

  • dfg/DFGNodeFlags.cpp:

(JSC::DFG::dumpNodeFlags):

  • dfg/DFGNodeFlags.h:

(JSC::DFG::canonicalResultRepresentation):

  • dfg/DFGNodeType.h:
  • dfg/DFGOSRExitCompiler32_64.cpp:

(JSC::DFG::OSRExitCompiler::compileExit):

  • dfg/DFGOSRExitCompiler64.cpp:

(JSC::DFG::OSRExitCompiler::compileExit):

  • dfg/DFGPredictionPropagationPhase.cpp:

(JSC::DFG::PredictionPropagationPhase::propagate):

  • dfg/DFGResurrectionForValidationPhase.cpp:

(JSC::DFG::ResurrectionForValidationPhase::run):

  • dfg/DFGSSAConversionPhase.cpp:

(JSC::DFG::SSAConversionPhase::run):

  • dfg/DFGSafeToExecute.h:

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

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):
(JSC::DFG::SpeculativeJIT::silentSavePlanForFPR):
(JSC::DFG::SpeculativeJIT::silentFill):
(JSC::DFG::JSValueRegsTemporary::JSValueRegsTemporary):
(JSC::DFG::JSValueRegsTemporary::~JSValueRegsTemporary):
(JSC::DFG::JSValueRegsTemporary::regs):
(JSC::DFG::SpeculativeJIT::compilePeepHoleBranch):
(JSC::DFG::SpeculativeJIT::checkGeneratedTypeForToInt32):
(JSC::DFG::SpeculativeJIT::compileValueToInt32):
(JSC::DFG::SpeculativeJIT::compileDoubleRep):
(JSC::DFG::SpeculativeJIT::compileValueRep):
(JSC::DFG::SpeculativeJIT::compilePutByValForIntTypedArray):
(JSC::DFG::SpeculativeJIT::compileGetByValOnFloatTypedArray):
(JSC::DFG::SpeculativeJIT::compileAdd):
(JSC::DFG::SpeculativeJIT::compileArithSub):
(JSC::DFG::SpeculativeJIT::compileArithNegate):
(JSC::DFG::SpeculativeJIT::compileArithMul):
(JSC::DFG::SpeculativeJIT::compileArithDiv):
(JSC::DFG::SpeculativeJIT::compileArithMod):
(JSC::DFG::SpeculativeJIT::compare):
(JSC::DFG::SpeculativeJIT::compileStrictEq):
(JSC::DFG::SpeculativeJIT::speculateNumber):
(JSC::DFG::SpeculativeJIT::speculateDoubleReal):
(JSC::DFG::SpeculativeJIT::speculate):
(JSC::DFG::SpeculativeJIT::compileInt32ToDouble): Deleted.
(JSC::DFG::SpeculativeJIT::speculateMachineInt): Deleted.
(JSC::DFG::SpeculativeJIT::speculateRealNumber): Deleted.

  • dfg/DFGSpeculativeJIT.h:

(JSC::DFG::SpeculativeJIT::allocate):
(JSC::DFG::SpeculativeJIT::use):
(JSC::DFG::SpeculativeJIT::boxDouble):
(JSC::DFG::SpeculativeJIT::spill):
(JSC::DFG::SpeculativeJIT::jsValueResult):
(JSC::DFG::SpeculateInt52Operand::SpeculateInt52Operand):
(JSC::DFG::SpeculateStrictInt52Operand::SpeculateStrictInt52Operand):
(JSC::DFG::SpeculateWhicheverInt52Operand::SpeculateWhicheverInt52Operand):
(JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::convertToDouble): Deleted.

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt32Internal):
(JSC::DFG::SpeculativeJIT::fillSpeculateInt52):
(JSC::DFG::SpeculativeJIT::fillSpeculateDouble):
(JSC::DFG::SpeculativeJIT::fillSpeculateCell):
(JSC::DFG::SpeculativeJIT::fillSpeculateBoolean):
(JSC::DFG::SpeculativeJIT::compileLogicalNot):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):
(JSC::DFG::SpeculativeJIT::convertToDouble): Deleted.

  • dfg/DFGStrengthReductionPhase.cpp:

(JSC::DFG::StrengthReductionPhase::handleNode):

  • dfg/DFGUseKind.cpp:

(WTF::printInternal):

  • dfg/DFGUseKind.h:

(JSC::DFG::typeFilterFor):
(JSC::DFG::shouldNotHaveTypeCheck):
(JSC::DFG::mayHaveTypeCheck):
(JSC::DFG::isNumerical):
(JSC::DFG::isDouble):
(JSC::DFG::isCell):
(JSC::DFG::usesStructure):
(JSC::DFG::useKindForResult):

  • dfg/DFGValidate.cpp:

(JSC::DFG::Validate::validate):

  • dfg/DFGVariadicFunction.h: Removed.
  • ftl/FTLCapabilities.cpp:

(JSC::FTL::canCompile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::createPhiVariables):
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileUpsilon):
(JSC::FTL::LowerDFGToLLVM::compilePhi):
(JSC::FTL::LowerDFGToLLVM::compileDoubleConstant):
(JSC::FTL::LowerDFGToLLVM::compileInt52Constant):
(JSC::FTL::LowerDFGToLLVM::compileWeakJSConstant):
(JSC::FTL::LowerDFGToLLVM::compileDoubleRep):
(JSC::FTL::LowerDFGToLLVM::compileValueRep):
(JSC::FTL::LowerDFGToLLVM::compileInt52Rep):
(JSC::FTL::LowerDFGToLLVM::compileValueToInt32):
(JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
(JSC::FTL::LowerDFGToLLVM::compileArithMul):
(JSC::FTL::LowerDFGToLLVM::compileArithDiv):
(JSC::FTL::LowerDFGToLLVM::compileArithMod):
(JSC::FTL::LowerDFGToLLVM::compileArithMinOrMax):
(JSC::FTL::LowerDFGToLLVM::compileArithAbs):
(JSC::FTL::LowerDFGToLLVM::compileArithNegate):
(JSC::FTL::LowerDFGToLLVM::compilePutByVal):
(JSC::FTL::LowerDFGToLLVM::compileCompareEq):
(JSC::FTL::LowerDFGToLLVM::compileCompareStrictEq):
(JSC::FTL::LowerDFGToLLVM::compare):
(JSC::FTL::LowerDFGToLLVM::boolify):
(JSC::FTL::LowerDFGToLLVM::lowInt52):
(JSC::FTL::LowerDFGToLLVM::lowStrictInt52):
(JSC::FTL::LowerDFGToLLVM::lowWhicheverInt52):
(JSC::FTL::LowerDFGToLLVM::lowDouble):
(JSC::FTL::LowerDFGToLLVM::lowJSValue):
(JSC::FTL::LowerDFGToLLVM::strictInt52ToDouble):
(JSC::FTL::LowerDFGToLLVM::jsValueToDouble):
(JSC::FTL::LowerDFGToLLVM::speculate):
(JSC::FTL::LowerDFGToLLVM::speculateNumber):
(JSC::FTL::LowerDFGToLLVM::speculateDoubleReal):
(JSC::FTL::LowerDFGToLLVM::compileInt52ToValue): Deleted.
(JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble): Deleted.
(JSC::FTL::LowerDFGToLLVM::setInt52WithStrictValue): Deleted.
(JSC::FTL::LowerDFGToLLVM::speculateRealNumber): Deleted.
(JSC::FTL::LowerDFGToLLVM::speculateMachineInt): Deleted.

  • ftl/FTLValueFormat.cpp:

(JSC::FTL::reboxAccordingToFormat):

  • jit/AssemblyHelpers.cpp:

(JSC::AssemblyHelpers::sanitizeDouble):

  • jit/AssemblyHelpers.h:

(JSC::AssemblyHelpers::boxDouble):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

    r167189 r167325  
    187187                LType type;
    188188                switch (node->flags() & NodeResultMask) {
    189                 case NodeResultNumber:
     189                case NodeResultDouble:
    190190                    type = m_out.doubleType;
    191191                    break;
     
    283283        case JSConstant:
    284284            break;
     285        case DoubleConstant:
     286            compileDoubleConstant();
     287            break;
     288        case Int52Constant:
     289            compileInt52Constant();
     290            break;
    285291        case WeakJSConstant:
    286292            compileWeakJSConstant();
     
    288294        case PhantomArguments:
    289295            compilePhantomArguments();
     296            break;
     297        case DoubleRep:
     298            compileDoubleRep();
     299            break;
     300        case ValueRep:
     301            compileValueRep();
     302            break;
     303        case Int52Rep:
     304            compileInt52Rep();
     305            break;
     306        case ValueToInt32:
     307            compileValueToInt32();
    290308            break;
    291309        case GetArgument:
     
    378396        case UInt32ToNumber:
    379397            compileUInt32ToNumber();
    380             break;
    381         case Int32ToDouble:
    382             compileInt32ToDouble();
    383398            break;
    384399        case CheckStructure:
     
    569584        case InvalidationPoint:
    570585            compileInvalidationPoint();
    571             break;
    572         case ValueToInt32:
    573             compileValueToInt32();
    574             break;
    575         case Int52ToValue:
    576             compileInt52ToValue();
    577586            break;
    578587        case CheckArgumentsNotCreated:
     
    634643    }
    635644
     645    void compileUpsilon()
     646    {
     647        LValue destination = m_phis.get(m_node->phi());
     648       
     649        switch (m_node->child1().useKind()) {
     650        case DoubleRepUse:
     651            m_out.set(lowDouble(m_node->child1()), destination);
     652            break;
     653        case Int32Use:
     654            m_out.set(lowInt32(m_node->child1()), destination);
     655            break;
     656        case Int52RepUse:
     657            m_out.set(lowInt52(m_node->child1()), destination);
     658            break;
     659        case BooleanUse:
     660            m_out.set(lowBoolean(m_node->child1()), destination);
     661            break;
     662        case CellUse:
     663            m_out.set(lowCell(m_node->child1()), destination);
     664            break;
     665        case UntypedUse:
     666            m_out.set(lowJSValue(m_node->child1()), destination);
     667            break;
     668        default:
     669            RELEASE_ASSERT_NOT_REACHED();
     670            break;
     671        }
     672    }
     673   
     674    void compilePhi()
     675    {
     676        LValue source = m_phis.get(m_node);
     677       
     678        switch (m_node->flags() & NodeResultMask) {
     679        case NodeResultDouble:
     680            setDouble(m_out.get(source));
     681            break;
     682        case NodeResultInt32:
     683            setInt32(m_out.get(source));
     684            break;
     685        case NodeResultInt52:
     686            setInt52(m_out.get(source));
     687            break;
     688        case NodeResultBoolean:
     689            setBoolean(m_out.get(source));
     690            break;
     691        case NodeResultJS:
     692            setJSValue(m_out.get(source));
     693            break;
     694        default:
     695            RELEASE_ASSERT_NOT_REACHED();
     696            break;
     697        }
     698    }
     699   
     700    void compileDoubleConstant()
     701    {
     702        setDouble(m_out.constDouble(m_graph.valueOfNumberConstant(m_node)));
     703    }
     704   
     705    void compileInt52Constant()
     706    {
     707        int64_t value = m_graph.valueOfJSConstant(m_node).asMachineInt();
     708       
     709        setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
     710        setStrictInt52(m_out.constInt64(value));
     711    }
     712
     713    void compileWeakJSConstant()
     714    {
     715        setJSValue(weakPointer(m_node->weakConstant()));
     716    }
     717   
     718    void compilePhantomArguments()
     719    {
     720        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
     721    }
     722   
     723    void compileDoubleRep()
     724    {
     725        switch (m_node->child1().useKind()) {
     726        case NumberUse: {
     727            LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
     728            setDouble(jsValueToDouble(m_node->child1(), value));
     729            return;
     730        }
     731           
     732        case Int52RepUse: {
     733            setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
     734            return;
     735        }
     736           
     737        default:
     738            RELEASE_ASSERT_NOT_REACHED();
     739        }
     740    }
     741   
     742    void compileValueRep()
     743    {
     744        switch (m_node->child1().useKind()) {
     745        case DoubleRepUse: {
     746            setJSValue(boxDouble(lowDouble(m_node->child1())));
     747            return;
     748        }
     749           
     750        case Int52RepUse: {
     751            setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
     752            return;
     753        }
     754           
     755        default:
     756            RELEASE_ASSERT_NOT_REACHED();
     757        }
     758    }
     759   
     760    void compileInt52Rep()
     761    {
     762        setStrictInt52(m_out.signExt(lowInt32(m_node->child1()), m_out.int64));
     763    }
     764   
    636765    void compileValueToInt32()
    637766    {
     
    641770            break;
    642771           
    643         case MachineIntUse:
     772        case Int52RepUse:
    644773            setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
     774            break;
     775           
     776        case DoubleRepUse:
     777            setInt32(doubleToInt32(lowDouble(m_node->child1())));
    645778            break;
    646779           
     
    659792            }
    660793           
    661             value = m_doubleValues.get(m_node->child1().node());
    662             if (isValid(value)) {
    663                 setInt32(doubleToInt32(value.value()));
    664                 break;
    665             }
    666            
    667794            // We'll basically just get here for constants. But it's good to have this
    668795            // catch-all since we often add new representations into the mix.
     
    684811    }
    685812
    686     void compileInt52ToValue()
    687     {
    688         setJSValue(lowJSValue(m_node->child1()));
    689     }
    690 
    691     void compileUpsilon()
    692     {
    693         LValue destination = m_phis.get(m_node->phi());
    694        
    695         switch (m_node->child1().useKind()) {
    696         case NumberUse:
    697             m_out.set(lowDouble(m_node->child1()), destination);
    698             break;
    699         case Int32Use:
    700             m_out.set(lowInt32(m_node->child1()), destination);
    701             break;
    702         case MachineIntUse:
    703             m_out.set(lowInt52(m_node->child1()), destination);
    704             break;
    705         case BooleanUse:
    706             m_out.set(lowBoolean(m_node->child1()), destination);
    707             break;
    708         case CellUse:
    709             m_out.set(lowCell(m_node->child1()), destination);
    710             break;
    711         case UntypedUse:
    712             m_out.set(lowJSValue(m_node->child1()), destination);
    713             break;
    714         default:
    715             RELEASE_ASSERT_NOT_REACHED();
    716             break;
    717         }
    718     }
    719    
    720     void compilePhi()
    721     {
    722         LValue source = m_phis.get(m_node);
    723        
    724         switch (m_node->flags() & NodeResultMask) {
    725         case NodeResultNumber:
    726             setDouble(m_out.get(source));
    727             break;
    728         case NodeResultInt32:
    729             setInt32(m_out.get(source));
    730             break;
    731         case NodeResultInt52:
    732             setInt52(m_out.get(source));
    733             break;
    734         case NodeResultBoolean:
    735             setBoolean(m_out.get(source));
    736             break;
    737         case NodeResultJS:
    738             setJSValue(m_out.get(source));
    739             break;
    740         default:
    741             RELEASE_ASSERT_NOT_REACHED();
    742             break;
    743         }
    744     }
    745 
    746     void compilePhantomArguments()
    747     {
    748         setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
    749     }
    750    
    751     void compileWeakJSConstant()
    752     {
    753         setJSValue(weakPointer(m_node->weakConstant()));
    754     }
    755    
    756813    void compileGetArgument()
    757814    {
     
    9671024        }
    9681025           
    969         case MachineIntUse: {
     1026        case Int52RepUse: {
    9701027            if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)
    9711028                && !m_state.forNode(m_node->child2()).couldBeType(SpecInt52)) {
     
    10171074        }
    10181075           
    1019         case NumberUse: {
     1076        case DoubleRepUse: {
    10201077            LValue C1 = lowDouble(m_node->child1());
    10211078            LValue C2 = lowDouble(m_node->child2());
     
    10661123        }
    10671124           
    1068         case MachineIntUse: {
     1125        case Int52RepUse: {
    10691126            Int52Kind kind;
    10701127            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     
    10931150        }
    10941151           
    1095         case NumberUse: {
     1152        case DoubleRepUse: {
    10961153            setDouble(
    10971154                m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
     
    11961253        }
    11971254           
    1198         case NumberUse: {
     1255        case DoubleRepUse: {
    11991256            setDouble(m_out.doubleDiv(
    12001257                lowDouble(m_node->child1()), lowDouble(m_node->child2())));
     
    12941351        }
    12951352           
    1296         case NumberUse: {
     1353        case DoubleRepUse: {
    12971354            setDouble(
    12981355                m_out.doubleRem(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
     
    13221379        }
    13231380           
    1324         case NumberUse: {
     1381        case DoubleRepUse: {
    13251382            LValue left = lowDouble(m_node->child1());
    13261383            LValue right = lowDouble(m_node->child2());
     
    13721429        }
    13731430           
    1374         case NumberUse: {
     1431        case DoubleRepUse: {
    13751432            setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
    13761433            break;
     
    14191476        }
    14201477           
    1421         case MachineIntUse: {
     1478        case Int52RepUse: {
    14221479            if (!m_state.forNode(m_node->child1()).couldBeType(SpecInt52)) {
    14231480                Int52Kind kind;
     
    14391496        }
    14401497           
    1441         case NumberUse: {
     1498        case DoubleRepUse: {
    14421499            setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
    14431500            break;
     
    14971554        speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
    14981555        setInt32(value);
    1499     }
    1500    
    1501     void compileInt32ToDouble()
    1502     {
    1503         setDouble(lowDouble(m_node->child1()));
    15041556    }
    15051557   
     
    22142266                    LValue intValue;
    22152267                    switch (child3.useKind()) {
    2216                     case MachineIntUse:
     2268                    case Int52RepUse:
    22172269                    case Int32Use: {
    22182270                        if (child3.useKind() == Int32Use)
     
    22472299                    }
    22482300                       
    2249                     case NumberUse: {
     2301                    case DoubleRepUse: {
    22502302                        LValue doubleValue = lowDouble(child3);
    22512303                       
     
    33293381    {
    33303382        if (m_node->isBinaryUseKind(Int32Use)
    3331             || m_node->isBinaryUseKind(MachineIntUse)
    3332             || m_node->isBinaryUseKind(NumberUse)
     3383            || m_node->isBinaryUseKind(Int52RepUse)
     3384            || m_node->isBinaryUseKind(DoubleRepUse)
    33333385            || m_node->isBinaryUseKind(ObjectUse)
    33343386            || m_node->isBinaryUseKind(BooleanUse)
     
    33723424        }
    33733425       
    3374         if (m_node->isBinaryUseKind(MachineIntUse)) {
     3426        if (m_node->isBinaryUseKind(Int52RepUse)) {
    33753427            Int52Kind kind;
    33763428            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     
    33803432        }
    33813433       
    3382         if (m_node->isBinaryUseKind(NumberUse)) {
     3434        if (m_node->isBinaryUseKind(DoubleRepUse)) {
    33833435            setBoolean(
    33843436                m_out.doubleEqual(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
     
    41244176        }
    41254177       
    4126         if (m_node->isBinaryUseKind(MachineIntUse)) {
     4178        if (m_node->isBinaryUseKind(Int52RepUse)) {
    41274179            Int52Kind kind;
    41284180            LValue left = lowWhicheverInt52(m_node->child1(), kind);
     
    41324184        }
    41334185       
    4134         if (m_node->isBinaryUseKind(NumberUse)) {
     4186        if (m_node->isBinaryUseKind(DoubleRepUse)) {
    41354187            LValue left = lowDouble(m_node->child1());
    41364188            LValue right = lowDouble(m_node->child2());
     
    43894441        case Int32Use:
    43904442            return m_out.notZero32(lowInt32(m_node->child1()));
    4391         case NumberUse:
     4443        case DoubleRepUse:
    43924444            return m_out.doubleNotEqual(lowDouble(edge), m_out.doubleZero);
    43934445        case ObjectOrOtherUse:
     
    47354787   
    47364788    enum Int52Kind { StrictInt52, Int52 };
    4737     LValue lowInt52(Edge edge, Int52Kind kind, OperandSpeculationMode mode = AutomaticOperandSpeculation)
    4738     {
    4739         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == MachineIntUse);
    4740        
    4741         if (edge->hasConstant()) {
    4742             JSValue value = m_graph.valueOfJSConstant(edge.node());
    4743             if (!value.isMachineInt()) {
    4744                 terminate(Uncountable);
    4745                 return m_out.int64Zero;
    4746             }
    4747             int64_t result = value.asMachineInt();
    4748             if (kind == Int52)
    4749                 result <<= JSValue::int52ShiftAmount;
    4750             return m_out.constInt64(result);
    4751         }
     4789    LValue lowInt52(Edge edge, Int52Kind kind)
     4790    {
     4791        RELEASE_ASSERT(edge.useKind() == Int52RepUse);
    47524792       
    47534793        LoweredNodeValue value;
     
    47744814            break;
    47754815        }
    4776        
    4777         value = m_int32Values.get(edge.node());
    4778         if (isValid(value)) {
    4779             return setInt52WithStrictValue(
    4780                 edge.node(), m_out.signExt(value.value(), m_out.int64), kind);
    4781         }
    4782        
    4783         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecInt52));
    4784        
    4785         value = m_jsValueValues.get(edge.node());
    4786         if (isValid(value)) {
    4787             LValue boxedResult = value.value();
    4788             FTL_TYPE_CHECK(
    4789                 jsValueValue(boxedResult), edge, SpecMachineInt, isNotInt32(boxedResult));
    4790             return setInt52WithStrictValue(
    4791                 edge.node(), m_out.signExt(unboxInt32(boxedResult), m_out.int64), kind);
    4792         }
    4793        
    4794         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecMachineInt));
     4816
     4817        RELEASE_ASSERT(!m_state.forNode(edge).m_type);
    47954818        terminate(Uncountable);
    47964819        return m_out.int64Zero;
    47974820    }
    47984821   
    4799     LValue lowInt52(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
    4800     {
    4801         return lowInt52(edge, Int52, mode);
    4802     }
    4803    
    4804     LValue lowStrictInt52(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
    4805     {
    4806         return lowInt52(edge, StrictInt52, mode);
     4822    LValue lowInt52(Edge edge)
     4823    {
     4824        return lowInt52(edge, Int52);
     4825    }
     4826   
     4827    LValue lowStrictInt52(Edge edge)
     4828    {
     4829        return lowInt52(edge, StrictInt52);
    48074830    }
    48084831   
     
    48314854    }
    48324855   
    4833     LValue lowWhicheverInt52(Edge edge, Int52Kind& kind, OperandSpeculationMode mode = AutomaticOperandSpeculation)
     4856    LValue lowWhicheverInt52(Edge edge, Int52Kind& kind)
    48344857    {
    48354858        kind = bestInt52Kind(edge);
    4836         return lowInt52(edge, kind, mode);
     4859        return lowInt52(edge, kind);
    48374860    }
    48384861   
     
    49324955    }
    49334956   
    4934     LValue lowDouble(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
    4935     {
    4936         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isDouble(edge.useKind()));
    4937        
    4938         if (edge->hasConstant()) {
    4939             JSValue value = m_graph.valueOfJSConstant(edge.node());
    4940             if (!value.isNumber()) {
    4941                 terminate(Uncountable);
    4942                 return m_out.doubleZero;
    4943             }
    4944             return m_out.constDouble(value.asNumber());
    4945         }
     4957    LValue lowDouble(Edge edge)
     4958    {
     4959        RELEASE_ASSERT(isDouble(edge.useKind()));
    49464960       
    49474961        LoweredNodeValue value = m_doubleValues.get(edge.node());
     
    49494963            return value.value();
    49504964       
    4951         value = m_int32Values.get(edge.node());
    4952         if (isValid(value)) {
    4953             LValue result = m_out.intToDouble(value.value());
    4954             setDouble(edge.node(), result);
    4955             return result;
    4956         }
    4957        
    4958         value = m_strictInt52Values.get(edge.node());
    4959         if (isValid(value))
    4960             return strictInt52ToDouble(edge, value.value());
    4961        
    4962         value = m_int52Values.get(edge.node());
    4963         if (isValid(value))
    4964             return strictInt52ToDouble(edge, int52ToStrictInt52(value.value()));
    4965        
    4966         value = m_jsValueValues.get(edge.node());
    4967         if (isValid(value)) {
    4968             LValue boxedResult = value.value();
    4969            
    4970             LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("Double unboxing int case"));
    4971             LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("Double unboxing double case"));
    4972             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Double unboxing continuation"));
    4973            
    4974             m_out.branch(isNotInt32(boxedResult), unsure(doubleCase), unsure(intCase));
    4975            
    4976             LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
    4977            
    4978             ValueFromBlock intToDouble = m_out.anchor(
    4979                 m_out.intToDouble(unboxInt32(boxedResult)));
    4980             m_out.jump(continuation);
    4981            
    4982             m_out.appendTo(doubleCase, continuation);
    4983            
    4984             FTL_TYPE_CHECK(
    4985                 jsValueValue(boxedResult), edge, SpecFullNumber, isCellOrMisc(boxedResult));
    4986            
    4987             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedResult));
    4988             m_out.jump(continuation);
    4989            
    4990             m_out.appendTo(continuation, lastNext);
    4991            
    4992             LValue result = m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
    4993            
    4994             setDouble(edge.node(), result);
    4995             return result;
    4996         }
    4997        
    4998         RELEASE_ASSERT(!(m_state.forNode(edge).m_type & SpecFullNumber));
     4965        RELEASE_ASSERT(!m_state.forNode(edge).m_type);
    49994966        terminate(Uncountable);
    50004967        return m_out.doubleZero;
     
    50044971    {
    50054972        ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
     4973        RELEASE_ASSERT(!isDouble(edge.useKind()));
     4974        RELEASE_ASSERT(edge.useKind() != Int52RepUse);
    50064975       
    50074976        if (edge->hasConstant())
     
    50194988        }
    50204989       
    5021         value = m_strictInt52Values.get(edge.node());
    5022         if (isValid(value))
    5023             return strictInt52ToJSValue(value.value());
    5024        
    5025         value = m_int52Values.get(edge.node());
    5026         if (isValid(value))
    5027             return strictInt52ToJSValue(int52ToStrictInt52(value.value()));
    5028        
    50294990        value = m_booleanValues.get(edge.node());
    50304991        if (isValid(value)) {
    50314992            LValue result = boxBoolean(value.value());
    5032             setJSValue(edge.node(), result);
    5033             return result;
    5034         }
    5035        
    5036         value = m_doubleValues.get(edge.node());
    5037         if (isValid(value)) {
    5038             LValue result = boxDouble(value.value());
    50394993            setJSValue(edge.node(), result);
    50404994            return result;
     
    50665020    }
    50675021   
    5068     LValue strictInt52ToDouble(Edge edge, LValue value)
    5069     {
    5070         LValue result = m_out.intToDouble(value);
    5071         setDouble(edge.node(), result);
    5072         return result;
     5022    LValue strictInt52ToDouble(LValue value)
     5023    {
     5024        return m_out.intToDouble(value);
    50735025    }
    50745026   
     
    51005052    }
    51015053   
    5102     LValue setInt52WithStrictValue(Node* node, LValue value, Int52Kind kind)
    5103     {
    5104         switch (kind) {
    5105         case StrictInt52:
    5106             setStrictInt52(node, value);
    5107             return value;
    5108            
    5109         case Int52:
    5110             value = strictInt52ToInt52(value);
    5111             setInt52(node, value);
    5112             return value;
    5113         }
    5114        
    5115         RELEASE_ASSERT_NOT_REACHED();
    5116         return 0;
    5117     }
    5118 
    51195054    LValue strictInt52ToInt52(LValue value)
    51205055    {
     
    51485083        return m_out.testNonZero64(jsValue, m_tagTypeNumber);
    51495084    }
     5085   
    51505086    LValue unboxDouble(LValue jsValue)
    51515087    {
     
    51555091    {
    51565092        return m_out.sub(m_out.bitCast(doubleValue, m_out.int64), m_tagTypeNumber);
     5093    }
     5094    LValue jsValueToDouble(Edge edge, LValue boxedValue)
     5095    {
     5096        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("DoubleRep unboxing int case"));
     5097        LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("DoubleRep unboxing double case"));
     5098        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("DoubleRep unboxing continuation"));
     5099           
     5100        LValue isNotInt32;
     5101        if (!m_interpreter.needsTypeCheck(edge, SpecInt32))
     5102            isNotInt32 = m_out.booleanFalse;
     5103        else if (!m_interpreter.needsTypeCheck(edge, ~SpecInt32))
     5104            isNotInt32 = m_out.booleanTrue;
     5105        else
     5106            isNotInt32 = this->isNotInt32(boxedValue);
     5107        m_out.branch(isNotInt32, unsure(doubleCase), unsure(intCase));
     5108           
     5109        LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
     5110           
     5111        ValueFromBlock intToDouble = m_out.anchor(
     5112            m_out.intToDouble(unboxInt32(boxedValue)));
     5113        m_out.jump(continuation);
     5114           
     5115        m_out.appendTo(doubleCase, continuation);
     5116           
     5117        FTL_TYPE_CHECK(
     5118            jsValueValue(boxedValue), edge, SpecBytecodeNumber, isCellOrMisc(boxedValue));
     5119           
     5120        ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedValue));
     5121        m_out.jump(continuation);
     5122           
     5123        m_out.appendTo(continuation, lastNext);
     5124           
     5125        return m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
    51575126    }
    51585127   
     
    52275196            break;
    52285197        case KnownInt32Use:
    5229         case KnownNumberUse:
    52305198        case KnownStringUse:
     5199        case DoubleRepUse:
     5200        case Int52RepUse:
    52315201            ASSERT(!m_interpreter.needsTypeCheck(edge));
    52325202            break;
     
    52615231            speculateStringOrStringObject(edge);
    52625232            break;
    5263         case RealNumberUse:
    5264             speculateRealNumber(edge);
    5265             break;
    52665233        case NumberUse:
    52675234            speculateNumber(edge);
    52685235            break;
    5269         case MachineIntUse:
    5270             speculateMachineInt(edge);
     5236        case DoubleRepRealUse:
     5237            speculateDoubleReal(edge);
    52715238            break;
    52725239        case BooleanUse:
     
    55305497    void speculateNumber(Edge edge)
    55315498    {
     5499        LValue value = lowJSValue(edge, ManualOperandSpeculation);
     5500        FTL_TYPE_CHECK(jsValueValue(value), edge, SpecBytecodeNumber, isNotNumber(value));
     5501    }
     5502   
     5503    void speculateDoubleReal(Edge edge)
     5504    {
    55325505        // Do an early return here because lowDouble() can create a lot of control flow.
    55335506        if (!m_interpreter.needsTypeCheck(edge))
    55345507            return;
    55355508       
    5536         lowDouble(edge);
    5537     }
    5538    
    5539     void speculateRealNumber(Edge edge)
    5540     {
    5541         // Do an early return here because lowDouble() can create a lot of control flow.
    5542         if (!m_interpreter.needsTypeCheck(edge))
    5543             return;
    5544        
    55455509        LValue value = lowDouble(edge);
    55465510        FTL_TYPE_CHECK(
    5547             doubleValue(value), edge, SpecFullRealNumber,
     5511            doubleValue(value), edge, SpecDoubleReal,
    55485512            m_out.doubleNotEqualOrUnordered(value, value));
    5549     }
    5550    
    5551     void speculateMachineInt(Edge edge)
    5552     {
    5553         if (!m_interpreter.needsTypeCheck(edge))
    5554             return;
    5555        
    5556         Int52Kind kind;
    5557         lowWhicheverInt52(edge, kind);
    55585513    }
    55595514   
Note: See TracChangeset for help on using the changeset viewer.