Replace WTF::move with WTFMove
[WebKit-https.git] / Source / JavaScriptCore / b3 / B3Procedure.cpp
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 #include "config.h"
27 #include "B3Procedure.h"
28
29 #if ENABLE(B3_JIT)
30
31 #include "AirCode.h"
32 #include "B3BasicBlockInlines.h"
33 #include "B3BasicBlockUtils.h"
34 #include "B3BlockWorklist.h"
35 #include "B3CFG.h"
36 #include "B3DataSection.h"
37 #include "B3Dominators.h"
38 #include "B3OpaqueByproducts.h"
39 #include "B3ValueInlines.h"
40
41 namespace JSC { namespace B3 {
42
43 Procedure::Procedure()
44     : m_cfg(new CFG(*this))
45     , m_lastPhaseName("initial")
46     , m_byproducts(std::make_unique<OpaqueByproducts>())
47     , m_code(new Air::Code(*this))
48 {
49 }
50
51 Procedure::~Procedure()
52 {
53 }
54
55 void Procedure::printOrigin(PrintStream& out, Origin origin) const
56 {
57     if (m_originPrinter)
58         m_originPrinter->run(out, origin);
59     else
60         out.print(origin);
61 }
62
63 BasicBlock* Procedure::addBlock(double frequency)
64 {
65     std::unique_ptr<BasicBlock> block(new BasicBlock(m_blocks.size(), frequency));
66     BasicBlock* result = block.get();
67     m_blocks.append(WTFMove(block));
68     return result;
69 }
70
71 Value* Procedure::addIntConstant(Origin origin, Type type, int64_t value)
72 {
73     switch (type) {
74     case Int32:
75         return add<Const32Value>(origin, static_cast<int32_t>(value));
76     case Int64:
77         return add<Const64Value>(origin, value);
78     case Double:
79         return add<ConstDoubleValue>(origin, static_cast<double>(value));
80     case Float:
81         return add<ConstFloatValue>(origin, static_cast<float>(value));
82     default:
83         RELEASE_ASSERT_NOT_REACHED();
84         return nullptr;
85     }
86 }
87
88 Value* Procedure::addIntConstant(Value* likeValue, int64_t value)
89 {
90     return addIntConstant(likeValue->origin(), likeValue->type(), value);
91 }
92
93 Value* Procedure::addBoolConstant(Origin origin, TriState triState)
94 {
95     int32_t value = 0;
96     switch (triState) {
97     case FalseTriState:
98         value = 0;
99         break;
100     case TrueTriState:
101         value = 1;
102         break;
103     case MixedTriState:
104         return nullptr;
105     }
106
107     return addIntConstant(origin, Int32, value);
108 }
109
110 void Procedure::resetValueOwners()
111 {
112     for (BasicBlock* block : *this) {
113         for (Value* value : *block)
114             value->owner = block;
115     }
116 }
117
118 void Procedure::resetReachability()
119 {
120     B3::resetReachability(
121         m_blocks,
122         [&] (BasicBlock* deleted) {
123             // Gotta delete the values in this block.
124             for (Value* value : *deleted)
125                 deleteValue(value);
126         });
127 }
128
129 void Procedure::invalidateCFG()
130 {
131     m_dominators = nullptr;
132 }
133
134 void Procedure::dump(PrintStream& out) const
135 {
136     for (BasicBlock* block : *this)
137         out.print(deepDump(*this, block));
138     if (m_byproducts->count())
139         out.print(*m_byproducts);
140 }
141
142 Vector<BasicBlock*> Procedure::blocksInPreOrder()
143 {
144     return B3::blocksInPreOrder(at(0));
145 }
146
147 Vector<BasicBlock*> Procedure::blocksInPostOrder()
148 {
149     return B3::blocksInPostOrder(at(0));
150 }
151
152 void Procedure::deleteValue(Value* value)
153 {
154     ASSERT(m_values[value->index()].get() == value);
155     m_valueIndexFreeList.append(value->index());
156     m_values[value->index()] = nullptr;
157 }
158
159 Dominators& Procedure::dominators()
160 {
161     if (!m_dominators)
162         m_dominators = std::make_unique<Dominators>(*this);
163     return *m_dominators;
164 }
165
166 void Procedure::addFastConstant(const ValueKey& constant)
167 {
168     RELEASE_ASSERT(constant.isConstant());
169     m_fastConstants.add(constant);
170 }
171
172 bool Procedure::isFastConstant(const ValueKey& constant)
173 {
174     if (!constant)
175         return false;
176     return m_fastConstants.contains(constant);
177 }
178
179 void* Procedure::addDataSection(size_t size)
180 {
181     if (!size)
182         return nullptr;
183     std::unique_ptr<DataSection> dataSection = std::make_unique<DataSection>(size);
184     void* result = dataSection->data();
185     m_byproducts->add(WTFMove(dataSection));
186     return result;
187 }
188
189 unsigned Procedure::callArgAreaSize() const
190 {
191     return code().callArgAreaSize();
192 }
193
194 void Procedure::requestCallArgAreaSize(unsigned size)
195 {
196     code().requestCallArgAreaSize(size);
197 }
198
199 unsigned Procedure::frameSize() const
200 {
201     return code().frameSize();
202 }
203
204 const RegisterAtOffsetList& Procedure::calleeSaveRegisters() const
205 {
206     return code().calleeSaveRegisters();
207 }
208
209 size_t Procedure::addValueIndex()
210 {
211     if (m_valueIndexFreeList.isEmpty()) {
212         size_t index = m_values.size();
213         m_values.append(nullptr);
214         return index;
215     }
216     
217     return m_valueIndexFreeList.takeLast();
218 }
219
220 } } // namespace JSC::B3
221
222 #endif // ENABLE(B3_JIT)