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
6 changes: 3 additions & 3 deletions Zend/Optimizer/nop_removal.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@

void zend_optimizer_nop_removal(zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
zend_op *end, *opline;
zend_op *opline;
uint32_t new_count, i, shift;
uint32_t *shiftlist;
ALLOCA_FLAG(use_heap);

shiftlist = (uint32_t *)do_alloca(sizeof(uint32_t) * op_array->last, use_heap);
i = new_count = shift = 0;
end = op_array->opcodes + op_array->last;
const zend_op *end = op_array->opcodes + op_array->last;
for (opline = op_array->opcodes; opline < end; opline++) {

/* Kill JMP-over-NOP-s */
if (opline->opcode == ZEND_JMP && ZEND_OP1_JMP_ADDR(opline) > op_array->opcodes + i) {
/* check if there are only NOPs under the branch */
zend_op *target = ZEND_OP1_JMP_ADDR(opline) - 1;
const zend_op *target = ZEND_OP1_JMP_ADDR(opline) - 1;

while (target->opcode == ZEND_NOP) {
target--;
Expand Down
6 changes: 3 additions & 3 deletions Zend/Optimizer/optimize_func_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ typedef struct _optimizer_call_info {
uint32_t func_arg_num;
} optimizer_call_info;

static void zend_delete_call_instructions(zend_op_array *op_array, zend_op *opline)
static void zend_delete_call_instructions(const zend_op_array *op_array, zend_op *opline)
{
int call = 0;

Expand Down Expand Up @@ -76,7 +76,7 @@ static void zend_delete_call_instructions(zend_op_array *op_array, zend_op *opli
}
}

static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_op *opline, zend_function *func)
static void zend_try_inline_call(zend_op_array *op_array, const zend_op *fcall, zend_op *opline, const zend_function *func)
{
const uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD;

Expand Down Expand Up @@ -153,7 +153,7 @@ static bool has_known_send_mode(const optimizer_call_info *info, uint32_t arg_nu
void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
{
zend_op *opline = op_array->opcodes;
zend_op *end = opline + op_array->last;
const zend_op *end = opline + op_array->last;
int call = 0;
void *checkpoint;
optimizer_call_info *call_stack;
Expand Down
2 changes: 1 addition & 1 deletion Zend/Optimizer/sccp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2037,7 +2037,7 @@ static void join_phi_values(zval *a, zval *b, bool escape) {
}
}

static void sccp_visit_phi(scdf_ctx *scdf, zend_ssa_phi *phi) {
static void sccp_visit_phi(scdf_ctx *scdf, const zend_ssa_phi *phi) {
sccp_ctx *ctx = (sccp_ctx *) scdf;
zend_ssa *ssa = scdf->ssa;
ZEND_ASSERT(phi->ssa_var >= 0);
Expand Down
34 changes: 15 additions & 19 deletions Zend/Optimizer/scdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,8 @@ void scdf_mark_edge_feasible(scdf_ctx *scdf, int from, int to) {
} else {
/* Block is already executable, only a new edge became feasible.
* Reevaluate phi nodes to account for changed source operands. */
zend_ssa_block *ssa_block = &scdf->ssa->blocks[to];
zend_ssa_phi *phi;
for (phi = ssa_block->phis; phi; phi = phi->next) {
const zend_ssa_block *ssa_block = &scdf->ssa->blocks[to];
for (const zend_ssa_phi *phi = ssa_block->phis; phi; phi = phi->next) {
zend_bitset_excl(scdf->phi_var_worklist, phi->ssa_var);
scdf->handlers.visit_phi(scdf, phi);
}
Expand Down Expand Up @@ -101,15 +100,15 @@ void scdf_init(zend_optimizer_ctx *ctx, scdf_ctx *scdf, zend_op_array *op_array,
}

void scdf_solve(scdf_ctx *scdf, const char *name) {
zend_ssa *ssa = scdf->ssa;
const zend_ssa *ssa = scdf->ssa;
DEBUG_PRINT("Start SCDF solve (%s)\n", name);
while (!zend_bitset_empty(scdf->instr_worklist, scdf->instr_worklist_len)
|| !zend_bitset_empty(scdf->phi_var_worklist, scdf->phi_var_worklist_len)
|| !zend_bitset_empty(scdf->block_worklist, scdf->block_worklist_len)
) {
int i;
while ((i = zend_bitset_pop_first(scdf->phi_var_worklist, scdf->phi_var_worklist_len)) >= 0) {
zend_ssa_phi *phi = ssa->vars[i].definition_phi;
const zend_ssa_phi *phi = ssa->vars[i].definition_phi;
ZEND_ASSERT(phi);
if (zend_bitset_in(scdf->executable_blocks, phi->block)) {
scdf->handlers.visit_phi(scdf, phi);
Expand Down Expand Up @@ -140,25 +139,22 @@ void scdf_solve(scdf_ctx *scdf, const char *name) {
while ((i = zend_bitset_pop_first(scdf->block_worklist, scdf->block_worklist_len)) >= 0) {
/* This block is now live. Interpret phis and instructions in it. */
zend_basic_block *block = &ssa->cfg.blocks[i];
zend_ssa_block *ssa_block = &ssa->blocks[i];
const zend_ssa_block *ssa_block = &ssa->blocks[i];

DEBUG_PRINT("Pop block %d from worklist\n", i);
zend_bitset_incl(scdf->executable_blocks, i);

{
zend_ssa_phi *phi;
for (phi = ssa_block->phis; phi; phi = phi->next) {
zend_bitset_excl(scdf->phi_var_worklist, phi->ssa_var);
scdf->handlers.visit_phi(scdf, phi);
}
for (const zend_ssa_phi *phi = ssa_block->phis; phi; phi = phi->next) {
zend_bitset_excl(scdf->phi_var_worklist, phi->ssa_var);
scdf->handlers.visit_phi(scdf, phi);
}

if (block->len == 0) {
/* Zero length blocks don't have a last instruction that would normally do this */
scdf_mark_edge_feasible(scdf, i, block->successors[0]);
} else {
zend_op *opline = NULL;
int j, end = block->start + block->len;
uint32_t j, end = block->start + block->len;
for (j = block->start; j < end; j++) {
opline = &scdf->op_array->opcodes[j];
zend_bitset_excl(scdf->instr_worklist, j);
Expand All @@ -185,7 +181,7 @@ void scdf_solve(scdf_ctx *scdf, const char *name) {
* not eliminate the latter. While it cannot be reached, the FREE opcode of the loop var
* is necessary for the correctness of temporary compaction. */
static bool is_live_loop_var_free(
scdf_ctx *scdf, const zend_op *opline, const zend_ssa_op *ssa_op) {
const scdf_ctx *scdf, const zend_op *opline, const zend_ssa_op *ssa_op) {
if (!zend_optimizer_is_loop_var_free(opline)) {
return false;
}
Expand All @@ -195,7 +191,7 @@ static bool is_live_loop_var_free(
return false;
}

zend_ssa_var *ssa_var = &scdf->ssa->vars[var];
const zend_ssa_var *ssa_var = &scdf->ssa->vars[var];
uint32_t def_block;
if (ssa_var->definition >= 0) {
def_block = scdf->ssa->cfg.map[ssa_var->definition];
Expand All @@ -205,7 +201,7 @@ static bool is_live_loop_var_free(
return zend_bitset_in(scdf->executable_blocks, def_block);
}

static bool kept_alive_by_loop_var_free(scdf_ctx *scdf, const zend_basic_block *block) {
static bool kept_alive_by_loop_var_free(const scdf_ctx *scdf, const zend_basic_block *block) {
const zend_op_array *op_array = scdf->op_array;
const zend_cfg *cfg = &scdf->ssa->cfg;
if (!(cfg->flags & ZEND_FUNC_FREE_LOOP_VAR)) {
Expand All @@ -220,7 +216,7 @@ static bool kept_alive_by_loop_var_free(scdf_ctx *scdf, const zend_basic_block *
return false;
}

static uint32_t cleanup_loop_var_free_block(scdf_ctx *scdf, zend_basic_block *block) {
static uint32_t cleanup_loop_var_free_block(const scdf_ctx *scdf, const zend_basic_block *block) {
zend_ssa *ssa = scdf->ssa;
const zend_op_array *op_array = scdf->op_array;
const zend_cfg *cfg = &ssa->cfg;
Expand Down Expand Up @@ -256,12 +252,12 @@ static uint32_t cleanup_loop_var_free_block(scdf_ctx *scdf, zend_basic_block *bl
/* Removes unreachable blocks. This will remove both the instructions (and phis) in the
* blocks, as well as remove them from the successor / predecessor lists and mark them
* unreachable. Blocks already marked unreachable are not removed. */
uint32_t scdf_remove_unreachable_blocks(scdf_ctx *scdf) {
uint32_t scdf_remove_unreachable_blocks(const scdf_ctx *scdf) {
zend_ssa *ssa = scdf->ssa;
int i;
uint32_t removed_ops = 0;
for (i = 0; i < ssa->cfg.blocks_count; i++) {
zend_basic_block *block = &ssa->cfg.blocks[i];
const zend_basic_block *block = &ssa->cfg.blocks[i];
if (!zend_bitset_in(scdf->executable_blocks, i) && (block->flags & ZEND_BB_REACHABLE)) {
if (!kept_alive_by_loop_var_free(scdf, block)) {
removed_ops += block->len;
Expand Down
8 changes: 4 additions & 4 deletions Zend/Optimizer/scdf.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ typedef struct _scdf_ctx {
void (*visit_instr)(
struct _scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_op);
void (*visit_phi)(
struct _scdf_ctx *scdf, zend_ssa_phi *phi);
struct _scdf_ctx *scdf, const zend_ssa_phi *phi);
void (*mark_feasible_successors)(
struct _scdf_ctx *scdf, int block_num, zend_basic_block *block,
zend_op *opline, zend_ssa_op *ssa_op);
Expand All @@ -49,10 +49,10 @@ typedef struct _scdf_ctx {
void scdf_init(zend_optimizer_ctx *ctx, scdf_ctx *scdf, zend_op_array *op_array, zend_ssa *ssa);
void scdf_solve(scdf_ctx *scdf, const char *name);

uint32_t scdf_remove_unreachable_blocks(scdf_ctx *scdf);
uint32_t scdf_remove_unreachable_blocks(const scdf_ctx *scdf);

/* Add uses to worklist */
static inline void scdf_add_to_worklist(scdf_ctx *scdf, int var_num) {
static inline void scdf_add_to_worklist(const scdf_ctx *scdf, int var_num) {
const zend_ssa *ssa = scdf->ssa;
const zend_ssa_var *var = &ssa->vars[var_num];
int use;
Expand All @@ -66,7 +66,7 @@ static inline void scdf_add_to_worklist(scdf_ctx *scdf, int var_num) {
}

/* This should usually not be necessary, however it's used for type narrowing. */
static inline void scdf_add_def_to_worklist(scdf_ctx *scdf, int var_num) {
static inline void scdf_add_def_to_worklist(const scdf_ctx *scdf, int var_num) {
const zend_ssa_var *var = &scdf->ssa->vars[var_num];
if (var->definition >= 0) {
zend_bitset_incl(scdf->instr_worklist, var->definition);
Expand Down
14 changes: 7 additions & 7 deletions Zend/Optimizer/zend_func_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static uint32_t zend_range_info(const zend_call_info *call_info, const zend_ssa
&& (call_info->num_args == 2 || call_info->num_args == 3)
&& ssa
&& !(ssa->cfg.flags & ZEND_SSA_TSSA)) {
zend_op_array *op_array = call_info->caller_op_array;
const zend_op_array *op_array = call_info->caller_op_array;
uint32_t t1 = _ssa_op1_info(op_array, ssa, call_info->arg_info[0].opline,
ssa->ops ? &ssa->ops[call_info->arg_info[0].opline - op_array->opcodes] : NULL);
uint32_t t2 = _ssa_op1_info(op_array, ssa, call_info->arg_info[1].opline,
Expand Down Expand Up @@ -116,7 +116,7 @@ uint32_t zend_get_internal_func_info(
return 0;
}

func_info_t *info = Z_PTR_P(zv);
const func_info_t *info = Z_PTR_P(zv);
if (info->info_func) {
return call_info ? info->info_func(call_info, ssa) : 0;
} else {
Expand Down Expand Up @@ -178,7 +178,7 @@ ZEND_API uint32_t zend_get_func_info(
} else {
if (!call_info->is_prototype) {
// FIXME: the order of functions matters!!!
zend_func_info *info = ZEND_FUNC_INFO((zend_op_array*)callee_func);
const zend_func_info *info = ZEND_FUNC_INFO((zend_op_array*)callee_func);
if (info) {
ret = info->return_info.type;
*ce = info->return_info.ce;
Expand All @@ -198,13 +198,13 @@ ZEND_API uint32_t zend_get_func_info(
return ret;
}

static void zend_func_info_add(const func_info_t *func_infos, size_t n)
static void zend_func_info_add(const func_info_t *new_func_infos, size_t n)
{
for (size_t i = 0; i < n; i++) {
zend_string *key = zend_string_init_interned(func_infos[i].name, func_infos[i].name_len, 1);
zend_string *key = zend_string_init_interned(new_func_infos[i].name, new_func_infos[i].name_len, 1);

if (zend_hash_add_ptr(&func_info, key, (void**)&func_infos[i]) == NULL) {
fprintf(stderr, "ERROR: Duplicate function info for \"%s\"\n", func_infos[i].name);
if (zend_hash_add_ptr(&func_info, key, (void**)&new_func_infos[i]) == NULL) {
fprintf(stderr, "ERROR: Duplicate function info for \"%s\"\n", new_func_infos[i].name);
}

zend_string_release_ex(key, 1);
Expand Down
34 changes: 17 additions & 17 deletions Zend/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ static bool zend_inference_calc_binary_op_range(
return 0;
}

static bool zend_inference_calc_range(const zend_op_array *op_array, const zend_ssa *ssa, int var, int widening, int narrowing, zend_ssa_range *tmp)
static bool zend_inference_calc_range(const zend_op_array *op_array, const zend_ssa *ssa, int var, int widening, bool narrowing, zend_ssa_range *tmp)
{
uint32_t line;
const zend_op *opline;
Expand Down Expand Up @@ -1735,15 +1735,15 @@ static void zend_infer_ranges_warmup(const zend_op_array *op_array, zend_ssa *ss
zend_bitset worklist = do_alloca(sizeof(zend_ulong) * worklist_len * 2, use_heap);
zend_bitset visited = worklist + worklist_len;
#ifdef NEG_RANGE
int has_inner_cycles = 0;
bool has_inner_cycles = false;

memset(worklist, 0, sizeof(zend_ulong) * worklist_len);
memset(visited, 0, sizeof(zend_ulong) * worklist_len);
j = scc_var[scc];
while (j >= 0) {
if (!zend_bitset_in(visited, j) &&
zend_check_inner_cycles(op_array, ssa, worklist, visited, j)) {
has_inner_cycles = 1;
has_inner_cycles = true;
break;
}
j = next_scc_var[j];
Expand Down Expand Up @@ -2130,7 +2130,7 @@ ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv)
}


ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, int write, int insert)
ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, bool write, bool insert)
{
uint32_t tmp = 0;

Expand Down Expand Up @@ -2464,7 +2464,7 @@ static const zend_property_info *zend_fetch_static_prop_info(const zend_script *
if (opline->op1_type == IS_CONST) {
zend_class_entry *ce = NULL;
if (opline->op2_type == IS_UNUSED) {
int fetch_type = opline->op2.num & ZEND_FETCH_CLASS_MASK;
uint32_t fetch_type = opline->op2.num & ZEND_FETCH_CLASS_MASK;
switch (fetch_type) {
case ZEND_FETCH_CLASS_SELF:
case ZEND_FETCH_CLASS_STATIC:
Expand Down Expand Up @@ -4142,7 +4142,7 @@ static uint32_t get_class_entry_rank(zend_class_entry *ce) {

/* Compute least common ancestor on class inheritance tree only */
static zend_class_entry *join_class_entries(
zend_class_entry *ce1, zend_class_entry *ce2, int *is_instanceof) {
zend_class_entry *ce1, zend_class_entry *ce2, bool *is_instanceof) {
uint32_t rank1, rank2;
if (ce1 == ce2) {
return ce1;
Expand Down Expand Up @@ -4170,7 +4170,7 @@ static zend_class_entry *join_class_entries(
}

if (ce1) {
*is_instanceof = 1;
*is_instanceof = true;
}
return ce1;
}
Expand Down Expand Up @@ -4204,7 +4204,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend
zend_ssa_phi *p = ssa_vars[j].definition_phi;
if (p->pi >= 0) {
zend_class_entry *ce = ssa_var_info[p->sources[0]].ce;
int is_instanceof = ssa_var_info[p->sources[0]].is_instanceof;
bool is_instanceof = ssa_var_info[p->sources[0]].is_instanceof;
tmp = get_ssa_var_info(ssa, p->sources[0]);

if (!p->has_range_constraint) {
Expand All @@ -4216,7 +4216,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend
if ((tmp & MAY_BE_OBJECT) && constraint->ce && ce != constraint->ce) {
if (!ce) {
ce = constraint->ce;
is_instanceof = 1;
is_instanceof = true;
} else if (is_instanceof && safe_instanceof(constraint->ce, ce)) {
ce = constraint->ce;
} else {
Expand All @@ -4233,8 +4233,8 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend
UPDATE_SSA_OBJ_TYPE(ce, is_instanceof, j);
}
} else {
int first = 1;
int is_instanceof = 0;
bool first = true;
bool is_instanceof = false;
zend_class_entry *ce = NULL;

tmp = 0;
Expand All @@ -4251,7 +4251,7 @@ static zend_result zend_infer_types_ex(const zend_op_array *op_array, const zend
if (first) {
ce = info->ce;
is_instanceof = info->is_instanceof;
first = 0;
first = false;
} else {
is_instanceof |= info->is_instanceof;
ce = join_class_entries(ce, info->ce, &is_instanceof);
Expand Down Expand Up @@ -4536,7 +4536,7 @@ uint32_t zend_get_return_info_from_signature_only(
&& !(func->common.fn_flags & ZEND_ACC_GENERATOR)) {
type |= MAY_BE_REF;
*ce = NULL;
*ce_is_instanceof = 0;
*ce_is_instanceof = false;
}
return type;
}
Expand All @@ -4557,8 +4557,8 @@ ZEND_API void zend_init_func_return_info(

static void zend_func_return_info(const zend_op_array *op_array,
const zend_script *script,
int recursive,
int widening,
bool recursive,
bool widening,
zend_ssa_var_info *ret)
{
zend_func_info *info = ZEND_FUNC_INFO(op_array);
Expand All @@ -4571,7 +4571,7 @@ static void zend_func_return_info(const zend_op_array *op_array,
zend_class_entry *tmp_ce = NULL;
int tmp_is_instanceof = -1;
zend_class_entry *arg_ce;
int arg_is_instanceof;
bool arg_is_instanceof;
zend_ssa_range tmp_range = {0, 0, 0, 0};
int tmp_has_range = -1;

Expand Down Expand Up @@ -4626,7 +4626,7 @@ static void zend_func_return_info(const zend_op_array *op_array,
arg_is_instanceof = info->ssa.var_info[ssa_op->op1_use].is_instanceof;
} else {
arg_ce = NULL;
arg_is_instanceof = 0;
arg_is_instanceof = false;
}

if (tmp_is_instanceof < 0) {
Expand Down
2 changes: 1 addition & 1 deletion Zend/Optimizer/zend_inference.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ ZEND_API void zend_ssa_find_false_dependencies(const zend_op_array *op_array, ze
ZEND_API void zend_ssa_find_sccs(const zend_op_array *op_array, zend_ssa *ssa);
ZEND_API zend_result zend_ssa_inference(zend_arena **raena, const zend_op_array *op_array, const zend_script *script, zend_ssa *ssa, zend_long optimization_level);

ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, int write, int insert);
ZEND_API uint32_t zend_array_element_type(uint32_t t1, uint8_t op_type, bool write, bool insert);

ZEND_API bool zend_inference_propagate_range(const zend_op_array *op_array, const zend_ssa *ssa, const zend_op *opline, const zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp);

Expand Down
Loading