1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #ifndef ZEND_OPTIMIZER_INTERNAL_H
23 #define ZEND_OPTIMIZER_INTERNAL_H
24
25 #include "ZendAccelerator.h"
26
27 #define VAR_NUM(v) EX_VAR_TO_NUM(v)
28 #define NUM_VAR(v) ((uint32_t)(zend_uintptr_t)ZEND_CALL_VAR_NUM(0, v))
29
30 #define INV_COND(op) ((op) == ZEND_JMPZ ? ZEND_JMPNZ : ZEND_JMPZ)
31 #define INV_EX_COND(op) ((op) == ZEND_JMPZ_EX ? ZEND_JMPNZ : ZEND_JMPZ)
32 #define INV_COND_EX(op) ((op) == ZEND_JMPZ ? ZEND_JMPNZ_EX : ZEND_JMPZ_EX)
33 #define INV_EX_COND_EX(op) ((op) == ZEND_JMPZ_EX ? ZEND_JMPNZ_EX : ZEND_JMPZ_EX)
34
35 #undef MAKE_NOP
36
37 #define MAKE_NOP(opline) do { \
38 (opline)->op1.num = 0; \
39 (opline)->op2.num = 0; \
40 (opline)->result.num = 0; \
41 (opline)->opcode = ZEND_NOP; \
42 (opline)->op1_type = IS_UNUSED; \
43 (opline)->op2_type = IS_UNUSED; \
44 (opline)->result_type = IS_UNUSED; \
45 zend_vm_set_opcode_handler(opline); \
46 } while (0)
47
48 #define RESULT_USED(op) (((op->result_type & IS_VAR) && !(op->result_type & EXT_TYPE_UNUSED)) || op->result_type == IS_TMP_VAR)
49 #define RESULT_UNUSED(op) ((op->result_type & EXT_TYPE_UNUSED) != 0)
50 #define SAME_VAR(op1, op2) ((((op1 ## _type & IS_VAR) && (op2 ## _type & IS_VAR)) || (op1 ## _type == IS_TMP_VAR && op2 ## _type == IS_TMP_VAR)) && op1.var == op2.var)
51
52 typedef struct _zend_optimizer_ctx {
53 zend_arena *arena;
54 zend_persistent_script *script;
55 HashTable *constants;
56 } zend_optimizer_ctx;
57
58 typedef struct _zend_code_block zend_code_block;
59 typedef struct _zend_block_source zend_block_source;
60
61 struct _zend_code_block {
62 int access;
63 zend_op *start_opline;
64 int start_opline_no;
65 int len;
66 zend_code_block *op1_to;
67 zend_code_block *op2_to;
68 zend_code_block *ext_to;
69 zend_code_block *follow_to;
70 zend_code_block *next;
71 zend_block_source *sources;
72 zend_bool protected;
73 };
74
75 typedef struct _zend_cfg {
76 zend_code_block *blocks;
77 zend_code_block **try;
78 zend_code_block **catch;
79 zend_code_block **loop_start;
80 zend_code_block **loop_cont;
81 zend_code_block **loop_brk;
82 zend_op **Tsource;
83 char *same_t;
84 } zend_cfg;
85
86 struct _zend_block_source {
87 zend_code_block *from;
88 zend_block_source *next;
89 };
90
91 #define OPTIMIZATION_LEVEL \
92 ZCG(accel_directives).optimization_level
93
94 #define LITERAL_LONG(op, val) do { \
95 zval _c; \
96 ZVAL_LONG(&_c, val); \
97 op.constant = zend_optimizer_add_literal(op_array, &_c); \
98 } while (0)
99
100 #define LITERAL_BOOL(op, val) do { \
101 zval _c; \
102 ZVAL_BOOL(&_c, val); \
103 op.constant = zend_optimizer_add_literal(op_array, &_c); \
104 } while (0)
105
106 #define literal_dtor(zv) do { \
107 zval_dtor(zv); \
108 ZVAL_NULL(zv); \
109 } while (0)
110
111 #define COPY_NODE(target, src) do { \
112 target ## _type = src ## _type; \
113 target = src; \
114 } while (0)
115
116 int zend_optimizer_add_literal(zend_op_array *op_array, zval *zv);
117 int zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy);
118 void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval* value);
119 int zend_optimizer_get_collected_constant(HashTable *constants, zval *name, zval* value);
120 int zend_optimizer_lookup_cv(zend_op_array *op_array, zend_string* name);
121 int zend_optimizer_update_op1_const(zend_op_array *op_array,
122 zend_op *opline,
123 zval *val);
124 int zend_optimizer_update_op2_const(zend_op_array *op_array,
125 zend_op *opline,
126 zval *val);
127 int zend_optimizer_replace_by_const(zend_op_array *op_array,
128 zend_op *opline,
129 zend_uchar type,
130 uint32_t var,
131 zval *val);
132
133 void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx);
134 void zend_optimizer_pass2(zend_op_array *op_array);
135 void zend_optimizer_pass3(zend_op_array *op_array);
136 void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx);
137 void optimize_cfg(zend_op_array *op_array, zend_optimizer_ctx *ctx);
138 void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *ctx);
139 void zend_optimizer_nop_removal(zend_op_array *op_array);
140 void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx);
141 int zend_optimizer_is_disabled_func(const char *name, size_t len);
142
143 #endif