Create a super rough prototype of B3
[WebKit-https.git] / Source / JavaScriptCore / b3 / B3Value.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 "B3Value.h"
28
29 #if ENABLE(B3_JIT)
30
31 #include "B3ValueInlines.h"
32 #include <wtf/CommaPrinter.h>
33 #include <wtf/StringPrintStream.h>
34
35 namespace JSC { namespace B3 {
36
37 const char* const Value::dumpPrefix = "@";
38
39 Value::~Value()
40 {
41 }
42
43 void Value::replaceWithIdentity(Value* value)
44 {
45     // This is a bit crazy. It does an in-place replacement of whatever Value subclass this is with
46     // a plain Identity Value. We first collect all of the information we need, then we destruct the
47     // previous value in place, and then we construct the Identity Value in place.
48
49     unsigned index = m_index;
50     Type type = m_type;
51     Origin origin = m_origin;
52     BasicBlock* owner = this->owner;
53
54     RELEASE_ASSERT(type == value->type());
55
56     this->Value::~Value();
57
58     new (this) Value(index, Identity, type, origin, value);
59
60     this->owner = owner;
61 }
62
63 void Value::replaceWithNop()
64 {
65     unsigned index = m_index;
66     Origin origin = m_origin;
67     BasicBlock* owner = this->owner;
68
69     this->Value::~Value();
70
71     new (this) Value(index, Nop, Void, origin);
72
73     this->owner = owner;
74 }
75
76 void Value::dump(PrintStream& out) const
77 {
78     out.print(dumpPrefix, m_index);
79 }
80
81 void Value::deepDump(PrintStream& out) const
82 {
83     out.print(m_type, " ", *this, " = ", m_opcode);
84
85     out.print("(");
86     CommaPrinter comma;
87     for (Value* child : children())
88         out.print(comma, pointerDump(child));
89
90     if (m_origin)
91         out.print(comma, m_origin);
92
93     {
94         StringPrintStream stringOut;
95         dumpMeta(stringOut);
96         CString string = stringOut.toCString();
97         if (string.length())
98             out.print(comma, string);
99     }
100
101     {
102         CString string = toCString(effects());
103         if (string.length())
104             out.print(comma, string);
105     }
106
107     out.print(")");
108 }
109
110 Value* Value::negConstant(Procedure&) const
111 {
112     return nullptr;
113 }
114
115 Value* Value::addConstant(Procedure&, int32_t) const
116 {
117     return nullptr;
118 }
119
120 Value* Value::addConstant(Procedure&, Value*) const
121 {
122     return nullptr;
123 }
124
125 Value* Value::subConstant(Procedure&, Value*) const
126 {
127     return nullptr;
128 }
129
130 Effects Value::effects() const
131 {
132     Effects result;
133     switch (opcode()) {
134     case Nop:
135     case Identity:
136     case Const32:
137     case Const64:
138     case ConstDouble:
139     case StackSlot:
140     case ArgumentReg:
141     case FramePointer:
142     case Add:
143     case Sub:
144     case Mul:
145     case ChillDiv:
146     case Mod:
147     case BitAnd:
148     case BitOr:
149     case BitXor:
150     case Shl:
151     case SShr:
152     case ZShr:
153     case SExt8:
154     case SExt16:
155     case SExt32:
156     case ZExt32:
157     case Trunc:
158     case FRound:
159     case IToD:
160     case DToI32:
161     case Equal:
162     case NotEqual:
163     case LessThan:
164     case GreaterThan:
165     case LessEqual:
166     case GreaterEqual:
167     case Above:
168     case Below:
169     case AboveEqual:
170     case BelowEqual:
171     case Phi:
172         break;
173     case Div:
174         result.controlDependent = true;
175         break;
176     case Load8Z:
177     case Load8S:
178     case Load16Z:
179     case Load16S:
180     case LoadFloat:
181     case Load:
182         // FIXME: MemoryValue should have a HeapRange.
183         // https://bugs.webkit.org/show_bug.cgi?id=150535
184         result.reads = HeapRange::top();
185         result.controlDependent = true;
186         break;
187     case Store8:
188     case Store16:
189     case StoreFloat:
190     case Store:
191         // FIXME: MemoryValue should have a HeapRange.
192         // https://bugs.webkit.org/show_bug.cgi?id=150535
193         result.writes = HeapRange::top();
194         result.controlDependent = true;
195         break;
196     case CCall:
197     case Patchpoint:
198         result.reads = HeapRange::top();
199         result.writes = HeapRange::top();
200         result.exitsSideways = true;
201         result.controlDependent = true;
202         break;
203     case CheckAdd:
204     case CheckSub:
205     case CheckMul:
206     case Check:
207         result.exitsSideways = true;
208         break;
209     case Upsilon:
210         result.writesSSAState = true;
211         break;
212     case Jump:
213     case Branch:
214     case Switch:
215     case Return:
216     case Oops:
217         result.terminal = true;
218         break;
219     }
220     return result;
221 }
222
223 void Value::performSubstitution()
224 {
225     for (Value*& child : children()) {
226         while (child->opcode() == Identity)
227             child = child->child(0);
228     }
229 }
230
231 void Value::dumpMeta(PrintStream&) const
232 {
233 }
234
235 Type Value::typeFor(Opcode opcode, Value* firstChild)
236 {
237     switch (opcode) {
238     case Identity:
239     case Add:
240     case Sub:
241     case Mul:
242     case Div:
243     case ChillDiv:
244     case Mod:
245     case BitAnd:
246     case BitOr:
247     case BitXor:
248     case Shl:
249     case SShr:
250     case ZShr:
251     case CheckAdd:
252     case CheckSub:
253     case CheckMul:
254         return firstChild->type();
255     case FramePointer:
256         return pointerType();
257     case SExt8:
258     case SExt16:
259     case Trunc:
260     case DToI32:
261     case Equal:
262     case NotEqual:
263     case LessThan:
264     case GreaterThan:
265     case LessEqual:
266     case GreaterEqual:
267     case Above:
268     case Below:
269     case AboveEqual:
270     case BelowEqual:
271         return Int32;
272     case SExt32:
273     case ZExt32:
274         return Int64;
275     case FRound:
276     case IToD:
277         return Double;
278     case Nop:
279         return Void;
280     default:
281         RELEASE_ASSERT_NOT_REACHED();
282     }
283 }
284
285 } } // namespace JSC::B3
286
287 #endif // ENABLE(B3_JIT)