Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 30 additions & 31 deletions Zend/Optimizer/block_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
#include "zend_dump.h"

/* Checks if a constant (like "true") may be replaced by its value */
bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int copy)
bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, bool copy)
{
zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name);
const zend_constant *c = zend_hash_find_ptr(EG(zend_constants), name);
if (c) {
if ((ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)
&& !(ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED)
Expand Down Expand Up @@ -62,17 +62,17 @@ bool zend_optimizer_get_persistent_constant(zend_string *name, zval *result, int
#define VAR_SOURCE(op) Tsource[VAR_NUM(op.var)]
#define SET_VAR_SOURCE(opline) Tsource[VAR_NUM(opline->result.var)] = opline

static void strip_leading_nops(zend_op_array *op_array, zend_basic_block *b)
static void strip_leading_nops(const zend_op_array *op_array, zend_basic_block *b)
{
zend_op *opcodes = op_array->opcodes;
const zend_op *opcodes = op_array->opcodes;

do {
b->start++;
b->len--;
} while (b->len > 0 && opcodes[b->start].opcode == ZEND_NOP);
}

static void strip_nops(zend_op_array *op_array, zend_basic_block *b)
static void strip_nops(const zend_op_array *op_array, zend_basic_block *b)
{
uint32_t i, j;

Expand Down Expand Up @@ -106,7 +106,7 @@ static void strip_nops(zend_op_array *op_array, zend_basic_block *b)
}
}

static int get_const_switch_target(zend_cfg *cfg, zend_op_array *op_array, zend_basic_block *block, zend_op *opline, zval *val) {
static uint32_t get_const_switch_target(const zend_cfg *cfg, const zend_op_array *op_array, const zend_basic_block *block, zend_op *opline, const zval *val) {
HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline));
zval *zv;
if ((opline->opcode == ZEND_SWITCH_LONG && Z_TYPE_P(val) != IS_LONG)
Expand Down Expand Up @@ -371,7 +371,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
}
} else if(flen == sizeof("constant")-1 && zend_binary_strcasecmp(fname, flen, "constant", sizeof("constant")-1) == 0) {
zval c;
if (zend_optimizer_get_persistent_constant(Z_STR_P(arg), &c, 1 ELS_CC)) {
if (zend_optimizer_get_persistent_constant(Z_STR_P(arg), &c, true ELS_CC)) {
literal_dtor(arg);
MAKE_NOP(sv);
MAKE_NOP(fcall);
Expand Down Expand Up @@ -409,7 +409,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
break;
}
if (opline->op1_type == IS_CONST) {
int target = get_const_switch_target(cfg, op_array, block, opline, &ZEND_OP1_LITERAL(opline));
uint32_t target = get_const_switch_target(cfg, op_array, block, opline, &ZEND_OP1_LITERAL(opline));
literal_dtor(&ZEND_OP1_LITERAL(opline));
literal_dtor(&ZEND_OP2_LITERAL(opline));
opline->opcode = ZEND_JMP;
Expand Down Expand Up @@ -822,7 +822,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
src->extended_value == IS_STRING &&
src->op1_type != IS_CONST) {
/* convert T1 = CAST(STRING, X), T2 = CONCAT(Y, T1) to T2 = CONCAT(Y,X) */
zend_op *src = VAR_SOURCE(opline->op2);
VAR_SOURCE(opline->op2) = NULL;
COPY_NODE(opline->op2, src->op1);
MAKE_NOP(src);
Expand Down Expand Up @@ -1009,10 +1008,10 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
}

/* Rebuild plain (optimized) op_array from CFG */
static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_optimizer_ctx *ctx)
static void assemble_code_blocks(const zend_cfg *cfg, zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
zend_basic_block *blocks = cfg->blocks;
zend_basic_block *end = blocks + cfg->blocks_count;
const zend_basic_block *end = blocks + cfg->blocks_count;
zend_basic_block *b;
zend_op *new_opcodes;
zend_op *opline;
Expand All @@ -1025,7 +1024,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
if (b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) {
opline = op_array->opcodes + b->start + b->len - 1;
if (opline->opcode == ZEND_JMP) {
zend_basic_block *next = b + 1;
const zend_basic_block *next = b + 1;

while (next < end && !(next->flags & ZEND_BB_REACHABLE)) {
next++;
Expand All @@ -1042,9 +1041,9 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
len += b->len;
} else {
/* this block will not be used, delete all constants there */
zend_op *op = op_array->opcodes + b->start;
zend_op *end = op + b->len;
for (; op < end; op++) {
const zend_op *op = op_array->opcodes + b->start;
const zend_op *last_op = op + b->len;
for (; op < last_op; op++) {
if (op->op1_type == IS_CONST) {
literal_dtor(&ZEND_OP1_LITERAL(op));
}
Expand Down Expand Up @@ -1109,7 +1108,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
case ZEND_SWITCH_STRING:
case ZEND_MATCH:
{
HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline));
const HashTable *jumptable = Z_ARRVAL(ZEND_OP2_LITERAL(opline));
zval *zv;
uint32_t s = 0;
ZEND_ASSERT(b->successors_count == (opline->opcode == ZEND_MATCH ? 1 : 2) + zend_hash_num_elements(jumptable));
Expand Down Expand Up @@ -1160,15 +1159,15 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
}

if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) {
zend_op *opline = new_opcodes;
zend_op *end = opline + len;
while (opline < end) {
if (opline->opcode == ZEND_FAST_RET &&
opline->op2.num != (uint32_t)-1 &&
opline->op2.num < j) {
opline->op2.num = map[opline->op2.num];
zend_op *finally_opline = new_opcodes;
const zend_op *last_finally_op = finally_opline + len;
while (finally_opline < last_finally_op) {
Comment on lines +1163 to +1164
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This is not the last finally op, it's the op after it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but isn't it a usual convention that "last" means +1? Or am I confused?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'm not blocking this change. There are some cases of last being used to mean +1, especially in op_array, but I find it confusing. end is slightly better.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do also find it confusing, just couldn't think of a name :) Might keep it like this for the time being tho

if (finally_opline->opcode == ZEND_FAST_RET &&
finally_opline->op2.num != (uint32_t)-1 &&
finally_opline->op2.num < j) {
finally_opline->op2.num = map[finally_opline->op2.num];
}
opline++;
finally_opline++;
}
}
}
Expand All @@ -1184,7 +1183,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
}
}

static zend_always_inline zend_basic_block *get_target_block(const zend_cfg *cfg, zend_basic_block *block, int n, uint32_t *opt_count)
static zend_always_inline zend_basic_block *get_target_block(const zend_cfg *cfg, const zend_basic_block *block, int n, uint32_t *opt_count)
{
int b;
zend_basic_block *target_block = cfg->blocks + block->successors[n];
Expand All @@ -1200,7 +1199,7 @@ static zend_always_inline zend_basic_block *get_target_block(const zend_cfg *cfg
return target_block;
}

static zend_always_inline zend_basic_block *get_follow_block(const zend_cfg *cfg, zend_basic_block *block, int n, uint32_t *opt_count)
static zend_always_inline zend_basic_block *get_follow_block(const zend_cfg *cfg, const zend_basic_block *block, int n, uint32_t *opt_count)
{
int b;
zend_basic_block *target_block = cfg->blocks + block->successors[n];
Expand All @@ -1219,7 +1218,7 @@ static zend_always_inline zend_basic_block *get_follow_block(const zend_cfg *cfg
static zend_always_inline zend_basic_block *get_next_block(const zend_cfg *cfg, zend_basic_block *block)
{
zend_basic_block *next_block = block + 1;
zend_basic_block *end = cfg->blocks + cfg->blocks_count;
const zend_basic_block *end = cfg->blocks + cfg->blocks_count;

while (1) {
if (next_block == end) {
Expand All @@ -1237,7 +1236,7 @@ static zend_always_inline zend_basic_block *get_next_block(const zend_cfg *cfg,


/* we use "jmp_hitlist" to avoid infinity loops during jmp optimization */
static zend_always_inline bool in_hitlist(int target, int *jmp_hitlist, int jmp_hitlist_count)
static zend_always_inline bool in_hitlist(int target, const int *jmp_hitlist, int jmp_hitlist_count)
{
int i;

Expand Down Expand Up @@ -1483,7 +1482,7 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr

/* Find a set of variables which are used outside of the block where they are
* defined. We won't apply some optimization patterns for such variables. */
static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset used_ext, zend_optimizer_ctx *ctx)
static void zend_t_usage(const zend_cfg *cfg, const zend_op_array *op_array, zend_bitset used_ext, zend_optimizer_ctx *ctx)
{
int n;
zend_basic_block *block, *next_block;
Expand Down Expand Up @@ -1687,7 +1686,7 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
zend_arena_release(&ctx->arena, checkpoint);
}

static void zend_merge_blocks(zend_op_array *op_array, zend_cfg *cfg, uint32_t *opt_count)
static void zend_merge_blocks(const zend_op_array *op_array, const zend_cfg *cfg, uint32_t *opt_count)
{
int i;
zend_basic_block *b, *bb;
Expand All @@ -1707,7 +1706,7 @@ static void zend_merge_blocks(zend_op_array *op_array, zend_cfg *cfg, uint32_t *

for (bb = prev + 1; bb != b; bb++) {
zend_op *op = op_array->opcodes + bb->start;
zend_op *end = op + bb->len;
const zend_op *end = op + bb->len;
while (op < end) {
if (op->op1_type == IS_CONST) {
literal_dtor(&ZEND_OP1_LITERAL(op));
Expand Down
34 changes: 17 additions & 17 deletions Zend/Optimizer/dce.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static inline bool is_bad_mod(const zend_ssa *ssa, int use, int def) {
}

static inline bool may_have_side_effects(
zend_op_array *op_array, zend_ssa *ssa,
const zend_op_array *op_array, const zend_ssa *ssa,
const zend_op *opline, const zend_ssa_op *ssa_op,
bool reorder_dtor_effects) {
switch (opline->opcode) {
Expand Down Expand Up @@ -271,8 +271,8 @@ static inline bool may_have_side_effects(
}
}

static zend_always_inline void add_to_worklists(context *ctx, int var_num, int check) {
zend_ssa_var *var = &ctx->ssa->vars[var_num];
static zend_always_inline void add_to_worklists(const context *ctx, int var_num, int check) {
const zend_ssa_var *var = &ctx->ssa->vars[var_num];
if (var->definition >= 0) {
if (!check || zend_bitset_in(ctx->instr_dead, var->definition)) {
zend_bitset_incl(ctx->instr_worklist, var->definition);
Expand All @@ -284,14 +284,14 @@ static zend_always_inline void add_to_worklists(context *ctx, int var_num, int c
}
}

static inline void add_to_phi_worklist_no_val(context *ctx, int var_num) {
zend_ssa_var *var = &ctx->ssa->vars[var_num];
static inline void add_to_phi_worklist_no_val(const context *ctx, int var_num) {
const zend_ssa_var *var = &ctx->ssa->vars[var_num];
if (var->definition_phi && zend_bitset_in(ctx->phi_dead, var_num)) {
zend_bitset_incl(ctx->phi_worklist_no_val, var_num);
}
}

static zend_always_inline void add_operands_to_worklists(context *ctx, zend_op *opline, zend_ssa_op *ssa_op, zend_ssa *ssa, int check) {
static zend_always_inline void add_operands_to_worklists(const context *ctx, const zend_op *opline, const zend_ssa_op *ssa_op, const zend_ssa *ssa, int check) {
if (ssa_op->result_use >= 0) {
add_to_worklists(ctx, ssa_op->result_use, check);
}
Expand All @@ -315,16 +315,16 @@ static zend_always_inline void add_operands_to_worklists(context *ctx, zend_op *
}
}

static zend_always_inline void add_phi_sources_to_worklists(context *ctx, zend_ssa_phi *phi, int check) {
zend_ssa *ssa = ctx->ssa;
static zend_always_inline void add_phi_sources_to_worklists(const context *ctx, zend_ssa_phi *phi, int check) {
const zend_ssa *ssa = ctx->ssa;
int source;
FOREACH_PHI_SOURCE(phi, source) {
add_to_worklists(ctx, source, check);
} FOREACH_PHI_SOURCE_END();
}

static inline bool is_var_dead(context *ctx, int var_num) {
zend_ssa_var *var = &ctx->ssa->vars[var_num];
static inline bool is_var_dead(const context *ctx, int var_num) {
const zend_ssa_var *var = &ctx->ssa->vars[var_num];
if (var->definition_phi) {
return zend_bitset_in(ctx->phi_dead, var_num);
} else if (var->definition >= 0) {
Expand All @@ -338,7 +338,7 @@ static inline bool is_var_dead(context *ctx, int var_num) {
}

// Sometimes we can mark the var as EXT_UNUSED
static bool try_remove_var_def(context *ctx, int free_var, int use_chain, zend_op *opline) {
static bool try_remove_var_def(const context *ctx, int free_var, int use_chain, const zend_op *opline) {
if (use_chain >= 0) {
return false;
}
Expand Down Expand Up @@ -394,7 +394,7 @@ static zend_always_inline bool may_be_refcounted(uint32_t type) {
return (type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) != 0;
}

static inline bool is_free_of_live_var(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
static inline bool is_free_of_live_var(const context *ctx, const zend_op *opline, const zend_ssa_op *ssa_op) {
switch (opline->opcode) {
case ZEND_FREE:
/* It is always safe to remove FREEs of non-refcounted values, even if they are live. */
Expand All @@ -411,8 +411,8 @@ static inline bool is_free_of_live_var(context *ctx, zend_op *opline, zend_ssa_o
}

/* Returns whether the instruction has been DCEd */
static bool dce_instr(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
zend_ssa *ssa = ctx->ssa;
static bool dce_instr(const context *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
const zend_ssa *ssa = ctx->ssa;
int free_var = -1;
uint8_t free_var_type;

Expand Down Expand Up @@ -464,7 +464,7 @@ static bool dce_instr(context *ctx, zend_op *opline, zend_ssa_op *ssa_op) {
return true;
}

static inline int get_common_phi_source(zend_ssa *ssa, zend_ssa_phi *phi) {
static inline int get_common_phi_source(const zend_ssa *ssa, zend_ssa_phi *phi) {
int common_source = -1;
int source;
FOREACH_PHI_SOURCE(phi, source) {
Expand All @@ -484,7 +484,7 @@ static inline int get_common_phi_source(zend_ssa *ssa, zend_ssa_phi *phi) {
return common_source;
}

static void try_remove_trivial_phi(context *ctx, zend_ssa_phi *phi) {
static void try_remove_trivial_phi(const context *ctx, zend_ssa_phi *phi) {
zend_ssa *ssa = ctx->ssa;
if (phi->pi < 0) {
/* Phi assignment with identical source operands */
Expand Down Expand Up @@ -567,7 +567,7 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *optimizer
int op_data = -1;

b--;
zend_basic_block *block = &ssa->cfg.blocks[b];
const zend_basic_block *block = &ssa->cfg.blocks[b];
if (!(block->flags & ZEND_BB_REACHABLE)) {
continue;
}
Expand Down
6 changes: 3 additions & 3 deletions Zend/Optimizer/pass1.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
if (opline->op2_type == IS_CONST &&
Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
/* substitute persistent constants */
if (!zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP2_LITERAL(opline)), &result, 1)) {
if (!zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP2_LITERAL(opline)), &result, true)) {
if (!ctx->constants || !zend_optimizer_get_collected_constant(ctx->constants, &ZEND_OP2_LITERAL(opline), &result)) {
break;
}
Expand All @@ -171,7 +171,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
if (Z_TYPE_P(c) == IS_CONSTANT_AST) {
zend_ast *ast = Z_ASTVAL_P(c);
if (ast->kind != ZEND_AST_CONSTANT
|| !zend_optimizer_get_persistent_constant(zend_ast_get_constant_name(ast), &result, 1)
|| !zend_optimizer_get_persistent_constant(zend_ast_get_constant_name(ast), &result, true)
|| Z_TYPE(result) == IS_CONSTANT_AST) {
break;
}
Expand Down Expand Up @@ -271,7 +271,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
}
break;
case ZEND_DEFINED:
if (!zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline)), &result, 0)) {
if (!zend_optimizer_get_persistent_constant(Z_STR(ZEND_OP1_LITERAL(opline)), &result, false)) {
break;
}
ZVAL_TRUE(&result);
Expand Down
Loading