]>
git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGDominators.h
e218ba792f261c1ad3f3055c7b0486eb1a9caa60
2 * Copyright (C) 2011, 2014 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 DFGDominators_h
27 #define DFGDominators_h
31 #include "DFGAnalysis.h"
32 #include "DFGBasicBlock.h"
33 #include "DFGBlockMap.h"
34 #include "DFGBlockSet.h"
35 #include "DFGCommon.h"
37 namespace JSC
{ namespace DFG
{
41 class Dominators
: public Analysis
<Dominators
> {
48 bool strictlyDominates(BasicBlock
* from
, BasicBlock
* to
) const
51 return m_data
[to
].preNumber
> m_data
[from
].preNumber
52 && m_data
[to
].postNumber
< m_data
[from
].postNumber
;
55 bool dominates(BasicBlock
* from
, BasicBlock
* to
) const
57 return from
== to
|| strictlyDominates(from
, to
);
60 BasicBlock
* immediateDominatorOf(BasicBlock
* block
) const
62 return m_data
[block
].idomParent
;
65 template<typename Functor
>
66 void forAllStrictDominatorsOf(BasicBlock
* to
, const Functor
& functor
) const
68 for (BasicBlock
* block
= m_data
[to
].idomParent
; block
; block
= m_data
[block
].idomParent
)
72 template<typename Functor
>
73 void forAllDominatorsOf(BasicBlock
* to
, const Functor
& functor
) const
75 for (BasicBlock
* block
= to
; block
; block
= m_data
[block
].idomParent
)
79 template<typename Functor
>
80 void forAllBlocksStrictlyDominatedBy(BasicBlock
* from
, const Functor
& functor
) const
82 Vector
<BasicBlock
*, 16> worklist
;
83 worklist
.appendVector(m_data
[from
].idomKids
);
84 while (!worklist
.isEmpty()) {
85 BasicBlock
* block
= worklist
.takeLast();
87 worklist
.appendVector(m_data
[block
].idomKids
);
91 template<typename Functor
>
92 void forAllBlocksDominatedBy(BasicBlock
* from
, const Functor
& functor
) const
94 Vector
<BasicBlock
*, 16> worklist
;
95 worklist
.append(from
);
96 while (!worklist
.isEmpty()) {
97 BasicBlock
* block
= worklist
.takeLast();
99 worklist
.appendVector(m_data
[block
].idomKids
);
103 BlockSet
strictDominatorsOf(BasicBlock
* to
) const;
104 BlockSet
dominatorsOf(BasicBlock
* to
) const;
105 BlockSet
blocksStrictlyDominatedBy(BasicBlock
* from
) const;
106 BlockSet
blocksDominatedBy(BasicBlock
* from
) const;
108 template<typename Functor
>
109 void forAllBlocksInDominanceFrontierOf(
110 BasicBlock
* from
, const Functor
& functor
) const
113 forAllBlocksInDominanceFrontierOfImpl(
115 [&] (BasicBlock
* block
) {
121 BlockSet
dominanceFrontierOf(BasicBlock
* from
) const;
123 template<typename Functor
>
124 void forAllBlocksInIteratedDominanceFrontierOf(
125 const BlockList
& from
, const Functor
& functor
)
127 forAllBlocksInPrunedIteratedDominanceFrontierOf(
129 [&] (BasicBlock
* block
) -> bool {
135 // This is a close relative of forAllBlocksInIteratedDominanceFrontierOf(), which allows the
136 // given functor to return false to indicate that we don't wish to consider the given block.
137 // Useful for computing pruned SSA form.
138 template<typename Functor
>
139 void forAllBlocksInPrunedIteratedDominanceFrontierOf(
140 const BlockList
& from
, const Functor
& functor
)
143 forAllBlocksInIteratedDominanceFrontierOfImpl(
145 [&] (BasicBlock
* block
) -> bool {
148 return functor(block
);
152 BlockSet
iteratedDominanceFrontierOf(const BlockList
& from
) const;
154 void dump(PrintStream
&) const;
157 bool naiveDominates(BasicBlock
* from
, BasicBlock
* to
) const;
159 template<typename Functor
>
160 void forAllBlocksInDominanceFrontierOfImpl(
161 BasicBlock
* from
, const Functor
& functor
) const
163 // Paraphrasing from http://en.wikipedia.org/wiki/Dominator_(graph_theory):
164 // "The dominance frontier of a block 'from' is the set of all blocks 'to' such that
165 // 'from' dominates an immediate predecessor of 'to', but 'from' does not strictly
168 // A useful corner case to remember: a block may be in its own dominance frontier if it has
169 // a loop edge to itself, since it dominates itself and so it dominates its own immediate
170 // predecessor, and a block never strictly dominates itself.
172 forAllBlocksDominatedBy(
174 [&] (BasicBlock
* block
) {
175 for (unsigned successorIndex
= block
->numSuccessors(); successorIndex
--;) {
176 BasicBlock
* to
= block
->successor(successorIndex
);
177 if (!strictlyDominates(from
, to
))
183 template<typename Functor
>
184 void forAllBlocksInIteratedDominanceFrontierOfImpl(
185 const BlockList
& from
, const Functor
& functor
) const
187 BlockList worklist
= from
;
188 while (!worklist
.isEmpty()) {
189 BasicBlock
* block
= worklist
.takeLast();
190 forAllBlocksInDominanceFrontierOfImpl(
192 [&] (BasicBlock
* otherBlock
) {
193 if (functor(otherBlock
))
194 worklist
.append(otherBlock
);
201 : idomParent(nullptr)
202 , preNumber(UINT_MAX
)
203 , postNumber(UINT_MAX
)
207 Vector
<BasicBlock
*> idomKids
;
208 BasicBlock
* idomParent
;
214 BlockMap
<BlockData
> m_data
;
217 } } // namespace JSC::DFG
219 #endif // ENABLE(DFG_JIT)
221 #endif // DFGDominators_h