f6888ca124d3d85e89cefa8022d5878f0b2db6be
[WebKit-https.git] / Source / JavaScriptCore / b3 / B3BasicBlock.h
1 /*
2  * Copyright (C) 2015 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 #ifndef B3BasicBlock_h
27 #define B3BasicBlock_h
28
29 #if ENABLE(B3_JIT)
30
31 #include "B3FrequentedBlock.h"
32 #include "B3Origin.h"
33 #include "B3SuccessorCollection.h"
34 #include "B3Type.h"
35 #include <wtf/Vector.h>
36
37 namespace JSC { namespace B3 {
38
39 class BlockInsertionSet;
40 class InsertionSet;
41 class Procedure;
42 class Value;
43
44 class BasicBlock {
45     WTF_MAKE_NONCOPYABLE(BasicBlock);
46     WTF_MAKE_FAST_ALLOCATED;
47 public:
48     typedef Vector<Value*> ValueList;
49     typedef Vector<BasicBlock*, 2> PredecessorList;
50     typedef Vector<FrequentedBlock, 2> SuccessorList; // This matches ControlValue::SuccessorList
51
52     static const char* const dumpPrefix;
53
54     ~BasicBlock();
55
56     unsigned index() const { return m_index; }
57
58     ValueList::iterator begin() { return m_values.begin(); }
59     ValueList::iterator end() { return m_values.end(); }
60     ValueList::const_iterator begin() const { return m_values.begin(); }
61     ValueList::const_iterator end() const { return m_values.end(); }
62
63     size_t size() const { return m_values.size(); }
64     Value* at(size_t index) const { return m_values[index]; }
65     Value*& at(size_t index) { return m_values[index]; }
66
67     Value* last() const { return m_values.last(); }
68     Value*& last() { return m_values.last(); }
69
70     const ValueList& values() const { return m_values; }
71     ValueList& values() { return m_values; }
72
73     JS_EXPORT_PRIVATE void append(Value*);
74     JS_EXPORT_PRIVATE void replaceLast(Procedure&, Value*);
75
76     template<typename ValueType, typename... Arguments>
77     ValueType* appendNew(Procedure&, Arguments...);
78
79     Value* appendIntConstant(Procedure&, Origin, Type, int64_t value);
80     Value* appendIntConstant(Procedure&, Value* likeValue, int64_t value);
81
82     void removeLast(Procedure&);
83     
84     template<typename ValueType, typename... Arguments>
85     ValueType* replaceLastWithNew(Procedure&, Arguments...);
86
87     unsigned numSuccessors() const;
88     const FrequentedBlock& successor(unsigned index) const;
89     FrequentedBlock& successor(unsigned index);
90     const SuccessorList& successors() const;
91     SuccessorList& successors();
92
93     BasicBlock* successorBlock(unsigned index) const;
94     BasicBlock*& successorBlock(unsigned index);
95     SuccessorCollection<BasicBlock, SuccessorList> successorBlocks();
96     SuccessorCollection<const BasicBlock, const SuccessorList> successorBlocks() const;
97
98     bool replaceSuccessor(BasicBlock* from, BasicBlock* to);
99
100     unsigned numPredecessors() const { return m_predecessors.size(); }
101     BasicBlock* predecessor(unsigned index) const { return m_predecessors[index]; }
102     BasicBlock*& predecessor(unsigned index) { return m_predecessors[index]; }
103     const PredecessorList& predecessors() const { return m_predecessors; }
104     PredecessorList& predecessors() { return m_predecessors; }
105     bool containsPredecessor(BasicBlock* block) { return m_predecessors.contains(block); }
106
107     bool addPredecessor(BasicBlock*);
108     bool removePredecessor(BasicBlock*);
109     bool replacePredecessor(BasicBlock* from, BasicBlock* to);
110
111     // Update predecessors starting with the successors of this block.
112     void updatePredecessorsAfter();
113
114     double frequency() const { return m_frequency; }
115
116     void dump(PrintStream&) const;
117     void deepDump(const Procedure&, PrintStream&) const;
118
119 private:
120     friend class BlockInsertionSet;
121     friend class InsertionSet;
122     friend class Procedure;
123     
124     // Instantiate via Procedure.
125     BasicBlock(unsigned index, double frequency);
126
127     unsigned m_index;
128     ValueList m_values;
129     PredecessorList m_predecessors;
130     double m_frequency;
131 };
132
133 class DeepBasicBlockDump {
134 public:
135     DeepBasicBlockDump(const Procedure& proc, const BasicBlock* block)
136         : m_proc(proc)
137         , m_block(block)
138     {
139     }
140
141     void dump(PrintStream& out) const
142     {
143         if (m_block)
144             m_block->deepDump(m_proc, out);
145         else
146             out.print("<null>");
147     }
148
149 private:
150     const Procedure& m_proc;
151     const BasicBlock* m_block;
152 };
153
154 inline DeepBasicBlockDump deepDump(const Procedure& proc, const BasicBlock* block)
155 {
156     return DeepBasicBlockDump(proc, block);
157 }
158
159 } } // namespace JSC::B3
160
161 #endif // ENABLE(B3_JIT)
162
163 #endif // B3BasicBlock_h
164