B3 -O1 should not allocateStackByGraphColoring
[WebKit-https.git] / Source / JavaScriptCore / b3 / air / AirArg.cpp
1 /*
2  * Copyright (C) 2015-2017 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 "AirArg.h"
28
29 #if ENABLE(B3_JIT)
30
31 #include "AirSpecial.h"
32 #include "AirStackSlot.h"
33 #include "B3Value.h"
34 #include "FPRInfo.h"
35 #include "GPRInfo.h"
36
37 #if COMPILER(GCC) && ASSERT_DISABLED
38 #pragma GCC diagnostic push
39 #pragma GCC diagnostic ignored "-Wreturn-type"
40 #endif // COMPILER(GCC) && ASSERT_DISABLED
41
42 namespace JSC { namespace B3 { namespace Air {
43
44 Arg Arg::stackAddr(int32_t offsetFromFP, unsigned frameSize, Width width)
45 {
46     Arg result = Arg::addr(Air::Tmp(GPRInfo::callFrameRegister), offsetFromFP);
47     if (!result.isValidForm(width)) {
48         result = Arg::addr(
49             Air::Tmp(MacroAssembler::stackPointerRegister),
50             offsetFromFP + frameSize);
51     }
52     return result;
53 }
54
55 bool Arg::isStackMemory() const
56 {
57     switch (kind()) {
58     case Addr:
59         return base() == Air::Tmp(GPRInfo::callFrameRegister)
60             || base() == Air::Tmp(MacroAssembler::stackPointerRegister);
61     case Stack:
62     case CallArg:
63         return true;
64     default:
65         return false;
66     }
67 }
68
69 bool Arg::isRepresentableAs(Width width, Signedness signedness) const
70 {
71     return isRepresentableAs(width, signedness, value());
72 }
73
74 bool Arg::usesTmp(Air::Tmp tmp) const
75 {
76     bool uses = false;
77     const_cast<Arg*>(this)->forEachTmpFast(
78         [&] (Air::Tmp otherTmp) {
79             if (otherTmp == tmp)
80                 uses = true;
81         });
82     return uses;
83 }
84
85 bool Arg::canRepresent(Value* value) const
86 {
87     return isBank(bankForType(value->type()));
88 }
89
90 bool Arg::isCompatibleBank(const Arg& other) const
91 {
92     if (hasBank())
93         return other.isBank(bank());
94     if (other.hasBank())
95         return isBank(other.bank());
96     return true;
97 }
98
99 unsigned Arg::jsHash() const
100 {
101     unsigned result = static_cast<unsigned>(m_kind);
102     
103     switch (m_kind) {
104     case Invalid:
105     case Special:
106         break;
107     case Tmp:
108         result += m_base.internalValue();
109         break;
110     case Imm:
111     case BitImm:
112     case CallArg:
113     case RelCond:
114     case ResCond:
115     case DoubleCond:
116     case StatusCond:
117     case WidthArg:
118         result += static_cast<unsigned>(m_offset);
119         break;
120     case BigImm:
121     case BitImm64:
122         result += static_cast<unsigned>(m_offset);
123         result += static_cast<unsigned>(m_offset >> 32);
124         break;
125     case SimpleAddr:
126         result += m_base.internalValue();
127         break;
128     case Addr:
129         result += m_offset;
130         result += m_base.internalValue();
131         break;
132     case Index:
133         result += static_cast<unsigned>(m_offset);
134         result += m_scale;
135         result += m_base.internalValue();
136         result += m_index.internalValue();
137         break;
138     case Stack:
139         result += static_cast<unsigned>(m_scale);
140         result += stackSlot()->index();
141         break;
142     }
143     
144     return result;
145 }
146
147 void Arg::dump(PrintStream& out) const
148 {
149     switch (m_kind) {
150     case Invalid:
151         out.print("<invalid>");
152         return;
153     case Tmp:
154         out.print(tmp());
155         return;
156     case Imm:
157         out.print("$", m_offset);
158         return;
159     case BigImm:
160         out.printf("$0x%llx", static_cast<long long unsigned>(m_offset));
161         return;
162     case BitImm:
163         out.print("$", m_offset);
164         return;
165     case BitImm64:
166         out.printf("$0x%llx", static_cast<long long unsigned>(m_offset));
167         return;
168     case SimpleAddr:
169         out.print("(", base(), ")");
170         return;
171     case Addr:
172         if (offset())
173             out.print(offset());
174         out.print("(", base(), ")");
175         return;
176     case Index:
177         if (offset())
178             out.print(offset());
179         out.print("(", base(), ",", index());
180         if (scale() != 1)
181             out.print(",", scale());
182         out.print(")");
183         return;
184     case Stack:
185         if (offset())
186             out.print(offset());
187         out.print("(", pointerDump(stackSlot()), ")");
188         return;
189     case CallArg:
190         if (offset())
191             out.print(offset());
192         out.print("(callArg)");
193         return;
194     case RelCond:
195         out.print(asRelationalCondition());
196         return;
197     case ResCond:
198         out.print(asResultCondition());
199         return;
200     case DoubleCond:
201         out.print(asDoubleCondition());
202         return;
203     case StatusCond:
204         out.print(asStatusCondition());
205         return;
206     case Special:
207         out.print(pointerDump(special()));
208         return;
209     case WidthArg:
210         out.print(width());
211         return;
212     }
213
214     RELEASE_ASSERT_NOT_REACHED();
215 }
216
217 } } } // namespace JSC::B3::Air
218
219 namespace WTF {
220
221 using namespace JSC::B3::Air;
222
223 void printInternal(PrintStream& out, Arg::Kind kind)
224 {
225     switch (kind) {
226     case Arg::Invalid:
227         out.print("Invalid");
228         return;
229     case Arg::Tmp:
230         out.print("Tmp");
231         return;
232     case Arg::Imm:
233         out.print("Imm");
234         return;
235     case Arg::BigImm:
236         out.print("BigImm");
237         return;
238     case Arg::BitImm:
239         out.print("BitImm");
240         return;
241     case Arg::BitImm64:
242         out.print("BitImm64");
243         return;
244     case Arg::SimpleAddr:
245         out.print("SimpleAddr");
246         return;
247     case Arg::Addr:
248         out.print("Addr");
249         return;
250     case Arg::Stack:
251         out.print("Stack");
252         return;
253     case Arg::CallArg:
254         out.print("CallArg");
255         return;
256     case Arg::Index:
257         out.print("Index");
258         return;
259     case Arg::RelCond:
260         out.print("RelCond");
261         return;
262     case Arg::ResCond:
263         out.print("ResCond");
264         return;
265     case Arg::DoubleCond:
266         out.print("DoubleCond");
267         return;
268     case Arg::StatusCond:
269         out.print("StatusCond");
270         return;
271     case Arg::Special:
272         out.print("Special");
273         return;
274     case Arg::WidthArg:
275         out.print("WidthArg");
276         return;
277     }
278
279     RELEASE_ASSERT_NOT_REACHED();
280 }
281
282 void printInternal(PrintStream& out, Arg::Temperature temperature)
283 {
284     switch (temperature) {
285     case Arg::Cold:
286         out.print("Cold");
287         return;
288     case Arg::Warm:
289         out.print("Warm");
290         return;
291     }
292
293     RELEASE_ASSERT_NOT_REACHED();
294 }
295
296 void printInternal(PrintStream& out, Arg::Phase phase)
297 {
298     switch (phase) {
299     case Arg::Early:
300         out.print("Early");
301         return;
302     case Arg::Late:
303         out.print("Late");
304         return;
305     }
306
307     RELEASE_ASSERT_NOT_REACHED();
308 }
309
310 void printInternal(PrintStream& out, Arg::Timing timing)
311 {
312     switch (timing) {
313     case Arg::OnlyEarly:
314         out.print("OnlyEarly");
315         return;
316     case Arg::OnlyLate:
317         out.print("OnlyLate");
318         return;
319     case Arg::EarlyAndLate:
320         out.print("EarlyAndLate");
321         return;
322     }
323
324     RELEASE_ASSERT_NOT_REACHED();
325 }
326
327 void printInternal(PrintStream& out, Arg::Role role)
328 {
329     switch (role) {
330     case Arg::Use:
331         out.print("Use");
332         return;
333     case Arg::Def:
334         out.print("Def");
335         return;
336     case Arg::UseDef:
337         out.print("UseDef");
338         return;
339     case Arg::ZDef:
340         out.print("ZDef");
341         return;
342     case Arg::UseZDef:
343         out.print("UseZDef");
344         return;
345     case Arg::UseAddr:
346         out.print("UseAddr");
347         return;
348     case Arg::ColdUse:
349         out.print("ColdUse");
350         return;
351     case Arg::LateUse:
352         out.print("LateUse");
353         return;
354     case Arg::LateColdUse:
355         out.print("LateColdUse");
356         return;
357     case Arg::EarlyDef:
358         out.print("EarlyDef");
359         return;
360     case Arg::EarlyZDef:
361         out.print("EarlyZDef");
362         return;
363     case Arg::Scratch:
364         out.print("Scratch");
365         return;
366     }
367
368     RELEASE_ASSERT_NOT_REACHED();
369 }
370
371 void printInternal(PrintStream& out, Arg::Signedness signedness)
372 {
373     switch (signedness) {
374     case Arg::Signed:
375         out.print("Signed");
376         return;
377     case Arg::Unsigned:
378         out.print("Unsigned");
379         return;
380     }
381
382     RELEASE_ASSERT_NOT_REACHED();
383 }
384
385 } // namespace WTF
386
387 #if COMPILER(GCC) && ASSERT_DISABLED
388 #pragma GCC diagnostic pop
389 #endif // COMPILER(GCC) && ASSERT_DISABLED
390
391 #endif // ENABLE(B3_JIT)