1/*
2 * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
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
26#pragma once
27
28#if ENABLE(DFG_JIT)
29
30#include "DFGBasicBlock.h"
31#include <wtf/BitVector.h>
32
33namespace JSC { namespace DFG {
34
35class Graph;
36
37class BlockSet {
38public:
39 BlockSet() { }
40
41 // Return true if the block was added, false if it was already present.
42 bool add(BasicBlock* block)
43 {
44 return !m_set.set(block->index);
45 }
46
47 // Return true if the block was removed, false if it was already absent.
48 bool remove(BasicBlock* block)
49 {
50 return m_set.clear(block->index);
51 }
52
53 bool contains(BasicBlock* block) const
54 {
55 if (!block)
56 return false;
57 return m_set.get(block->index);
58 }
59
60 class iterator {
61 public:
62 iterator()
63 : m_graph(nullptr)
64 , m_set(nullptr)
65 , m_index(0)
66 {
67 }
68
69 iterator& operator++()
70 {
71 m_index = m_set->m_set.findBit(m_index + 1, true);
72 return *this;
73 }
74
75 BasicBlock* operator*() const;
76
77 bool operator==(const iterator& other) const
78 {
79 return m_index == other.m_index;
80 }
81
82 bool operator!=(const iterator& other) const
83 {
84 return !(*this == other);
85 }
86
87 private:
88 friend class BlockSet;
89
90 Graph* m_graph;
91 const BlockSet* m_set;
92 size_t m_index;
93 };
94
95 class Iterable {
96 public:
97 Iterable(Graph& graph, const BlockSet& set)
98 : m_graph(graph)
99 , m_set(set)
100 {
101 }
102
103 iterator begin() const
104 {
105 iterator result;
106 result.m_graph = &m_graph;
107 result.m_set = &m_set;
108 result.m_index = m_set.m_set.findBit(0, true);
109 return result;
110 }
111
112 iterator end() const
113 {
114 iterator result;
115 result.m_graph = &m_graph;
116 result.m_set = &m_set;
117 result.m_index = m_set.m_set.size();
118 return result;
119 }
120
121 private:
122 Graph& m_graph;
123 const BlockSet& m_set;
124 };
125
126 Iterable iterable(Graph& graph) const
127 {
128 return Iterable(graph, *this);
129 }
130
131 void dump(PrintStream&) const;
132
133private:
134 BitVector m_set;
135};
136
137class BlockAdder {
138public:
139 BlockAdder(BlockSet& set)
140 : m_set(set)
141 {
142 }
143
144 bool operator()(BasicBlock* block) const
145 {
146 return m_set.add(block);
147 }
148private:
149 BlockSet& m_set;
150};
151
152} } // namespace JSC::DFG
153
154#endif // ENABLE(DFG_JIT)
155