Switch-related cleanup
[hiphop-php.git] / hphp / runtime / vm / jit / ir-opcode.cpp
blob66b51b18f841f22b8937a03ac9282c8ab4d414bd
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/vm/jit/ir-opcode.h"
19 #include "hphp/runtime/base/string-data.h"
20 #include "hphp/runtime/vm/jit/cfg.h"
21 #include "hphp/runtime/vm/jit/extra-data.h"
22 #include "hphp/runtime/vm/jit/ir-instruction.h"
23 #include "hphp/runtime/vm/jit/ir-unit.h"
24 #include "hphp/runtime/vm/jit/ssa-tmp.h"
25 #include "hphp/runtime/vm/jit/print.h"
26 #include "hphp/runtime/vm/jit/type.h"
27 #include "hphp/runtime/vm/runtime.h"
29 #include "hphp/util/trace.h"
31 // Include last to localize effects to this file
32 #include "hphp/util/assert-throw.h"
34 namespace HPHP { namespace jit {
35 ///////////////////////////////////////////////////////////////////////////////
37 TRACE_SET_MOD(hhir);
39 #define NF 0
40 #define Er MayRaiseError
41 #define PRc ProducesRC
42 #define CRc ConsumesRC
43 #define T Terminal
44 #define B Branch
45 #define P Passthrough
46 #define K KillsSources
47 #define MProp MInstrProp
48 #define MElem MInstrElem
50 #define ND 0
51 #define D(n) HasDest
52 #define DofS(n) HasDest
53 #define DRefineS(n) HasDest
54 #define DParamMayRelax HasDest
55 #define DParam HasDest
56 #define DParamPtr(k) HasDest
57 #define DUnboxPtr HasDest
58 #define DBoxPtr HasDest
59 #define DAllocObj HasDest
60 #define DArrElem HasDest
61 #define DArrPacked HasDest
62 #define DCol HasDest
63 #define DThis HasDest
64 #define DCtx HasDest
65 #define DMulti NaryDest
66 #define DSetElem HasDest
67 #define DPtrToParam HasDest
68 #define DBuiltin HasDest
69 #define DSubtract(n,t) HasDest
70 #define DCns HasDest
72 OpInfo g_opInfo[] = {
73 #define O(name, dsts, srcs, flags) \
74 { #name, \
75 (OpHasExtraData<name>::value ? HasExtra : 0) | \
76 dsts | (flags) \
78 IR_OPCODES
79 #undef O
80 { 0 }
83 #undef NF
84 #undef C
85 #undef E
86 #undef PRc
87 #undef CRc
88 #undef Er
89 #undef T
90 #undef B
91 #undef P
92 #undef K
93 #undef MProp
94 #undef MElem
96 #undef ND
97 #undef D
98 #undef DofS
99 #undef DRefineS
100 #undef DParamMayRelax
101 #undef DParam
102 #undef DParamPtr
103 #undef DUnboxPtr
104 #undef DBoxPtr
105 #undef DArrElem
106 #undef DArrPacked
107 #undef DCol
108 #undef DAllocObj
109 #undef DThis
110 #undef DCtx
111 #undef DMulti
112 #undef DSetElem
113 #undef DPtrToParam
114 #undef DBuiltin
115 #undef DSubtract
116 #undef DCns
118 ///////////////////////////////////////////////////////////////////////////////
120 const StringData* findClassName(SSATmp* cls) {
121 assertx(cls->isA(TCls));
123 if (cls->hasConstVal()) {
124 return cls->clsVal()->preClass()->name();
126 // Try to get the class name from a LdCls
127 IRInstruction* clsInst = cls->inst();
128 if (clsInst->op() == LdCls || clsInst->op() == LdClsCached) {
129 SSATmp* clsName = clsInst->src(0);
130 assertx(clsName->isA(TStr));
131 if (clsName->hasConstVal()) {
132 return clsName->strVal();
135 return nullptr;
138 bool isCallOp(Opcode opc) {
139 // CallBuiltin doesn't count because it is not a php-level call. (It will
140 // call a C++ helper and we can push/pop around it normally.)
141 switch (opc) {
142 case Call:
143 case CallArray:
144 case ContEnter:
145 return true;
146 default:
147 return false;
151 bool isGuardOp(Opcode opc) {
152 switch (opc) {
153 case CheckLoc:
154 case CheckStk:
155 case CheckType:
156 return true;
158 default:
159 return false;
163 bool isQueryOp(Opcode opc) {
164 switch (opc) {
165 case Gt:
166 case Gte:
167 case Lt:
168 case Lte:
169 case Eq:
170 case Neq:
171 case GtInt:
172 case GteInt:
173 case LtInt:
174 case LteInt:
175 case EqInt:
176 case NeqInt:
177 case GtDbl:
178 case GteDbl:
179 case LtDbl:
180 case LteDbl:
181 case EqDbl:
182 case NeqDbl:
183 case Same:
184 case NSame:
185 case InstanceOfBitmask:
186 case NInstanceOfBitmask:
187 case IsType:
188 case IsNType:
189 return true;
190 default:
191 return false;
195 bool isIntQueryOp(Opcode opc) {
196 switch (opc) {
197 case GtInt:
198 case GteInt:
199 case LtInt:
200 case LteInt:
201 case EqInt:
202 case NeqInt:
203 return true;
204 default:
205 return false;
209 bool isDblQueryOp(Opcode opc) {
210 switch (opc) {
211 case GtDbl:
212 case GteDbl:
213 case LtDbl:
214 case LteDbl:
215 case EqDbl:
216 case NeqDbl:
217 return true;
218 default:
219 return false;
223 Opcode negateQueryOp(Opcode opc) {
224 assertx(isQueryOp(opc));
225 switch (opc) {
226 case Gt: return Lte;
227 case Gte: return Lt;
228 case Lt: return Gte;
229 case Lte: return Gt;
230 case Eq: return Neq;
231 case Neq: return Eq;
232 case GtInt: return LteInt;
233 case GteInt: return LtInt;
234 case LtInt: return GteInt;
235 case LteInt: return GtInt;
236 case EqInt: return NeqInt;
237 case NeqInt: return EqInt;
238 case EqDbl: return NeqDbl;
239 case NeqDbl: return EqDbl;
240 case Same: return NSame;
241 case NSame: return Same;
242 case InstanceOfBitmask: return NInstanceOfBitmask;
243 case NInstanceOfBitmask: return InstanceOfBitmask;
244 case IsType: return IsNType;
245 case IsNType: return IsType;
246 case GtDbl:
247 case GteDbl:
248 case LtDbl:
249 case LteDbl:
250 // Negating dbl relational ops probably isn't what you want:
251 // (X < Y) != !(X >= Y) -- when NaN gets involved
252 always_assert(false);
253 default: always_assert(0);
257 Opcode commuteQueryOp(Opcode opc) {
258 assertx(isQueryOp(opc));
259 switch (opc) {
260 case Gt: return Lt;
261 case Gte: return Lte;
262 case Lt: return Gt;
263 case Lte: return Gte;
264 case Eq: return Eq;
265 case Neq: return Neq;
266 case GtInt: return LtInt;
267 case GteInt:return LteInt;
268 case LtInt: return GtInt;
269 case LteInt:return GteInt;
270 case EqInt: return EqInt;
271 case NeqInt:return NeqInt;
272 case GtDbl: return LtDbl;
273 case GteDbl:return LteDbl;
274 case LtDbl: return GtDbl;
275 case LteDbl:return GteDbl;
276 case EqDbl: return EqDbl;
277 case NeqDbl:return NeqDbl;
278 case Same: return Same;
279 case NSame: return NSame;
280 default: always_assert(0);
284 Opcode queryToIntQueryOp(Opcode opc) {
285 assertx(isQueryOp(opc));
286 switch (opc) {
287 case Gt: return GtInt;
288 case Gte: return GteInt;
289 case Lt: return LtInt;
290 case Lte: return LteInt;
291 case Eq: return EqInt;
292 case Neq: return NeqInt;
293 case GtDbl: return GtInt;
294 case GteDbl:return GteInt;
295 case LtDbl: return LtInt;
296 case LteDbl:return LteInt;
297 case EqDbl: return EqInt;
298 case NeqDbl:return NeqInt;
299 default: always_assert(0);
303 Opcode queryToDblQueryOp(Opcode opc) {
304 assertx(isQueryOp(opc));
305 switch (opc) {
306 case Gt: return GtDbl;
307 case Gte: return GteDbl;
308 case Lt: return LtDbl;
309 case Lte: return LteDbl;
310 case Eq: return EqDbl;
311 case Neq: return NeqDbl;
312 case GtInt: return GtDbl;
313 case GteInt:return GteDbl;
314 case LtInt: return LtDbl;
315 case LteInt:return LteDbl;
316 case EqInt: return EqDbl;
317 case NeqInt:return NeqDbl;
318 default: always_assert(0);
322 ///////////////////////////////////////////////////////////////////////////////