2 ** SSA IR (Intermediate Representation) emitter.
3 ** Copyright (C) 2005-2023 Mike Pall. See Copyright Notice in luajit.h
9 /* For pointers to libc/libm functions. */
23 #include "lj_ircall.h"
29 #include "lj_carith.h"
32 #include "lj_strscan.h"
33 #include "lj_serialize.h"
34 #include "lj_strfmt.h"
37 /* Some local macros to save typing. Undef'd at the end. */
38 #define IR(ref) (&J->cur.ir[(ref)])
39 #define fins (&J->fold.ins)
41 /* Pass IR on to next optimization in chain (FOLD). */
42 #define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
44 /* -- IR tables ----------------------------------------------------------- */
46 /* IR instruction modes. */
47 LJ_DATADEF
const uint8_t lj_ir_mode
[IR__MAX
+1] = {
53 LJ_DATADEF
const uint8_t lj_ir_type_size
[IRT__MAX
+1] = {
54 #define IRTSIZE(name, size) size,
60 /* C call info for CALL* instructions. */
61 LJ_DATADEF
const CCallInfo lj_ir_callinfo
[] = {
62 #define IRCALLCI(cond, name, nargs, kind, type, flags) \
63 { (ASMFunction)IRCALLCOND_##cond(name), \
64 (nargs)|(CCI_CALL_##kind)|(IRT_##type<<CCI_OTSHIFT)|(flags) },
70 /* -- IR emitter ---------------------------------------------------------- */
72 /* Grow IR buffer at the top. */
73 void LJ_FASTCALL
lj_ir_growtop(jit_State
*J
)
75 IRIns
*baseir
= J
->irbuf
+ J
->irbotlim
;
76 MSize szins
= J
->irtoplim
- J
->irbotlim
;
78 baseir
= (IRIns
*)lj_mem_realloc(J
->L
, baseir
, szins
*sizeof(IRIns
),
79 2*szins
*sizeof(IRIns
));
80 J
->irtoplim
= J
->irbotlim
+ 2*szins
;
82 baseir
= (IRIns
*)lj_mem_realloc(J
->L
, NULL
, 0, LJ_MIN_IRSZ
*sizeof(IRIns
));
83 J
->irbotlim
= REF_BASE
- LJ_MIN_IRSZ
/4;
84 J
->irtoplim
= J
->irbotlim
+ LJ_MIN_IRSZ
;
86 J
->cur
.ir
= J
->irbuf
= baseir
- J
->irbotlim
;
89 /* Grow IR buffer at the bottom or shift it up. */
90 static void lj_ir_growbot(jit_State
*J
)
92 IRIns
*baseir
= J
->irbuf
+ J
->irbotlim
;
93 MSize szins
= J
->irtoplim
- J
->irbotlim
;
94 lj_assertJ(szins
!= 0, "zero IR size");
95 lj_assertJ(J
->cur
.nk
== J
->irbotlim
|| J
->cur
.nk
-1 == J
->irbotlim
,
96 "unexpected IR growth");
97 if (J
->cur
.nins
+ (szins
>> 1) < J
->irtoplim
) {
98 /* More than half of the buffer is free on top: shift up by a quarter. */
99 MSize ofs
= szins
>> 2;
100 memmove(baseir
+ ofs
, baseir
, (J
->cur
.nins
- J
->irbotlim
)*sizeof(IRIns
));
103 J
->cur
.ir
= J
->irbuf
= baseir
- J
->irbotlim
;
105 /* Double the buffer size, but split the growth amongst top/bottom. */
106 IRIns
*newbase
= lj_mem_newt(J
->L
, 2*szins
*sizeof(IRIns
), IRIns
);
107 MSize ofs
= szins
>= 256 ? 128 : (szins
>> 1); /* Limit bottom growth. */
108 memcpy(newbase
+ ofs
, baseir
, (J
->cur
.nins
- J
->irbotlim
)*sizeof(IRIns
));
109 lj_mem_free(G(J
->L
), baseir
, szins
*sizeof(IRIns
));
111 J
->irtoplim
= J
->irbotlim
+ 2*szins
;
112 J
->cur
.ir
= J
->irbuf
= newbase
- J
->irbotlim
;
116 /* Emit IR without any optimizations. */
117 TRef LJ_FASTCALL
lj_ir_emit(jit_State
*J
)
119 IRRef ref
= lj_ir_nextins(J
);
122 ir
->prev
= J
->chain
[op
];
123 J
->chain
[op
] = (IRRef1
)ref
;
127 J
->guardemit
.irt
|= fins
->t
.irt
;
128 return TREF(ref
, irt_t((ir
->t
= fins
->t
)));
131 /* Emit call to a C function. */
132 TRef
lj_ir_call(jit_State
*J
, IRCallID id
, ...)
134 const CCallInfo
*ci
= &lj_ir_callinfo
[id
];
135 uint32_t n
= CCI_NARGS(ci
);
139 if ((ci
->flags
& CCI_L
)) n
--;
141 tr
= va_arg(argp
, IRRef
);
143 tr
= emitir(IRT(IR_CARG
, IRT_NIL
), tr
, va_arg(argp
, IRRef
));
145 if (CCI_OP(ci
) == IR_CALLS
)
146 J
->needsnap
= 1; /* Need snapshot after call with side effect. */
147 return emitir(CCI_OPTYPE(ci
), tr
, id
);
150 /* Load field of type t from GG_State + offset. Must be 32 bit aligned. */
151 TRef
lj_ir_ggfload(jit_State
*J
, IRType t
, uintptr_t ofs
)
153 lj_assertJ((ofs
& 3) == 0, "unaligned GG_State field offset");
155 lj_assertJ(ofs
>= IRFL__MAX
&& ofs
<= 0x3ff,
156 "GG_State field offset breaks 10 bit FOLD key limit");
157 lj_ir_set(J
, IRT(IR_FLOAD
, t
), REF_NIL
, ofs
);
158 return lj_opt_fold(J
);
161 /* -- Interning of constants ---------------------------------------------- */
164 ** IR instructions for constants are kept between J->cur.nk >= ref < REF_BIAS.
165 ** They are chained like all other instructions, but grow downwards.
166 ** The are interned (like strings in the VM) to facilitate reference
167 ** comparisons. The same constant must get the same reference.
170 /* Get ref of next IR constant and optionally grow IR.
171 ** Note: this may invalidate all IRIns *!
173 static LJ_AINLINE IRRef
ir_nextk(jit_State
*J
)
175 IRRef ref
= J
->cur
.nk
;
176 if (LJ_UNLIKELY(ref
<= J
->irbotlim
)) lj_ir_growbot(J
);
181 /* Get ref of next 64 bit IR constant and optionally grow IR.
182 ** Note: this may invalidate all IRIns *!
184 static LJ_AINLINE IRRef
ir_nextk64(jit_State
*J
)
186 IRRef ref
= J
->cur
.nk
- 2;
187 lj_assertJ(J
->state
!= LJ_TRACE_ASM
, "bad JIT state");
188 if (LJ_UNLIKELY(ref
< J
->irbotlim
)) lj_ir_growbot(J
);
194 #define ir_nextkgc ir_nextk64
196 #define ir_nextkgc ir_nextk
199 /* Intern int32_t constant. */
200 TRef LJ_FASTCALL
lj_ir_kint(jit_State
*J
, int32_t k
)
202 IRIns
*ir
, *cir
= J
->cur
.ir
;
204 for (ref
= J
->chain
[IR_KINT
]; ref
; ref
= cir
[ref
].prev
)
212 ir
->prev
= J
->chain
[IR_KINT
];
213 J
->chain
[IR_KINT
] = (IRRef1
)ref
;
215 return TREF(ref
, IRT_INT
);
218 /* Intern 64 bit constant, given by its 64 bit pattern. */
219 TRef
lj_ir_k64(jit_State
*J
, IROp op
, uint64_t u64
)
221 IRIns
*ir
, *cir
= J
->cur
.ir
;
223 IRType t
= op
== IR_KNUM
? IRT_NUM
: IRT_I64
;
224 for (ref
= J
->chain
[op
]; ref
; ref
= cir
[ref
].prev
)
225 if (ir_k64(&cir
[ref
])->u64
== u64
)
233 ir
->prev
= J
->chain
[op
];
234 J
->chain
[op
] = (IRRef1
)ref
;
239 /* Intern FP constant, given by its 64 bit pattern. */
240 TRef
lj_ir_knum_u64(jit_State
*J
, uint64_t u64
)
242 return lj_ir_k64(J
, IR_KNUM
, u64
);
245 /* Intern 64 bit integer constant. */
246 TRef
lj_ir_kint64(jit_State
*J
, uint64_t u64
)
248 return lj_ir_k64(J
, IR_KINT64
, u64
);
251 /* Check whether a number is int and return it. -0 is NOT considered an int. */
252 static int numistrueint(lua_Number n
, int32_t *kp
)
254 int32_t k
= lj_num2int(n
);
255 if (n
== (lua_Number
)k
) {
257 if (k
== 0) { /* Special check for -0. */
268 /* Intern number as int32_t constant if possible, otherwise as FP constant. */
269 TRef
lj_ir_knumint(jit_State
*J
, lua_Number n
)
272 if (numistrueint(n
, &k
))
273 return lj_ir_kint(J
, k
);
275 return lj_ir_knum(J
, n
);
278 /* Intern GC object "constant". */
279 TRef
lj_ir_kgc(jit_State
*J
, GCobj
*o
, IRType t
)
281 IRIns
*ir
, *cir
= J
->cur
.ir
;
283 lj_assertJ(!isdead(J2G(J
), o
), "interning of dead GC object");
284 for (ref
= J
->chain
[IR_KGC
]; ref
; ref
= cir
[ref
].prev
)
285 if (ir_kgc(&cir
[ref
]) == o
)
289 /* NOBARRIER: Current trace is a GC root. */
291 setgcref(ir
[LJ_GC64
].gcr
, o
);
292 ir
->t
.irt
= (uint8_t)t
;
294 ir
->prev
= J
->chain
[IR_KGC
];
295 J
->chain
[IR_KGC
] = (IRRef1
)ref
;
300 /* Allocate GCtrace constant placeholder (no interning). */
301 TRef
lj_ir_ktrace(jit_State
*J
)
303 IRRef ref
= ir_nextkgc(J
);
305 lj_assertJ(irt_toitype_(IRT_P64
) == LJ_TTRACE
, "mismatched type mapping");
307 ir
->o
= LJ_GC64
? IR_KNUM
: IR_KNULL
; /* Not IR_KGC yet, but same size. */
310 return TREF(ref
, IRT_P64
);
313 /* Intern pointer constant. */
314 TRef
lj_ir_kptr_(jit_State
*J
, IROp op
, void *ptr
)
316 IRIns
*ir
, *cir
= J
->cur
.ir
;
318 #if LJ_64 && !LJ_GC64
319 lj_assertJ((void *)(uintptr_t)u32ptr(ptr
) == ptr
, "out-of-range GC pointer");
321 for (ref
= J
->chain
[op
]; ref
; ref
= cir
[ref
].prev
)
322 if (ir_kptr(&cir
[ref
]) == ptr
)
331 setmref(ir
[LJ_GC64
].ptr
, ptr
);
334 ir
->prev
= J
->chain
[op
];
335 J
->chain
[op
] = (IRRef1
)ref
;
337 return TREF(ref
, IRT_PGC
);
340 /* Intern typed NULL constant. */
341 TRef
lj_ir_knull(jit_State
*J
, IRType t
)
343 IRIns
*ir
, *cir
= J
->cur
.ir
;
345 for (ref
= J
->chain
[IR_KNULL
]; ref
; ref
= cir
[ref
].prev
)
346 if (irt_t(cir
[ref
].t
) == t
)
351 ir
->t
.irt
= (uint8_t)t
;
353 ir
->prev
= J
->chain
[IR_KNULL
];
354 J
->chain
[IR_KNULL
] = (IRRef1
)ref
;
359 /* Intern key slot. */
360 TRef
lj_ir_kslot(jit_State
*J
, TRef key
, IRRef slot
)
362 IRIns
*ir
, *cir
= J
->cur
.ir
;
363 IRRef2 op12
= IRREF2((IRRef1
)key
, (IRRef1
)slot
);
365 /* Const part is not touched by CSE/DCE, so 0-65535 is ok for IRMlit here. */
366 lj_assertJ(tref_isk(key
) && slot
== (IRRef
)(IRRef1
)slot
,
367 "out-of-range key/slot");
368 for (ref
= J
->chain
[IR_KSLOT
]; ref
; ref
= cir
[ref
].prev
)
369 if (cir
[ref
].op12
== op12
)
376 ir
->prev
= J
->chain
[IR_KSLOT
];
377 J
->chain
[IR_KSLOT
] = (IRRef1
)ref
;
379 return TREF(ref
, IRT_P32
);
382 /* -- Access to IR constants ---------------------------------------------- */
384 /* Copy value of IR constant. */
385 void lj_ir_kvalue(lua_State
*L
, TValue
*tv
, const IRIns
*ir
)
388 lj_assertL(ir
->o
!= IR_KSLOT
, "unexpected KSLOT"); /* Common mistake. */
390 case IR_KPRI
: setpriV(tv
, irt_toitype(ir
->t
)); break;
391 case IR_KINT
: setintV(tv
, ir
->i
); break;
392 case IR_KGC
: setgcV(L
, tv
, ir_kgc(ir
), irt_toitype(ir
->t
)); break;
393 case IR_KPTR
: case IR_KKPTR
:
394 setnumV(tv
, (lua_Number
)(uintptr_t)ir_kptr(ir
));
396 case IR_KNULL
: setintV(tv
, 0); break;
397 case IR_KNUM
: setnumV(tv
, ir_knum(ir
)->n
); break;
400 GCcdata
*cd
= lj_cdata_new_(L
, CTID_INT64
, 8);
401 *(uint64_t *)cdataptr(cd
) = ir_kint64(ir
)->u64
;
402 setcdataV(L
, tv
, cd
);
406 default: lj_assertL(0, "bad IR constant op %d", ir
->o
); break;
410 /* -- Convert IR operand types -------------------------------------------- */
412 /* Convert from string to number. */
413 TRef LJ_FASTCALL
lj_ir_tonumber(jit_State
*J
, TRef tr
)
415 if (!tref_isnumber(tr
)) {
417 tr
= emitir(IRTG(IR_STRTO
, IRT_NUM
), tr
, 0);
419 lj_trace_err(J
, LJ_TRERR_BADTYPE
);
424 /* Convert from integer or string to number. */
425 TRef LJ_FASTCALL
lj_ir_tonum(jit_State
*J
, TRef tr
)
427 if (!tref_isnum(tr
)) {
428 if (tref_isinteger(tr
))
429 tr
= emitir(IRTN(IR_CONV
), tr
, IRCONV_NUM_INT
);
430 else if (tref_isstr(tr
))
431 tr
= emitir(IRTG(IR_STRTO
, IRT_NUM
), tr
, 0);
433 lj_trace_err(J
, LJ_TRERR_BADTYPE
);
438 /* Convert from integer or number to string. */
439 TRef LJ_FASTCALL
lj_ir_tostr(jit_State
*J
, TRef tr
)
441 if (!tref_isstr(tr
)) {
442 if (!tref_isnumber(tr
))
443 lj_trace_err(J
, LJ_TRERR_BADTYPE
);
444 tr
= emitir(IRT(IR_TOSTR
, IRT_STR
), tr
,
445 tref_isnum(tr
) ? IRTOSTR_NUM
: IRTOSTR_INT
);
450 /* -- Miscellaneous IR ops ------------------------------------------------ */
452 /* Evaluate numeric comparison. */
453 int lj_ir_numcmp(lua_Number a
, lua_Number b
, IROp op
)
456 case IR_EQ
: return (a
== b
);
457 case IR_NE
: return (a
!= b
);
458 case IR_LT
: return (a
< b
);
459 case IR_GE
: return (a
>= b
);
460 case IR_LE
: return (a
<= b
);
461 case IR_GT
: return (a
> b
);
462 case IR_ULT
: return !(a
>= b
);
463 case IR_UGE
: return !(a
< b
);
464 case IR_ULE
: return !(a
> b
);
465 case IR_UGT
: return !(a
<= b
);
466 default: lj_assertX(0, "bad IR op %d", op
); return 0;
470 /* Evaluate string comparison. */
471 int lj_ir_strcmp(GCstr
*a
, GCstr
*b
, IROp op
)
473 int res
= lj_str_cmp(a
, b
);
475 case IR_LT
: return (res
< 0);
476 case IR_GE
: return (res
>= 0);
477 case IR_LE
: return (res
<= 0);
478 case IR_GT
: return (res
> 0);
479 default: lj_assertX(0, "bad IR op %d", op
); return 0;
483 /* Rollback IR to previous state. */
484 void lj_ir_rollback(jit_State
*J
, IRRef ref
)
486 IRRef nins
= J
->cur
.nins
;
491 J
->chain
[ir
->o
] = ir
->prev
;