1 /* 2 +----------------------------------------------------------------------+ 3 | Zend OPcache | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1998-2017 The PHP Group | 6 +----------------------------------------------------------------------+ 7 | This source file is subject to version 3.01 of the PHP license, | 8 | that is bundled with this package in the file LICENSE, and is | 9 | available through the world-wide-web at the following url: | 10 | http://www.php.net/license/3_01.txt | 11 | If you did not receive a copy of the PHP license and are unable to | 12 | obtain it through the world-wide-web, please send a note to | 13 | license@php.net so we can mail you a copy immediately. | 14 +----------------------------------------------------------------------+ 15 | Authors: Andi Gutmans <andi@zend.com> | 16 | Zeev Suraski <zeev@zend.com> | 17 | Stanislav Malyshev <stas@zend.com> | 18 | Dmitry Stogov <dmitry@zend.com> | 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; /* don't merge this block with others */ 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 144