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