Changeset 208364 in webkit for trunk/Source/JavaScriptCore/dfg/DFGLivenessAnalysisPhase.cpp
- Timestamp:
- Nov 3, 2016, 7:37:45 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGLivenessAnalysisPhase.cpp
r204112 r208364 31 31 #include "DFGBasicBlockInlines.h" 32 32 #include "DFGBlockMapInlines.h" 33 #include "DFGFlowIndexing.h" 33 34 #include "DFGGraph.h" 34 35 #include "DFGInsertionSet.h" … … 45 46 : Phase(graph, "liveness analysis") 46 47 , m_dirtyBlocks(m_graph.numBlocks()) 48 , m_indexing(*m_graph.m_indexingCache) 47 49 , m_liveAtHead(m_graph) 48 50 , m_liveAtTail(m_graph) 49 , m_workset(graph.maxNodeCount() - 1)50 51 { 52 m_graph.m_indexingCache->recompute(); 53 m_workset = std::make_unique<IndexSparseSet<UnsafeVectorOverflow>>(m_graph.m_indexingCache->numIndices()); 51 54 } 52 55 … … 81 84 82 85 { 83 const auto& liveAtHeadIndices = m_liveAtHead[blockIndex];84 Vector<Node *>& liveAtHead = block->ssa->liveAtHead;86 const Vector<unsigned, 0, UnsafeVectorOverflow, 1>& liveAtHeadIndices = m_liveAtHead[blockIndex]; 87 Vector<NodeFlowProjection>& liveAtHead = block->ssa->liveAtHead; 85 88 liveAtHead.resize(0); 86 89 liveAtHead.reserveCapacity(liveAtHeadIndices.size()); 87 90 for (unsigned index : liveAtHeadIndices) 88 liveAtHead.uncheckedAppend(m_ graph.nodeAt(index));91 liveAtHead.uncheckedAppend(m_indexing.nodeProjection(index)); 89 92 } 90 93 { 91 const auto& liveAtTailIndices = m_liveAtTail[blockIndex];92 Vector<Node *>& liveAtTail = block->ssa->liveAtTail;94 const HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>>& liveAtTailIndices = m_liveAtTail[blockIndex]; 95 Vector<NodeFlowProjection>& liveAtTail = block->ssa->liveAtTail; 93 96 liveAtTail.resize(0); 94 97 liveAtTail.reserveCapacity(liveAtTailIndices.size()); 95 98 for (unsigned index : m_liveAtTail[blockIndex]) 96 liveAtTail.uncheckedAppend(m_ graph.nodeAt(index));99 liveAtTail.uncheckedAppend(m_indexing.nodeProjection(index)); 97 100 } 98 101 } … … 107 110 ASSERT_WITH_MESSAGE(block, "Only dirty blocks needs updates. A null block should never be dirty."); 108 111 109 m_workset .clear();112 m_workset->clear(); 110 113 for (unsigned index : m_liveAtTail[blockIndex]) 111 m_workset .add(index);114 m_workset->add(index); 112 115 113 116 for (unsigned nodeIndex = block->size(); nodeIndex--;) { 114 117 Node* node = block->at(nodeIndex); 115 118 116 // Given an Upsilon: 117 // 118 // n: Upsilon(@x, ^p) 119 // 120 // We say that it def's @p and @n and uses @x. 121 // 122 // Given a Phi: 123 // 124 // p: Phi() 125 // 126 // We say nothing. It's neither a use nor a def. 127 // 128 // Given a node: 129 // 130 // n: Thingy(@a, @b, @c) 131 // 132 // We say that it def's @n and uses @a, @b, @c. 119 auto handleEdge = [&] (Edge& edge) { 120 bool newEntry = m_workset->add(m_indexing.index(edge.node())); 121 edge.setKillStatus(newEntry ? DoesKill : DoesNotKill); 122 }; 133 123 134 124 switch (node->op()) { 135 125 case Upsilon: { 136 ASSERT_WITH_MESSAGE(!m_workset .contains(node->index()), "Upsilon should not be used as defs by other nodes.");126 ASSERT_WITH_MESSAGE(!m_workset->contains(node->index()), "Upsilon should not be used as defs by other nodes."); 137 127 138 128 Node* phi = node->phi(); 139 m_workset .remove(phi->index());140 m_workset.add(node->child1()->index());129 m_workset->remove(m_indexing.shadowIndex(phi)); 130 handleEdge(node->child1()); 141 131 break; 142 132 } 143 133 case Phi: { 134 m_workset->remove(m_indexing.index(node)); 135 m_workset->add(m_indexing.shadowIndex(node)); 144 136 break; 145 137 } 146 138 default: 147 m_workset .remove(node->index());148 DFG_NODE_DO_TO_CHILDREN(m_graph, node, addChildUse);139 m_workset->remove(m_indexing.index(node)); 140 m_graph.doToChildren(node, handleEdge); 149 141 break; 150 142 } … … 152 144 153 145 // Update live at head. 154 auto& liveAtHead = m_liveAtHead[blockIndex];155 if (m_workset .size() == liveAtHead.size())146 Vector<unsigned, 0, UnsafeVectorOverflow, 1>& liveAtHead = m_liveAtHead[blockIndex]; 147 if (m_workset->size() == liveAtHead.size()) 156 148 return false; 157 149 158 150 for (unsigned liveIndexAtHead : liveAtHead) 159 m_workset .remove(liveIndexAtHead);160 ASSERT(!m_workset .isEmpty());151 m_workset->remove(liveIndexAtHead); 152 ASSERT(!m_workset->isEmpty()); 161 153 162 liveAtHead.reserveCapacity(liveAtHead.size() + m_workset .size());163 for (unsigned newValue : m_workset)154 liveAtHead.reserveCapacity(liveAtHead.size() + m_workset->size()); 155 for (unsigned newValue : *m_workset) 164 156 liveAtHead.uncheckedAppend(newValue); 165 157 166 158 bool changedPredecessor = false; 167 159 for (BasicBlock* predecessor : block->predecessors) { 168 auto& liveAtTail = m_liveAtTail[predecessor]; 169 for (unsigned newValue : m_workset) { 160 HashSet<unsigned, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned>>& 161 liveAtTail = m_liveAtTail[predecessor]; 162 for (unsigned newValue : *m_workset) { 170 163 if (liveAtTail.add(newValue)) { 171 164 if (!m_dirtyBlocks.quickSet(predecessor->index)) … … 177 170 } 178 171 179 ALWAYS_INLINE void addChildUse(Node*, Edge& edge)180 {181 bool newEntry = m_workset.add(edge->index());182 edge.setKillStatus(newEntry ? DoesKill : DoesNotKill);183 }184 185 172 // Blocks with new live values at tail. 186 173 BitVector m_dirtyBlocks; 174 175 FlowIndexing& m_indexing; 187 176 188 177 // Live values per block edge. … … 191 180 192 181 // Single sparse set allocated once and used by every basic block. 193 IndexSparseSet<UnsafeVectorOverflow> m_workset;182 std::unique_ptr<IndexSparseSet<UnsafeVectorOverflow>> m_workset; 194 183 }; 195 184
Note:
See TracChangeset
for help on using the changeset viewer.