]>
git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGNaturalLoops.h
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.
26 #ifndef DFGNaturalLoops_h
27 #define DFGNaturalLoops_h
31 #include "DFGAnalysis.h"
32 #include "DFGBasicBlock.h"
33 #include "DFGCommon.h"
35 namespace JSC
{ namespace DFG
{
43 , m_outerLoopIndex(UINT_MAX
)
47 NaturalLoop(BasicBlock
* header
, unsigned index
)
49 , m_outerLoopIndex(UINT_MAX
)
54 BasicBlock
* header() const { return m_header
; }
56 unsigned size() const { return m_body
.size(); }
57 BasicBlock
* at(unsigned i
) const { return m_body
[i
]; }
58 BasicBlock
* operator[](unsigned i
) const { return at(i
); }
60 // This is the slower, but simpler, way of asking if a block belongs to
61 // a natural loop. It's faster to call NaturalLoops::belongsTo(), which
62 // tries to be O(loop depth) rather than O(loop size). Loop depth is
63 // almost always smaller than loop size. A *lot* smaller.
64 bool contains(BasicBlock
* block
) const
66 for (unsigned i
= m_body
.size(); i
--;) {
67 if (m_body
[i
] == block
)
70 ASSERT(block
!= header()); // Header should be contained.
74 // The index of this loop in NaturalLoops.
75 unsigned index() const { return m_index
; }
77 bool isOuterMostLoop() const { return m_outerLoopIndex
== UINT_MAX
; }
79 void dump(PrintStream
&) const;
81 friend class NaturalLoops
;
83 void addBlock(BasicBlock
* block
) { m_body
.append(block
); }
86 Vector
<BasicBlock
*, 4> m_body
;
87 unsigned m_outerLoopIndex
;
91 class NaturalLoops
: public Analysis
<NaturalLoops
> {
98 unsigned numLoops() const
101 return m_loops
.size();
103 const NaturalLoop
& loop(unsigned i
) const
109 // Return either null if the block isn't a loop header, or the
110 // loop it belongs to.
111 const NaturalLoop
* headerOf(BasicBlock
* block
) const
114 const NaturalLoop
* loop
= innerMostLoopOf(block
);
117 if (loop
->header() == block
)
119 if (!ASSERT_DISABLED
) {
120 for (; loop
; loop
= innerMostOuterLoop(*loop
))
121 ASSERT(loop
->header() != block
);
126 const NaturalLoop
* innerMostLoopOf(BasicBlock
* block
) const
129 unsigned index
= block
->innerMostLoopIndices
[0];
130 if (index
== UINT_MAX
)
132 return &m_loops
[index
];
135 const NaturalLoop
* innerMostOuterLoop(const NaturalLoop
& loop
) const
138 if (loop
.m_outerLoopIndex
== UINT_MAX
)
140 return &m_loops
[loop
.m_outerLoopIndex
];
143 bool belongsTo(BasicBlock
* block
, const NaturalLoop
& candidateLoop
) const
146 // It's faster to do this test using the loop itself, if it's small.
147 if (candidateLoop
.size() < 4)
148 return candidateLoop
.contains(block
);
150 for (const NaturalLoop
* loop
= innerMostLoopOf(block
); loop
; loop
= innerMostOuterLoop(*loop
)) {
151 if (loop
== &candidateLoop
)
157 unsigned loopDepth(BasicBlock
* block
) const
160 for (const NaturalLoop
* loop
= innerMostLoopOf(block
); loop
; loop
= innerMostOuterLoop(*loop
))
165 // Return the indices of all loops this belongs to.
166 Vector
<const NaturalLoop
*> loopsOf(BasicBlock
*) const;
168 void dump(PrintStream
&) const;
170 // If we ever had a scalability problem in our natural loop finder, we could
171 // use some HashMap's here. But it just feels a heck of a lot less convenient.
172 Vector
<NaturalLoop
, 4> m_loops
;
175 } } // namespace JSC::DFG
177 #endif // ENABLE(DFG_JIT)
179 #endif // DFGNaturalLoops_h