Ignore:
Timestamp:
Sep 15, 2014, 12:32:01 PM (11 years ago)
Author:
[email protected]
Message:

DFG ref count calculation should be reusable
https://bugs.webkit.org/show_bug.cgi?id=136811

Reviewed by Oliver Hunt.

Henceforth if you call Graph::computeRefCounts(), a nifty O(n) operation, every Node
will be able to tell you how many places it is used from. Currently only DCE uses this,
but it will be useful for https://bugs.webkit.org/show_bug.cgi?id=136330.

  • dfg/DFGDCEPhase.cpp:

(JSC::DFG::DCEPhase::run):
(JSC::DFG::DCEPhase::findTypeCheckRoot): Deleted.
(JSC::DFG::DCEPhase::countNode): Deleted.
(JSC::DFG::DCEPhase::countEdge): Deleted.

  • dfg/DFGGraph.cpp:

(JSC::DFG::Graph::computeRefCounts):

  • dfg/DFGGraph.h:
File:
1 edited

Legend:

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

    r173413 r173626  
    4949        ASSERT(m_graph.m_form == ThreadedCPS || m_graph.m_form == SSA);
    5050       
    51         // First reset the counts to 0 for all nodes.
    52         //
    53         // Also take this opportunity to pretend that Check nodes are not NodeMustGenerate. Check
    54         // nodes are MustGenerate because they are executed for effect, but they follow the same
    55         // DCE rules as nodes that aren't MustGenerate: they only contribute to the ref count of
    56         // their children if the edges require checks. Non-checking edges are removed. Note that
    57         // for any Checks left over, this phase will turn them back into NodeMustGenerate.
    58         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
    59             BasicBlock* block = m_graph.block(blockIndex);
    60             if (!block)
    61                 continue;
    62             for (unsigned indexInBlock = block->size(); indexInBlock--;) {
    63                 Node* node = block->at(indexInBlock);
    64                 if (node->op() == Check)
    65                     node->clearFlags(NodeMustGenerate);
    66                 node->setRefCount(0);
    67             }
    68             for (unsigned phiIndex = block->phis.size(); phiIndex--;)
    69                 block->phis[phiIndex]->setRefCount(0);
    70         }
    71    
    72         // Now find the roots:
    73         // - Nodes that are must-generate.
    74         // - Nodes that are reachable from type checks.
    75         // Set their ref counts to 1 and put them on the worklist.
    76         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
    77             BasicBlock* block = m_graph.block(blockIndex);
    78             if (!block)
    79                 continue;
    80             for (unsigned indexInBlock = block->size(); indexInBlock--;) {
    81                 Node* node = block->at(indexInBlock);
    82                 DFG_NODE_DO_TO_CHILDREN(m_graph, node, findTypeCheckRoot);
    83                 if (!(node->flags() & NodeMustGenerate))
    84                     continue;
    85                 if (!node->postfixRef())
    86                     m_worklist.append(node);
    87             }
    88         }
    89        
    90         while (!m_worklist.isEmpty()) {
    91             while (!m_worklist.isEmpty()) {
    92                 Node* node = m_worklist.last();
    93                 m_worklist.removeLast();
    94                 ASSERT(node->shouldGenerate()); // It should not be on the worklist unless it's ref'ed.
    95                 DFG_NODE_DO_TO_CHILDREN(m_graph, node, countEdge);
    96             }
    97            
    98             if (m_graph.m_form == SSA) {
    99                 // Find Phi->Upsilon edges, which are represented as meta-data in the
    100                 // Upsilon.
    101                 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
    102                     BasicBlock* block = m_graph.block(blockIndex);
    103                     if (!block)
    104                         continue;
    105                     for (unsigned nodeIndex = block->size(); nodeIndex--;) {
    106                         Node* node = block->at(nodeIndex);
    107                         if (node->op() != Upsilon)
    108                             continue;
    109                         if (node->shouldGenerate())
    110                             continue;
    111                         if (node->phi()->shouldGenerate())
    112                             countNode(node);
    113                     }
    114                 }
    115             }
    116         }
     51        m_graph.computeRefCounts();
    11752       
    11853        if (m_graph.m_form == SSA) {
     
    15893
    15994private:
    160     void findTypeCheckRoot(Node*, Edge edge)
    161     {
    162         // We may have an "unproved" untyped use for code that is unreachable. The CFA
    163         // will just not have gotten around to it.
    164         if (edge.isProved() || edge.willNotHaveCheck())
    165             return;
    166         if (!edge->postfixRef())
    167             m_worklist.append(edge.node());
    168     }
    169    
    170     void countNode(Node* node)
    171     {
    172         if (node->postfixRef())
    173             return;
    174         m_worklist.append(node);
    175     }
    176    
    177     void countEdge(Node*, Edge edge)
    178     {
    179         // Don't count edges that are already counted for their type checks.
    180         if (!(edge.isProved() || edge.willNotHaveCheck()))
    181             return;
    182         countNode(edge.node());
    183     }
    184    
    18595    void fixupBlock(BasicBlock* block)
    18696    {
     
    328238    }
    329239   
    330     Vector<Node*, 128> m_worklist;
    331240    InsertionSet m_insertionSet;
    332241};
Note: See TracChangeset for help on using the changeset viewer.