Ignore:
Timestamp:
Feb 20, 2014, 12:00:28 AM (11 years ago)
Author:
[email protected]
Message:

DFG should have a way of carrying and preserving conditional branch weights
https://bugs.webkit.org/show_bug.cgi?id=129083

Reviewed by Michael Saboff.

Branch and Switch now have branch counts/weights for each target. This is encapsulated
behind DFG::BranchTarget. We carry this data all the way to the FTL, and the DFG
backend ignores it.

We don't set this data yet; that's for https://bugs.webkit.org/show_bug.cgi?id=129055.

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::branchData):
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::parseBlock):
(JSC::DFG::ByteCodeParser::linkBlock):

  • dfg/DFGCFGSimplificationPhase.cpp:

(JSC::DFG::CFGSimplificationPhase::run):

  • dfg/DFGFixupPhase.cpp:

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

  • dfg/DFGGraph.cpp:

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

  • dfg/DFGGraph.h:
  • dfg/DFGInPlaceAbstractState.cpp:

(JSC::DFG::InPlaceAbstractState::mergeToSuccessors):

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::JITCompiler::link):

  • dfg/DFGNode.cpp:

(JSC::DFG::BranchTarget::dump):

  • dfg/DFGNode.h:

(JSC::DFG::BranchTarget::BranchTarget):
(JSC::DFG::BranchTarget::setBytecodeIndex):
(JSC::DFG::BranchTarget::bytecodeIndex):
(JSC::DFG::BranchData::withBytecodeIndices):
(JSC::DFG::BranchData::takenBytecodeIndex):
(JSC::DFG::BranchData::notTakenBytecodeIndex):
(JSC::DFG::BranchData::forCondition):
(JSC::DFG::SwitchCase::SwitchCase):
(JSC::DFG::SwitchCase::withBytecodeIndex):
(JSC::DFG::SwitchData::SwitchData):
(JSC::DFG::Node::targetBytecodeOffsetDuringParsing):
(JSC::DFG::Node::targetBlock):
(JSC::DFG::Node::branchData):
(JSC::DFG::Node::successor):
(JSC::DFG::Node::successorForCondition):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compilePeepHoleDoubleBranch):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleBooleanBranch):
(JSC::DFG::SpeculativeJIT::compilePeepHoleInt32Branch):
(JSC::DFG::SpeculativeJIT::compileStrictEqForConstant):
(JSC::DFG::SpeculativeJIT::compileRegExpExec):
(JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
(JSC::DFG::SpeculativeJIT::emitSwitchImm):
(JSC::DFG::SpeculativeJIT::emitSwitchCharStringJump):
(JSC::DFG::SpeculativeJIT::emitSwitchChar):
(JSC::DFG::SpeculativeJIT::emitBinarySwitchStringRecurse):
(JSC::DFG::SpeculativeJIT::emitSwitchStringOnString):
(JSC::DFG::SpeculativeJIT::emitSwitchString):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNull):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranch):
(JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeStrictEq):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleInt52Branch):
(JSC::DFG::SpeculativeJIT::emitBranch):
(JSC::DFG::SpeculativeJIT::compile):

  • ftl/FTLLowerDFGToLLVM.cpp:

(JSC::FTL::LowerDFGToLLVM::compileJump):
(JSC::FTL::LowerDFGToLLVM::compileBranch):
(JSC::FTL::LowerDFGToLLVM::compileSwitch):
(JSC::FTL::LowerDFGToLLVM::buildSwitch):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGNode.h

    r164207 r164417  
    7979};
    8080
     81struct BranchTarget {
     82    BranchTarget()
     83        : block(0)
     84        , count(QNaN)
     85    {
     86    }
     87   
     88    explicit BranchTarget(BasicBlock* block)
     89        : block(block)
     90        , count(QNaN)
     91    {
     92    }
     93   
     94    void setBytecodeIndex(unsigned bytecodeIndex)
     95    {
     96        block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
     97    }
     98    unsigned bytecodeIndex() const { return bitwise_cast<uintptr_t>(block); }
     99   
     100    void dump(PrintStream&) const;
     101   
     102    BasicBlock* block;
     103    float count;
     104};
     105
     106struct BranchData {
     107    static BranchData withBytecodeIndices(
     108        unsigned takenBytecodeIndex, unsigned notTakenBytecodeIndex)
     109    {
     110        BranchData result;
     111        result.taken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(takenBytecodeIndex));
     112        result.notTaken.block = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(notTakenBytecodeIndex));
     113        return result;
     114    }
     115   
     116    unsigned takenBytecodeIndex() const { return taken.bytecodeIndex(); }
     117    unsigned notTakenBytecodeIndex() const { return notTaken.bytecodeIndex(); }
     118   
     119    BasicBlock*& forCondition(bool condition)
     120    {
     121        if (condition)
     122            return taken.block;
     123        return notTaken.block;
     124    }
     125   
     126    BranchTarget taken;
     127    BranchTarget notTaken;
     128};
     129
    81130// The SwitchData and associated data structures duplicate the information in
    82131// JumpTable. The DFG may ultimately end up using the JumpTable, though it may
     
    92141struct SwitchCase {
    93142    SwitchCase()
    94         : target(0)
    95143    {
    96144    }
     
    106154        SwitchCase result;
    107155        result.value = value;
    108         result.target = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
     156        result.target.setBytecodeIndex(bytecodeIndex);
    109157        return result;
    110158    }
    111159   
    112     unsigned targetBytecodeIndex() const { return bitwise_cast<uintptr_t>(target); }
    113    
    114160    LazyJSValue value;
    115     BasicBlock* target;
     161    BranchTarget target;
    116162};
    117163
     
    127173    // care about manually.
    128174    SwitchData()
    129         : fallThrough(0)
    130         , kind(static_cast<SwitchKind>(-1))
     175        : kind(static_cast<SwitchKind>(-1))
    131176        , switchTableIndex(UINT_MAX)
    132177        , didUseJumpTable(false)
     
    134179    }
    135180   
    136     void setFallThroughBytecodeIndex(unsigned bytecodeIndex)
    137     {
    138         fallThrough = bitwise_cast<BasicBlock*>(static_cast<uintptr_t>(bytecodeIndex));
    139     }
    140     unsigned fallThroughBytecodeIndex() const { return bitwise_cast<uintptr_t>(fallThrough); }
    141    
    142181    Vector<SwitchCase> cases;
    143     BasicBlock* fallThrough;
     182    BranchTarget fallThrough;
    144183    SwitchKind kind;
    145184    unsigned switchTableIndex;
     
    820859    }
    821860
    822     unsigned takenBytecodeOffsetDuringParsing()
    823     {
    824         ASSERT(isBranch() || isJump());
     861    unsigned targetBytecodeOffsetDuringParsing()
     862    {
     863        ASSERT(isJump());
    825864        return m_opInfo;
    826865    }
    827866
    828     unsigned notTakenBytecodeOffsetDuringParsing()
     867    BasicBlock*& targetBlock()
     868    {
     869        ASSERT(isJump());
     870        return *bitwise_cast<BasicBlock**>(&m_opInfo);
     871    }
     872   
     873    BranchData* branchData()
    829874    {
    830875        ASSERT(isBranch());
    831         return m_opInfo2;
    832     }
    833    
    834     void setTakenBlock(BasicBlock* block)
    835     {
    836         ASSERT(isBranch() || isJump());
    837         m_opInfo = bitwise_cast<uintptr_t>(block);
    838     }
    839    
    840     void setNotTakenBlock(BasicBlock* block)
    841     {
    842         ASSERT(isBranch());
    843         m_opInfo2 = bitwise_cast<uintptr_t>(block);
    844     }
    845    
    846     BasicBlock*& takenBlock()
    847     {
    848         ASSERT(isBranch() || isJump());
    849         return *bitwise_cast<BasicBlock**>(&m_opInfo);
    850     }
    851    
    852     BasicBlock*& notTakenBlock()
    853     {
    854         ASSERT(isBranch());
    855         return *bitwise_cast<BasicBlock**>(&m_opInfo2);
     876        return bitwise_cast<BranchData*>(m_opInfo);
    856877    }
    857878   
     
    880901        if (isSwitch()) {
    881902            if (index < switchData()->cases.size())
    882                 return switchData()->cases[index].target;
     903                return switchData()->cases[index].target.block;
    883904            RELEASE_ASSERT(index == switchData()->cases.size());
    884             return switchData()->fallThrough;
     905            return switchData()->fallThrough.block;
    885906        }
    886907        switch (index) {
    887908        case 0:
    888             return takenBlock();
     909            if (isJump())
     910                return targetBlock();
     911            return branchData()->taken.block;
    889912        case 1:
    890             return notTakenBlock();
     913            return branchData()->notTaken.block;
    891914        default:
    892915            RELEASE_ASSERT_NOT_REACHED();
    893             return takenBlock();
     916            return targetBlock();
    894917        }
    895918    }
     
    897920    BasicBlock*& successorForCondition(bool condition)
    898921    {
    899         ASSERT(isBranch());
    900         return condition ? takenBlock() : notTakenBlock();
     922        return branchData()->forCondition(condition);
    901923    }
    902924   
Note: See TracChangeset for help on using the changeset viewer.