Coverage Report

Created: 2026-10-28 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/ext/opcache/jit/ir/ir.h
Line
Count
Source
1
/*
2
 * IR - Lightweight JIT Compilation Framework
3
 * (Public API)
4
 * This file is part of the IR Project distributed under the MIT-style LICENSE.
5
 * Authors: Dmitry Stogov <dmitry@php.net>
6
 */
7
8
#ifndef IR_H
9
#define IR_H
10
11
#ifdef __cplusplus
12
extern "C" {
13
#endif
14
15
#include <inttypes.h>
16
#include <stdint.h>
17
#include <stdbool.h>
18
#include <stdio.h>
19
#include <stdlib.h>
20
21
#define IR_VERSION "0.0.1"
22
23
#ifdef _WIN32
24
/* TODO Handle ARM, too. */
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
29
# endif
30
/* Only supported is little endian for any arch on Windows,
31
   so just fake the same for all. */
32
# ifndef __ORDER_LITTLE_ENDIAN__
33
#  define __ORDER_LITTLE_ENDIAN__ 1
34
# endif
35
# define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
36
# ifndef __has_builtin
37
#  define __has_builtin(arg) (0)
38
# endif
39
#endif
40
41
/* target auto detection */
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)
44
#  define IR_TARGET_X64
45
# elif defined(i386) || defined(__i386) || defined(__i386__) || defined(_M_IX86)
46
#  define IR_TARGET_X86
47
# elif defined(__aarch64__) || defined(_M_ARM64)
48
#  define IR_TARGET_AARCH64
49
# elif defined (_WIN64)
50
#  define IR_TARGET_X64
51
# elif defined (_WIN32)
52
#  define IR_TARGET_X86
53
# endif
54
#endif
55
56
#ifndef IR_TARGET_TRIPLET
57
# if defined(IR_TARGET_X64)
58
#  if defined(_WIN32)
59
#   define IR_TARGET_TRIPLET "x86-windows-msvc"
60
#  elif defined(__APPLE__)
61
#   define IR_TARGET_TRIPLET "x86-darwin"
62
#  elif defined(__linux__)
63
#   define IR_TARGET_TRIPLET "x86-linux-sysv"
64
#  elif defined(__FreeBSD__)
65
#   define IR_TARGET_TRIPLET "x86-freebsd-sysv"
66
#  elif defined(__NetBSD__)
67
#   define IR_TARGET_TRIPLET "x86-netbsd-sysv"
68
#  elif defined(__OpenBSD__)
69
#   define IR_TARGET_TRIPLET "x86-openbsd-sysv"
70
#  else
71
#   define IR_TARGET_TRIPLET "x86-unknown-sysv"
72
#  endif
73
# elif defined(IR_TARGET_X86)
74
#  if defined(_WIN32)
75
#   define IR_TARGET_TRIPLET "x86_64-windows-msvc"
76
#  elif defined(__APPLE__)
77
#   define IR_TARGET_TRIPLET "x86_64-darwin"
78
#  elif defined(__linux__)
79
#   define IR_TARGET_TRIPLET "x86_64-linux-sysv"
80
#  elif defined(__FreeBSD__)
81
#   define IR_TARGET_TRIPLET "x86_64-freebsd-sysv"
82
#  elif defined(__NetBSD__)
83
#   define IR_TARGET_TRIPLET "x86_64-netbsd-sysv"
84
#  elif defined(__OpenBSD__)
85
#   define IR_TARGET_TRIPLET "x86_64-openbsd-sysv"
86
#  else
87
#   define IR_TARGET_TRIPLET "x86_64-unknown-sysv"
88
#  endif
89
# elif defined(IR_TARGET_AARCH64)
90
#  if defined(_WIN32)
91
#   define IR_TARGET_TRIPLET "aarch64-windows"
92
#  elif defined(__APPLE__)
93
#   define IR_TARGET_TRIPLET "aarch64-darwin"
94
#  elif defined(__linux__)
95
#   define IR_TARGET_TRIPLET "aarch64-linux-sysv"
96
#  elif defined(__FreeBSD__)
97
#   define IR_TARGET_TRIPLET "aarch64-freebsd-sysv"
98
#  elif defined(__NetBSD__)
99
#   define IR_TARGET_TRIPLET "aarch64-netbsd-sysv"
100
#  elif defined(__OpenBSD__)
101
#   define IR_TARGET_TRIPLET "aarch64-openbsd-sysv"
102
#  else
103
#   define IR_TARGET_TRIPLET "aarch64-unknown-sysv"
104
#  endif
105
# else
106
#  error "Unknown IR_TARGET"
107
# endif
108
#endif
109
110
#if defined(__SIZEOF_SIZE_T__)
111
# if __SIZEOF_SIZE_T__ == 8
112
#  define IR_64 1
113
# elif __SIZEOF_SIZE_T__ != 4
114
#  error "Unknown addr size"
115
# endif
116
#else
117
# error "Unknown addr size"
118
#endif
119
120
#if defined(__BYTE_ORDER__)
121
# if defined(__ORDER_LITTLE_ENDIAN__)
122
#  if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
123
#   define IR_STRUCT_LOHI(lo, hi) struct {lo; hi;}
124
#  endif
125
# endif
126
# if defined(__ORDER_BIG_ENDIAN__)
127
#  if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
128
#   define IR_STRUCT_LOHI(lo, hi) struct {hi; lo;}
129
#  endif
130
# endif
131
#endif
132
#ifndef IR_STRUCT_LOHI
133
# error "Unknown byte order"
134
#endif
135
136
#ifdef __has_attribute
137
# if __has_attribute(always_inline)
138
#  define IR_ALWAYS_INLINE static inline __attribute__((always_inline))
139
# endif
140
# if __has_attribute(noinline)
141
#  define IR_NEVER_INLINE __attribute__((noinline))
142
# endif
143
#else
144
# define __has_attribute(x) 0
145
#endif
146
147
#ifndef IR_ALWAYS_INLINE
148
# define IR_ALWAYS_INLINE static inline
149
#endif
150
#ifndef IR_NEVER_INLINE
151
# define IR_NEVER_INLINE
152
#endif
153
154
#ifdef IR_PHP
155
# include "ir_php.h"
156
#endif
157
158
#ifdef IR_TARGET_X86
159
# ifndef IR_X86_I64
160
#  define IR_X86_I64 1
161
# endif
162
#else
163
# define IR_X86_I64 0
164
#endif
165
166
#ifndef IR_SIMD
167
# define IR_SIMD 1
168
#endif
169
170
/* IR Type flags */
171
#define IR_TYPE_SIGNED     (1<<0)
172
#define IR_TYPE_UNSIGNED   (1<<1)
173
#define IR_TYPE_FP         (1<<2)
174
#define IR_TYPE_SPECIAL    (1<<3)
175
#define IR_TYPE_BOOL       (IR_TYPE_SPECIAL|IR_TYPE_UNSIGNED)
176
#define IR_TYPE_ADDR       (IR_TYPE_SPECIAL|IR_TYPE_UNSIGNED)
177
#define IR_TYPE_CHAR       (IR_TYPE_SPECIAL|IR_TYPE_SIGNED)
178
179
/* List of IR types */
180
#define IR_TYPES(_) \
181
  _(BOOL,   bool,      b,    IR_TYPE_BOOL)     \
182
  _(U8,     uint8_t,   u8,   IR_TYPE_UNSIGNED) \
183
  _(U16,    uint16_t,  u16,  IR_TYPE_UNSIGNED) \
184
  _(U32,    uint32_t,  u32,  IR_TYPE_UNSIGNED) \
185
  _(U64,    uint64_t,  u64,  IR_TYPE_UNSIGNED) \
186
  _(ADDR,   uintptr_t, addr, IR_TYPE_ADDR)     \
187
  _(CHAR,   char,      c,    IR_TYPE_CHAR)     \
188
  _(I8,     int8_t,    i8,   IR_TYPE_SIGNED)   \
189
  _(I16,    int16_t,   i16,  IR_TYPE_SIGNED)   \
190
  _(I32,    int32_t,   i32,  IR_TYPE_SIGNED)   \
191
  _(I64,    int64_t,   i64,  IR_TYPE_SIGNED)   \
192
  _(DOUBLE, double,    d,    IR_TYPE_FP)       \
193
  _(FLOAT,  float,     f,    IR_TYPE_FP)       \
194
195
3.26k
#define IR_IS_TYPE_UNSIGNED(t) ((t) < IR_CHAR)
196
119k
#define IR_IS_TYPE_SIGNED(t)   ((t) >= IR_CHAR && (t) < IR_DOUBLE)
197
3.04M
#define IR_IS_TYPE_INT(t)      ((t) < IR_DOUBLE)
198
476k
#define IR_IS_TYPE_FP(t)       ((t) >= IR_DOUBLE && (t) <= IR_FLOAT)
199
200
#define IR_TYPE_ENUM(name, type, field, flags) IR_ ## name,
201
202
typedef enum _ir_type {
203
  IR_VOID,
204
  IR_TYPES(IR_TYPE_ENUM)
205
  IR_LAST_TYPE,
206
207
  IR_BASE_TYPE_MASK = 0x0f,
208
  IR_VECTOR_MASK    = 0x70,
209
210
  IR_VECTOR_1       = 0x10,
211
  IR_VECTOR_2       = 0x20,
212
  IR_VECTOR_4       = 0x30,
213
  IR_VECTOR_8       = 0x40,
214
  IR_VECTOR_16      = 0x50,
215
  IR_VECTOR_32      = 0x60,
216
  IR_VECTOR_64      = 0x70,
217
} ir_type;
218
219
16.1k
#define IR_IS_TYPE_SCALAR(t)   (((t) & IR_VECTOR_MASK) == 0)
220
554k
#define IR_IS_TYPE_VECTOR(t)   (((t) & IR_VECTOR_MASK) != 0)
221
222
0
#define IR_VECTOR_BASE_TYPE(t) ((t) & IR_BASE_TYPE_MASK)
223
0
#define IR_VECTOR_LENGTH(t)    (1U << ((((t) & IR_VECTOR_MASK) >> 4) - 1))
224
225
#ifdef IR_64
226
# define IR_SIZE_T          IR_U64
227
# define IR_SSIZE_T         IR_I64
228
60
# define IR_UINTPTR_T       IR_U64
229
30
# define IR_INTPTR_T        IR_I64
230
# define IR_C_UINTPTR       IR_U64
231
# define IR_C_INTPTR        IR_I64
232
# define ir_const_size_t    ir_const_u64
233
# define ir_const_ssize_t   ir_const_i64
234
# define ir_const_uintptr_t ir_const_u64
235
# define ir_const_intptr_t  ir_const_i64
236
#else
237
# define IR_SIZE_T          IR_U32
238
# define IR_SSIZE_T         IR_I32
239
# define IR_UINTPTR_T       IR_U32
240
# define IR_INTPTR_T        IR_I32
241
# define IR_C_UINTPTR       IR_U32
242
# define IR_C_INTPTR        IR_I32
243
# define ir_const_size_t    ir_const_u32
244
# define ir_const_ssize_t   ir_const_i32
245
# define ir_const_uintptr_t ir_const_u32
246
# define ir_const_intptr_t  ir_const_i32
247
#endif
248
249
/* List of IR opcodes
250
 * ==================
251
 *
252
 * Each instruction is described by a type (opcode, flags, op1_type, op2_type, op3_type)
253
 *
254
 * flags
255
 * -----
256
 * v     - void
257
 * d     - data      IR_OP_FLAG_DATA
258
 * r     - ref       IR_OP_FLAG_DATA alias
259
 * p     - pinned    IR_OP_FLAG_DATA + IR_OP_FLAG_PINNED
260
 * c     - control   IR_OP_FLAG_CONTROL
261
 * S     - control   IR_OP_FLAG_CONTROL + IR_OP_FLAG_BB_START
262
 * E     - control   IR_OP_FLAG_CONTROL + IR_OP_FLAG_BB_END
263
 * T     - control   IR_OP_FLAG_CONTROL + IR_OP_FLAG_BB_END + IR_OP_FLAG_TERMINATOR
264
 * l     - load      IR_OP_FLAG_MEM + IR_OP_FLAG_MEM_LOAD
265
 * s     - store     IR_OP_FLAG_MEM + IR_OP_FLAG_MEM_STORE
266
 * x     - call      IR_OP_FLAG_MEM + IR_OP_FLAG_MEM_CALL
267
 * a     - alloc     IR_OP_FLAG_MEM + IR_OP_FLAG_MEM_ALLOC
268
 * 0-3   - number of input edges
269
 * N     - number of arguments is defined in the insn->inputs_count (MERGE, PHI, CALL)
270
 * X1-X3 - number of extra data ops
271
 * C     - commutative operation ("d2C" => IR_OP_FLAG_DATA + IR_OP_FLAG_COMMUTATIVE)
272
 *
273
 * operand types
274
 * -------------
275
 * ___ - unused
276
 * def - reference to a definition op (data-flow use-def dependency edge)
277
 * ref - memory reference (data-flow use-def dependency edge)
278
 * var - variable reference (data-flow use-def dependency edge)
279
 * arg - argument reference CALL/TAILCALL/CARG->CARG
280
 * src - reference to a previous control region (IF, IF_TRUE, IF_FALSE, MERGE, LOOP_BEGIN, LOOP_END, RETURN)
281
 * reg - data-control dependency on region (PHI, VAR, PARAM)
282
 * grd - optional data-control dependency guard (DIV, MOD)
283
 * ret - reference to a previous RETURN instruction (RETURN)
284
 * str - string: variable/argument name (VAR, PARAM, CALL, TAILCALL)
285
 * num - number: argument number (PARAM)
286
 * prb - branch probability 1-99 (0 - unspecified): (IF_TRUE, IF_FALSE, CASE_VAL, CASE_DEFAULT)
287
 * opt - optional number
288
 * alg - optional alignment
289
 * pro - function prototype
290
 * lbl - label used as value (a reference to constant): (BEGIN)
291
 *
292
 * The order of IR opcodes is carefully selected for efficient folding.
293
 * - foldable instruction go first
294
 * - NOP is never used (code 0 is used as ANY pattern)
295
 * - CONST is the most often used instruction (encode with 1 bit)
296
 * - equality inversion:  EQ <-> NE                         => op =^ 1
297
 * - comparison inversion: [U]LT <-> [U]GT, [U]LE <-> [U]GE  => op =^ 3
298
 */
299
300
#define IR_OPS(_) \
301
  /* special op (must be the first !!!)                               */ \
302
  _(NOP,          v,    ___, ___, ___) /* empty instruction           */ \
303
  \
304
  /* constants reference                                              */ \
305
  _(C_BOOL,       r0,   ___, ___, ___) /* constant                    */ \
306
  _(C_U8,         r0,   ___, ___, ___) /* constant                    */ \
307
  _(C_U16,        r0,   ___, ___, ___) /* constant                    */ \
308
  _(C_U32,        r0,   ___, ___, ___) /* constant                    */ \
309
  _(C_U64,        r0,   ___, ___, ___) /* constant                    */ \
310
  _(C_ADDR,       r0,   ___, ___, ___) /* constant                    */ \
311
  _(C_CHAR,       r0,   ___, ___, ___) /* constant                    */ \
312
  _(C_I8,         r0,   ___, ___, ___) /* constant                    */ \
313
  _(C_I16,        r0,   ___, ___, ___) /* constant                    */ \
314
  _(C_I32,        r0,   ___, ___, ___) /* constant                    */ \
315
  _(C_I64,        r0,   ___, ___, ___) /* constant                    */ \
316
  _(C_DOUBLE,     r0,   ___, ___, ___) /* constant                    */ \
317
  _(C_FLOAT,      r0,   ___, ___, ___) /* constant                    */ \
318
  \
319
  /* equality ops  */                                                    \
320
  _(EQ,           d2C,  def, def, ___) /* equal                       */ \
321
  _(NE,           d2C,  def, def, ___) /* not equal                   */ \
322
  \
323
  /* comparison ops (order matters, LT must be a modulo of 4 !!!)     */ \
324
  _(LT,           d2,   def, def, ___) /* less (signed)               */ \
325
  _(GE,           d2,   def, def, ___) /* greater or equal (signed)   */ \
326
  _(LE,           d2,   def, def, ___) /* less or equal (signed)      */ \
327
  _(GT,           d2,   def, def, ___) /* greater (signed)            */ \
328
  _(ULT,          d2,   def, def, ___) /* unsigned less               */ \
329
  _(UGE,          d2,   def, def, ___) /* unsigned greater or equal   */ \
330
  _(ULE,          d2,   def, def, ___) /* unsigned less or equal      */ \
331
  _(UGT,          d2,   def, def, ___) /* unsigned greater            */ \
332
  _(ORDERED,      d2,   def, def, ___) /* both operands are not NAN   */ \
333
  _(UNORDERED,    d2,   def, def, ___) /* one of operands is NAN      */ \
334
  \
335
  /* arithmetic ops                                                   */ \
336
  _(ADD,          d2C,  def, def, ___) /* addition                    */ \
337
  _(SUB,          d2,   def, def, ___) /* subtraction (must be ADD+1) */ \
338
  _(MUL,          d2C,  def, def, ___) /* multiplication              */ \
339
  _(DIV,          d3,   def, def, grd) /* division                    */ \
340
  _(MOD,          d3,   def, def, grd) /* modulo                      */ \
341
  _(NEG,          d1,   def, ___, ___) /* change sign                 */ \
342
  _(ABS,          d1,   def, ___, ___) /* absolute value              */ \
343
  /* (LDEXP, MIN, MAX, FPMATH)                                        */ \
344
  \
345
  /* type conversion ops                                              */ \
346
  _(SEXT,         d1,   def, ___, ___) /* sign extension              */ \
347
  _(ZEXT,         d1,   def, ___, ___) /* zero extension              */ \
348
  _(TRUNC,        d1,   def, ___, ___) /* truncates to int type       */ \
349
  _(BITCAST,      d1,   def, ___, ___) /* binary representation       */ \
350
  _(INT2FP,       d1,   def, ___, ___) /* int to float conversion     */ \
351
  _(FP2INT,       d1,   def, ___, ___) /* float to int conversion     */ \
352
  _(FP2FP,        d1,   def, ___, ___) /* float to float conversion   */ \
353
  _(PROTO,        d1X1, def, pro, ___) /* apply function prototype    */ \
354
  \
355
  /* overflow-check                                                   */ \
356
  _(ADD_OV,       d2C,  def, def, ___) /* addition                    */ \
357
  _(SUB_OV,       d2,   def, def, ___) /* subtraction                 */ \
358
  _(MUL_OV,       d2C,  def, def, ___) /* multiplication              */ \
359
  _(OVERFLOW,     d1,   def, ___, ___) /* overflow check add/sub/mul  */ \
360
  \
361
  /* bitwise and shift ops                                            */ \
362
  _(NOT,          d1,   def, ___, ___) /* bitwise NOT                 */ \
363
  _(OR,           d2C,  def, def, ___) /* bitwise OR                  */ \
364
  _(AND,          d2C,  def, def, ___) /* bitwise AND                 */ \
365
  _(XOR,          d2C,  def, def, ___) /* bitwise XOR                 */ \
366
  _(SHL,          d2,   def, def, ___) /* logic shift left            */ \
367
  _(SHR,          d2,   def, def, ___) /* logic shift right           */ \
368
  _(SAR,          d2,   def, def, ___) /* arithmetic shift right      */ \
369
  _(ROL,          d2,   def, def, ___) /* rotate left                 */ \
370
  _(ROR,          d2,   def, def, ___) /* rotate right                */ \
371
  _(BSWAP,        d1,   def, ___, ___) /* byte swap                   */ \
372
  _(CTPOP,        d1,   def, ___, ___) /* count population            */ \
373
  _(CTLZ,         d1,   def, ___, ___) /* count leading zeros         */ \
374
  _(CTTZ,         d1,   def, ___, ___) /* count trailing zeros        */ \
375
  \
376
  /* branch-less conditional ops                                      */ \
377
  _(MIN,          d2C,  def, def, ___) /* min(op1, op2)               */ \
378
  _(MAX,          d2C,  def, def, ___) /* max(op1, op2)               */ \
379
  _(COND,         d3,   def, def, def) /* op1 ? op2 : op3             */ \
380
  \
381
  /* SIMD vector ops                                                  */ \
382
  _(EXTRACT,      d2,   def, def, ___) /* get element of vector       */ \
383
  _(REPLACE,      d3,   def, def, def) /* set element of vector       */ \
384
  _(SPLAT,        d1,   def, ___, ___) /* set all elements of vector  */ \
385
  _(SHUFFLE,      d3,   def, def, def) /* shuffle elements of vectors */ \
386
  \
387
  /* data-flow and miscellaneous ops                                  */ \
388
  _(VADDR,        d1,   var, ___, ___) /* load address of local var   */ \
389
  _(FRAME_ADDR,   d0,   ___, ___, ___) /* function frame address      */ \
390
  _(PHI,          pN,   reg, def, def) /* SSA Phi function            */ \
391
  _(COPY,         d1X1, def, opt, ___) /* COPY (last foldable op)     */ \
392
  _(PI,           p2,   reg, def, ___) /* e-SSA Pi constraint ???     */ \
393
  _(ARGVAL,       d1X2, def, num, num) /* pass struct arg by value    */ \
394
                                       /* (op2 - size, op3 - align)   */ \
395
  /* (USE, RENAME)                                                    */ \
396
  \
397
  /* data ops                                                         */ \
398
  _(PARAM,        p1X2, reg, str, num) /* incoming parameter proj.    */ \
399
  _(VAR,          p1X2, reg, str, alg) /* local variable              */ \
400
  _(FUNC_ADDR,    r0,   ___, ___, ___) /* constant func ref           */ \
401
  _(FUNC,         r0,   ___, ___, ___) /* constant func ref           */ \
402
  _(SYM,          r0,   ___, ___, ___) /* constant symbol ref         */ \
403
  _(LABEL,        r0,   ___, ___, ___) /* label address ref           */ \
404
  _(STR,          r0,   ___, ___, ___) /* constant str ref            */ \
405
  _(LONG_CONST,   r0,   ___, ___, ___) /* long constant (vector)      */ \
406
  \
407
  /* call ops                                                         */ \
408
  _(CALL,         xN,   src, def, def) /* CALL(src, func, args...)    */ \
409
  _(TAILCALL,     xN,   src, def, def) /* CALL+RETURN                 */ \
410
  \
411
  /* memory reference and load/store ops                              */ \
412
  _(ALLOCA,       a2X1, src, def, alg) /* alloca(def)                 */ \
413
  _(AFREE,        s2,   src, def, ___) /* revert alloca(def)          */ \
414
  _(BLOCK_BEGIN,  a1,   src, ___, ___) /* stacksave                   */ \
415
  _(BLOCK_END,    s2,   src, def, ___) /* stackrestore                */ \
416
  _(VLOAD,        l2,   src, var, ___) /* load value of local var     */ \
417
  _(VLOAD_v,      l2,   src, var, ___) /* volatile variant of VLOAD   */ \
418
  _(VSTORE,       s3,   src, var, def) /* store value to local var    */ \
419
  _(VSTORE_v,     s3,   src, var, def) /* volatile variant of VSTORE  */ \
420
  _(RLOAD,        l1X2, src, num, opt) /* load value from register    */ \
421
  _(RSTORE,       s2X1, src, def, num) /* store value into register   */ \
422
  _(LOAD,         l2,   src, ref, ___) /* load from memory            */ \
423
  _(LOAD_v,       l2,   src, ref, ___) /* volatile variant of VLOAD   */ \
424
  _(STORE,        s3,   src, ref, def) /* store to memory             */ \
425
  _(STORE_v,      s3,   src, ref, def) /* volatile variant of VSTORE  */ \
426
  _(TLS_ADDR,     l1X2, src, num, num) /* TLS_ADDR(_, module, offset) */ \
427
                                       /* for static TLS module is -1 */ \
428
  _(TRAP,         x1,   src, ___, ___) /* DebugBreak                  */ \
429
  /* memory reference ops (A, H, U, S, TMP, STR, NEW, X, V) ???       */ \
430
  \
431
  /* va_args                                                          */ \
432
  _(VA_START,     x2,   src, def, ___) /* va_start(va_list)           */ \
433
  _(VA_END,       x2,   src, def, ___) /* va_end(va_list)             */ \
434
  _(VA_COPY,      x3,   src, def, def) /* va_copy(dst, stc)           */ \
435
  _(VA_ARG,       x2X1, src, def, opt) /* va_arg(va_list)             */ \
436
                                       /* op3 - (size<<3)+log2(align) */ \
437
  \
438
  /* guards                                                           */ \
439
  _(GUARD,        c3,   src, def, def) /* IF without second successor */ \
440
  _(GUARD_NOT  ,  c3,   src, def, def) /* IF without second successor */ \
441
  \
442
  /* deoptimization                                                   */ \
443
  _(SNAPSHOT,     xN,   src, def, def) /* SNAPSHOT(src, args...)      */ \
444
  \
445
  /* control-flow nodes                                               */ \
446
  _(START,        S0X1, ret, ___, ___) /* function start              */ \
447
  _(ENTRY,        S1X1, src, num, ___) /* entry with a fake src edge  */ \
448
  _(BEGIN,        S1X1, src, lbl, ___) /* block start, optional &&lbl */ \
449
  _(IF_TRUE,      S1X1, src, prb, ___) /* IF TRUE proj.               */ \
450
  _(IF_FALSE,     S1X1, src, prb, ___) /* IF FALSE proj.              */ \
451
  _(CASE_VAL,     S2X1, src, def, prb) /* switch proj.                */ \
452
  _(CASE_RANGE,   S3,   src, def, def) /* switch proj.                */ \
453
  _(CASE_DEFAULT, S1X1, src, prb, ___) /* switch proj.                */ \
454
  _(MERGE,        SN,   src, src, src) /* control merge               */ \
455
  _(LOOP_BEGIN,   SN,   src, src, src) /* loop start                  */ \
456
  _(END,          E1,   src, ___, ___) /* block end                   */ \
457
  _(LOOP_END,     E1,   src, ___, ___) /* loop end                    */ \
458
  _(IF,           E2,   src, def, ___) /* conditional control split   */ \
459
  _(SWITCH,       E2,   src, def, ___) /* multi-way control split     */ \
460
  _(IGOTO,        E2,   src, def, ___) /* computed goto (internal)    */ \
461
  _(IJMP,         T2X1, src, def, ret) /* computed goto (terminating) */ \
462
  _(RETURN,       T2X1, src, def, ret) /* function return             */ \
463
  _(UNREACHABLE,  T1X2, src, ___, ret) /* unreachable (tailcall, etc) */ \
464
  \
465
  /* inline assembler                                                 */ \
466
  _(ASM,          xN,   src, def, def) /* GCC inline assembler        */ \
467
                                       /* op2 - asm template string   */ \
468
                                       /* op3 - asm constraint string */ \
469
                                       /* opN - asm input argument    */ \
470
  _(ASM_OUT,      x1,   src, ___, ___) /* ASM data output projection  */ \
471
  _(ASM_GOTO,     E1,   src, ___, ___) /* ASM goto (bb end after ASM) */ \
472
  \
473
  /* deoptimization helper                                            */ \
474
  _(EXITCALL,     x2,   src, def, ___) /* save CPU regs and call op2  */ \
475
476
477
#define IR_OP_ENUM(name, flags, op1, op2, op3) IR_ ## name,
478
479
typedef enum _ir_op {
480
  IR_OPS(IR_OP_ENUM)
481
#ifdef IR_PHP
482
  IR_PHP_OPS(IR_OP_ENUM)
483
#endif
484
  IR_LAST_OP
485
} ir_op;
486
487
/* IR Opcode and Type Union */
488
1.07M
#define IR_OPT_OP_MASK       0x00ff
489
14.0k
#define IR_OPT_TYPE_MASK     0xff00
490
1.58M
#define IR_OPT_TYPE_SHIFT    8
491
282k
#define IR_OPT_INPUTS_SHIFT  16
492
493
1.35M
#define IR_OPT(op, type)     ((uint16_t)(op) | ((uint16_t)(type) << IR_OPT_TYPE_SHIFT))
494
216k
#define IR_OPTX(op, type, n) ((uint32_t)(op) | ((uint32_t)(type) << IR_OPT_TYPE_SHIFT) | ((uint32_t)(n) << IR_OPT_INPUTS_SHIFT))
495
13.9k
#define IR_OPT_TYPE(opt)     (((opt) & IR_OPT_TYPE_MASK) >> IR_OPT_TYPE_SHIFT)
496
497
/* "opt" modifiers */
498
7.36k
#define IR_COPY_HARD         (1<<0)
499
500
0
#define IR_VA_ARG_SIZE(op3)  (((uint32_t)(op3) >> 3))
501
0
#define IR_VA_ARG_ALIGN(op3) (1U << ((uint32_t)(op3) & 0x7))
502
0
#define IR_VA_ARG_OP3(s, a)  (((s) << 3) | ir_ntzl(a))
503
504
/* IR Reference: index of ir_insn in ir_ctx.ir_base[], positive - instructions, negaive - constants */
505
typedef int32_t ir_ref;
506
507
15.2M
#define IR_IS_CONST_REF(ref) ((ref) < 0)
508
509
/* IR String: string index; positive - index in ir_strtab, negative - resolved through loader.get_str() */
510
typedef int32_t ir_str;
511
512
44
#define IR_IS_EXT_STR(str)   ((str) < 0)
513
#define IR_EXT_STR(str)      (-(str))
514
515
/* IR Constant Value */
516
17.3M
#define IR_UNUSED            0
517
68.7k
#define IR_NULL              (-1)
518
74.5k
#define IR_FALSE             (-2)
519
877k
#define IR_TRUE              (-3)
520
191k
#define IR_LAST_FOLDABLE_OP  IR_COPY
521
522
#define IR_CONSTS_LIMIT_MIN (-(IR_TRUE - 1))
523
#define IR_INSNS_LIMIT_MIN (IR_UNUSED + 1)
524
525
/* ADDR_MEMBER is neccessary to workaround MSVC C preprocessor bug */
526
#ifndef IR_64
527
# define ADDR_MEMBER            uintptr_t                  addr; \
528
                void                      *ptr;
529
#else
530
# define ADDR_MEMBER
531
#endif
532
typedef union _ir_val {
533
  double                             d;
534
  uint64_t                           u64;
535
  int64_t                            i64;
536
#ifdef IR_64
537
  uintptr_t                          addr;
538
  void                              *ptr;
539
#endif
540
  IR_STRUCT_LOHI(
541
    union {
542
      uint32_t                   u32;
543
      int32_t                    i32;
544
      float                      f;
545
      ADDR_MEMBER
546
      ir_str                     name;
547
      ir_str                     str;
548
      IR_STRUCT_LOHI(
549
        union {
550
          uint16_t           u16;
551
          int16_t            i16;
552
          IR_STRUCT_LOHI(
553
            union {
554
              uint8_t    u8;
555
              int8_t     i8;
556
              bool       b;
557
              char       c;
558
            },
559
            uint8_t        u8_hi
560
          );
561
        },
562
        uint16_t               u16_hi
563
      );
564
    },
565
    uint32_t                       u32_hi
566
  );
567
} ir_val;
568
#undef ADDR_MEMBER
569
570
/* IR Instruction */
571
typedef struct _ir_insn {
572
  IR_STRUCT_LOHI(
573
    union {
574
      IR_STRUCT_LOHI(
575
        union {
576
          IR_STRUCT_LOHI(
577
            uint8_t        op,
578
            uint8_t        type
579
          );
580
          uint16_t           opt;
581
        },
582
        union {
583
          uint16_t           inputs_count;       /* number of input control edges for MERGE, PHI, CALL, TAILCALL */
584
          uint16_t           prev_insn_offset;   /* 16-bit backward offset from current instruction for CSE */
585
          uint16_t           proto;
586
          uint16_t           long_const_size;
587
        }
588
      );
589
      uint32_t                   optx;
590
      ir_ref                     ops[1];
591
    },
592
    union {
593
      ir_ref                     op1;
594
      ir_ref                     ref;
595
      ir_ref                     prev_const;
596
    }
597
  );
598
  union {
599
    IR_STRUCT_LOHI(
600
      ir_ref                     op2,
601
      ir_ref                     op3
602
    );
603
    ir_val                         val;
604
  };
605
} ir_insn;
606
607
/* IR Hash Tables API (private) */
608
typedef struct _ir_hashtab ir_hashtab;
609
610
/* IR String Tables API (implementation in ir_strtab.c) */
611
typedef struct _ir_strtab {
612
  void       *data;
613
  uint32_t    mask;
614
  uint32_t    size;
615
  uint32_t    count;
616
  uint32_t    pos;
617
  char       *buf;
618
  uint32_t    buf_size;
619
  uint32_t    buf_top;
620
} ir_strtab;
621
622
64
#define ir_strtab_count(strtab) (strtab)->count
623
624
typedef void (*ir_strtab_apply_t)(const char *str, uint32_t len, ir_str val);
625
626
void ir_strtab_init(ir_strtab *strtab, uint32_t count, uint32_t buf_size);
627
ir_str ir_strtab_lookup(ir_strtab *strtab, const char *str, uint32_t len, ir_str val);
628
ir_str ir_strtab_find(const ir_strtab *strtab, const char *str, uint32_t len);
629
ir_str ir_strtab_update(ir_strtab *strtab, const char *str, uint32_t len, ir_str val);
630
void ir_strtab_set(ir_strtab *strtab, const char *str, uint32_t len, ir_str val);
631
const char *ir_strtab_str(const ir_strtab *strtab, ir_str idx);
632
const char *ir_strtab_strl(const ir_strtab *strtab, ir_str idx, size_t *len);
633
void ir_strtab_apply(const ir_strtab *strtab, ir_strtab_apply_t func);
634
void ir_strtab_free(ir_strtab *strtab);
635
636
/* IR Context Flags */
637
#define IR_PROTO_MASK          0xff
638
207k
#define IR_CALL_CONV_MASK      0x0f
639
640
22.9k
#define IR_VARARG_FUNC         (1<<4)
641
0
#define IR_CONST_FUNC          (1<<5)
642
0
#define IR_PURE_FUNC           (1<<6)
643
644
#define IR_CONST               (1<<5)
645
#define IR_INITIALIZED         (1<<6) /* sym data flag: constant or an initialized variable */
646
#define IR_CONST_STRING        (1<<7) /* sym data flag: constant string */
647
648
39.3k
#define IR_FUNCTION            (1<<8) /* Generate a function. */
649
0
#define IR_STATIC              (1<<9)
650
#define IR_EXTERN              (1<<10)
651
652
307k
#define IR_USE_FRAME_POINTER   (1<<11)
653
19.4k
#define IR_NO_STACK_COMBINE    (1<<12)
654
13.1k
#define IR_GEN_ENDBR           (1<<13)
655
12.4k
#define IR_GEN_CACHE_DEMOTE    (1<<14) /* Demote the generated code from closest CPU caches */
656
657
9.95k
#define IR_SKIP_PROLOGUE       (1<<15) /* Don't generate function prologue. */
658
2.51k
#define IR_START_BR_TARGET     (1<<16)
659
0
#define IR_ENTRY_BR_TARGET     (1<<17)
660
9.92k
#define IR_MERGE_EMPTY_ENTRIES (1<<18)
661
662
#define IR_OPT_INLINE          (1<<19)
663
9.96k
#define IR_OPT_FOLDING         (1<<20)
664
86.9k
#define IR_OPT_CFG             (1<<21) /* merge BBs, by remove END->BEGIN nodes during CFG construction */
665
#define IR_OPT_MEM2SSA         (1<<22)
666
10.5k
#define IR_OPT_CODEGEN         (1<<23)
667
9.93k
#define IR_OPT_TAILCALL        (1<<24)
668
669
/* debug related */
670
#ifdef IR_DEBUG
671
9.93k
# define IR_DEBUG_SCCP         (1<<26)
672
13.9k
# define IR_DEBUG_GCM          (1<<27)
673
2.07k
# define IR_DEBUG_GCM_SPLIT    (1<<28)
674
651k
# define IR_DEBUG_SCHEDULE     (1<<29)
675
496k
# define IR_DEBUG_RA           (1<<30)
676
27.3k
# define IR_DEBUG_BB_SCHEDULE  (1U<<31)
677
#endif
678
679
/* Calling Conventions */
680
563k
#define IR_CC_DEFAULT          0x00
681
0
#define IR_CC_BUILTIN          0x01
682
42.4k
#define IR_CC_FASTCALL         0x02
683
0
#define IR_CC_PRESERVE_NONE    0x03
684
685
#if defined(IR_TARGET_X64)
686
0
# define IR_CC_X86_64_SYSV     0x08
687
0
# define IR_CC_X86_64_MS       0x09
688
#elif defined(IR_TARGET_AARCH64)
689
# define IR_CC_AARCH64_SYSV    0x08
690
# define IR_CC_AARCH64_DARWIN  0x09
691
#endif
692
693
/* Deprecated constants */
694
#define IR_BUILTIN_FUNC        IR_CC_BUILTIN
695
22.6k
#define IR_FASTCALL_FUNC       IR_CC_FASTCALL
696
697
typedef struct _ir_ctx           ir_ctx;
698
typedef struct _ir_use_list      ir_use_list;
699
typedef struct _ir_block         ir_block;
700
typedef struct _ir_arena         ir_arena;
701
typedef struct _ir_live_interval ir_live_interval;
702
typedef struct _ir_live_range    ir_live_range;
703
typedef struct _ir_loader        ir_loader;
704
typedef int8_t ir_regs[4];
705
706
typedef void (*ir_snapshot_create_t)(ir_ctx *ctx, ir_ref addr);
707
708
#if defined(IR_TARGET_AARCH64)
709
typedef const void *(*ir_get_exit_addr_t)(uint32_t exit_num);
710
typedef const void *(*ir_get_veneer_t)(ir_ctx *ctx, const void *addr);
711
typedef bool (*ir_set_veneer_t)(ir_ctx *ctx, const void *addr, const void *veneer);
712
#endif
713
714
typedef struct _ir_code_buffer {
715
  void *start;
716
  void *end;
717
  void *pos;
718
} ir_code_buffer;
719
720
typedef struct {
721
  int   size;
722
  int   align;
723
} ir_value_param;
724
725
typedef struct _ir_bitqueue ir_bitqueue;
726
727
20.3k
#define IR_CONST_HASH_SIZE 64
728
729
struct _ir_ctx {
730
  ir_insn           *ir_base;                 /* two directional array - instructions grow down, constants grow up */
731
  ir_ref             insns_count;             /* number of instructions stored in instructions buffer */
732
  ir_ref             insns_limit;             /* size of allocated instructions buffer (it's extended when overflow) */
733
  ir_ref             consts_count;            /* number of constants stored in constants buffer */
734
  ir_ref             consts_limit;            /* size of allocated constants buffer (it's extended when overflow) */
735
  uintptr_t          const_hash_mask;
736
  ir_ref            *const_hash;
737
  uint32_t           flags;                   /* IR context flags (see IR_* defines above) */
738
  uint32_t           flags2;                  /* IR context private flags (see IR_* defines in ir_private.h) */
739
  ir_type            ret_type;                /* Function return type */
740
  uint32_t           mflags;                  /* CPU specific flags (see IR_X86_... macros below) */
741
  int32_t            status;                  /* non-zero error code (see IR_ERROR_... macros), app may use negative codes */
742
  ir_ref             fold_cse_limit;          /* CSE finds identical insns backward from "insn_count" to "fold_cse_limit" */
743
  ir_insn            fold_insn;               /* temporary storage for folding engine */
744
  ir_bitqueue       *iter_worklist;
745
  ir_value_param    *value_params;            /* information about "by-val" struct parameters */
746
  ir_hashtab        *binding;
747
  ir_use_list       *use_lists;               /* def->use lists for each instruction */
748
  ir_ref            *use_edges;               /* the actual uses: use = ctx->use_edges[ctx->use_lists[def].refs + n] */
749
  ir_ref             use_edges_count;         /* number of elements in use_edges[] array */
750
  uint32_t           cfg_blocks_count;        /* number of elements in cfg_blocks[] array */
751
  uint32_t           cfg_edges_count;         /* number of elements in cfg_edges[] array */
752
  ir_block          *cfg_blocks;              /* list of basic blocks (starts from 1) */
753
  uint32_t          *cfg_edges;               /* the actual basic blocks predecessors and successors edges */
754
  uint32_t          *cfg_map;                 /* map of instructions to basic block number */
755
  uint32_t          *cfg_schedule;            /* BB order for code generation */
756
  uint32_t          *rules;                   /* array of target specific code-generation rules (for each instruction) */
757
  int32_t           *vregs;                   /* map of insns to virtual regs (positive) or stack slots (negative) */
758
  int32_t            vregs_count;
759
  ir_str             func_name;               /* Function name (should be set through ir_string()/ir_stringl()) */
760
  int32_t            spill_base;              /* base register for special spill area (e.g. PHP VM frame pointer) */
761
  uint64_t           fixed_regset;            /* fixed registers, excluded for regular register allocation */
762
  int32_t            fixed_stack_red_zone;    /* reusable stack allocated by caller (default 0) */
763
  int32_t            fixed_stack_frame_size;  /* fixed stack allocated by generated code for spills and registers save/restore */
764
  int32_t            fixed_call_stack_size;   /* fixed preallocated stack for parameter passing (default 0) */
765
  uint64_t           fixed_save_regset;       /* registers that always saved/restored in prologue/epilogue */
766
  uint32_t           locals_area_size;
767
  uint32_t           gp_reg_params;
768
  uint32_t           fp_reg_params;
769
  int32_t            param_stack_size;
770
  ir_live_interval **live_intervals;
771
  ir_arena          *arena;
772
  ir_live_range     *unused_ranges;
773
  ir_regs           *regs;
774
  int8_t            *tmp_regs;                /* additional tmp registers, used for COND(I64, _, _) and SIMD */
775
  ir_strtab         *fused_regs;
776
  ir_ref            *prev_ref;
777
  union {
778
    void          *data;
779
    ir_ref         control;                 /* used by IR construction API (see ir_builder.h) */
780
    ir_ref         bb_start;                /* used by target CPU instruction matcher */
781
    ir_ref         vars;                    /* list of VARs (used by register allocator) */
782
  };
783
  ir_snapshot_create_t   snapshot_create;
784
  int32_t            stack_frame_size;        /* spill stack frame size (used by register allocator and code generator) */
785
  int32_t            call_stack_size;         /* stack for parameter passing (used by register allocator and code generator) */
786
  uint64_t           used_preserved_regs;
787
#ifdef IR_TARGET_X86
788
  int32_t            ret_slot;
789
#endif
790
  uint32_t           rodata_offset;
791
  uint32_t           jmp_table_offset;
792
  uint32_t           entries_count;
793
  uint32_t          *entries;                /* array of ENTRY blocks */
794
  void              *osr_entry_loads;
795
  ir_code_buffer    *code_buffer;
796
#if defined(IR_TARGET_AARCH64)
797
  int32_t            deoptimization_exits;
798
  const void        *deoptimization_exits_base;
799
  ir_get_exit_addr_t get_exit_addr;
800
  ir_get_veneer_t    get_veneer;
801
  ir_set_veneer_t    set_veneer;
802
#endif
803
  ir_loader         *loader;
804
  ir_strtab          strtab;
805
  ir_ref             prev_insn_chain[IR_LAST_FOLDABLE_OP + 1];
806
  ir_ref             _const_hash[IR_CONST_HASH_SIZE];
807
};
808
809
/* Basic IR Construction API (implementation in ir.c) */
810
void ir_init(ir_ctx *ctx, uint32_t flags, ir_ref consts_limit, ir_ref insns_limit);
811
void ir_free(ir_ctx *ctx);
812
void ir_truncate(ir_ctx *ctx);
813
814
ir_ref ir_const(ir_ctx *ctx, ir_val val, uint8_t type);
815
ir_ref ir_const_i8(ir_ctx *ctx, int8_t c);
816
ir_ref ir_const_i16(ir_ctx *ctx, int16_t c);
817
ir_ref ir_const_i32(ir_ctx *ctx, int32_t c);
818
ir_ref ir_const_i64(ir_ctx *ctx, int64_t c);
819
ir_ref ir_const_u8(ir_ctx *ctx, uint8_t c);
820
ir_ref ir_const_u16(ir_ctx *ctx, uint16_t c);
821
ir_ref ir_const_u32(ir_ctx *ctx, uint32_t c);
822
ir_ref ir_const_u64(ir_ctx *ctx, uint64_t c);
823
ir_ref ir_const_bool(ir_ctx *ctx, bool c);
824
ir_ref ir_const_char(ir_ctx *ctx, char c);
825
ir_ref ir_const_float(ir_ctx *ctx, float c);
826
ir_ref ir_const_double(ir_ctx *ctx, double c);
827
ir_ref ir_const_addr(ir_ctx *ctx, uintptr_t c);
828
829
ir_ref ir_const_func_addr(ir_ctx *ctx, uintptr_t c, ir_str proto);
830
ir_ref ir_const_func(ir_ctx *ctx, ir_str str, ir_str proto);
831
ir_ref ir_const_sym(ir_ctx *ctx, ir_str str);
832
ir_ref ir_const_str(ir_ctx *ctx, ir_str str);
833
ir_ref ir_const_label(ir_ctx *ctx, ir_str str);
834
835
ir_ref ir_unique_const_addr(ir_ctx *ctx, uintptr_t c);
836
837
ir_ref ir_long_const(ir_ctx *ctx, ir_type type, size_t size);
838
void *ir_long_const_ptr(ir_ctx *ctx, ir_ref ref);
839
ir_ref ir_long_const_commit(ir_ctx *ctx, ir_ref ref);
840
841
ir_ref ir_const_vector(ir_ctx *ctx, ir_type type);
842
843
void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted);
844
845
ir_str ir_string(ir_ctx *ctx, const char *s);
846
ir_str ir_stringl(ir_ctx *ctx, const char *s, size_t len);
847
const char *ir_get_str(const ir_ctx *ctx, ir_str idx);
848
const char *ir_get_strl(const ir_ctx *ctx, ir_str idx, size_t *len);
849
850
#define IR_MAX_PROTO_PARAMS 255
851
852
typedef struct _ir_proto_t {
853
  uint8_t flags; /* first 8 bits of ir_ctx.flags */
854
  uint8_t ret_type;
855
  uint8_t params_count;
856
  uint8_t param_types[5];
857
} ir_proto_t;
858
859
ir_str ir_proto_0(ir_ctx *ctx, uint8_t flags, ir_type ret_type);
860
ir_str ir_proto_1(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1);
861
ir_str ir_proto_2(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2);
862
ir_str ir_proto_3(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3);
863
ir_str ir_proto_4(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3,
864
                                                                ir_type t4);
865
ir_str ir_proto_5(ir_ctx *ctx, uint8_t flags, ir_type ret_type, ir_type t1, ir_type t2, ir_type t3,
866
                                                                ir_type t4, ir_type t5);
867
ir_str ir_proto(ir_ctx *ctx, uint8_t flags, ir_type ret_type, uint32_t params_counts, uint8_t *param_types);
868
869
ir_ref ir_emit(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3);
870
871
ir_ref ir_emit0(ir_ctx *ctx, uint32_t opt);
872
ir_ref ir_emit1(ir_ctx *ctx, uint32_t opt, ir_ref op1);
873
ir_ref ir_emit2(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2);
874
ir_ref ir_emit3(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3);
875
876
ir_ref ir_emit_N(ir_ctx *ctx, uint32_t opt, int32_t count);
877
void   ir_set_op(ir_ctx *ctx, ir_ref ref, int32_t n, ir_ref val);
878
ir_ref ir_get_op(const ir_ctx *ctx, ir_ref ref, int32_t n);
879
880
IR_ALWAYS_INLINE void ir_set_op1(ir_ctx *ctx, ir_ref ref, ir_ref val)
881
0
{
882
0
  ctx->ir_base[ref].op1 = val;
883
0
}
Unexecuted instantiation: ir_cfg.c:ir_set_op1
Unexecuted instantiation: ir_check.c:ir_set_op1
Unexecuted instantiation: ir_dump.c:ir_set_op1
Unexecuted instantiation: ir_emit.c:ir_set_op1
Unexecuted instantiation: ir_gcm.c:ir_set_op1
Unexecuted instantiation: ir_gdb.c:ir_set_op1
Unexecuted instantiation: ir_patch.c:ir_set_op1
Unexecuted instantiation: ir_perf.c:ir_set_op1
Unexecuted instantiation: ir_ra.c:ir_set_op1
Unexecuted instantiation: ir_ra_simple.c:ir_set_op1
Unexecuted instantiation: ir_save.c:ir_set_op1
Unexecuted instantiation: ir_sccp.c:ir_set_op1
Unexecuted instantiation: ir_strtab.c:ir_set_op1
Unexecuted instantiation: ir.c:ir_set_op1
Unexecuted instantiation: zend_jit.c:ir_set_op1
884
885
IR_ALWAYS_INLINE void ir_set_op2(ir_ctx *ctx, ir_ref ref, ir_ref val)
886
0
{
887
0
  ctx->ir_base[ref].op2 = val;
888
0
}
Unexecuted instantiation: ir_cfg.c:ir_set_op2
Unexecuted instantiation: ir_check.c:ir_set_op2
Unexecuted instantiation: ir_dump.c:ir_set_op2
Unexecuted instantiation: ir_emit.c:ir_set_op2
Unexecuted instantiation: ir_gcm.c:ir_set_op2
Unexecuted instantiation: ir_gdb.c:ir_set_op2
Unexecuted instantiation: ir_patch.c:ir_set_op2
Unexecuted instantiation: ir_perf.c:ir_set_op2
Unexecuted instantiation: ir_ra.c:ir_set_op2
Unexecuted instantiation: ir_ra_simple.c:ir_set_op2
Unexecuted instantiation: ir_save.c:ir_set_op2
Unexecuted instantiation: ir_sccp.c:ir_set_op2
Unexecuted instantiation: ir_strtab.c:ir_set_op2
Unexecuted instantiation: ir.c:ir_set_op2
Unexecuted instantiation: zend_jit.c:ir_set_op2
889
890
IR_ALWAYS_INLINE void ir_set_op3(ir_ctx *ctx, ir_ref ref, ir_ref val)
891
0
{
892
0
  ctx->ir_base[ref].op3 = val;
893
0
}
Unexecuted instantiation: ir_cfg.c:ir_set_op3
Unexecuted instantiation: ir_check.c:ir_set_op3
Unexecuted instantiation: ir_dump.c:ir_set_op3
Unexecuted instantiation: ir_emit.c:ir_set_op3
Unexecuted instantiation: ir_gcm.c:ir_set_op3
Unexecuted instantiation: ir_gdb.c:ir_set_op3
Unexecuted instantiation: ir_patch.c:ir_set_op3
Unexecuted instantiation: ir_perf.c:ir_set_op3
Unexecuted instantiation: ir_ra.c:ir_set_op3
Unexecuted instantiation: ir_ra_simple.c:ir_set_op3
Unexecuted instantiation: ir_save.c:ir_set_op3
Unexecuted instantiation: ir_sccp.c:ir_set_op3
Unexecuted instantiation: ir_strtab.c:ir_set_op3
Unexecuted instantiation: ir.c:ir_set_op3
Unexecuted instantiation: zend_jit.c:ir_set_op3
894
895
IR_ALWAYS_INLINE ir_ref ir_insn_op(const ir_insn *insn, int32_t n)
896
507k
{
897
507k
  const ir_ref *p = insn->ops + n;
898
507k
  return *p;
899
507k
}
ir_cfg.c:ir_insn_op
Line
Count
Source
896
90
{
897
90
  const ir_ref *p = insn->ops + n;
898
90
  return *p;
899
90
}
Unexecuted instantiation: ir_check.c:ir_insn_op
Unexecuted instantiation: ir_dump.c:ir_insn_op
ir_emit.c:ir_insn_op
Line
Count
Source
896
405k
{
897
405k
  const ir_ref *p = insn->ops + n;
898
405k
  return *p;
899
405k
}
ir_gcm.c:ir_insn_op
Line
Count
Source
896
2
{
897
2
  const ir_ref *p = insn->ops + n;
898
2
  return *p;
899
2
}
Unexecuted instantiation: ir_gdb.c:ir_insn_op
Unexecuted instantiation: ir_patch.c:ir_insn_op
Unexecuted instantiation: ir_perf.c:ir_insn_op
ir_ra.c:ir_insn_op
Line
Count
Source
896
101k
{
897
101k
  const ir_ref *p = insn->ops + n;
898
101k
  return *p;
899
101k
}
Unexecuted instantiation: ir_ra_simple.c:ir_insn_op
Unexecuted instantiation: ir_save.c:ir_insn_op
ir_sccp.c:ir_insn_op
Line
Count
Source
896
259
{
897
259
  const ir_ref *p = insn->ops + n;
898
259
  return *p;
899
259
}
Unexecuted instantiation: ir_strtab.c:ir_insn_op
Unexecuted instantiation: ir.c:ir_insn_op
zend_jit.c:ir_insn_op
Line
Count
Source
896
591
{
897
591
  const ir_ref *p = insn->ops + n;
898
591
  return *p;
899
591
}
900
901
IR_ALWAYS_INLINE void ir_insn_set_op(ir_insn *insn, int32_t n, ir_ref val)
902
241k
{
903
241k
  ir_ref *p = insn->ops + n;
904
241k
  *p = val;
905
241k
}
ir_cfg.c:ir_insn_set_op
Line
Count
Source
902
81
{
903
81
  ir_ref *p = insn->ops + n;
904
81
  *p = val;
905
81
}
Unexecuted instantiation: ir_check.c:ir_insn_set_op
Unexecuted instantiation: ir_dump.c:ir_insn_set_op
Unexecuted instantiation: ir_emit.c:ir_insn_set_op
ir_gcm.c:ir_insn_set_op
Line
Count
Source
902
1
{
903
1
  ir_ref *p = insn->ops + n;
904
1
  *p = val;
905
1
}
Unexecuted instantiation: ir_gdb.c:ir_insn_set_op
Unexecuted instantiation: ir_patch.c:ir_insn_set_op
Unexecuted instantiation: ir_perf.c:ir_insn_set_op
Unexecuted instantiation: ir_ra.c:ir_insn_set_op
Unexecuted instantiation: ir_ra_simple.c:ir_insn_set_op
Unexecuted instantiation: ir_save.c:ir_insn_set_op
ir_sccp.c:ir_insn_set_op
Line
Count
Source
902
184
{
903
184
  ir_ref *p = insn->ops + n;
904
184
  *p = val;
905
184
}
Unexecuted instantiation: ir_strtab.c:ir_insn_set_op
ir.c:ir_insn_set_op
Line
Count
Source
902
241k
{
903
241k
  ir_ref *p = insn->ops + n;
904
241k
  *p = val;
905
241k
}
Unexecuted instantiation: zend_jit.c:ir_insn_set_op
906
907
IR_ALWAYS_INLINE uint32_t ir_insn_find_op(const ir_insn *insn, ir_ref val)
908
93
{
909
93
  int i, n = insn->inputs_count;
910
911
151
  for (i = 1; i <= n; i++) {
912
151
    if (ir_insn_op(insn, i) == val) {
913
93
      return i;
914
93
    }
915
151
  }
916
0
  return 0;
917
93
}
Unexecuted instantiation: ir_cfg.c:ir_insn_find_op
Unexecuted instantiation: ir_check.c:ir_insn_find_op
Unexecuted instantiation: ir_dump.c:ir_insn_find_op
Unexecuted instantiation: ir_emit.c:ir_insn_find_op
Unexecuted instantiation: ir_gcm.c:ir_insn_find_op
Unexecuted instantiation: ir_gdb.c:ir_insn_find_op
Unexecuted instantiation: ir_patch.c:ir_insn_find_op
Unexecuted instantiation: ir_perf.c:ir_insn_find_op
Unexecuted instantiation: ir_ra.c:ir_insn_find_op
Unexecuted instantiation: ir_ra_simple.c:ir_insn_find_op
Unexecuted instantiation: ir_save.c:ir_insn_find_op
ir_sccp.c:ir_insn_find_op
Line
Count
Source
908
93
{
909
93
  int i, n = insn->inputs_count;
910
911
151
  for (i = 1; i <= n; i++) {
912
151
    if (ir_insn_op(insn, i) == val) {
913
93
      return i;
914
93
    }
915
151
  }
916
0
  return 0;
917
93
}
Unexecuted instantiation: ir_strtab.c:ir_insn_find_op
Unexecuted instantiation: ir.c:ir_insn_find_op
Unexecuted instantiation: zend_jit.c:ir_insn_find_op
918
919
ir_ref ir_fold(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3);
920
921
ir_ref ir_fold0(ir_ctx *ctx, uint32_t opt);
922
ir_ref ir_fold1(ir_ctx *ctx, uint32_t opt, ir_ref op1);
923
ir_ref ir_fold2(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2);
924
ir_ref ir_fold3(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3);
925
926
ir_ref ir_param(ir_ctx *ctx, ir_type type, ir_ref region, const char *name, int pos);
927
ir_ref ir_param_ex(ir_ctx *ctx, ir_type type, ir_ref region, ir_str name, int pos);
928
ir_ref ir_var(ir_ctx *ctx, ir_type type, ir_ref region, const char *name);
929
ir_ref ir_var_ex(ir_ctx *ctx, ir_type type, ir_ref region, ir_str name);
930
931
/* IR Binding */
932
ir_ref ir_bind(ir_ctx *ctx, ir_ref var, ir_ref def);
933
ir_ref ir_binding_find(const ir_ctx *ctx, ir_ref ref);
934
935
/* Def -> Use lists */
936
void ir_build_def_use_lists(ir_ctx *ctx);
937
938
/* SSA Construction */
939
int ir_mem2ssa(ir_ctx *ctx);
940
941
/* CFG - Control Flow Graph (implementation in ir_cfg.c) */
942
int ir_build_cfg(ir_ctx *ctx);
943
int ir_build_dominators_tree(ir_ctx *ctx);
944
int ir_find_loops(ir_ctx *ctx);
945
int ir_schedule_blocks(ir_ctx *ctx);
946
void ir_reset_cfg(ir_ctx *ctx);
947
948
/* SCCP - Sparse Conditional Constant Propagation (implementation in ir_sccp.c) */
949
int ir_sccp(ir_ctx *ctx);
950
951
/* GCM - Global Code Motion and scheduling (implementation in ir_gcm.c) */
952
int ir_gcm(ir_ctx *ctx);
953
int ir_schedule(ir_ctx *ctx);
954
955
/* Liveness & Register Allocation (implementation in ir_ra.c) */
956
8.39M
#define IR_REG_NONE          -1
957
1.31M
#define IR_REG_SPILL_LOAD    (1<<6)
958
1.22M
#define IR_REG_SPILL_STORE   (1<<6)
959
1.22M
#define IR_REG_SPILL_SPECIAL (1<<7)
960
#define IR_REG_SPILLED(r) \
961
1.18M
  ((r) & (IR_REG_SPILL_LOAD|IR_REG_SPILL_STORE|IR_REG_SPILL_SPECIAL))
962
#define IR_REG_NUM(r) \
963
253k
  ((int8_t)((r) == IR_REG_NONE ? IR_REG_NONE : ((r) & ~(IR_REG_SPILL_LOAD|IR_REG_SPILL_STORE|IR_REG_SPILL_SPECIAL))))
964
965
int ir_assign_virtual_registers(ir_ctx *ctx);
966
int ir_compute_live_ranges(ir_ctx *ctx);
967
int ir_coalesce(ir_ctx *ctx);
968
int ir_compute_dessa_moves(ir_ctx *ctx);
969
int ir_reg_alloc(ir_ctx *ctx);
970
int ir_reg_alloc_simple(ir_ctx *ctx);
971
972
#define ir_reg_alloc_O0(_ctx) ir_reg_alloc_simple(_ctx)
973
974
int ir_regs_number(void);
975
bool ir_reg_is_int(int32_t reg);
976
const char *ir_reg_name(int8_t reg, ir_type type);
977
int32_t ir_get_spill_slot_offset(const ir_ctx *ctx, ir_ref ref);
978
979
/* Target CPU instruction selection and code generation (see ir_x86.c) */
980
int ir_match(ir_ctx *ctx);
981
void *ir_emit_code(ir_ctx *ctx, size_t *size);
982
983
bool ir_needs_thunk(const ir_code_buffer *code_buffer, void *addr);
984
void *ir_emit_thunk(ir_code_buffer *code_buffer, void *addr, size_t *size_ptr);
985
void ir_fix_thunk(void *thunk_entry, void *addr);
986
987
#if defined(_MSC_VER) && defined(IR_TARGET_X86)
988
/* MSVC doesn't enforce 16-byte stack alignment */
989
int ir_call_with_aligned_stack(int (*func)(int, const char**), int argc, const char **argv);
990
#endif
991
992
/* Target address resolution (implementation in ir_emit.c) */
993
void *ir_resolve_sym_name(const char *name);
994
995
/* Target CPU disassembler (implementation in ir_disasm.c) */
996
int  ir_disasm_init(void);
997
void ir_disasm_free(void);
998
void ir_disasm_add_symbol(const char *name, uint64_t addr, uint64_t size);
999
const char* ir_disasm_find_symbol(uint64_t addr, int64_t *offset);
1000
int  ir_disasm(const char *name,
1001
               const void *start,
1002
               size_t      size,
1003
               bool        asm_addr,
1004
               ir_ctx     *ctx,
1005
               FILE       *f);
1006
1007
/* Linux perf interface (implementation in ir_perf.c) */
1008
int ir_perf_jitdump_open(void);
1009
int ir_perf_jitdump_close(void);
1010
int ir_perf_jitdump_register(const char *name, const void *start, size_t size);
1011
void ir_perf_map_register(const char *name, const void *start, size_t size);
1012
1013
/* GDB JIT interface (implementation in ir_gdb.c) */
1014
int ir_gdb_register(const char    *name,
1015
                    const void    *start,
1016
                    size_t         size,
1017
                    uint32_t       sp_offset,
1018
                    uint32_t       sp_adjustment);
1019
void ir_gdb_unregister_all(void);
1020
bool ir_gdb_present(void);
1021
1022
/* IR load API (implementation in ir_load.c) */
1023
0
#define IR_RESOLVE_SYM_ADD_THUNK (1<<0)
1024
0
#define IR_RESOLVE_SYM_SILENT    (1<<1)
1025
1026
struct _ir_loader {
1027
  uint32_t default_func_flags;
1028
  bool (*init_module)       (ir_loader *loader, const char *name, const char *filename, const char *target);
1029
  bool (*external_sym_dcl)  (ir_loader *loader, const char *name, uint32_t flags);
1030
  bool (*external_func_dcl) (ir_loader *loader, const char *name,
1031
                               uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types);
1032
  bool (*forward_func_dcl)  (ir_loader *loader, const char *name,
1033
                               uint32_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types);
1034
  bool (*sym_dcl)           (ir_loader *loader, const char *name, uint32_t flags, size_t size);
1035
  bool (*sym_data)          (ir_loader *loader, ir_type type, uint32_t count, const void *data);
1036
  bool (*sym_data_str)      (ir_loader *loader, const char *str, size_t len);
1037
  bool (*sym_data_pad)      (ir_loader *loader, size_t offset);
1038
  bool (*sym_data_ref)      (ir_loader *loader, ir_op op, const char *ref, uintptr_t offset);
1039
  bool (*sym_data_end)      (ir_loader *loader, uint32_t flags);
1040
  bool (*func_init)         (ir_loader *loader, ir_ctx *ctx, const char *name);
1041
  bool (*func_process)      (ir_loader *loader, ir_ctx *ctx, const char *name);
1042
  void*(*resolve_sym_name)  (ir_loader *loader, ir_ctx *ctx, ir_str name, uint32_t flags);
1043
  bool (*has_sym)           (ir_loader *loader, const char *name);
1044
  bool (*add_sym)           (ir_loader *loader, const char *name, void *addr);
1045
  bool (*add_label)         (ir_loader *loader, const char *name, void *addr);
1046
  const char * (*get_str)   (ir_loader *loader, ir_str idx);
1047
  const char * (*get_strl)  (ir_loader *loader, ir_str idx, size_t *len);
1048
};
1049
1050
void ir_loader_init(void);
1051
void ir_loader_free(void);
1052
int ir_load(ir_loader *loader, FILE *f);
1053
1054
/* IR LLVM load API (implementation in ir_load_llvm.c) */
1055
int ir_load_llvm_bitcode(ir_loader *loader, const char *filename);
1056
int ir_load_llvm_asm(ir_loader *loader, const char *filename);
1057
1058
/* IR save API (implementation in ir_save.c) */
1059
0
#define IR_SAVE_CFG        (1<<0) /* add info about CFG */
1060
0
#define IR_SAVE_CFG_MAP    (1<<1) /* add info about CFG block assignment */
1061
0
#define IR_SAVE_USE_LISTS  (1<<2) /* add info about def->use lists */
1062
0
#define IR_SAVE_RULES      (1<<3) /* add info about selected code-generation rules */
1063
0
#define IR_SAVE_REGS       (1<<4) /* add info about selected registers */
1064
0
#define IR_SAVE_SAFE_NAMES (1<<5) /* add '@' prefix to symbol names */
1065
1066
void ir_print_func_proto(const ir_ctx *ctx, const char *name, bool prefix, FILE *f);
1067
void ir_print_proto(const ir_ctx *ctx, ir_ref proto, FILE *f);
1068
void ir_print_proto_ex(uint8_t flags, ir_type ret_type, uint32_t params_count, const uint8_t *param_types, FILE *f);
1069
void ir_print_type_cname(ir_type type, FILE *f);
1070
void ir_save(const ir_ctx *ctx, uint32_t save_flags, FILE *f);
1071
1072
/* IR debug dump API (implementation in ir_dump.c) */
1073
void ir_dump(const ir_ctx *ctx, FILE *f);
1074
void ir_dump_dot(const ir_ctx *ctx, const char *name, const char *comments, FILE *f);
1075
void ir_dump_use_lists(const ir_ctx *ctx, FILE *f);
1076
void ir_dump_cfg(ir_ctx *ctx, FILE *f);
1077
void ir_dump_cfg_map(const ir_ctx *ctx, FILE *f);
1078
void ir_dump_live_ranges(const ir_ctx *ctx, FILE *f);
1079
void ir_dump_codegen(const ir_ctx *ctx, FILE *f);
1080
1081
/* IR to C conversion (implementation in ir_emit_c.c) */
1082
int ir_emit_c(ir_ctx *ctx, const char *name, FILE *f);
1083
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);
1084
void ir_emit_c_sym_decl(const char *name, uint32_t flags, FILE *f);
1085
1086
/* IR to LLVM conversion (implementation in ir_emit_llvm.c) */
1087
int ir_emit_llvm(ir_ctx *ctx, const char *name, FILE *f);
1088
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);
1089
void ir_emit_llvm_sym_decl(const char *name, uint32_t flags, FILE *f);
1090
1091
/* IR verification API (implementation in ir_check.c) */
1092
bool ir_check(const ir_ctx *ctx);
1093
bool ir_check_prototype(const ir_ctx *ctx, uint32_t flags, uint8_t ret_type, uint32_t params_count, uint8_t *param_types);
1094
void ir_consistency_check(void);
1095
1096
/* Code patching (implementation in ir_patch.c) */
1097
int ir_patch(const void *code, size_t size, uint32_t jmp_table_size, const void *from_addr, const void *to_addr);
1098
1099
/* CPU information (implementation in ir_cpuinfo.c) */
1100
#if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
1101
# define IR_X86_SSE2     (1<<0)
1102
0
# define IR_X86_SSE3     (1<<1)
1103
0
# define IR_X86_SSSE3    (1<<2)
1104
0
# define IR_X86_SSE41    (1<<3)
1105
0
# define IR_X86_SSE42    (1<<4)
1106
14.6k
# define IR_X86_AVX      (1<<5)
1107
0
# define IR_X86_AVX2     (1<<6)
1108
0
# define IR_X86_BMI1     (1<<7)
1109
# define IR_X86_BMI2     (1<<8)
1110
2.50k
# define IR_X86_CLDEMOTE (1<<9)
1111
#endif
1112
1113
uint32_t ir_cpuinfo(void);
1114
1115
/* Deoptimization helpers */
1116
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);
1117
1118
/* A reference IR JIT compiler */
1119
IR_ALWAYS_INLINE void *ir_jit_compile(ir_ctx *ctx, int opt_level, size_t *size)
1120
0
{
1121
0
  if (opt_level == 0) {
1122
0
    if (ctx->flags & IR_OPT_FOLDING) {
1123
0
      // IR_ASSERT(0 && "IR_OPT_FOLDING is incompatible with -O0");
1124
0
      return NULL;
1125
0
    }
1126
0
    ctx->flags &= ~(IR_OPT_CFG | IR_OPT_CODEGEN | IR_OPT_TAILCALL);
1127
0
1128
0
    ir_build_def_use_lists(ctx);
1129
0
1130
0
    if (!ir_build_cfg(ctx)
1131
0
     || !ir_match(ctx)
1132
0
     || !ir_assign_virtual_registers(ctx)
1133
0
     || !ir_compute_dessa_moves(ctx)
1134
0
     || !ir_reg_alloc_O0(ctx)) {
1135
0
      return NULL;
1136
0
    }
1137
0
1138
0
    return ir_emit_code(ctx, size);
1139
0
  } else if (opt_level > 0) {
1140
0
    if (!(ctx->flags & IR_OPT_FOLDING)) {
1141
0
      // IR_ASSERT(0 && "IR_OPT_FOLDING must be set in ir_init() for -O1 and -O2");
1142
0
      return NULL;
1143
0
    }
1144
0
    ctx->flags |= IR_OPT_CFG | IR_OPT_CODEGEN | IR_OPT_TAILCALL;
1145
0
1146
0
    ir_build_def_use_lists(ctx);
1147
0
1148
0
    if (ctx->flags & IR_OPT_MEM2SSA) {
1149
0
      if (!ir_build_cfg(ctx)
1150
0
       || !ir_build_dominators_tree(ctx)
1151
0
       || !ir_mem2ssa(ctx)) {
1152
0
        return NULL;
1153
0
      }
1154
0
      ir_reset_cfg(ctx);
1155
0
    }
1156
0
1157
0
    if (opt_level > 1) {
1158
0
      if (!ir_sccp(ctx)) {
1159
0
        return NULL;
1160
0
      }
1161
0
    }
1162
0
1163
0
    if (!ctx->cfg_blocks) {
1164
0
      if (!ir_build_cfg(ctx)
1165
0
       || !ir_build_dominators_tree(ctx)) {
1166
0
        return NULL;
1167
0
      }
1168
0
    }
1169
0
1170
0
    if (!ir_find_loops(ctx)
1171
0
     || !ir_gcm(ctx)
1172
0
     || !ir_schedule(ctx)
1173
0
     || !ir_match(ctx)
1174
0
     || !ir_assign_virtual_registers(ctx)
1175
0
     || !ir_compute_live_ranges(ctx)
1176
0
     || !ir_coalesce(ctx)
1177
0
     || !ir_reg_alloc(ctx)
1178
0
     || !ir_schedule_blocks(ctx)) {
1179
0
      return NULL;
1180
0
    }
1181
0
1182
0
    return ir_emit_code(ctx, size);
1183
0
  } else {
1184
0
    // IR_ASSERT(0 && "wrong optimization level");
1185
0
    return NULL;
1186
0
  }
1187
0
}
Unexecuted instantiation: ir_cfg.c:ir_jit_compile
Unexecuted instantiation: ir_check.c:ir_jit_compile
Unexecuted instantiation: ir_dump.c:ir_jit_compile
Unexecuted instantiation: ir_emit.c:ir_jit_compile
Unexecuted instantiation: ir_gcm.c:ir_jit_compile
Unexecuted instantiation: ir_gdb.c:ir_jit_compile
Unexecuted instantiation: ir_patch.c:ir_jit_compile
Unexecuted instantiation: ir_perf.c:ir_jit_compile
Unexecuted instantiation: ir_ra.c:ir_jit_compile
Unexecuted instantiation: ir_ra_simple.c:ir_jit_compile
Unexecuted instantiation: ir_save.c:ir_jit_compile
Unexecuted instantiation: ir_sccp.c:ir_jit_compile
Unexecuted instantiation: ir_strtab.c:ir_jit_compile
Unexecuted instantiation: ir.c:ir_jit_compile
Unexecuted instantiation: zend_jit.c:ir_jit_compile
1188
1189
0
#define IR_ERROR_CODE_MEM_OVERFLOW               1
1190
0
#define IR_ERROR_FIXED_STACK_FRAME_OVERFLOW      2
1191
0
#define IR_ERROR_UNSUPPORTED_CODE_RULE           3
1192
0
#define IR_ERROR_LINK                            4
1193
0
#define IR_ERROR_ENCODE                          5
1194
0
#define IR_ERROR_TOO_LARGE                       6
1195
1196
/* IR Memmory Allocation */
1197
#ifndef ir_mem_malloc
1198
# define ir_mem_malloc   malloc
1199
#endif
1200
#ifndef ir_mem_calloc
1201
# define ir_mem_calloc   calloc
1202
#endif
1203
#ifndef ir_mem_realloc
1204
# define ir_mem_realloc  realloc
1205
#endif
1206
#ifndef ir_mem_free
1207
# define ir_mem_free     free
1208
#endif
1209
1210
#ifndef ir_mem_pmalloc
1211
# define ir_mem_pmalloc  malloc
1212
#endif
1213
#ifndef ir_mem_pcalloc
1214
# define ir_mem_pcalloc  calloc
1215
#endif
1216
#ifndef ir_mem_prealloc
1217
# define ir_mem_prealloc realloc
1218
#endif
1219
#ifndef ir_mem_pfree
1220
# define ir_mem_pfree    free
1221
#endif
1222
1223
void *ir_mem_mmap(size_t size);
1224
int ir_mem_unmap(void *ptr, size_t size);
1225
int ir_mem_protect(void *ptr, size_t size);
1226
int ir_mem_unprotect(void *ptr, size_t size);
1227
int ir_mem_flush(void *ptr, size_t size);
1228
1229
#ifdef __cplusplus
1230
} /* extern "C" */
1231
#endif
1232
1233
#endif /* IR_H */