]>
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
> {
96 void computeDependencies(Graph
&);
99 unsigned numLoops() const
102 return m_loops
.size();
104 const NaturalLoop
& loop(unsigned i
) const
110 // Return either null if the block isn't a loop header, or the
111 // loop it belongs to.
112 const NaturalLoop
* headerOf(BasicBlock
* block
) const
115 const NaturalLoop
* loop
= innerMostLoopOf(block
);
118 if (loop
->header() == block
)
120 if (!ASSERT_DISABLED
) {
121 for (; loop
; loop
= innerMostOuterLoop(*loop
))
122 ASSERT(loop
->header() != block
);
127 const NaturalLoop
* innerMostLoopOf(BasicBlock
* block
) const
130 unsigned index
= block
->innerMostLoopIndices
[0];
131 if (index
== UINT_MAX
)
133 return &m_loops
[index
];
136 const NaturalLoop
* innerMostOuterLoop(const NaturalLoop
& loop
) const
139 if (loop
.m_outerLoopIndex
== UINT_MAX
)
141 return &m_loops
[loop
.m_outerLoopIndex
];
144 bool belongsTo(BasicBlock
* block
, const NaturalLoop
& candidateLoop
) const
147 // It's faster to do this test using the loop itself, if it's small.
148 if (candidateLoop
.size() < 4)
149 return candidateLoop
.contains(block
);
151 for (const NaturalLoop
* loop
= innerMostLoopOf(block
); loop
; loop
= innerMostOuterLoop(*loop
)) {
152 if (loop
== &candidateLoop
)
158 unsigned loopDepth(BasicBlock
* block
) const
161 for (const NaturalLoop
* loop
= innerMostLoopOf(block
); loop
; loop
= innerMostOuterLoop(*loop
))
166 // Return the indices of all loops this belongs to.
167 Vector
<const NaturalLoop
*> loopsOf(BasicBlock
*) const;
169 void dump(PrintStream
&) const;
171 // If we ever had a scalability problem in our natural loop finder, we could
172 // use some HashMap's here. But it just feels a heck of a lot less convenient.
173 Vector
<NaturalLoop
, 4> m_loops
;
176 } } // namespace JSC::DFG
178 #endif // ENABLE(DFG_JIT)
180 #endif // DFGNaturalLoops_h