]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGDominators.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGDominators.h
CommitLineData
f9bf01c6 1/*
ed1e77d3 2 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved.
f9bf01c6
A
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
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.
24 */
25
93a37866
A
26#ifndef DFGDominators_h
27#define DFGDominators_h
28
6fe7ccc8 29#if ENABLE(DFG_JIT)
f9bf01c6 30
81345200
A
31#include "DFGAnalysis.h"
32#include "DFGBasicBlock.h"
ed1e77d3
A
33#include "DFGBlockMap.h"
34#include "DFGBlockSet.h"
93a37866 35#include "DFGCommon.h"
f9bf01c6 36
6fe7ccc8 37namespace JSC { namespace DFG {
f9bf01c6 38
93a37866
A
39class Graph;
40
81345200 41class Dominators : public Analysis<Dominators> {
93a37866
A
42public:
43 Dominators();
44 ~Dominators();
45
81345200 46 void compute(Graph&);
93a37866 47
ed1e77d3 48 bool strictlyDominates(BasicBlock* from, BasicBlock* to) const
93a37866
A
49 {
50 ASSERT(isValid());
ed1e77d3
A
51 return m_data[to].preNumber > m_data[from].preNumber
52 && m_data[to].postNumber < m_data[from].postNumber;
93a37866
A
53 }
54
81345200
A
55 bool dominates(BasicBlock* from, BasicBlock* to) const
56 {
ed1e77d3 57 return from == to || strictlyDominates(from, to);
81345200
A
58 }
59
ed1e77d3
A
60 BasicBlock* immediateDominatorOf(BasicBlock* block) const
61 {
62 return m_data[block].idomParent;
63 }
64
65 template<typename Functor>
66 void forAllStrictDominatorsOf(BasicBlock* to, const Functor& functor) const
67 {
68 for (BasicBlock* block = m_data[to].idomParent; block; block = m_data[block].idomParent)
69 functor(block);
70 }
71
72 template<typename Functor>
73 void forAllDominatorsOf(BasicBlock* to, const Functor& functor) const
74 {
75 for (BasicBlock* block = to; block; block = m_data[block].idomParent)
76 functor(block);
77 }
78
79 template<typename Functor>
80 void forAllBlocksStrictlyDominatedBy(BasicBlock* from, const Functor& functor) const
81 {
82 Vector<BasicBlock*, 16> worklist;
83 worklist.appendVector(m_data[from].idomKids);
84 while (!worklist.isEmpty()) {
85 BasicBlock* block = worklist.takeLast();
86 functor(block);
87 worklist.appendVector(m_data[block].idomKids);
88 }
89 }
90
91 template<typename Functor>
92 void forAllBlocksDominatedBy(BasicBlock* from, const Functor& functor) const
93 {
94 Vector<BasicBlock*, 16> worklist;
95 worklist.append(from);
96 while (!worklist.isEmpty()) {
97 BasicBlock* block = worklist.takeLast();
98 functor(block);
99 worklist.appendVector(m_data[block].idomKids);
100 }
101 }
102
103 BlockSet strictDominatorsOf(BasicBlock* to) const;
104 BlockSet dominatorsOf(BasicBlock* to) const;
105 BlockSet blocksStrictlyDominatedBy(BasicBlock* from) const;
106 BlockSet blocksDominatedBy(BasicBlock* from) const;
107
108 template<typename Functor>
109 void forAllBlocksInDominanceFrontierOf(
110 BasicBlock* from, const Functor& functor) const
111 {
112 BlockSet set;
113 forAllBlocksInDominanceFrontierOfImpl(
114 from,
115 [&] (BasicBlock* block) {
116 if (set.add(block))
117 functor(block);
118 });
119 }
120
121 BlockSet dominanceFrontierOf(BasicBlock* from) const;
122
123 template<typename Functor>
124 void forAllBlocksInIteratedDominanceFrontierOf(
125 const BlockList& from, const Functor& functor)
126 {
127 forAllBlocksInPrunedIteratedDominanceFrontierOf(
128 from,
129 [&] (BasicBlock* block) -> bool {
130 functor(block);
131 return true;
132 });
133 }
134
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)
141 {
142 BlockSet set;
143 forAllBlocksInIteratedDominanceFrontierOfImpl(
144 from,
145 [&] (BasicBlock* block) -> bool {
146 if (!set.add(block))
147 return false;
148 return functor(block);
149 });
150 }
151
152 BlockSet iteratedDominanceFrontierOf(const BlockList& from) const;
153
154 void dump(PrintStream&) const;
81345200 155
93a37866 156private:
ed1e77d3
A
157 bool naiveDominates(BasicBlock* from, BasicBlock* to) const;
158
159 template<typename Functor>
160 void forAllBlocksInDominanceFrontierOfImpl(
161 BasicBlock* from, const Functor& functor) const
162 {
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
166 // dominate 'to'."
167 //
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.
171
172 forAllBlocksDominatedBy(
173 from,
174 [&] (BasicBlock* block) {
175 for (unsigned successorIndex = block->numSuccessors(); successorIndex--;) {
176 BasicBlock* to = block->successor(successorIndex);
177 if (!strictlyDominates(from, to))
178 functor(to);
179 }
180 });
181 }
182
183 template<typename Functor>
184 void forAllBlocksInIteratedDominanceFrontierOfImpl(
185 const BlockList& from, const Functor& functor) const
186 {
187 BlockList worklist = from;
188 while (!worklist.isEmpty()) {
189 BasicBlock* block = worklist.takeLast();
190 forAllBlocksInDominanceFrontierOfImpl(
191 block,
192 [&] (BasicBlock* otherBlock) {
193 if (functor(otherBlock))
194 worklist.append(otherBlock);
195 });
196 }
197 }
198
199 struct BlockData {
200 BlockData()
201 : idomParent(nullptr)
202 , preNumber(UINT_MAX)
203 , postNumber(UINT_MAX)
204 {
205 }
206
207 Vector<BasicBlock*> idomKids;
208 BasicBlock* idomParent;
209
210 unsigned preNumber;
211 unsigned postNumber;
212 };
93a37866 213
ed1e77d3 214 BlockMap<BlockData> m_data;
93a37866 215};
f9bf01c6 216
6fe7ccc8 217} } // namespace JSC::DFG
f9bf01c6 218
6fe7ccc8 219#endif // ENABLE(DFG_JIT)
93a37866
A
220
221#endif // DFGDominators_h