B3 should be able to compile a program with ChillDiv
[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     template<typename ValueType, typename... Arguments>
83     ValueType* replaceLastWithNew(Procedure&, Arguments...);
84
85     unsigned numSuccessors() const;
86     const FrequentedBlock& successor(unsigned index) const;
87     FrequentedBlock& successor(unsigned index);
88     const SuccessorList& successors() const;
89     SuccessorList& successors();
90
91     BasicBlock* successorBlock(unsigned index) const;
92     BasicBlock*& successorBlock(unsigned index);
93     SuccessorCollection<BasicBlock, SuccessorList> successorBlocks();
94     SuccessorCollection<const BasicBlock, const SuccessorList> successorBlocks() const;
95
96     bool replaceSuccessor(BasicBlock* from, BasicBlock* to);
97
98     unsigned numPredecessors() const { return m_predecessors.size(); }
99     BasicBlock* predecessor(unsigned index) const { return m_predecessors[index]; }
100     BasicBlock*& predecessor(unsigned index) { return m_predecessors[index]; }
101     const PredecessorList& predecessors() const { return m_predecessors; }
102     PredecessorList& predecessors() { return m_predecessors; }
103     bool containsPredecessor(BasicBlock* block) { return m_predecessors.contains(block); }
104
105     bool addPredecessor(BasicBlock*);
106     bool removePredecessor(BasicBlock*);
107     bool replacePredecessor(BasicBlock* from, BasicBlock* to);
108
109     // Update predecessors starting with the successors of this block.
110     void updatePredecessorsAfter();
111
112     double frequency() const { return m_frequency; }
113
114     void dump(PrintStream&) const;
115     void deepDump(PrintStream&) const;
116
117 private:
118     friend class BlockInsertionSet;
119     friend class InsertionSet;
120     friend class Procedure;
121     
122     // Instantiate via Procedure.
123     BasicBlock(unsigned index, double frequency);
124
125     unsigned m_index;
126     ValueList m_values;
127     PredecessorList m_predecessors;
128     double m_frequency;
129 };
130
131 class DeepBasicBlockDump {
132 public:
133     DeepBasicBlockDump(const BasicBlock* block)
134         : m_block(block)
135     {
136     }
137
138     void dump(PrintStream& out) const
139     {
140         if (m_block)
141             m_block->deepDump(out);
142         else
143             out.print("<null>");
144     }
145
146 private:
147     const BasicBlock* m_block;
148 };
149
150 inline DeepBasicBlockDump deepDump(const BasicBlock* block)
151 {
152     return DeepBasicBlockDump(block);
153 }
154
155 } } // namespace JSC::B3
156
157 #endif // ENABLE(B3_JIT)
158
159 #endif // B3BasicBlock_h
160