DFGDCEPhase.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*
  2. * Copyright (C) 2013 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  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.
  12. *
  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.
  24. */
  25. #include "config.h"
  26. #include "DFGDCEPhase.h"
  27. #if ENABLE(DFG_JIT)
  28. #include "DFGBasicBlockInlines.h"
  29. #include "DFGGraph.h"
  30. #include "DFGInsertionSet.h"
  31. #include "DFGPhase.h"
  32. #include "Operations.h"
  33. namespace JSC { namespace DFG {
  34. class DCEPhase : public Phase {
  35. public:
  36. DCEPhase(Graph& graph)
  37. : Phase(graph, "dead code elimination")
  38. {
  39. }
  40. bool run()
  41. {
  42. // First reset the counts to 0 for all nodes.
  43. for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
  44. BasicBlock* block = m_graph.m_blocks[blockIndex].get();
  45. if (!block)
  46. continue;
  47. for (unsigned indexInBlock = block->size(); indexInBlock--;)
  48. block->at(indexInBlock)->setRefCount(0);
  49. for (unsigned phiIndex = block->phis.size(); phiIndex--;)
  50. block->phis[phiIndex]->setRefCount(0);
  51. }
  52. // Now find the roots:
  53. // - Nodes that are must-generate.
  54. // - Nodes that are reachable from type checks.
  55. // Set their ref counts to 1 and put them on the worklist.
  56. for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
  57. BasicBlock* block = m_graph.m_blocks[blockIndex].get();
  58. if (!block)
  59. continue;
  60. for (unsigned indexInBlock = block->size(); indexInBlock--;) {
  61. Node* node = block->at(indexInBlock);
  62. DFG_NODE_DO_TO_CHILDREN(m_graph, node, findTypeCheckRoot);
  63. if (!(node->flags() & NodeMustGenerate))
  64. continue;
  65. if (!node->postfixRef())
  66. m_worklist.append(node);
  67. }
  68. }
  69. while (!m_worklist.isEmpty()) {
  70. Node* node = m_worklist.last();
  71. m_worklist.removeLast();
  72. ASSERT(node->shouldGenerate()); // It should not be on the worklist unless it's ref'ed.
  73. DFG_NODE_DO_TO_CHILDREN(m_graph, node, countEdge);
  74. }
  75. for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
  76. BasicBlock* block = m_graph.m_blocks[blockIndex].get();
  77. if (!block)
  78. continue;
  79. InsertionSet insertionSet(m_graph);
  80. for (unsigned indexInBlock = block->size(); indexInBlock--;) {
  81. Node* node = block->at(indexInBlock);
  82. if (node->shouldGenerate())
  83. continue;
  84. switch (node->op()) {
  85. case SetLocal: {
  86. if (node->child1().isProved() || node->child1().useKind() == UntypedUse) {
  87. // Consider the possibility that UInt32ToNumber is dead but its
  88. // child isn't; if so then we should MovHint the child.
  89. if (!node->child1()->shouldGenerate()
  90. && node->child1()->op() == UInt32ToNumber)
  91. node->child1() = node->child1()->child1();
  92. if (!node->child1()->shouldGenerate()) {
  93. node->setOpAndDefaultFlags(ZombieHint);
  94. node->child1() = Edge();
  95. break;
  96. }
  97. node->setOpAndDefaultFlags(MovHint);
  98. break;
  99. }
  100. node->setOpAndDefaultFlags(MovHintAndCheck);
  101. node->setRefCount(1);
  102. break;
  103. }
  104. case GetLocal:
  105. case SetArgument: {
  106. // Leave them as not shouldGenerate.
  107. break;
  108. }
  109. default: {
  110. if (node->flags() & NodeHasVarArgs) {
  111. for (unsigned childIdx = node->firstChild(); childIdx < node->firstChild() + node->numChildren(); childIdx++) {
  112. Edge edge = m_graph.m_varArgChildren[childIdx];
  113. if (!edge || edge.isProved() || edge.useKind() == UntypedUse)
  114. continue;
  115. insertionSet.insertNode(indexInBlock, SpecNone, Phantom, node->codeOrigin, edge);
  116. }
  117. node->convertToPhantomUnchecked();
  118. node->children.reset();
  119. node->setRefCount(1);
  120. break;
  121. }
  122. node->convertToPhantom();
  123. eliminateIrrelevantPhantomChildren(node);
  124. node->setRefCount(1);
  125. break;
  126. } }
  127. }
  128. insertionSet.execute(block);
  129. }
  130. m_graph.m_refCountState = ExactRefCount;
  131. return true;
  132. }
  133. private:
  134. void findTypeCheckRoot(Node*, Edge edge)
  135. {
  136. // We may have an "unproved" untyped use for code that is unreachable. The CFA
  137. // will just not have gotten around to it.
  138. if (edge.isProved() || edge.useKind() == UntypedUse)
  139. return;
  140. if (!edge->postfixRef())
  141. m_worklist.append(edge.node());
  142. }
  143. void countEdge(Node*, Edge edge)
  144. {
  145. // Don't count edges that are already counted for their type checks.
  146. if (!(edge.isProved() || edge.useKind() == UntypedUse))
  147. return;
  148. if (edge->postfixRef())
  149. return;
  150. m_worklist.append(edge.node());
  151. }
  152. void eliminateIrrelevantPhantomChildren(Node* node)
  153. {
  154. for (unsigned i = 0; i < AdjacencyList::Size; ++i) {
  155. Edge edge = node->children.child(i);
  156. if (!edge)
  157. continue;
  158. if (edge.isProved() || edge.useKind() == UntypedUse)
  159. node->children.removeEdge(i--);
  160. }
  161. }
  162. Vector<Node*, 128> m_worklist;
  163. };
  164. bool performDCE(Graph& graph)
  165. {
  166. SamplingRegion samplingRegion("DFG DCE Phase");
  167. return runPhase<DCEPhase>(graph);
  168. }
  169. } } // namespace JSC::DFG
  170. #endif // ENABLE(DFG_JIT)