WebKit Bugzilla
Attachment 342413 Details for
Bug 184829
: The NaturalLoops algorithm only works when the list of blocks in a loop is de-duplicated
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
c-backup.diff (text/plain), 8.64 KB, created by
Saam Barati
on 2018-06-11 01:02:30 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Saam Barati
Created:
2018-06-11 01:02:30 PDT
Size:
8.64 KB
patch
obsolete
>Index: Source/JavaScriptCore/dfg/DFGGraph.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGGraph.cpp (revision 232668) >+++ Source/JavaScriptCore/dfg/DFGGraph.cpp (working copy) >@@ -465,8 +465,8 @@ void Graph::dumpBlockHeader(PrintStream& > if (const auto* loop = naturalLoops->headerOf(block)) { > out.print(prefix, " Loop header, contains:"); > Vector<BlockIndex> sortedBlockList; >- for (unsigned i = 0; i < loop->size(); ++i) >- sortedBlockList.append(unboxLoopNode(loop->at(i))->index); >+ for (auto node : *loop) >+ sortedBlockList.append(unboxLoopNode(node)->index); > std::sort(sortedBlockList.begin(), sortedBlockList.end()); > for (unsigned i = 0; i < sortedBlockList.size(); ++i) > out.print(" #", sortedBlockList[i]); >Index: Source/JavaScriptCore/dfg/DFGLICMPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGLICMPhase.cpp (revision 232668) >+++ Source/JavaScriptCore/dfg/DFGLICMPhase.cpp (working copy) >@@ -277,8 +277,7 @@ private: > // Modify the states at the end of the preHeader of the loop we hoisted to, > // and all pre-headers inside the loop. This isn't a stability bottleneck right now > // because most loops are small and most blocks belong to few loops. >- for (unsigned bodyIndex = loop->size(); bodyIndex--;) { >- BasicBlock* subBlock = loop->at(bodyIndex); >+ for (BasicBlock* subBlock : *loop) { > const NaturalLoop* subLoop = m_graph.m_ssaNaturalLoops->headerOf(subBlock); > if (!subLoop) > continue; >Index: Source/WTF/wtf/NaturalLoops.h >=================================================================== >--- Source/WTF/wtf/NaturalLoops.h (revision 232668) >+++ Source/WTF/wtf/NaturalLoops.h (working copy) >@@ -53,10 +53,10 @@ public: > Graph* graph() const { return m_graph; } > > typename Graph::Node header() const { return m_header; } >- >+ > unsigned size() const { return m_body.size(); } >- typename Graph::Node at(unsigned i) const { return m_body[i]; } >- typename Graph::Node operator[](unsigned i) const { return at(i); } >+ typename HashSet<typename Graph::Node>::iterator begin() const { return m_body.begin(); } >+ typename HashSet<typename Graph::Node>::iterator end() const { return m_body.end(); } > > // This is the slower, but simpler, way of asking if a block belongs to > // a natural loop. It's faster to call NaturalLoops::belongsTo(), which >@@ -64,12 +64,10 @@ public: > // almost always smaller than loop size. A *lot* smaller. > bool contains(typename Graph::Node block) const > { >- for (unsigned i = m_body.size(); i--;) { >- if (m_body[i] == block) >- return true; >- } >- ASSERT(block != header()); // Header should be contained. >- return false; >+ bool result = m_body.contains(block); >+ if (!result) >+ ASSERT(block != header()); // Header should be contained. >+ return result; > } > > // The index of this loop in NaturalLoops. >@@ -85,8 +83,8 @@ public: > } > > out.print("[Header: ", m_graph->dump(header()), ", Body:"); >- for (unsigned i = 0; i < m_body.size(); ++i) >- out.print(" ", m_graph->dump(m_body[i])); >+ for (auto node : m_body) >+ out.print(" ", m_graph->dump(node)); > out.print("]"); > } > >@@ -94,11 +92,11 @@ private: > template<typename> > friend class NaturalLoops; > >- void addBlock(typename Graph::Node block) { m_body.append(block); } >+ void addBlock(typename Graph::Node block) { m_body.add(block); } > > Graph* m_graph; > typename Graph::Node m_header; >- Vector<typename Graph::Node, 4> m_body; >+ HashSet<typename Graph::Node> m_body; > unsigned m_outerLoopIndex; > unsigned m_index; > }; >@@ -170,9 +168,9 @@ public: > if (verbose) > dataLog("Dealing with loop ", loop, "\n"); > >- for (unsigned j = loop.size(); j--;) { >- seenBlocks[graph.index(loop[j])] = true; >- blockWorklist.append(loop[j]); >+ for (typename Graph::Node block : loop) { >+ seenBlocks[graph.index(block)] = true; >+ blockWorklist.append(block); > } > > while (!blockWorklist.isEmpty()) { >@@ -207,9 +205,7 @@ public: > for (unsigned loopIndex = m_loops.size(); loopIndex--;) { > NaturalLoop<Graph>& loop = m_loops[loopIndex]; > >- for (unsigned blockIndexInLoop = loop.size(); blockIndexInLoop--;) { >- typename Graph::Node block = loop[blockIndexInLoop]; >- >+ for (typename Graph::Node block : loop) { > for (unsigned i = 0; i < std::tuple_size<InnerMostLoopIndices>::value; ++i) { > unsigned thisIndex = m_innerMostLoopIndices[block][i]; > if (thisIndex == UINT_MAX || loop.size() < m_loops[thisIndex].size()) { >@@ -221,7 +217,7 @@ public: > } > } > } >- >+ > // Now each block knows its inner-most loop and its next-to-inner-most loop. Use > // this to figure out loop parenting. > for (unsigned i = m_loops.size(); i--;) { >@@ -303,15 +299,7 @@ public: > > bool belongsTo(typename Graph::Node block, const NaturalLoop<Graph>& candidateLoop) const > { >- // It's faster to do this test using the loop itself, if it's small. >- if (candidateLoop.size() < 4) >- return candidateLoop.contains(block); >- >- for (const NaturalLoop<Graph>* loop = innerMostLoopOf(block); loop; loop = innerMostOuterLoop(*loop)) { >- if (loop == &candidateLoop) >- return true; >- } >- return false; >+ return candidateLoop.contains(block); > } > > unsigned loopDepth(typename Graph::Node block) const >Index: Source/WTF/wtf/SingleRootGraph.h >=================================================================== >--- Source/WTF/wtf/SingleRootGraph.h (revision 232668) >+++ Source/WTF/wtf/SingleRootGraph.h (working copy) >@@ -39,7 +39,13 @@ public: > // We use "#root" to refer to the synthetic root we have created. > static const char* rootName() { return "#root"; }; > >- SingleRootGraphNode(typename Graph::Node node = typename Graph::Node()) >+ SingleRootGraphNode() >+ { >+ m_node = 0; >+ m_isRoot = 0; >+ } >+ >+ SingleRootGraphNode(typename Graph::Node node) > : m_node(node) > { > } >@@ -76,11 +82,41 @@ public: > return m_node; > } > >+ static void makeDeletedValue(SingleRootGraphNode& node) >+ { >+ node.m_node = bitwise_cast<typename Graph::Node>(static_cast<uintptr_t>(1)); >+ node.m_isRoot = true; >+ } >+ >+ bool isHashTableDeletedValue() const >+ { >+ return bitwise_cast<uintptr_t>(m_node) == 1 && !!m_isRoot; >+ } >+ >+ static unsigned hash(const SingleRootGraphNode& node) { return WTF::PtrHash<typename Graph::Node>::hash(node.m_node) ^ node.m_isRoot; } >+ static bool equal(const SingleRootGraphNode& a, const SingleRootGraphNode& b) { return a == b; } >+ static const bool safeToCompareToEmptyOrDeleted = true; >+ > private: > typename Graph::Node m_node; >+ static_assert(std::is_pointer<decltype(m_node)>::value, "We rely on this in our construction of deleted and empty values, and comparisons to empty and deleted values"); > bool m_isRoot { false }; > }; > >+template <typename T> >+struct DefaultHash<SingleRootGraphNode<T>> { >+ using Hash = SingleRootGraphNode<T>; >+}; >+ >+template <typename T> >+struct HashTraits<SingleRootGraphNode<T>> : GenericHashTraits<SingleRootGraphNode<T>> { >+ static const bool emptyValueIsZero = true; >+ static SingleRootGraphNode<T> emptyValue() { return SingleRootGraphNode<T>(); } >+ >+ static void constructDeletedValue(SingleRootGraphNode<T>& node) { SingleRootGraphNode<T>::makeDeletedValue(node); } >+ static bool isDeletedValue(const SingleRootGraphNode<T>& key) { return key.isHashTableDeletedValue(); } >+}; >+ > template <typename Graph> > class SingleRootGraphSet { > using Node = SingleRootGraphNode<Graph>; >Index: Source/WebCore/page/FrameView.cpp >=================================================================== >--- Source/WebCore/page/FrameView.cpp (revision 232668) >+++ Source/WebCore/page/FrameView.cpp (working copy) >@@ -4137,7 +4137,7 @@ void FrameView::paintContents(GraphicsCo > if (!layoutContext().inPaintableState()) > return; > >- ASSERT(!needsLayout()); >+ //ASSERT(!needsLayout()); > if (needsLayout()) > return; >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 184829
:
342340
|
342341
|
342413
|
342494
|
342504