mirror of
https://github.com/php/php-src.git
synced 2026-04-28 18:53:33 +02:00
2f4973fd88
Cf. <https://github.com/php/php-src/pull/10220#issuecomment-1383739816>. This reverts commit45a128c9de. This reverts commit1eb71c3f15. This reverts commit492523a779. This reverts commitc7a4633891. This reverts commit308adb915c. This reverts commitcd27d5e07f. This reverts commitc5933409b4. This reverts commit46371f4eb3. This reverts commit623e2e9fc6. This reverts commite7434c1247. This reverts commitd28d323ca2. This reverts commit1a067b84ee. This reverts commita55c0c5fc3. This reverts commitb5aeb3a4d4. This reverts commitf061a035e4. This reverts commitb088575119. This reverts commitb1d48774a7. This reverts commit94f9a20ce6. This reverts commit4831e48708. This reverts commitcd985de190. This reverts commit9521d21681. This reverts commitd6136151e9.
100 lines
3.5 KiB
C
100 lines
3.5 KiB
C
/*
|
|
+----------------------------------------------------------------------+
|
|
| Zend Engine, Call Graph |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) The PHP Group |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 3.01 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available through the world-wide-web at the following url: |
|
|
| https://www.php.net/license/3_01.txt |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
| Authors: Nikita Popov <nikic@php.net> |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
#ifndef _SCDF_H
|
|
#define _SCDF_H
|
|
|
|
#include "zend_bitset.h"
|
|
|
|
typedef struct _scdf_ctx {
|
|
zend_op_array *op_array;
|
|
zend_ssa *ssa;
|
|
zend_bitset instr_worklist;
|
|
/* Represent phi-instructions through the defining var */
|
|
zend_bitset phi_var_worklist;
|
|
zend_bitset block_worklist;
|
|
zend_bitset executable_blocks;
|
|
/* 1 bit per edge, see scdf_edge(cfg, from, to) */
|
|
zend_bitset feasible_edges;
|
|
uint32_t instr_worklist_len;
|
|
uint32_t phi_var_worklist_len;
|
|
uint32_t block_worklist_len;
|
|
|
|
struct {
|
|
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);
|
|
void (*mark_feasible_successors)(
|
|
struct _scdf_ctx *scdf, int block_num, zend_basic_block *block,
|
|
zend_op *opline, zend_ssa_op *ssa_op);
|
|
} handlers;
|
|
} 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);
|
|
|
|
/* Add uses to worklist */
|
|
static inline void scdf_add_to_worklist(scdf_ctx *scdf, int var_num) {
|
|
zend_ssa *ssa = scdf->ssa;
|
|
zend_ssa_var *var = &ssa->vars[var_num];
|
|
int use;
|
|
zend_ssa_phi *phi;
|
|
FOREACH_USE(var, use) {
|
|
zend_bitset_incl(scdf->instr_worklist, use);
|
|
} FOREACH_USE_END();
|
|
FOREACH_PHI_USE(var, phi) {
|
|
zend_bitset_incl(scdf->phi_var_worklist, phi->ssa_var);
|
|
} FOREACH_PHI_USE_END();
|
|
}
|
|
|
|
/* 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) {
|
|
zend_ssa_var *var = &scdf->ssa->vars[var_num];
|
|
if (var->definition >= 0) {
|
|
zend_bitset_incl(scdf->instr_worklist, var->definition);
|
|
} else if (var->definition_phi) {
|
|
zend_bitset_incl(scdf->phi_var_worklist, var_num);
|
|
}
|
|
}
|
|
|
|
static inline uint32_t scdf_edge(zend_cfg *cfg, int from, int to) {
|
|
zend_basic_block *to_block = cfg->blocks + to;
|
|
int i;
|
|
|
|
for (i = 0; i < to_block->predecessors_count; i++) {
|
|
uint32_t edge = to_block->predecessor_offset + i;
|
|
|
|
if (cfg->predecessors[edge] == from) {
|
|
return edge;
|
|
}
|
|
}
|
|
ZEND_UNREACHABLE();
|
|
}
|
|
|
|
static inline bool scdf_is_edge_feasible(scdf_ctx *scdf, int from, int to) {
|
|
uint32_t edge = scdf_edge(&scdf->ssa->cfg, from, to);
|
|
return zend_bitset_in(scdf->feasible_edges, edge);
|
|
}
|
|
|
|
void scdf_mark_edge_feasible(scdf_ctx *scdf, int from, int to);
|
|
|
|
#endif
|