Coverage Report

Created: 2025-09-27 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/Zend/Optimizer/zend_ssa.h
Line
Count
Source
1
/*
2
   +----------------------------------------------------------------------+
3
   | Zend Engine, SSA - Static Single Assignment Form                     |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) 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
   | https://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: Dmitry Stogov <dmitry@php.net>                              |
16
   +----------------------------------------------------------------------+
17
*/
18
19
#ifndef ZEND_SSA_H
20
#define ZEND_SSA_H
21
22
#include "zend_optimizer.h"
23
#include "zend_cfg.h"
24
25
typedef struct _zend_ssa_range {
26
  zend_long              min;
27
  zend_long              max;
28
  bool              underflow;
29
  bool              overflow;
30
} zend_ssa_range;
31
32
typedef enum _zend_ssa_negative_lat {
33
  NEG_NONE      = 0,
34
  NEG_INIT      = 1,
35
  NEG_INVARIANT = 2,
36
  NEG_USE_LT    = 3,
37
  NEG_USE_GT    = 4,
38
  NEG_UNKNOWN   = 5
39
} zend_ssa_negative_lat;
40
41
/* Special kind of SSA Phi function used in eSSA */
42
typedef struct _zend_ssa_range_constraint {
43
  zend_ssa_range         range;       /* simple range constraint */
44
  int                    min_var;
45
  int                    max_var;
46
  int                    min_ssa_var; /* ((min_var>0) ? MIN(ssa_var) : 0) + range.min */
47
  int                    max_ssa_var; /* ((max_var>0) ? MAX(ssa_var) : 0) + range.max */
48
  zend_ssa_negative_lat  negative;
49
} zend_ssa_range_constraint;
50
51
typedef struct _zend_ssa_type_constraint {
52
  uint32_t               type_mask;   /* Type mask to intersect with */
53
  zend_class_entry      *ce;          /* Class entry for instanceof constraints */
54
} zend_ssa_type_constraint;
55
56
typedef union _zend_ssa_pi_constraint {
57
  zend_ssa_range_constraint range;
58
  zend_ssa_type_constraint type;
59
} zend_ssa_pi_constraint;
60
61
/* SSA Phi - ssa_var = Phi(source0, source1, ...sourceN) */
62
typedef struct _zend_ssa_phi zend_ssa_phi;
63
struct _zend_ssa_phi {
64
  zend_ssa_phi          *next;          /* next Phi in the same BB */
65
  int                    pi;            /* if >= 0 this is actually a e-SSA Pi */
66
  zend_ssa_pi_constraint constraint;    /* e-SSA Pi constraint */
67
  int                    var;           /* Original CV, VAR or TMP variable index */
68
  int                    ssa_var;       /* SSA variable index */
69
  int                    block;         /* current BB index */
70
  bool                   has_range_constraint;
71
  zend_ssa_phi         **use_chains;
72
  zend_ssa_phi          *sym_use_chain;
73
  int                   *sources;       /* Array of SSA IDs that produce this var.
74
                           As many as this block has
75
                           predecessors.  */
76
};
77
78
typedef struct _zend_ssa_block {
79
  zend_ssa_phi          *phis;
80
} zend_ssa_block;
81
82
typedef struct _zend_ssa_op {
83
  int                    op1_use;
84
  int                    op2_use;
85
  int                    result_use;
86
  int                    op1_def;
87
  int                    op2_def;
88
  int                    result_def;
89
  int                    op1_use_chain;
90
  int                    op2_use_chain;
91
  int                    res_use_chain;
92
} zend_ssa_op;
93
94
typedef enum _zend_ssa_alias_kind {
95
  NO_ALIAS,
96
  SYMTABLE_ALIAS,
97
  HTTP_RESPONSE_HEADER_ALIAS
98
} zend_ssa_alias_kind;
99
100
typedef enum _zend_ssa_escape_state {
101
  ESCAPE_STATE_UNKNOWN,
102
  ESCAPE_STATE_NO_ESCAPE,
103
  ESCAPE_STATE_FUNCTION_ESCAPE,
104
  ESCAPE_STATE_GLOBAL_ESCAPE
105
} zend_ssa_escape_state;
106
107
typedef struct _zend_ssa_var {
108
  int                    var;            /* original var number; op.var for CVs and following numbers for VARs and TMP_VARs */
109
  int                    scc;            /* strongly connected component */
110
  int                    definition;     /* opcode that defines this value */
111
  int                    use_chain;      /* uses of this value, linked through opN_use_chain */
112
  zend_ssa_phi          *definition_phi; /* phi that defines this value */
113
  zend_ssa_phi          *phi_use_chain;  /* uses of this value in Phi, linked through use_chain */
114
  zend_ssa_phi          *sym_use_chain;  /* uses of this value in Pi constraints */
115
  bool                   no_val : 1;     /* value doesn't matter (used as op1 in ZEND_ASSIGN) */
116
  bool                   scc_entry : 1;
117
  unsigned int           alias : 2;  /* value may be changed indirectly */
118
  unsigned int           escape_state : 2;
119
} zend_ssa_var;
120
121
typedef struct _zend_ssa_var_info {
122
  uint32_t               type; /* inferred type (see zend_inference.h) */
123
  bool                   has_range : 1;
124
  bool                   is_instanceof : 1; /* 0 - class == "ce", 1 - may be child of "ce" */
125
  bool                   recursive : 1;
126
  bool                   use_as_double : 1;
127
  bool                   delayed_fetch_this : 1;
128
  bool                   avoid_refcounting : 1;
129
  bool                   guarded_reference : 1;
130
  bool                   indirect_reference : 1; /* IS_INDIRECT returned by FETCH_DIM_W/FETCH_OBJ_W */
131
  zend_ssa_range         range;
132
  zend_class_entry      *ce;
133
} zend_ssa_var_info;
134
135
typedef struct _zend_ssa {
136
  zend_cfg               cfg;            /* control flow graph             */
137
  int                    vars_count;     /* number of SSA variables        */
138
  int                    sccs;           /* number of SCCs                 */
139
  zend_ssa_block        *blocks;         /* array of SSA blocks            */
140
  zend_ssa_op           *ops;            /* array of SSA instructions      */
141
  zend_ssa_var          *vars;           /* use/def chain of SSA variables */
142
  zend_ssa_var_info     *var_info;
143
} zend_ssa;
144
145
BEGIN_EXTERN_C()
146
147
ZEND_API zend_result zend_build_ssa(zend_arena **arena, const zend_script *script, const zend_op_array *op_array, uint32_t build_flags, zend_ssa *ssa);
148
ZEND_API void zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_array, zend_ssa *ssa);
149
ZEND_API int zend_ssa_rename_op(const zend_op_array *op_array, const zend_op *opline, uint32_t k, uint32_t build_flags, int ssa_vars_count, zend_ssa_op *ssa_ops, int *var);
150
void zend_ssa_unlink_use_chain(zend_ssa *ssa, int op, int var);
151
void zend_ssa_replace_use_chain(zend_ssa *ssa, int op, int new_op, int var);
152
153
void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to);
154
void zend_ssa_remove_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op);
155
void zend_ssa_remove_instr(zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op);
156
void zend_ssa_remove_phi(zend_ssa *ssa, zend_ssa_phi *phi);
157
void zend_ssa_remove_uses_of_var(zend_ssa *ssa, int var_num);
158
void zend_ssa_remove_block(zend_op_array *op_array, zend_ssa *ssa, int b);
159
void zend_ssa_rename_var_uses(zend_ssa *ssa, int old_var, int new_var, bool update_types);
160
void zend_ssa_remove_block_from_cfg(zend_ssa *ssa, int b);
161
162
static zend_always_inline void _zend_ssa_remove_def(zend_ssa_var *var)
163
20.4k
{
164
20.4k
  ZEND_ASSERT(var->definition >= 0);
165
20.4k
  ZEND_ASSERT(var->use_chain < 0);
166
20.4k
  ZEND_ASSERT(!var->phi_use_chain);
167
20.4k
  var->definition = -1;
168
20.4k
}
Unexecuted instantiation: zend_persist.c:_zend_ssa_remove_def
Unexecuted instantiation: ZendAccelerator.c:_zend_ssa_remove_def
Unexecuted instantiation: zend_jit_vm_helpers.c:_zend_ssa_remove_def
Unexecuted instantiation: zend_jit.c:_zend_ssa_remove_def
Unexecuted instantiation: block_pass.c:_zend_ssa_remove_def
Unexecuted instantiation: compact_literals.c:_zend_ssa_remove_def
Unexecuted instantiation: compact_vars.c:_zend_ssa_remove_def
Unexecuted instantiation: dce.c:_zend_ssa_remove_def
dfa_pass.c:_zend_ssa_remove_def
Line
Count
Source
163
2.99k
{
164
2.99k
  ZEND_ASSERT(var->definition >= 0);
165
2.99k
  ZEND_ASSERT(var->use_chain < 0);
166
2.99k
  ZEND_ASSERT(!var->phi_use_chain);
167
2.99k
  var->definition = -1;
168
2.99k
}
Unexecuted instantiation: escape_analysis.c:_zend_ssa_remove_def
Unexecuted instantiation: nop_removal.c:_zend_ssa_remove_def
Unexecuted instantiation: optimize_func_calls.c:_zend_ssa_remove_def
Unexecuted instantiation: optimize_temp_vars_5.c:_zend_ssa_remove_def
Unexecuted instantiation: pass1.c:_zend_ssa_remove_def
Unexecuted instantiation: pass3.c:_zend_ssa_remove_def
sccp.c:_zend_ssa_remove_def
Line
Count
Source
163
3.49k
{
164
3.49k
  ZEND_ASSERT(var->definition >= 0);
165
3.49k
  ZEND_ASSERT(var->use_chain < 0);
166
3.49k
  ZEND_ASSERT(!var->phi_use_chain);
167
3.49k
  var->definition = -1;
168
3.49k
}
Unexecuted instantiation: scdf.c:_zend_ssa_remove_def
Unexecuted instantiation: zend_call_graph.c:_zend_ssa_remove_def
Unexecuted instantiation: zend_cfg.c:_zend_ssa_remove_def
Unexecuted instantiation: zend_dump.c:_zend_ssa_remove_def
Unexecuted instantiation: zend_func_info.c:_zend_ssa_remove_def
Unexecuted instantiation: zend_inference.c:_zend_ssa_remove_def
Unexecuted instantiation: zend_optimizer.c:_zend_ssa_remove_def
zend_ssa.c:_zend_ssa_remove_def
Line
Count
Source
163
13.9k
{
164
13.9k
  ZEND_ASSERT(var->definition >= 0);
165
13.9k
  ZEND_ASSERT(var->use_chain < 0);
166
13.9k
  ZEND_ASSERT(!var->phi_use_chain);
167
13.9k
  var->definition = -1;
168
13.9k
}
Unexecuted instantiation: zend_execute.c:_zend_ssa_remove_def
169
170
static zend_always_inline void zend_ssa_remove_result_def(zend_ssa *ssa, zend_ssa_op *ssa_op)
171
19.8k
{
172
19.8k
  zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
173
19.8k
  _zend_ssa_remove_def(var);
174
19.8k
  ssa_op->result_def = -1;
175
19.8k
}
Unexecuted instantiation: zend_persist.c:zend_ssa_remove_result_def
Unexecuted instantiation: ZendAccelerator.c:zend_ssa_remove_result_def
Unexecuted instantiation: zend_jit_vm_helpers.c:zend_ssa_remove_result_def
Unexecuted instantiation: zend_jit.c:zend_ssa_remove_result_def
Unexecuted instantiation: block_pass.c:zend_ssa_remove_result_def
Unexecuted instantiation: compact_literals.c:zend_ssa_remove_result_def
Unexecuted instantiation: compact_vars.c:zend_ssa_remove_result_def
Unexecuted instantiation: dce.c:zend_ssa_remove_result_def
dfa_pass.c:zend_ssa_remove_result_def
Line
Count
Source
171
2.99k
{
172
2.99k
  zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
173
2.99k
  _zend_ssa_remove_def(var);
174
2.99k
  ssa_op->result_def = -1;
175
2.99k
}
Unexecuted instantiation: escape_analysis.c:zend_ssa_remove_result_def
Unexecuted instantiation: nop_removal.c:zend_ssa_remove_result_def
Unexecuted instantiation: optimize_func_calls.c:zend_ssa_remove_result_def
Unexecuted instantiation: optimize_temp_vars_5.c:zend_ssa_remove_result_def
Unexecuted instantiation: pass1.c:zend_ssa_remove_result_def
Unexecuted instantiation: pass3.c:zend_ssa_remove_result_def
sccp.c:zend_ssa_remove_result_def
Line
Count
Source
171
3.42k
{
172
3.42k
  zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
173
3.42k
  _zend_ssa_remove_def(var);
174
3.42k
  ssa_op->result_def = -1;
175
3.42k
}
Unexecuted instantiation: scdf.c:zend_ssa_remove_result_def
Unexecuted instantiation: zend_call_graph.c:zend_ssa_remove_result_def
Unexecuted instantiation: zend_cfg.c:zend_ssa_remove_result_def
Unexecuted instantiation: zend_dump.c:zend_ssa_remove_result_def
Unexecuted instantiation: zend_func_info.c:zend_ssa_remove_result_def
Unexecuted instantiation: zend_inference.c:zend_ssa_remove_result_def
Unexecuted instantiation: zend_optimizer.c:zend_ssa_remove_result_def
zend_ssa.c:zend_ssa_remove_result_def
Line
Count
Source
171
13.4k
{
172
13.4k
  zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
173
13.4k
  _zend_ssa_remove_def(var);
174
13.4k
  ssa_op->result_def = -1;
175
13.4k
}
Unexecuted instantiation: zend_execute.c:zend_ssa_remove_result_def
176
177
static zend_always_inline void zend_ssa_remove_op1_def(zend_ssa *ssa, zend_ssa_op *ssa_op)
178
580
{
179
580
  zend_ssa_var *var = &ssa->vars[ssa_op->op1_def];
180
580
  _zend_ssa_remove_def(var);
181
580
  ssa_op->op1_def = -1;
182
580
}
Unexecuted instantiation: zend_persist.c:zend_ssa_remove_op1_def
Unexecuted instantiation: ZendAccelerator.c:zend_ssa_remove_op1_def
Unexecuted instantiation: zend_jit_vm_helpers.c:zend_ssa_remove_op1_def
Unexecuted instantiation: zend_jit.c:zend_ssa_remove_op1_def
Unexecuted instantiation: block_pass.c:zend_ssa_remove_op1_def
Unexecuted instantiation: compact_literals.c:zend_ssa_remove_op1_def
Unexecuted instantiation: compact_vars.c:zend_ssa_remove_op1_def
Unexecuted instantiation: dce.c:zend_ssa_remove_op1_def
Unexecuted instantiation: dfa_pass.c:zend_ssa_remove_op1_def
Unexecuted instantiation: escape_analysis.c:zend_ssa_remove_op1_def
Unexecuted instantiation: nop_removal.c:zend_ssa_remove_op1_def
Unexecuted instantiation: optimize_func_calls.c:zend_ssa_remove_op1_def
Unexecuted instantiation: optimize_temp_vars_5.c:zend_ssa_remove_op1_def
Unexecuted instantiation: pass1.c:zend_ssa_remove_op1_def
Unexecuted instantiation: pass3.c:zend_ssa_remove_op1_def
sccp.c:zend_ssa_remove_op1_def
Line
Count
Source
178
74
{
179
74
  zend_ssa_var *var = &ssa->vars[ssa_op->op1_def];
180
74
  _zend_ssa_remove_def(var);
181
74
  ssa_op->op1_def = -1;
182
74
}
Unexecuted instantiation: scdf.c:zend_ssa_remove_op1_def
Unexecuted instantiation: zend_call_graph.c:zend_ssa_remove_op1_def
Unexecuted instantiation: zend_cfg.c:zend_ssa_remove_op1_def
Unexecuted instantiation: zend_dump.c:zend_ssa_remove_op1_def
Unexecuted instantiation: zend_func_info.c:zend_ssa_remove_op1_def
Unexecuted instantiation: zend_inference.c:zend_ssa_remove_op1_def
Unexecuted instantiation: zend_optimizer.c:zend_ssa_remove_op1_def
zend_ssa.c:zend_ssa_remove_op1_def
Line
Count
Source
178
506
{
179
506
  zend_ssa_var *var = &ssa->vars[ssa_op->op1_def];
180
506
  _zend_ssa_remove_def(var);
181
506
  ssa_op->op1_def = -1;
182
506
}
Unexecuted instantiation: zend_execute.c:zend_ssa_remove_op1_def
183
184
static zend_always_inline void zend_ssa_remove_op2_def(zend_ssa *ssa, zend_ssa_op *ssa_op)
185
6
{
186
6
  zend_ssa_var *var = &ssa->vars[ssa_op->op2_def];
187
6
  _zend_ssa_remove_def(var);
188
6
  ssa_op->op2_def = -1;
189
6
}
Unexecuted instantiation: zend_persist.c:zend_ssa_remove_op2_def
Unexecuted instantiation: ZendAccelerator.c:zend_ssa_remove_op2_def
Unexecuted instantiation: zend_jit_vm_helpers.c:zend_ssa_remove_op2_def
Unexecuted instantiation: zend_jit.c:zend_ssa_remove_op2_def
Unexecuted instantiation: block_pass.c:zend_ssa_remove_op2_def
Unexecuted instantiation: compact_literals.c:zend_ssa_remove_op2_def
Unexecuted instantiation: compact_vars.c:zend_ssa_remove_op2_def
Unexecuted instantiation: dce.c:zend_ssa_remove_op2_def
Unexecuted instantiation: dfa_pass.c:zend_ssa_remove_op2_def
Unexecuted instantiation: escape_analysis.c:zend_ssa_remove_op2_def
Unexecuted instantiation: nop_removal.c:zend_ssa_remove_op2_def
Unexecuted instantiation: optimize_func_calls.c:zend_ssa_remove_op2_def
Unexecuted instantiation: optimize_temp_vars_5.c:zend_ssa_remove_op2_def
Unexecuted instantiation: pass1.c:zend_ssa_remove_op2_def
Unexecuted instantiation: pass3.c:zend_ssa_remove_op2_def
Unexecuted instantiation: sccp.c:zend_ssa_remove_op2_def
Unexecuted instantiation: scdf.c:zend_ssa_remove_op2_def
Unexecuted instantiation: zend_call_graph.c:zend_ssa_remove_op2_def
Unexecuted instantiation: zend_cfg.c:zend_ssa_remove_op2_def
Unexecuted instantiation: zend_dump.c:zend_ssa_remove_op2_def
Unexecuted instantiation: zend_func_info.c:zend_ssa_remove_op2_def
Unexecuted instantiation: zend_inference.c:zend_ssa_remove_op2_def
Unexecuted instantiation: zend_optimizer.c:zend_ssa_remove_op2_def
zend_ssa.c:zend_ssa_remove_op2_def
Line
Count
Source
185
6
{
186
6
  zend_ssa_var *var = &ssa->vars[ssa_op->op2_def];
187
6
  _zend_ssa_remove_def(var);
188
6
  ssa_op->op2_def = -1;
189
6
}
Unexecuted instantiation: zend_execute.c:zend_ssa_remove_op2_def
190
191
END_EXTERN_C()
192
193
static zend_always_inline int zend_ssa_next_use(const zend_ssa_op *ssa_op, int var, int use)
194
39.5M
{
195
39.5M
  ssa_op += use;
196
39.5M
  if (ssa_op->op1_use == var) {
197
29.7M
    return ssa_op->op1_use_chain;
198
29.7M
  } else if (ssa_op->op2_use == var) {
199
9.33M
    return ssa_op->op2_use_chain;
200
9.33M
  } else {
201
430k
    return ssa_op->res_use_chain;
202
430k
  }
203
39.5M
}
Unexecuted instantiation: zend_persist.c:zend_ssa_next_use
Unexecuted instantiation: ZendAccelerator.c:zend_ssa_next_use
Unexecuted instantiation: zend_jit_vm_helpers.c:zend_ssa_next_use
Unexecuted instantiation: zend_jit.c:zend_ssa_next_use
Unexecuted instantiation: block_pass.c:zend_ssa_next_use
Unexecuted instantiation: compact_literals.c:zend_ssa_next_use
Unexecuted instantiation: compact_vars.c:zend_ssa_next_use
Unexecuted instantiation: dce.c:zend_ssa_next_use
dfa_pass.c:zend_ssa_next_use
Line
Count
Source
194
34.6M
{
195
34.6M
  ssa_op += use;
196
34.6M
  if (ssa_op->op1_use == var) {
197
26.0M
    return ssa_op->op1_use_chain;
198
26.0M
  } else if (ssa_op->op2_use == var) {
199
8.25M
    return ssa_op->op2_use_chain;
200
8.25M
  } else {
201
338k
    return ssa_op->res_use_chain;
202
338k
  }
203
34.6M
}
escape_analysis.c:zend_ssa_next_use
Line
Count
Source
194
30.8k
{
195
30.8k
  ssa_op += use;
196
30.8k
  if (ssa_op->op1_use == var) {
197
18.7k
    return ssa_op->op1_use_chain;
198
18.7k
  } else if (ssa_op->op2_use == var) {
199
4.55k
    return ssa_op->op2_use_chain;
200
7.56k
  } else {
201
7.56k
    return ssa_op->res_use_chain;
202
7.56k
  }
203
30.8k
}
Unexecuted instantiation: nop_removal.c:zend_ssa_next_use
Unexecuted instantiation: optimize_func_calls.c:zend_ssa_next_use
Unexecuted instantiation: optimize_temp_vars_5.c:zend_ssa_next_use
Unexecuted instantiation: pass1.c:zend_ssa_next_use
Unexecuted instantiation: pass3.c:zend_ssa_next_use
sccp.c:zend_ssa_next_use
Line
Count
Source
194
1.09M
{
195
1.09M
  ssa_op += use;
196
1.09M
  if (ssa_op->op1_use == var) {
197
847k
    return ssa_op->op1_use_chain;
198
847k
  } else if (ssa_op->op2_use == var) {
199
215k
    return ssa_op->op2_use_chain;
200
215k
  } else {
201
33.4k
    return ssa_op->res_use_chain;
202
33.4k
  }
203
1.09M
}
Unexecuted instantiation: scdf.c:zend_ssa_next_use
Unexecuted instantiation: zend_call_graph.c:zend_ssa_next_use
Unexecuted instantiation: zend_cfg.c:zend_ssa_next_use
Unexecuted instantiation: zend_dump.c:zend_ssa_next_use
Unexecuted instantiation: zend_func_info.c:zend_ssa_next_use
zend_inference.c:zend_ssa_next_use
Line
Count
Source
194
3.70M
{
195
3.70M
  ssa_op += use;
196
3.70M
  if (ssa_op->op1_use == var) {
197
2.80M
    return ssa_op->op1_use_chain;
198
2.80M
  } else if (ssa_op->op2_use == var) {
199
847k
    return ssa_op->op2_use_chain;
200
847k
  } else {
201
50.7k
    return ssa_op->res_use_chain;
202
50.7k
  }
203
3.70M
}
Unexecuted instantiation: zend_optimizer.c:zend_ssa_next_use
zend_ssa.c:zend_ssa_next_use
Line
Count
Source
194
52.0k
{
195
52.0k
  ssa_op += use;
196
52.0k
  if (ssa_op->op1_use == var) {
197
43.3k
    return ssa_op->op1_use_chain;
198
43.3k
  } else if (ssa_op->op2_use == var) {
199
8.57k
    return ssa_op->op2_use_chain;
200
8.57k
  } else {
201
195
    return ssa_op->res_use_chain;
202
195
  }
203
52.0k
}
Unexecuted instantiation: zend_execute.c:zend_ssa_next_use
204
205
static zend_always_inline zend_ssa_phi* zend_ssa_next_use_phi(const zend_ssa *ssa, int var, const zend_ssa_phi *p)
206
5.97M
{
207
5.97M
  if (p->pi >= 0) {
208
942k
    return p->use_chains[0];
209
5.03M
  } else {
210
5.03M
    int j;
211
7.62M
    for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
212
7.62M
      if (p->sources[j] == var) {
213
5.03M
        return p->use_chains[j];
214
5.03M
      }
215
7.62M
    }
216
5.03M
  }
217
4
  return NULL;
218
5.97M
}
Unexecuted instantiation: zend_persist.c:zend_ssa_next_use_phi
Unexecuted instantiation: ZendAccelerator.c:zend_ssa_next_use_phi
Unexecuted instantiation: zend_jit_vm_helpers.c:zend_ssa_next_use_phi
Unexecuted instantiation: zend_jit.c:zend_ssa_next_use_phi
Unexecuted instantiation: block_pass.c:zend_ssa_next_use_phi
Unexecuted instantiation: compact_literals.c:zend_ssa_next_use_phi
Unexecuted instantiation: compact_vars.c:zend_ssa_next_use_phi
Unexecuted instantiation: dce.c:zend_ssa_next_use_phi
dfa_pass.c:zend_ssa_next_use_phi
Line
Count
Source
206
4.85M
{
207
4.85M
  if (p->pi >= 0) {
208
692k
    return p->use_chains[0];
209
4.16M
  } else {
210
4.16M
    int j;
211
6.27M
    for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
212
6.27M
      if (p->sources[j] == var) {
213
4.16M
        return p->use_chains[j];
214
4.16M
      }
215
6.27M
    }
216
4.16M
  }
217
0
  return NULL;
218
4.85M
}
Unexecuted instantiation: escape_analysis.c:zend_ssa_next_use_phi
Unexecuted instantiation: nop_removal.c:zend_ssa_next_use_phi
Unexecuted instantiation: optimize_func_calls.c:zend_ssa_next_use_phi
Unexecuted instantiation: optimize_temp_vars_5.c:zend_ssa_next_use_phi
Unexecuted instantiation: pass1.c:zend_ssa_next_use_phi
Unexecuted instantiation: pass3.c:zend_ssa_next_use_phi
sccp.c:zend_ssa_next_use_phi
Line
Count
Source
206
221k
{
207
221k
  if (p->pi >= 0) {
208
41.3k
    return p->use_chains[0];
209
179k
  } else {
210
179k
    int j;
211
282k
    for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
212
282k
      if (p->sources[j] == var) {
213
179k
        return p->use_chains[j];
214
179k
      }
215
282k
    }
216
179k
  }
217
0
  return NULL;
218
221k
}
Unexecuted instantiation: scdf.c:zend_ssa_next_use_phi
Unexecuted instantiation: zend_call_graph.c:zend_ssa_next_use_phi
Unexecuted instantiation: zend_cfg.c:zend_ssa_next_use_phi
Unexecuted instantiation: zend_dump.c:zend_ssa_next_use_phi
Unexecuted instantiation: zend_func_info.c:zend_ssa_next_use_phi
zend_inference.c:zend_ssa_next_use_phi
Line
Count
Source
206
835k
{
207
835k
  if (p->pi >= 0) {
208
174k
    return p->use_chains[0];
209
661k
  } else {
210
661k
    int j;
211
1.02M
    for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
212
1.02M
      if (p->sources[j] == var) {
213
661k
        return p->use_chains[j];
214
661k
      }
215
1.02M
    }
216
661k
  }
217
0
  return NULL;
218
835k
}
Unexecuted instantiation: zend_optimizer.c:zend_ssa_next_use_phi
zend_ssa.c:zend_ssa_next_use_phi
Line
Count
Source
206
58.2k
{
207
58.2k
  if (p->pi >= 0) {
208
35.2k
    return p->use_chains[0];
209
35.2k
  } else {
210
23.0k
    int j;
211
33.6k
    for (j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
212
33.6k
      if (p->sources[j] == var) {
213
23.0k
        return p->use_chains[j];
214
23.0k
      }
215
33.6k
    }
216
23.0k
  }
217
4
  return NULL;
218
58.2k
}
Unexecuted instantiation: zend_execute.c:zend_ssa_next_use_phi
219
220
static zend_always_inline bool zend_ssa_is_no_val_use(const zend_op *opline, const zend_ssa_op *ssa_op, int var)
221
1.38M
{
222
1.38M
  if (opline->opcode == ZEND_ASSIGN
223
1.26M
       || opline->opcode == ZEND_UNSET_CV
224
1.25M
       || opline->opcode == ZEND_BIND_GLOBAL
225
1.25M
       || opline->opcode == ZEND_BIND_STATIC) {
226
135k
    return ssa_op->op1_use == var && ssa_op->op2_use != var;
227
135k
  }
228
1.24M
  if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) {
229
8.29k
    return ssa_op->op2_use == var && ssa_op->op1_use != var;
230
8.29k
  }
231
1.23M
  if (ssa_op->result_use == var
232
729
      && opline->opcode != ZEND_ADD_ARRAY_ELEMENT
233
16
      && opline->opcode != ZEND_ADD_ARRAY_UNPACK) {
234
0
    return ssa_op->op1_use != var && ssa_op->op2_use != var;
235
0
  }
236
1.23M
  return 0;
237
1.23M
}
Unexecuted instantiation: zend_persist.c:zend_ssa_is_no_val_use
Unexecuted instantiation: ZendAccelerator.c:zend_ssa_is_no_val_use
Unexecuted instantiation: zend_jit_vm_helpers.c:zend_ssa_is_no_val_use
Unexecuted instantiation: zend_jit.c:zend_ssa_is_no_val_use
Unexecuted instantiation: block_pass.c:zend_ssa_is_no_val_use
Unexecuted instantiation: compact_literals.c:zend_ssa_is_no_val_use
Unexecuted instantiation: compact_vars.c:zend_ssa_is_no_val_use
dce.c:zend_ssa_is_no_val_use
Line
Count
Source
221
1.09M
{
222
1.09M
  if (opline->opcode == ZEND_ASSIGN
223
1.00M
       || opline->opcode == ZEND_UNSET_CV
224
1.00M
       || opline->opcode == ZEND_BIND_GLOBAL
225
1.00M
       || opline->opcode == ZEND_BIND_STATIC) {
226
98.1k
    return ssa_op->op1_use == var && ssa_op->op2_use != var;
227
98.1k
  }
228
998k
  if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) {
229
6.32k
    return ssa_op->op2_use == var && ssa_op->op1_use != var;
230
6.32k
  }
231
992k
  if (ssa_op->result_use == var
232
0
      && opline->opcode != ZEND_ADD_ARRAY_ELEMENT
233
0
      && opline->opcode != ZEND_ADD_ARRAY_UNPACK) {
234
0
    return ssa_op->op1_use != var && ssa_op->op2_use != var;
235
0
  }
236
992k
  return 0;
237
992k
}
Unexecuted instantiation: dfa_pass.c:zend_ssa_is_no_val_use
Unexecuted instantiation: escape_analysis.c:zend_ssa_is_no_val_use
Unexecuted instantiation: nop_removal.c:zend_ssa_is_no_val_use
Unexecuted instantiation: optimize_func_calls.c:zend_ssa_is_no_val_use
Unexecuted instantiation: optimize_temp_vars_5.c:zend_ssa_is_no_val_use
Unexecuted instantiation: pass1.c:zend_ssa_is_no_val_use
Unexecuted instantiation: pass3.c:zend_ssa_is_no_val_use
Unexecuted instantiation: sccp.c:zend_ssa_is_no_val_use
Unexecuted instantiation: scdf.c:zend_ssa_is_no_val_use
Unexecuted instantiation: zend_call_graph.c:zend_ssa_is_no_val_use
Unexecuted instantiation: zend_cfg.c:zend_ssa_is_no_val_use
Unexecuted instantiation: zend_dump.c:zend_ssa_is_no_val_use
Unexecuted instantiation: zend_func_info.c:zend_ssa_is_no_val_use
zend_inference.c:zend_ssa_is_no_val_use
Line
Count
Source
221
283k
{
222
283k
  if (opline->opcode == ZEND_ASSIGN
223
253k
       || opline->opcode == ZEND_UNSET_CV
224
253k
       || opline->opcode == ZEND_BIND_GLOBAL
225
252k
       || opline->opcode == ZEND_BIND_STATIC) {
226
37.2k
    return ssa_op->op1_use == var && ssa_op->op2_use != var;
227
37.2k
  }
228
246k
  if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) {
229
1.96k
    return ssa_op->op2_use == var && ssa_op->op1_use != var;
230
1.96k
  }
231
244k
  if (ssa_op->result_use == var
232
729
      && opline->opcode != ZEND_ADD_ARRAY_ELEMENT
233
16
      && opline->opcode != ZEND_ADD_ARRAY_UNPACK) {
234
0
    return ssa_op->op1_use != var && ssa_op->op2_use != var;
235
0
  }
236
244k
  return 0;
237
244k
}
Unexecuted instantiation: zend_optimizer.c:zend_ssa_is_no_val_use
Unexecuted instantiation: zend_ssa.c:zend_ssa_is_no_val_use
Unexecuted instantiation: zend_execute.c:zend_ssa_is_no_val_use
238
239
15.6k
static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op) {
240
  /* Rename def to use if possible. Mark variable as not defined otherwise. */
241
15.6k
  if (ssa_op->op1_def >= 0) {
242
4.43k
    if (ssa_op->op1_use >= 0) {
243
4.43k
      zend_ssa_rename_var_uses(ssa, ssa_op->op1_def, ssa_op->op1_use, true);
244
4.43k
    }
245
4.43k
    ssa->vars[ssa_op->op1_def].definition = -1;
246
4.43k
    ssa_op->op1_def = -1;
247
4.43k
  }
248
15.6k
  if (ssa_op->op2_def >= 0) {
249
0
    if (ssa_op->op2_use >= 0) {
250
0
      zend_ssa_rename_var_uses(ssa, ssa_op->op2_def, ssa_op->op2_use, true);
251
0
    }
252
0
    ssa->vars[ssa_op->op2_def].definition = -1;
253
0
    ssa_op->op2_def = -1;
254
0
  }
255
15.6k
  if (ssa_op->result_def >= 0) {
256
4.95k
    if (ssa_op->result_use >= 0) {
257
118
      zend_ssa_rename_var_uses(ssa, ssa_op->result_def, ssa_op->result_use, true);
258
118
    }
259
4.95k
    ssa->vars[ssa_op->result_def].definition = -1;
260
4.95k
    ssa_op->result_def = -1;
261
4.95k
  }
262
15.6k
}
Unexecuted instantiation: zend_persist.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: ZendAccelerator.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: zend_jit_vm_helpers.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: zend_jit.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: block_pass.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: compact_literals.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: compact_vars.c:zend_ssa_rename_defs_of_instr
dce.c:zend_ssa_rename_defs_of_instr
Line
Count
Source
239
15.6k
static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op) {
240
  /* Rename def to use if possible. Mark variable as not defined otherwise. */
241
15.6k
  if (ssa_op->op1_def >= 0) {
242
4.43k
    if (ssa_op->op1_use >= 0) {
243
4.43k
      zend_ssa_rename_var_uses(ssa, ssa_op->op1_def, ssa_op->op1_use, true);
244
4.43k
    }
245
4.43k
    ssa->vars[ssa_op->op1_def].definition = -1;
246
4.43k
    ssa_op->op1_def = -1;
247
4.43k
  }
248
15.6k
  if (ssa_op->op2_def >= 0) {
249
0
    if (ssa_op->op2_use >= 0) {
250
0
      zend_ssa_rename_var_uses(ssa, ssa_op->op2_def, ssa_op->op2_use, true);
251
0
    }
252
0
    ssa->vars[ssa_op->op2_def].definition = -1;
253
0
    ssa_op->op2_def = -1;
254
0
  }
255
15.6k
  if (ssa_op->result_def >= 0) {
256
4.95k
    if (ssa_op->result_use >= 0) {
257
      zend_ssa_rename_var_uses(ssa, ssa_op->result_def, ssa_op->result_use, true);
258
118
    }
259
4.95k
    ssa->vars[ssa_op->result_def].definition = -1;
260
4.95k
    ssa_op->result_def = -1;
261
4.95k
  }
262
15.6k
}
Unexecuted instantiation: dfa_pass.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: escape_analysis.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: nop_removal.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: optimize_func_calls.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: optimize_temp_vars_5.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: pass1.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: pass3.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: sccp.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: scdf.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: zend_call_graph.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: zend_cfg.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: zend_dump.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: zend_func_info.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: zend_inference.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: zend_optimizer.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: zend_ssa.c:zend_ssa_rename_defs_of_instr
Unexecuted instantiation: zend_execute.c:zend_ssa_rename_defs_of_instr
263
264
#define NUM_PHI_SOURCES(phi) \
265
2.18M
  ((phi)->pi >= 0 ? 1 : (ssa->cfg.blocks[(phi)->block].predecessors_count))
266
267
/* FOREACH_USE and FOREACH_PHI_USE explicitly support "continue"
268
 * and changing the use chain of the current element */
269
13.6M
#define FOREACH_USE(var, use) do { \
270
13.6M
  int _var_num = (var) - ssa->vars, next; \
271
32.2M
  for (use = (var)->use_chain; use >= 0; use = next) { \
272
24.5M
    next = zend_ssa_next_use(ssa->ops, _var_num, use);
273
#define FOREACH_USE_END() \
274
24.5M
  } \
275
13.6M
} while (0)
276
277
8.64M
#define FOREACH_PHI_USE(var, phi) do { \
278
8.64M
  int _var_num = (var) - ssa->vars; \
279
8.64M
  zend_ssa_phi *next_phi; \
280
10.2M
  for (phi = (var)->phi_use_chain; phi; phi = next_phi) { \
281
2.85M
    next_phi = zend_ssa_next_use_phi(ssa, _var_num, phi);
282
#define FOREACH_PHI_USE_END() \
283
2.85M
  } \
284
8.64M
} while (0)
285
286
1.47M
#define FOREACH_PHI_SOURCE(phi, source) do { \
287
1.47M
  zend_ssa_phi *_phi = (phi); \
288
1.47M
  int _i, _end = NUM_PHI_SOURCES(phi); \
289
2.38M
  for (_i = 0; _i < _end; _i++) { \
290
2.21M
    ZEND_ASSERT(_phi->sources[_i] >= 0); \
291
2.21M
    source = _phi->sources[_i];
292
#define FOREACH_PHI_SOURCE_END() \
293
2.21M
  } \
294
1.47M
} while (0)
295
296
526k
#define FOREACH_PHI(phi) do { \
297
526k
  int _i; \
298
1.97M
  for (_i = 0; _i < ssa->cfg.blocks_count; _i++) { \
299
1.44M
    phi = ssa->blocks[_i].phis; \
300
2.41M
    for (; phi; phi = phi->next) {
301
#define FOREACH_PHI_END() \
302
973k
    } \
303
1.44M
  } \
304
526k
} while (0)
305
306
377k
#define FOREACH_BLOCK(block) do { \
307
377k
  int _i; \
308
1.42M
  for (_i = 0; _i < ssa->cfg.blocks_count; _i++) { \
309
1.04M
    (block) = &ssa->cfg.blocks[_i]; \
310
1.04M
    if (!((block)->flags & ZEND_BB_REACHABLE)) { \
311
38.7k
      continue; \
312
38.7k
    }
313
#define FOREACH_BLOCK_END() \
314
1.00M
  } \
315
377k
} while (0)
316
317
/* Does not support "break" */
318
377k
#define FOREACH_INSTR_NUM(i) do { \
319
377k
  zend_basic_block *_block; \
320
1.04M
  FOREACH_BLOCK(_block) { \
321
1.00M
    uint32_t _end = _block->start + _block->len; \
322
9.23M
    for ((i) = _block->start; (i) < _end; (i)++) {
323
#define FOREACH_INSTR_NUM_END() \
324
8.23M
    } \
325
1.00M
  } FOREACH_BLOCK_END(); \
326
377k
} while (0)
327
328
#endif /* ZEND_SSA_H */