]>
git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGDCEPhase.cpp
   2  * Copyright (C) 2013 Apple Inc. All rights reserved. 
   4  * Redistribution and use in source and binary forms, with or without 
   5  * modification, are permitted provided that the following conditions 
   7  * 1. Redistributions of source code must retain the above copyright 
   8  *    notice, this list of conditions and the following disclaimer. 
   9  * 2. Redistributions in binary form must reproduce the above copyright 
  10  *    notice, this list of conditions and the following disclaimer in the 
  11  *    documentation and/or other materials provided with the distribution. 
  13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 
  14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR 
  17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
  19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
  20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
  21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
  27 #include "DFGDCEPhase.h" 
  31 #include "DFGBasicBlockInlines.h" 
  33 #include "DFGInsertionSet.h" 
  35 #include "Operations.h" 
  37 namespace JSC 
{ namespace DFG 
{ 
  39 class DCEPhase 
: public Phase 
{ 
  41     DCEPhase(Graph
& graph
) 
  42         : Phase(graph
, "dead code elimination") 
  48         // First reset the counts to 0 for all nodes. 
  49         for (BlockIndex blockIndex 
= 0; blockIndex 
< m_graph
.m_blocks
.size(); ++blockIndex
) { 
  50             BasicBlock
* block 
= m_graph
.m_blocks
[blockIndex
].get(); 
  53             for (unsigned indexInBlock 
= block
->size(); indexInBlock
--;) 
  54                 block
->at(indexInBlock
)->setRefCount(0); 
  55             for (unsigned phiIndex 
= block
->phis
.size(); phiIndex
--;) 
  56                 block
->phis
[phiIndex
]->setRefCount(0); 
  59         // Now find the roots: 
  60         // - Nodes that are must-generate. 
  61         // - Nodes that are reachable from type checks. 
  62         // Set their ref counts to 1 and put them on the worklist. 
  63         for (BlockIndex blockIndex 
= 0; blockIndex 
< m_graph
.m_blocks
.size(); ++blockIndex
) { 
  64             BasicBlock
* block 
= m_graph
.m_blocks
[blockIndex
].get(); 
  67             for (unsigned indexInBlock 
= block
->size(); indexInBlock
--;) { 
  68                 Node
* node 
= block
->at(indexInBlock
); 
  69                 DFG_NODE_DO_TO_CHILDREN(m_graph
, node
, findTypeCheckRoot
); 
  70                 if (!(node
->flags() & NodeMustGenerate
)) 
  72                 if (!node
->postfixRef()) 
  73                     m_worklist
.append(node
); 
  77         while (!m_worklist
.isEmpty()) { 
  78             Node
* node 
= m_worklist
.last(); 
  79             m_worklist
.removeLast(); 
  80             ASSERT(node
->shouldGenerate()); // It should not be on the worklist unless it's ref'ed. 
  81             DFG_NODE_DO_TO_CHILDREN(m_graph
, node
, countEdge
); 
  84         for (BlockIndex blockIndex 
= 0; blockIndex 
< m_graph
.m_blocks
.size(); ++blockIndex
) { 
  85             BasicBlock
* block 
= m_graph
.m_blocks
[blockIndex
].get(); 
  89             InsertionSet 
insertionSet(m_graph
); 
  91             for (unsigned indexInBlock 
= block
->size(); indexInBlock
--;) { 
  92                 Node
* node 
= block
->at(indexInBlock
); 
  93                 if (node
->shouldGenerate()) 
  98                     if (node
->child1().isProved() || node
->child1().useKind() == UntypedUse
) { 
  99                         // Consider the possibility that UInt32ToNumber is dead but its 
 100                         // child isn't; if so then we should MovHint the child. 
 101                         if (!node
->child1()->shouldGenerate() 
 102                             && node
->child1()->op() == UInt32ToNumber
) 
 103                             node
->child1() = node
->child1()->child1(); 
 105                         if (!node
->child1()->shouldGenerate()) { 
 106                             node
->setOpAndDefaultFlags(ZombieHint
); 
 107                             node
->child1() = Edge(); 
 110                         node
->setOpAndDefaultFlags(MovHint
); 
 113                     node
->setOpAndDefaultFlags(MovHintAndCheck
); 
 114                     node
->setRefCount(1); 
 120                     // Leave them as not shouldGenerate. 
 125                     if (node
->flags() & NodeHasVarArgs
) { 
 126                         for (unsigned childIdx 
= node
->firstChild(); childIdx 
< node
->firstChild() + node
->numChildren(); childIdx
++) { 
 127                             Edge edge 
= m_graph
.m_varArgChildren
[childIdx
]; 
 129                             if (!edge 
|| edge
.isProved() || edge
.useKind() == UntypedUse
) 
 132                             insertionSet
.insertNode(indexInBlock
, SpecNone
, Phantom
, node
->codeOrigin
, edge
); 
 135                         node
->convertToPhantomUnchecked(); 
 136                         node
->children
.reset(); 
 137                         node
->setRefCount(1); 
 141                     node
->convertToPhantom(); 
 142                     eliminateIrrelevantPhantomChildren(node
); 
 143                     node
->setRefCount(1); 
 148             insertionSet
.execute(block
); 
 151         m_graph
.m_refCountState 
= ExactRefCount
; 
 157     void findTypeCheckRoot(Node
*, Edge edge
) 
 159         // We may have an "unproved" untyped use for code that is unreachable. The CFA 
 160         // will just not have gotten around to it. 
 161         if (edge
.isProved() || edge
.useKind() == UntypedUse
) 
 163         if (!edge
->postfixRef()) 
 164             m_worklist
.append(edge
.node()); 
 167     void countEdge(Node
*, Edge edge
) 
 169         // Don't count edges that are already counted for their type checks. 
 170         if (!(edge
.isProved() || edge
.useKind() == UntypedUse
)) 
 173         if (edge
->postfixRef()) 
 175         m_worklist
.append(edge
.node()); 
 178     void eliminateIrrelevantPhantomChildren(Node
* node
) 
 180         for (unsigned i 
= 0; i 
< AdjacencyList::Size
; ++i
) { 
 181             Edge edge 
= node
->children
.child(i
); 
 184             if (edge
.isProved() || edge
.useKind() == UntypedUse
) 
 185                 node
->children
.removeEdge(i
--); 
 189     Vector
<Node
*, 128> m_worklist
; 
 192 bool performDCE(Graph
& graph
) 
 194     SamplingRegion 
samplingRegion("DFG DCE Phase"); 
 195     return runPhase
<DCEPhase
>(graph
); 
 198 } } // namespace JSC::DFG 
 200 #endif // ENABLE(DFG_JIT)