Coverage Report

Created: 2026-07-25 06:39

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 © The PHP Group and Contributors.                          |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to the Modified BSD License that is      |
8
   | bundled with this package in the file LICENSE, and is available      |
9
   | through the World Wide Web at <https://www.php.net/license/>.        |
10
   |                                                                      |
11
   | SPDX-License-Identifier: BSD-3-Clause                                |
12
   +----------------------------------------------------------------------+
13
   | Authors: Dmitry Stogov <dmitry@php.net>                              |
14
   +----------------------------------------------------------------------+
15
*/
16
17
#ifndef ZEND_SSA_H
18
#define ZEND_SSA_H
19
20
#include "zend_optimizer.h"
21
#include "zend_cfg.h"
22
23
typedef struct _zend_ssa_range {
24
  zend_long              min;
25
  zend_long              max;
26
  bool              underflow;
27
  bool              overflow;
28
} zend_ssa_range;
29
30
typedef enum _zend_ssa_negative_lat {
31
  NEG_NONE      = 0,
32
  NEG_INIT      = 1,
33
  NEG_INVARIANT = 2,
34
  NEG_USE_LT    = 3,
35
  NEG_USE_GT    = 4,
36
  NEG_UNKNOWN   = 5
37
} zend_ssa_negative_lat;
38
39
/* Special kind of SSA Phi function used in eSSA */
40
typedef struct _zend_ssa_range_constraint {
41
  zend_ssa_range         range;       /* simple range constraint */
42
  int                    min_var;
43
  int                    max_var;
44
  int                    min_ssa_var; /* ((min_var>0) ? MIN(ssa_var) : 0) + range.min */
45
  int                    max_ssa_var; /* ((max_var>0) ? MAX(ssa_var) : 0) + range.max */
46
  zend_ssa_negative_lat  negative;
47
} zend_ssa_range_constraint;
48
49
typedef struct _zend_ssa_type_constraint {
50
  uint32_t               type_mask;   /* Type mask to intersect with */
51
  zend_class_entry      *ce;          /* Class entry for instanceof constraints */
52
} zend_ssa_type_constraint;
53
54
typedef union _zend_ssa_pi_constraint {
55
  zend_ssa_range_constraint range;
56
  zend_ssa_type_constraint type;
57
} zend_ssa_pi_constraint;
58
59
/* SSA Phi - ssa_var = Phi(source0, source1, ...sourceN) */
60
typedef struct _zend_ssa_phi zend_ssa_phi;
61
struct _zend_ssa_phi {
62
  zend_ssa_phi          *next;          /* next Phi in the same BB */
63
  int                    pi;            /* if >= 0 this is actually a e-SSA Pi */
64
  zend_ssa_pi_constraint constraint;    /* e-SSA Pi constraint */
65
  int                    var;           /* Original CV, VAR or TMP variable index */
66
  int                    ssa_var;       /* SSA variable index */
67
  uint32_t               block;         /* current BB index */
68
  bool                   has_range_constraint;
69
  zend_ssa_phi         **use_chains;
70
  zend_ssa_phi          *sym_use_chain;
71
  int                   *sources;       /* Array of SSA IDs that produce this var.
72
                           As many as this block has
73
                           predecessors.  */
74
};
75
76
typedef struct _zend_ssa_block {
77
  zend_ssa_phi          *phis;
78
} zend_ssa_block;
79
80
typedef struct _zend_ssa_op {
81
  int                    op1_use;
82
  int                    op2_use;
83
  int                    result_use;
84
  int                    op1_def;
85
  int                    op2_def;
86
  int                    result_def;
87
  int                    op1_use_chain;
88
  int                    op2_use_chain;
89
  int                    res_use_chain;
90
} zend_ssa_op;
91
92
typedef enum _zend_ssa_alias_kind {
93
  NO_ALIAS,
94
  SYMTABLE_ALIAS,
95
  HTTP_RESPONSE_HEADER_ALIAS
96
} zend_ssa_alias_kind;
97
98
typedef enum _zend_ssa_escape_state {
99
  ESCAPE_STATE_UNKNOWN,
100
  ESCAPE_STATE_NO_ESCAPE,
101
  ESCAPE_STATE_FUNCTION_ESCAPE,
102
  ESCAPE_STATE_GLOBAL_ESCAPE
103
} zend_ssa_escape_state;
104
105
typedef struct _zend_ssa_var {
106
  int                    var;            /* original var number; op.var for CVs and following numbers for VARs and TMP_VARs */
107
  int                    scc;            /* strongly connected component */
108
  int                    definition;     /* opcode that defines this value */
109
  int                    use_chain;      /* uses of this value, linked through opN_use_chain */
110
  zend_ssa_phi          *definition_phi; /* phi that defines this value */
111
  zend_ssa_phi          *phi_use_chain;  /* uses of this value in Phi, linked through use_chain */
112
  zend_ssa_phi          *sym_use_chain;  /* uses of this value in Pi constraints */
113
  bool                   no_val : 1;     /* value doesn't matter (used as op1 in ZEND_ASSIGN) */
114
  bool                   scc_entry : 1;
115
  unsigned int           alias : 2;  /* value may be changed indirectly */
116
  unsigned int           escape_state : 2;
117
} zend_ssa_var;
118
119
typedef struct _zend_ssa_var_info {
120
  uint32_t               type; /* inferred type (see zend_inference.h) */
121
  bool                   has_range : 1;
122
  bool                   is_instanceof : 1; /* 0 - class == "ce", 1 - may be child of "ce" */
123
  bool                   recursive : 1;
124
  bool                   use_as_double : 1;
125
  bool                   delayed_fetch_this : 1;
126
  bool                   avoid_refcounting : 1;
127
  bool                   guarded_reference : 1;
128
  bool                   indirect_reference : 1; /* IS_INDIRECT returned by FETCH_DIM_W/FETCH_OBJ_W */
129
  zend_ssa_range         range;
130
  zend_class_entry      *ce;
131
} zend_ssa_var_info;
132
133
typedef struct _zend_ssa {
134
  zend_cfg               cfg;            /* control flow graph             */
135
  int                    vars_count;     /* number of SSA variables        */
136
  int                    sccs;           /* number of SCCs                 */
137
  zend_ssa_block        *blocks;         /* array of SSA blocks            */
138
  zend_ssa_op           *ops;            /* array of SSA instructions      */
139
  zend_ssa_var          *vars;           /* use/def chain of SSA variables */
140
  zend_ssa_var_info     *var_info;
141
} zend_ssa;
142
143
BEGIN_EXTERN_C()
144
145
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);
146
ZEND_API void zend_ssa_compute_use_def_chains(zend_arena **arena, const zend_op_array *op_array, zend_ssa *ssa);
147
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);
148
void zend_ssa_unlink_use_chain(const zend_ssa *ssa, int op, int var);
149
void zend_ssa_replace_use_chain(const zend_ssa *ssa, int op, int new_op, int var);
150
151
void zend_ssa_remove_predecessor(zend_ssa *ssa, int from, int to);
152
void zend_ssa_remove_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op);
153
void zend_ssa_remove_instr(const zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op);
154
void zend_ssa_remove_phi(const zend_ssa *ssa, zend_ssa_phi *phi);
155
void zend_ssa_remove_uses_of_var(const zend_ssa *ssa, int var_num);
156
void zend_ssa_remove_block(const zend_op_array *op_array, zend_ssa *ssa, uint32_t b);
157
void zend_ssa_rename_var_uses(zend_ssa *ssa, int old_var, int new_var, bool update_types);
158
void zend_ssa_remove_block_from_cfg(zend_ssa *ssa, int b);
159
160
static zend_always_inline void _zend_ssa_remove_def(zend_ssa_var *var)
161
17.0k
{
162
17.0k
  ZEND_ASSERT(var->definition >= 0);
163
17.0k
  ZEND_ASSERT(var->use_chain < 0);
164
17.0k
  ZEND_ASSERT(!var->phi_use_chain);
165
17.0k
  var->definition = -1;
166
17.0k
}
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
161
3.44k
{
162
3.44k
  ZEND_ASSERT(var->definition >= 0);
163
3.44k
  ZEND_ASSERT(var->use_chain < 0);
164
3.44k
  ZEND_ASSERT(!var->phi_use_chain);
165
3.44k
  var->definition = -1;
166
3.44k
}
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
161
4.98k
{
162
4.98k
  ZEND_ASSERT(var->definition >= 0);
163
4.98k
  ZEND_ASSERT(var->use_chain < 0);
164
4.98k
  ZEND_ASSERT(!var->phi_use_chain);
165
4.98k
  var->definition = -1;
166
4.98k
}
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
161
8.59k
{
162
8.59k
  ZEND_ASSERT(var->definition >= 0);
163
8.59k
  ZEND_ASSERT(var->use_chain < 0);
164
8.59k
  ZEND_ASSERT(!var->phi_use_chain);
165
8.59k
  var->definition = -1;
166
8.59k
}
Unexecuted instantiation: zend_execute.c:_zend_ssa_remove_def
167
168
static zend_always_inline void zend_ssa_remove_result_def(zend_ssa *ssa, zend_ssa_op *ssa_op)
169
15.8k
{
170
15.8k
  zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
171
15.8k
  _zend_ssa_remove_def(var);
172
15.8k
  ssa_op->result_def = -1;
173
15.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
169
3.44k
{
170
3.44k
  zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
171
3.44k
  _zend_ssa_remove_def(var);
172
3.44k
  ssa_op->result_def = -1;
173
3.44k
}
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
169
4.93k
{
170
4.93k
  zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
171
4.93k
  _zend_ssa_remove_def(var);
172
4.93k
  ssa_op->result_def = -1;
173
4.93k
}
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
169
7.47k
{
170
7.47k
  zend_ssa_var *var = &ssa->vars[ssa_op->result_def];
171
7.47k
  _zend_ssa_remove_def(var);
172
7.47k
  ssa_op->result_def = -1;
173
7.47k
}
Unexecuted instantiation: zend_execute.c:zend_ssa_remove_result_def
174
175
static zend_always_inline void zend_ssa_remove_op1_def(zend_ssa *ssa, zend_ssa_op *ssa_op)
176
1.12k
{
177
1.12k
  zend_ssa_var *var = &ssa->vars[ssa_op->op1_def];
178
1.12k
  _zend_ssa_remove_def(var);
179
1.12k
  ssa_op->op1_def = -1;
180
1.12k
}
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
176
46
{
177
46
  zend_ssa_var *var = &ssa->vars[ssa_op->op1_def];
178
46
  _zend_ssa_remove_def(var);
179
46
  ssa_op->op1_def = -1;
180
46
}
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
176
1.07k
{
177
1.07k
  zend_ssa_var *var = &ssa->vars[ssa_op->op1_def];
178
1.07k
  _zend_ssa_remove_def(var);
179
1.07k
  ssa_op->op1_def = -1;
180
1.07k
}
Unexecuted instantiation: zend_execute.c:zend_ssa_remove_op1_def
181
182
static zend_always_inline void zend_ssa_remove_op2_def(zend_ssa *ssa, zend_ssa_op *ssa_op)
183
51
{
184
51
  zend_ssa_var *var = &ssa->vars[ssa_op->op2_def];
185
51
  _zend_ssa_remove_def(var);
186
51
  ssa_op->op2_def = -1;
187
51
}
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
183
51
{
184
51
  zend_ssa_var *var = &ssa->vars[ssa_op->op2_def];
185
51
  _zend_ssa_remove_def(var);
186
51
  ssa_op->op2_def = -1;
187
51
}
Unexecuted instantiation: zend_execute.c:zend_ssa_remove_op2_def
188
189
END_EXTERN_C()
190
191
static zend_always_inline int zend_ssa_next_use(const zend_ssa_op *ssa_op, int var, int use)
192
48.4M
{
193
48.4M
  ssa_op += use;
194
48.4M
  if (ssa_op->op1_use == var) {
195
36.6M
    return ssa_op->op1_use_chain;
196
36.6M
  } else if (ssa_op->op2_use == var) {
197
11.2M
    return ssa_op->op2_use_chain;
198
11.2M
  } else {
199
575k
    return ssa_op->res_use_chain;
200
575k
  }
201
48.4M
}
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
192
42.2M
{
193
42.2M
  ssa_op += use;
194
42.2M
  if (ssa_op->op1_use == var) {
195
31.9M
    return ssa_op->op1_use_chain;
196
31.9M
  } else if (ssa_op->op2_use == var) {
197
9.86M
    return ssa_op->op2_use_chain;
198
9.86M
  } else {
199
454k
    return ssa_op->res_use_chain;
200
454k
  }
201
42.2M
}
escape_analysis.c:zend_ssa_next_use
Line
Count
Source
192
42.8k
{
193
42.8k
  ssa_op += use;
194
42.8k
  if (ssa_op->op1_use == var) {
195
27.6k
    return ssa_op->op1_use_chain;
196
27.6k
  } else if (ssa_op->op2_use == var) {
197
6.68k
    return ssa_op->op2_use_chain;
198
8.54k
  } else {
199
8.54k
    return ssa_op->res_use_chain;
200
8.54k
  }
201
42.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
192
1.36M
{
193
1.36M
  ssa_op += use;
194
1.36M
  if (ssa_op->op1_use == var) {
195
1.05M
    return ssa_op->op1_use_chain;
196
1.05M
  } else if (ssa_op->op2_use == var) {
197
267k
    return ssa_op->op2_use_chain;
198
267k
  } else {
199
44.5k
    return ssa_op->res_use_chain;
200
44.5k
  }
201
1.36M
}
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
192
4.71M
{
193
4.71M
  ssa_op += use;
194
4.71M
  if (ssa_op->op1_use == var) {
195
3.51M
    return ssa_op->op1_use_chain;
196
3.51M
  } else if (ssa_op->op2_use == var) {
197
1.13M
    return ssa_op->op2_use_chain;
198
1.13M
  } else {
199
67.8k
    return ssa_op->res_use_chain;
200
67.8k
  }
201
4.71M
}
Unexecuted instantiation: zend_optimizer.c:zend_ssa_next_use
zend_ssa.c:zend_ssa_next_use
Line
Count
Source
192
78.4k
{
193
78.4k
  ssa_op += use;
194
78.4k
  if (ssa_op->op1_use == var) {
195
64.7k
    return ssa_op->op1_use_chain;
196
64.7k
  } else if (ssa_op->op2_use == var) {
197
13.2k
    return ssa_op->op2_use_chain;
198
13.2k
  } else {
199
420
    return ssa_op->res_use_chain;
200
420
  }
201
78.4k
}
Unexecuted instantiation: zend_execute.c:zend_ssa_next_use
202
203
static zend_always_inline zend_ssa_phi* zend_ssa_next_use_phi(const zend_ssa *ssa, int var, const zend_ssa_phi *p)
204
8.36M
{
205
8.36M
  if (p->pi >= 0) {
206
1.30M
    return p->use_chains[0];
207
7.06M
  } else {
208
10.7M
    for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
209
10.7M
      if (p->sources[j] == var) {
210
7.06M
        return p->use_chains[j];
211
7.06M
      }
212
10.7M
    }
213
7.06M
  }
214
8
  return NULL;
215
8.36M
}
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
204
6.80M
{
205
6.80M
  if (p->pi >= 0) {
206
956k
    return p->use_chains[0];
207
5.84M
  } else {
208
8.86M
    for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
209
8.86M
      if (p->sources[j] == var) {
210
5.84M
        return p->use_chains[j];
211
5.84M
      }
212
8.86M
    }
213
5.84M
  }
214
0
  return NULL;
215
6.80M
}
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
204
305k
{
205
305k
  if (p->pi >= 0) {
206
56.0k
    return p->use_chains[0];
207
249k
  } else {
208
395k
    for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
209
395k
      if (p->sources[j] == var) {
210
249k
        return p->use_chains[j];
211
249k
      }
212
395k
    }
213
249k
  }
214
0
  return NULL;
215
305k
}
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
204
1.17M
{
205
1.17M
  if (p->pi >= 0) {
206
242k
    return p->use_chains[0];
207
930k
  } else {
208
1.46M
    for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
209
1.46M
      if (p->sources[j] == var) {
210
930k
        return p->use_chains[j];
211
930k
      }
212
1.46M
    }
213
930k
  }
214
0
  return NULL;
215
1.17M
}
Unexecuted instantiation: zend_optimizer.c:zend_ssa_next_use_phi
zend_ssa.c:zend_ssa_next_use_phi
Line
Count
Source
204
83.9k
{
205
83.9k
  if (p->pi >= 0) {
206
47.8k
    return p->use_chains[0];
207
47.8k
  } else {
208
54.0k
    for (uint32_t j = 0; j < ssa->cfg.blocks[p->block].predecessors_count; j++) {
209
54.0k
      if (p->sources[j] == var) {
210
36.1k
        return p->use_chains[j];
211
36.1k
      }
212
54.0k
    }
213
36.1k
  }
214
8
  return NULL;
215
83.9k
}
Unexecuted instantiation: zend_execute.c:zend_ssa_next_use_phi
216
217
static zend_always_inline bool zend_ssa_is_no_val_use(const zend_op *opline, const zend_ssa_op *ssa_op, int var)
218
1.78M
{
219
1.78M
  if (opline->opcode == ZEND_ASSIGN
220
1.60M
       || opline->opcode == ZEND_UNSET_CV
221
1.60M
       || opline->opcode == ZEND_BIND_GLOBAL
222
1.60M
       || opline->opcode == ZEND_BIND_STATIC) {
223
199k
    return ssa_op->op1_use == var && ssa_op->op2_use != var;
224
199k
  }
225
1.58M
  if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) {
226
12.5k
    return ssa_op->op2_use == var && ssa_op->op1_use != var;
227
12.5k
  }
228
1.57M
  if (ssa_op->result_use == var
229
1.08k
      && opline->opcode != ZEND_ADD_ARRAY_ELEMENT
230
19
      && opline->opcode != ZEND_ADD_ARRAY_UNPACK) {
231
0
    return ssa_op->op1_use != var && ssa_op->op2_use != var;
232
0
  }
233
1.57M
  return 0;
234
1.57M
}
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
218
1.37M
{
219
1.37M
  if (opline->opcode == ZEND_ASSIGN
220
1.24M
       || opline->opcode == ZEND_UNSET_CV
221
1.24M
       || opline->opcode == ZEND_BIND_GLOBAL
222
1.24M
       || opline->opcode == ZEND_BIND_STATIC) {
223
137k
    return ssa_op->op1_use == var && ssa_op->op2_use != var;
224
137k
  }
225
1.23M
  if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) {
226
9.38k
    return ssa_op->op2_use == var && ssa_op->op1_use != var;
227
9.38k
  }
228
1.22M
  if (ssa_op->result_use == var
229
0
      && opline->opcode != ZEND_ADD_ARRAY_ELEMENT
230
0
      && opline->opcode != ZEND_ADD_ARRAY_UNPACK) {
231
0
    return ssa_op->op1_use != var && ssa_op->op2_use != var;
232
0
  }
233
1.22M
  return 0;
234
1.22M
}
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
218
410k
{
219
410k
  if (opline->opcode == ZEND_ASSIGN
220
359k
       || opline->opcode == ZEND_UNSET_CV
221
359k
       || opline->opcode == ZEND_BIND_GLOBAL
222
358k
       || opline->opcode == ZEND_BIND_STATIC) {
223
61.8k
    return ssa_op->op1_use == var && ssa_op->op2_use != var;
224
61.8k
  }
225
348k
  if (opline->opcode == ZEND_FE_FETCH_R || opline->opcode == ZEND_FE_FETCH_RW) {
226
3.18k
    return ssa_op->op2_use == var && ssa_op->op1_use != var;
227
3.18k
  }
228
345k
  if (ssa_op->result_use == var
229
1.08k
      && opline->opcode != ZEND_ADD_ARRAY_ELEMENT
230
19
      && opline->opcode != ZEND_ADD_ARRAY_UNPACK) {
231
0
    return ssa_op->op1_use != var && ssa_op->op2_use != var;
232
0
  }
233
345k
  return 0;
234
345k
}
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
235
236
30.7k
static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op) {
237
  /* Rename def to use if possible. Mark variable as not defined otherwise. */
238
30.7k
  if (ssa_op->op1_def >= 0) {
239
8.52k
    if (ssa_op->op1_use >= 0) {
240
8.52k
      zend_ssa_rename_var_uses(ssa, ssa_op->op1_def, ssa_op->op1_use, true);
241
8.52k
    }
242
8.52k
    ssa->vars[ssa_op->op1_def].definition = -1;
243
8.52k
    ssa_op->op1_def = -1;
244
8.52k
  }
245
30.7k
  if (ssa_op->op2_def >= 0) {
246
0
    if (ssa_op->op2_use >= 0) {
247
0
      zend_ssa_rename_var_uses(ssa, ssa_op->op2_def, ssa_op->op2_use, true);
248
0
    }
249
0
    ssa->vars[ssa_op->op2_def].definition = -1;
250
0
    ssa_op->op2_def = -1;
251
0
  }
252
30.7k
  if (ssa_op->result_def >= 0) {
253
10.8k
    if (ssa_op->result_use >= 0) {
254
160
      zend_ssa_rename_var_uses(ssa, ssa_op->result_def, ssa_op->result_use, true);
255
160
    }
256
10.8k
    ssa->vars[ssa_op->result_def].definition = -1;
257
10.8k
    ssa_op->result_def = -1;
258
10.8k
  }
259
30.7k
}
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
236
30.7k
static zend_always_inline void zend_ssa_rename_defs_of_instr(zend_ssa *ssa, zend_ssa_op *ssa_op) {
237
  /* Rename def to use if possible. Mark variable as not defined otherwise. */
238
30.7k
  if (ssa_op->op1_def >= 0) {
239
8.52k
    if (ssa_op->op1_use >= 0) {
240
8.52k
      zend_ssa_rename_var_uses(ssa, ssa_op->op1_def, ssa_op->op1_use, true);
241
8.52k
    }
242
8.52k
    ssa->vars[ssa_op->op1_def].definition = -1;
243
8.52k
    ssa_op->op1_def = -1;
244
8.52k
  }
245
30.7k
  if (ssa_op->op2_def >= 0) {
246
0
    if (ssa_op->op2_use >= 0) {
247
0
      zend_ssa_rename_var_uses(ssa, ssa_op->op2_def, ssa_op->op2_use, true);
248
0
    }
249
0
    ssa->vars[ssa_op->op2_def].definition = -1;
250
0
    ssa_op->op2_def = -1;
251
0
  }
252
30.7k
  if (ssa_op->result_def >= 0) {
253
10.8k
    if (ssa_op->result_use >= 0) {
254
      zend_ssa_rename_var_uses(ssa, ssa_op->result_def, ssa_op->result_use, true);
255
160
    }
256
10.8k
    ssa->vars[ssa_op->result_def].definition = -1;
257
10.8k
    ssa_op->result_def = -1;
258
10.8k
  }
259
30.7k
}
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
260
261
#define NUM_PHI_SOURCES(phi) \
262
3.03M
  ((phi)->pi >= 0 ? 1 : (ssa->cfg.blocks[(phi)->block].predecessors_count))
263
264
/* FOREACH_USE and FOREACH_PHI_USE explicitly support "continue"
265
 * and changing the use chain of the current element */
266
17.2M
#define FOREACH_USE(var, use) do { \
267
17.2M
  int _var_num = (var) - ssa->vars, next; \
268
39.3M
  for (use = (var)->use_chain; use >= 0; use = next) { \
269
29.7M
    next = zend_ssa_next_use(ssa->ops, _var_num, use);
270
#define FOREACH_USE_END() \
271
29.7M
  } \
272
17.2M
} while (0)
273
274
11.0M
#define FOREACH_PHI_USE(var, phi) do { \
275
11.0M
  int _var_num = (var) - ssa->vars; \
276
11.0M
  zend_ssa_phi *next_phi; \
277
13.2M
  for (phi = (var)->phi_use_chain; phi; phi = next_phi) { \
278
3.98M
    next_phi = zend_ssa_next_use_phi(ssa, _var_num, phi);
279
#define FOREACH_PHI_USE_END() \
280
3.98M
  } \
281
11.0M
} while (0)
282
283
2.04M
#define FOREACH_PHI_SOURCE(phi, source) do { \
284
2.04M
  zend_ssa_phi *_phi = (phi); \
285
2.04M
  uint32_t _i, _end = NUM_PHI_SOURCES(phi); \
286
3.33M
  for (_i = 0; _i < _end; _i++) { \
287
3.10M
    ZEND_ASSERT(_phi->sources[_i] >= 0); \
288
3.10M
    source = _phi->sources[_i];
289
#define FOREACH_PHI_SOURCE_END() \
290
3.09M
  } \
291
2.04M
} while (0)
292
293
634k
#define FOREACH_PHI(phi) do { \
294
2.54M
  for (uint32_t _i = 0; _i < ssa->cfg.blocks_count; _i++) { \
295
1.91M
    phi = ssa->blocks[_i].phis; \
296
3.26M
    for (; phi; phi = phi->next) {
297
#define FOREACH_PHI_END() \
298
1.35M
    } \
299
1.91M
  } \
300
634k
} while (0)
301
302
456k
#define FOREACH_BLOCK(block) do { \
303
1.84M
  for (uint32_t _i = 0; _i < ssa->cfg.blocks_count; _i++) { \
304
1.38M
    (block) = &ssa->cfg.blocks[_i]; \
305
1.38M
    if (!((block)->flags & ZEND_BB_REACHABLE)) { \
306
36.4k
      continue; \
307
36.4k
    }
308
#define FOREACH_BLOCK_END() \
309
1.35M
  } \
310
456k
} while (0)
311
312
/* Does not support "break" */
313
456k
#define FOREACH_INSTR_NUM(i) do { \
314
456k
  zend_basic_block *_block; \
315
1.38M
  FOREACH_BLOCK(_block) { \
316
1.35M
    uint32_t _end = _block->start + _block->len; \
317
11.1M
    for ((i) = _block->start; (i) < _end; (i)++) {
318
#define FOREACH_INSTR_NUM_END() \
319
9.76M
    } \
320
1.35M
  } FOREACH_BLOCK_END(); \
321
456k
} while (0)
322
323
#endif /* ZEND_SSA_H */