21#define IR_VERSION "0.0.1"
25# if defined(_M_X64) || defined(_M_ARM64)
26# define __SIZEOF_SIZE_T__ 8
27# elif defined(_M_IX86)
28# define __SIZEOF_SIZE_T__ 4
32# ifndef __ORDER_LITTLE_ENDIAN__
33# define __ORDER_LITTLE_ENDIAN__ 1
35# define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
37# define __has_builtin(arg) (0)
42#if !defined(IR_TARGET_X86) && !defined(IR_TARGET_X64) && !defined(IR_TARGET_AARCH64)
43# if defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
45# elif defined(i386) || defined(__i386) || defined(__i386__) || defined(_M_IX86)
47# elif defined(__aarch64__) || defined(_M_ARM64)
48# define IR_TARGET_AARCH64
49# elif defined (_WIN64)
51# elif defined (_WIN32)
56#if defined(IR_TARGET_X86)
57# define IR_TARGET "x86"
58#elif defined(IR_TARGET_X64)
60# define IR_TARGET "Windows-x86_64"
62# define IR_TARGET "x86_64"
64#elif defined(IR_TARGET_AARCH64)
65# define IR_TARGET "aarch64"
67# error "Unknown IR target"
70#if defined(__SIZEOF_SIZE_T__)
71# if __SIZEOF_SIZE_T__ == 8
73# elif __SIZEOF_SIZE_T__ != 4
74# error "Unknown addr size"
77# error "Unknown addr size"
80#if defined(__BYTE_ORDER__)
81# if defined(__ORDER_LITTLE_ENDIAN__)
82# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
83# define IR_STRUCT_LOHI(lo, hi) struct {lo; hi;}
86# if defined(__ORDER_BIG_ENDIAN__)
87# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
88# define IR_STRUCT_LOHI(lo, hi) struct {hi; lo;}
93# error "Unknown byte order"
97# if __has_attribute(always_inline)
98# define IR_ALWAYS_INLINE static inline __attribute__((always_inline))
100# if __has_attribute(noinline)
101# define IR_NEVER_INLINE __attribute__((noinline))
104# define __has_attribute(x) 0
107#ifndef IR_ALWAYS_INLINE
108# define IR_ALWAYS_INLINE static inline
110#ifndef IR_NEVER_INLINE
111# define IR_NEVER_INLINE
119#define IR_TYPE_SIGNED (1<<4)
120#define IR_TYPE_UNSIGNED (1<<5)
121#define IR_TYPE_FP (1<<6)
122#define IR_TYPE_SPECIAL (1<<7)
123#define IR_TYPE_BOOL (IR_TYPE_SPECIAL|IR_TYPE_UNSIGNED)
124#define IR_TYPE_ADDR (IR_TYPE_SPECIAL|IR_TYPE_UNSIGNED)
125#define IR_TYPE_CHAR (IR_TYPE_SPECIAL|IR_TYPE_SIGNED)
129 _(BOOL, bool, b, IR_TYPE_BOOL) \
130 _(U8, uint8_t, u8, IR_TYPE_UNSIGNED) \
131 _(U16, uint16_t, u16, IR_TYPE_UNSIGNED) \
132 _(U32, uint32_t, u32, IR_TYPE_UNSIGNED) \
133 _(U64, uint64_t, u64, IR_TYPE_UNSIGNED) \
134 _(ADDR, uintptr_t, addr, IR_TYPE_ADDR) \
135 _(CHAR, char, c, IR_TYPE_CHAR) \
136 _(I8, int8_t, i8, IR_TYPE_SIGNED) \
137 _(I16, int16_t, i16, IR_TYPE_SIGNED) \
138 _(I32, int32_t, i32, IR_TYPE_SIGNED) \
139 _(I64, int64_t, i64, IR_TYPE_SIGNED) \
140 _(DOUBLE, double, d, IR_TYPE_FP) \
141 _(FLOAT, float, f, IR_TYPE_FP) \
143#define IR_IS_TYPE_UNSIGNED(t) ((t) < IR_CHAR)
144#define IR_IS_TYPE_SIGNED(t) ((t) >= IR_CHAR && (t) < IR_DOUBLE)
145#define IR_IS_TYPE_INT(t) ((t) < IR_DOUBLE)
146#define IR_IS_TYPE_FP(t) ((t) >= IR_DOUBLE)
148#define IR_TYPE_ENUM(name, type, field, flags) IR_ ## name,
157# define IR_SIZE_T IR_U64
158# define IR_SSIZE_T IR_I64
159# define IR_UINTPTR_T IR_U64
160# define IR_INTPTR_T IR_I64
161# define IR_C_UINTPTR IR_U64
162# define IR_C_INTPTR IR_I64
164# define IR_SIZE_T IR_U32
165# define IR_SSIZE_T IR_I32
166# define IR_UINTPTR_T IR_U32
167# define IR_INTPTR_T IR_I32
168# define IR_C_UINTPTR IR_U32
169# define IR_C_INTPTR IR_I32
222 _(NOP, v, ___, ___, ___) \
225 _(C_BOOL, r0, ___, ___, ___) \
226 _(C_U8, r0, ___, ___, ___) \
227 _(C_U16, r0, ___, ___, ___) \
228 _(C_U32, r0, ___, ___, ___) \
229 _(C_U64, r0, ___, ___, ___) \
230 _(C_ADDR, r0, ___, ___, ___) \
231 _(C_CHAR, r0, ___, ___, ___) \
232 _(C_I8, r0, ___, ___, ___) \
233 _(C_I16, r0, ___, ___, ___) \
234 _(C_I32, r0, ___, ___, ___) \
235 _(C_I64, r0, ___, ___, ___) \
236 _(C_DOUBLE, r0, ___, ___, ___) \
237 _(C_FLOAT, r0, ___, ___, ___) \
240 _(EQ, d2C, def, def, ___) \
241 _(NE, d2C, def, def, ___) \
244 _(LT, d2, def, def, ___) \
245 _(GE, d2, def, def, ___) \
246 _(LE, d2, def, def, ___) \
247 _(GT, d2, def, def, ___) \
248 _(ULT, d2, def, def, ___) \
249 _(UGE, d2, def, def, ___) \
250 _(ULE, d2, def, def, ___) \
251 _(UGT, d2, def, def, ___) \
254 _(ADD, d2C, def, def, ___) \
255 _(SUB, d2, def, def, ___) \
256 _(MUL, d2C, def, def, ___) \
257 _(DIV, d2, def, def, ___) \
258 _(MOD, d2, def, def, ___) \
259 _(NEG, d1, def, ___, ___) \
260 _(ABS, d1, def, ___, ___) \
264 _(SEXT, d1, def, ___, ___) \
265 _(ZEXT, d1, def, ___, ___) \
266 _(TRUNC, d1, def, ___, ___) \
267 _(BITCAST, d1, def, ___, ___) \
268 _(INT2FP, d1, def, ___, ___) \
269 _(FP2INT, d1, def, ___, ___) \
270 _(FP2FP, d1, def, ___, ___) \
271 _(PROTO, d1X1, def, pro, ___) \
274 _(ADD_OV, d2C, def, def, ___) \
275 _(SUB_OV, d2, def, def, ___) \
276 _(MUL_OV, d2C, def, def, ___) \
277 _(OVERFLOW, d1, def, ___, ___) \
280 _(NOT, d1, def, ___, ___) \
281 _(OR, d2C, def, def, ___) \
282 _(AND, d2C, def, def, ___) \
283 _(XOR, d2C, def, def, ___) \
284 _(SHL, d2, def, def, ___) \
285 _(SHR, d2, def, def, ___) \
286 _(SAR, d2, def, def, ___) \
287 _(ROL, d2, def, def, ___) \
288 _(ROR, d2, def, def, ___) \
289 _(BSWAP, d1, def, ___, ___) \
290 _(CTPOP, d1, def, ___, ___) \
291 _(CTLZ, d1, def, ___, ___) \
292 _(CTTZ, d1, def, ___, ___) \
295 _(MIN, d2C, def, def, ___) \
296 _(MAX, d2C, def, def, ___) \
297 _(COND, d3, def, def, def) \
300 _(VADDR, d1, var, ___, ___) \
301 _(FRAME_ADDR, d0, ___, ___, ___) \
302 _(PHI, pN, reg, def, def) \
303 _(COPY, d1X1, def, opt, ___) \
304 _(PI, p2, reg, def, ___) \
308 _(PARAM, p1X2, reg, str, num) \
309 _(VAR, p1X1, reg, str, ___) \
310 _(FUNC_ADDR, r0, ___, ___, ___) \
311 _(FUNC, r0, ___, ___, ___) \
312 _(SYM, r0, ___, ___, ___) \
313 _(STR, r0, ___, ___, ___) \
316 _(CALL, xN, src, def, def) \
317 _(TAILCALL, xN, src, def, def) \
320 _(ALLOCA, a2, src, def, ___) \
321 _(AFREE, a2, src, def, ___) \
322 _(BLOCK_BEGIN, a1, src, ___, ___) \
323 _(BLOCK_END, a2, src, def, ___) \
324 _(VLOAD, l2, src, var, ___) \
325 _(VSTORE, s3, src, var, def) \
326 _(RLOAD, l1X2, src, num, opt) \
327 _(RSTORE, s2X1, src, def, num) \
328 _(LOAD, l2, src, ref, ___) \
329 _(STORE, s3, src, ref, def) \
330 _(TLS, l1X2, src, num, num) \
331 _(TRAP, x1, src, ___, ___) \
335 _(VA_START, x2, src, def, ___) \
336 _(VA_END, x2, src, def, ___) \
337 _(VA_COPY, x3, src, def, def) \
338 _(VA_ARG, x2, src, def, ___) \
341 _(GUARD, c3, src, def, def) \
342 _(GUARD_NOT , c3, src, def, def) \
345 _(SNAPSHOT, xN, src, def, def) \
348 _(START, S0X1, ret, ___, ___) \
349 _(ENTRY, S1X1, src, num, ___) \
350 _(BEGIN, S1, src, ___, ___) \
351 _(IF_TRUE, S1X1, src, prb, ___) \
352 _(IF_FALSE, S1X1, src, prb, ___) \
353 _(CASE_VAL, S2X1, src, def, prb) \
354 _(CASE_DEFAULT, S1X1, src, prb, ___) \
355 _(MERGE, SN, src, src, src) \
356 _(LOOP_BEGIN, SN, src, src, src) \
357 _(END, E1, src, ___, ___) \
358 _(LOOP_END, E1, src, ___, ___) \
359 _(IF, E2, src, def, ___) \
360 _(SWITCH, E2, src, def, ___) \
361 _(RETURN, T2X1, src, def, ret) \
362 _(IJMP, T2X1, src, def, ret) \
363 _(UNREACHABLE, T1X2, src, ___, ret) \
366 _(EXITCALL, x2, src, def, ___) \
369#define IR_OP_ENUM(name, flags, op1, op2, op3) IR_ ## name,
380#define IR_OPT_OP_MASK 0x00ff
381#define IR_OPT_TYPE_MASK 0xff00
382#define IR_OPT_TYPE_SHIFT 8
383#define IR_OPT_INPUTS_SHIFT 16
385#define IR_OPT(op, type) ((uint16_t)(op) | ((uint16_t)(type) << IR_OPT_TYPE_SHIFT))
386#define IR_OPTX(op, type, n) ((uint32_t)(op) | ((uint32_t)(type) << IR_OPT_TYPE_SHIFT) | ((uint32_t)(n) << IR_OPT_INPUTS_SHIFT))
387#define IR_OPT_TYPE(opt) (((opt) & IR_OPT_TYPE_MASK) >> IR_OPT_TYPE_SHIFT)
392#define IR_IS_CONST_REF(ref) ((ref) < 0)
399#define IR_LAST_FOLDABLE_OP IR_COPY
401#define IR_CONSTS_LIMIT_MIN (-(IR_TRUE - 1))
402#define IR_INSNS_LIMIT_MIN (IR_UNUSED + 1)
405# define ADDR_MEMBER uintptr_t addr;
459 uint16_t inputs_count;
460 uint16_t prev_insn_offset;
496#define ir_strtab_count(strtab) (strtab)->count
510#define IR_FUNCTION (1<<0)
511#define IR_FASTCALL_FUNC (1<<1)
512#define IR_VARARG_FUNC (1<<2)
513#define IR_BUILTIN_FUNC (1<<3)
514#define IR_STATIC (1<<4)
515#define IR_EXTERN (1<<5)
516#define IR_CONST (1<<6)
518#define IR_INITIALIZED (1<<7)
519#define IR_CONST_STRING (1<<8)
521#define IR_SKIP_PROLOGUE (1<<8)
522#define IR_USE_FRAME_POINTER (1<<9)
523#define IR_PREALLOCATED_STACK (1<<10)
524#define IR_NO_STACK_COMBINE (1<<11)
525#define IR_START_BR_TARGET (1<<12)
526#define IR_ENTRY_BR_TARGET (1<<13)
527#define IR_GEN_ENDBR (1<<14)
528#define IR_MERGE_EMPTY_ENTRIES (1<<15)
530#define IR_OPT_INLINE (1<<16)
531#define IR_OPT_FOLDING (1<<17)
532#define IR_OPT_CFG (1<<18)
533#define IR_OPT_MEM2SSA (1<<19)
534#define IR_OPT_CODEGEN (1<<20)
535#define IR_GEN_NATIVE (1<<21)
536#define IR_GEN_CODE (1<<22)
538#define IR_GEN_CACHE_DEMOTE (1<<23)
542# define IR_DEBUG_SCCP (1<<26)
543# define IR_DEBUG_GCM (1<<27)
544# define IR_DEBUG_GCM_SPLIT (1<<28)
545# define IR_DEBUG_SCHEDULE (1<<29)
546# define IR_DEBUG_RA (1<<30)
547# define IR_DEBUG_BB_SCHEDULE (1U<<31)
561#if defined(IR_TARGET_AARCH64)
562typedef const void *(*ir_get_exit_addr_t)(uint32_t exit_num);
563typedef const void *(*ir_get_veneer_t)(
ir_ctx *ctx,
const void *
addr);
564typedef bool (*ir_set_veneer_t)(
ir_ctx *ctx,
const void *
addr,
const void *veneer);
635#if defined(IR_TARGET_AARCH64)
636 int32_t deoptimization_exits;
637 const void *deoptimization_exits_base;
638 ir_get_exit_addr_t get_exit_addr;
639 ir_get_veneer_t get_veneer;
640 ir_set_veneer_t set_veneer;
682#define IR_MAX_PROTO_PARAMS 255
741 int i,
n = insn->inputs_count;
743 for (i = 1; i <=
n; i++) {
786#define IR_REG_NONE -1
787#define IR_REG_SPILL_LOAD (1<<6)
788#define IR_REG_SPILL_STORE (1<<6)
789#define IR_REG_SPILL_SPECIAL (1<<7)
790#define IR_REG_SPILLED(r) \
791 ((r) & (IR_REG_SPILL_LOAD|IR_REG_SPILL_STORE|IR_REG_SPILL_SPECIAL))
792#define IR_REG_NUM(r) \
793 ((int8_t)((r) == IR_REG_NONE ? IR_REG_NONE : ((r) & ~(IR_REG_SPILL_LOAD|IR_REG_SPILL_STORE|IR_REG_SPILL_SPECIAL))))
840 uint32_t sp_adjustment);
850 uint32_t
flags,
ir_type ret_type, uint32_t params_count,
const uint8_t *param_types);
852 uint32_t
flags,
ir_type ret_type, uint32_t params_count,
const uint8_t *param_types);
861 void*(*resolve_sym_name) (
ir_loader *loader,
const char *
name,
bool add_thunk);
875#define IR_SAVE_CFG (1<<0)
876#define IR_SAVE_CFG_MAP (1<<1)
877#define IR_SAVE_USE_LISTS (1<<2)
878#define IR_SAVE_RULES (1<<3)
879#define IR_SAVE_REGS (1<<4)
882void ir_save(
const ir_ctx *ctx, uint32_t save_flags, FILE *f);
908int ir_patch(
const void *code,
size_t size, uint32_t jmp_table_size,
const void *from_addr,
const void *to_addr);
911#if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
912# define IR_X86_SSE2 (1<<0)
913# define IR_X86_SSE3 (1<<1)
914# define IR_X86_SSSE3 (1<<2)
915# define IR_X86_SSE41 (1<<3)
916# define IR_X86_SSE42 (1<<4)
917# define IR_X86_AVX (1<<5)
918# define IR_X86_AVX2 (1<<6)
919# define IR_X86_BMI1 (1<<7)
920# define IR_X86_CLDEMOTE (1<<8)
931 if (opt_level == 0) {
948 }
else if (opt_level > 0) {
998#define IR_ERROR_CODE_MEM_OVERFLOW 1
999#define IR_ERROR_FIXED_STACK_FRAME_OVERFLOW 2
1000#define IR_ERROR_UNSUPPORTED_CODE_RULE 3
1001#define IR_ERROR_LINK 4
1002#define IR_ERROR_ENCODE 5
1005#ifndef ir_mem_malloc
1006# define ir_mem_malloc malloc
1008#ifndef ir_mem_calloc
1009# define ir_mem_calloc calloc
1011#ifndef ir_mem_realloc
1012# define ir_mem_realloc realloc
1015# define ir_mem_free free
1018#ifndef ir_mem_pmalloc
1019# define ir_mem_pmalloc malloc
1021#ifndef ir_mem_pcalloc
1022# define ir_mem_pcalloc calloc
1024#ifndef ir_mem_prealloc
1025# define ir_mem_prealloc realloc
1028# define ir_mem_pfree free
count(Countable|array $value, int $mode=COUNT_NORMAL)
const php_stream_filter_ops * ops
const char * ir_get_strl(const ir_ctx *ctx, ir_ref idx, size_t *len)
IR_ALWAYS_INLINE void * ir_jit_compile(ir_ctx *ctx, int opt_level, size_t *size)
ir_ref ir_strtab_find(const ir_strtab *strtab, const char *str, uint32_t len)
void ir_loader_free(void)
struct _ir_live_range ir_live_range
ir_ref ir_binding_find(const ir_ctx *ctx, ir_ref ref)
ir_ref ir_fold2(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2)
void ir_free(ir_ctx *ctx)
int ir_load(ir_loader *loader, FILE *f)
ir_ref ir_str(ir_ctx *ctx, const char *s)
int ir_load_llvm_bitcode(ir_loader *loader, const char *filename)
const char * ir_strtab_strl(const ir_strtab *strtab, ir_ref idx, size_t *len)
ir_ref ir_emit3(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3)
ir_ref ir_const_func(ir_ctx *ctx, ir_ref str, ir_ref proto)
ir_ref ir_bind(ir_ctx *ctx, ir_ref var, ir_ref def)
ir_ref ir_const_i64(ir_ctx *ctx, int64_t c)
ir_ref ir_get_op(ir_ctx *ctx, ir_ref ref, int32_t n)
ir_ref ir_fold3(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3)
void ir_truncate(ir_ctx *ctx)
int ir_match(ir_ctx *ctx)
uint32_t ir_cpuinfo(void)
IR_ALWAYS_INLINE uint32_t ir_insn_find_op(const ir_insn *insn, ir_ref val)
ir_ref ir_const_i32(ir_ctx *ctx, int32_t c)
ir_ref ir_emit2(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2)
bool ir_reg_is_int(int32_t reg)
int ir_coalesce(ir_ctx *ctx)
struct _ir_live_interval ir_live_interval
ir_ref ir_const_addr(ir_ctx *ctx, uintptr_t c)
int ir_assign_virtual_registers(ir_ctx *ctx)
void ir_strtab_apply(const ir_strtab *strtab, ir_strtab_apply_t func)
ir_ref ir_const_double(ir_ctx *ctx, double c)
ir_ref ir_strtab_update(ir_strtab *strtab, const char *str, uint32_t len, ir_ref val)
ir_ref ir_const_bool(ir_ctx *ctx, bool c)
void ir_build_def_use_lists(ir_ctx *ctx)
bool ir_needs_thunk(ir_code_buffer *code_buffer, void *addr)
struct _ir_hashtab ir_hashtab
int ir_mem_unprotect(void *ptr, size_t size)
int ir_mem_unmap(void *ptr, size_t size)
int ir_schedule_blocks(ir_ctx *ctx)
void ir_emit_c_sym_decl(const char *name, uint32_t flags, FILE *f)
int ir_mem_flush(void *ptr, size_t size)
void ir_dump_dot(const ir_ctx *ctx, const char *name, FILE *f)
void ir_disasm_free(void)
ir_ref ir_const_i8(ir_ctx *ctx, int8_t c)
int32_t ir_get_spill_slot_offset(ir_ctx *ctx, ir_ref ref)
int ir_compute_dessa_moves(ir_ctx *ctx)
ir_ref ir_emit1(ir_ctx *ctx, uint32_t opt, ir_ref op1)
void ir_consistency_check(void)
int ir_find_loops(ir_ctx *ctx)
ir_ref ir_fold(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3)
int ir_disasm(const char *name, const void *start, size_t size, bool asm_addr, ir_ctx *ctx, FILE *f)
ir_ref ir_const_func_addr(ir_ctx *ctx, uintptr_t c, ir_ref proto)
const void * ir_emit_exitgroup(uint32_t first_exit_point, uint32_t exit_points_per_group, const void *exit_addr, ir_code_buffer *code_buffer, size_t *size_ptr)
int ir_gdb_register(const char *name, const void *start, size_t size, uint32_t sp_offset, uint32_t sp_adjustment)
IR_ALWAYS_INLINE void ir_set_op1(ir_ctx *ctx, ir_ref ref, ir_ref val)
ir_ref ir_emit_N(ir_ctx *ctx, uint32_t opt, int32_t count)
void ir_print_proto(const ir_ctx *ctx, ir_ref proto, FILE *f)
ir_ref ir_const_u64(ir_ctx *ctx, uint64_t c)
#define IR_OP_ENUM(name, flags, op1, op2, op3)
void ir_dump_live_ranges(const ir_ctx *ctx, FILE *f)
void ir_dump_cfg(ir_ctx *ctx, FILE *f)
int ir_build_dominators_tree(ir_ctx *ctx)
ir_ref ir_const_i16(ir_ctx *ctx, int16_t c)
ir_ref ir_const(ir_ctx *ctx, ir_val val, uint8_t type)
int ir_mem2ssa(ir_ctx *ctx)
ir_ref ir_proto_5(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3, ir_type t4, ir_type t5)
void ir_fix_thunk(void *thunk_entry, void *addr)
int ir_build_cfg(ir_ctx *ctx)
IR_ALWAYS_INLINE ir_ref ir_insn_op(const ir_insn *insn, int32_t n)
struct _ir_proto_t ir_proto_t
void ir_disasm_add_symbol(const char *name, uint64_t addr, uint64_t size)
const char * ir_get_str(const ir_ctx *ctx, ir_ref idx)
void ir_dump_use_lists(const ir_ctx *ctx, FILE *f)
void * ir_emit_code(ir_ctx *ctx, size_t *size)
int ir_perf_jitdump_register(const char *name, const void *start, size_t size)
ir_ref ir_var(ir_ctx *ctx, ir_type type, ir_ref region, const char *name)
ir_ref ir_emit(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3)
const char * ir_disasm_find_symbol(uint64_t addr, int64_t *offset)
IR_ALWAYS_INLINE void ir_insn_set_op(ir_insn *insn, int32_t n, ir_ref val)
ir_ref ir_fold1(ir_ctx *ctx, uint32_t opt, ir_ref op1)
int ir_compute_live_ranges(ir_ctx *ctx)
const char * ir_strtab_str(const ir_strtab *strtab, ir_ref idx)
ir_ref ir_const_sym(ir_ctx *ctx, ir_ref str)
struct _ir_arena ir_arena
bool ir_check(const ir_ctx *ctx)
void ir_emit_llvm_func_decl(const char *name, uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types, FILE *f)
int ir_patch(const void *code, size_t size, uint32_t jmp_table_size, const void *from_addr, const void *to_addr)
void(* ir_snapshot_create_t)(ir_ctx *ctx, ir_ref addr)
IR_ALWAYS_INLINE void ir_set_op3(ir_ctx *ctx, ir_ref ref, ir_ref val)
ir_ref ir_strtab_lookup(ir_strtab *strtab, const char *str, uint32_t len, ir_ref val)
ir_ref ir_strl(ir_ctx *ctx, const char *s, size_t len)
#define IR_LAST_FOLDABLE_OP
void ir_set_op(ir_ctx *ctx, ir_ref ref, int32_t n, ir_ref val)
void * ir_resolve_sym_name(const char *name)
struct _ir_code_buffer ir_code_buffer
void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted)
void ir_reset_cfg(ir_ctx *ctx)
int ir_emit_llvm(ir_ctx *ctx, const char *name, FILE *f)
struct _ir_loader ir_loader
void ir_dump(const ir_ctx *ctx, FILE *f)
int ir_perf_jitdump_open(void)
const char * ir_reg_name(int8_t reg, ir_type type)
struct _ir_strtab ir_strtab
void ir_init(ir_ctx *ctx, uint32_t flags, ir_ref consts_limit, ir_ref insns_limit)
void ir_gdb_unregister_all(void)
#define IR_TYPE_ENUM(name, type, field, flags)
int ir_load_llvm_asm(ir_loader *loader, const char *filename)
void * ir_emit_thunk(ir_code_buffer *code_buffer, void *addr, size_t *size_ptr)
ir_ref ir_proto_2(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2)
ir_ref ir_const_u8(ir_ctx *ctx, uint8_t c)
ir_ref ir_const_u32(ir_ctx *ctx, uint32_t c)
int ir_mem_protect(void *ptr, size_t size)
ir_ref ir_unique_const_addr(ir_ctx *ctx, uintptr_t c)
ir_ref ir_const_float(ir_ctx *ctx, float c)
void ir_strtab_free(ir_strtab *strtab)
int ir_perf_jitdump_close(void)
void ir_emit_c_func_decl(const char *name, uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types, FILE *f)
int ir_reg_alloc(ir_ctx *ctx)
ir_ref ir_proto_0(ir_ctx *ctx, uint8_t flags, ir_type ret_type)
ir_ref ir_param(ir_ctx *ctx, ir_type type, ir_ref region, const char *name, int pos)
void ir_emit_llvm_sym_decl(const char *name, uint32_t flags, FILE *f)
void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f)
ir_ref ir_proto_1(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1)
ir_ref ir_const_str(ir_ctx *ctx, ir_ref str)
ir_ref ir_const_char(ir_ctx *ctx, char c)
int ir_schedule(ir_ctx *ctx)
void ir_dump_codegen(const ir_ctx *ctx, FILE *f)
IR_ALWAYS_INLINE void ir_set_op2(ir_ctx *ctx, ir_ref ref, ir_ref val)
void ir_loader_init(void)
ir_ref ir_proto_4(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3, ir_type t4)
ir_ref ir_const_u16(ir_ctx *ctx, uint16_t c)
void ir_perf_map_register(const char *name, const void *start, size_t size)
int ir_emit_c(ir_ctx *ctx, const char *name, FILE *f)
void * ir_mem_mmap(size_t size)
ir_ref ir_fold0(ir_ctx *ctx, uint32_t opt)
void ir_dump_cfg_map(const ir_ctx *ctx, FILE *f)
void ir_strtab_init(ir_strtab *strtab, uint32_t count, uint32_t buf_size)
void(* ir_strtab_apply_t)(const char *str, uint32_t len, ir_ref val)
bool ir_gdb_present(void)
struct _ir_use_list ir_use_list
ir_ref ir_proto(ir_ctx *ctx, uint8_t flags, ir_type ret_type, uint32_t params_counts, uint8_t *param_types)
ir_ref ir_proto_3(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3)
ir_ref ir_emit0(ir_ctx *ctx, uint32_t opt)
struct _ir_block ir_block
unsigned const char * pos
ir_live_interval ** live_intervals
int32_t fixed_stack_red_zone
ir_live_range * unused_ranges
ir_ref prev_const_chain[IR_LAST_TYPE]
int32_t fixed_stack_frame_size
ir_snapshot_create_t snapshot_create
ir_code_buffer * code_buffer
int32_t stack_frame_alignment
uint32_t jmp_table_offset
uint32_t cfg_blocks_count
uint64_t fixed_save_regset
ir_ref prev_insn_chain[IR_LAST_FOLDABLE_OP+1]
int32_t fixed_call_stack_size
uint64_t used_preserved_regs
uint32_t locals_area_size
IR_STRUCT_LOHI(union { IR_STRUCT_LOHI(union { IR_STRUCT_LOHI(uint8_t op, uint8_t type);uint16_t opt;}, union { uint16_t inputs_count;uint16_t prev_insn_offset;uint16_t proto;});uint32_t optx;ir_ref ops[1];}, union { ir_ref op1;ir_ref prev_const;})
bool(* func_process)(ir_loader *loader, ir_ctx *ctx, const char *name)
bool(* sym_data_str)(ir_loader *loader, const char *str, size_t len)
bool(* sym_data_pad)(ir_loader *loader, size_t offset)
bool(* external_sym_dcl)(ir_loader *loader, const char *name, uint32_t flags)
bool(* sym_data)(ir_loader *loader, ir_type type, uint32_t count, const void *data)
bool(* sym_data_end)(ir_loader *loader, uint32_t flags)
uint32_t default_func_flags
bool(* sym_dcl)(ir_loader *loader, const char *name, uint32_t flags, size_t size)
bool(* sym_data_ref)(ir_loader *loader, ir_op op, const char *ref, uintptr_t offset)
bool(* has_sym)(ir_loader *loader, const char *name)
bool(* forward_func_dcl)(ir_loader *loader, const char *name, uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types)
bool(* external_func_dcl)(ir_loader *loader, const char *name, uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types)
bool(* init_module)(ir_loader *loader, const char *name, const char *filename, const char *target)
bool(* add_sym)(ir_loader *loader, const char *name, void *addr)
bool(* func_init)(ir_loader *loader, ir_ctx *ctx, const char *name)
IR_STRUCT_LOHI(union { uint32_t u32;int32_t i32;float f;ADDR_MEMBER ir_ref name;ir_ref str;IR_STRUCT_LOHI(union { uint16_t u16;int16_t i16;IR_STRUCT_LOHI(union { uint8_t u8;int8_t i8;bool b;char c;}, uint8_t u8_hi);}, uint16_t u16_hi);}, uint32_t u32_hi)
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)