diff options
Diffstat (limited to 'Zend/Optimizer/zend_cfg.h')
-rw-r--r-- | Zend/Optimizer/zend_cfg.h | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/Zend/Optimizer/zend_cfg.h b/Zend/Optimizer/zend_cfg.h new file mode 100644 index 0000000000..6fff720ed3 --- /dev/null +++ b/Zend/Optimizer/zend_cfg.h @@ -0,0 +1,127 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine, CFG - Control Flow 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: | + | http://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: Dmitry Stogov <dmitry@php.net> | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_CFG_H +#define ZEND_CFG_H + +/* zend_basic_block.flags */ +#define ZEND_BB_START (1<<0) /* first block */ +#define ZEND_BB_FOLLOW (1<<1) /* follows the next block */ +#define ZEND_BB_TARGET (1<<2) /* jump target */ +#define ZEND_BB_EXIT (1<<3) /* without successors */ +#define ZEND_BB_ENTRY (1<<4) /* stackless entry */ +#define ZEND_BB_TRY (1<<5) /* start of try block */ +#define ZEND_BB_CATCH (1<<6) /* start of catch block */ +#define ZEND_BB_FINALLY (1<<7) /* start of finally block */ +#define ZEND_BB_FINALLY_END (1<<8) /* end of finally block */ +#define ZEND_BB_UNREACHABLE_FREE (1<<11) /* unreachable loop free */ +#define ZEND_BB_RECV_ENTRY (1<<12) /* RECV entry */ + +#define ZEND_BB_LOOP_HEADER (1<<16) +#define ZEND_BB_IRREDUCIBLE_LOOP (1<<17) + +#define ZEND_BB_REACHABLE (1U<<31) + +#define ZEND_BB_PROTECTED (ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY|ZEND_BB_TRY|ZEND_BB_CATCH|ZEND_BB_FINALLY|ZEND_BB_FINALLY_END|ZEND_BB_UNREACHABLE_FREE) + +typedef struct _zend_basic_block { + int *successors; /* successor block indices */ + uint32_t flags; + uint32_t start; /* first opcode number */ + uint32_t len; /* number of opcodes */ + int successors_count; /* number of successors */ + int predecessors_count; /* number of predecessors */ + int predecessor_offset; /* offset of 1-st predecessor */ + int idom; /* immediate dominator block */ + int loop_header; /* closest loop header, or -1 */ + int level; /* steps away from the entry in the dom. tree */ + int children; /* list of dominated blocks */ + int next_child; /* next dominated block */ + int successors_storage[2]; /* up to 2 successor blocks */ +} zend_basic_block; + +/* ++------------+---+---+---+---+---+ +| |OP1|OP2|EXT| 0 | 1 | ++------------+---+---+---+---+---+ +|JMP |ADR| | |OP1| - | +|JMPZ | |ADR| |OP2|FOL| +|JMPNZ | |ADR| |OP2|FOL| +|JMPZNZ | |ADR|ADR|OP2|EXT| +|JMPZ_EX | |ADR| |OP2|FOL| +|JMPNZ_EX | |ADR| |OP2|FOL| +|JMP_SET | |ADR| |OP2|FOL| +|COALESCE | |ADR| |OP2|FOL| +|ASSERT_CHK | |ADR| |OP2|FOL| +|NEW | |ADR| |OP2|FOL| +|DCL_ANON* |ADR| | |OP1|FOL| +|FE_RESET_* | |ADR| |OP2|FOL| +|FE_FETCH_* | | |ADR|EXT|FOL| +|CATCH | | |ADR|EXT|FOL| +|FAST_CALL |ADR| | |OP1|FOL| +|FAST_RET | | | | - | - | +|RETURN* | | | | - | - | +|EXIT | | | | - | - | +|THROW | | | | - | - | +|* | | | |FOL| - | ++------------+---+---+---+---+---+ +*/ + +typedef struct _zend_cfg { + int blocks_count; /* number of basic blocks */ + int edges_count; /* number of edges */ + zend_basic_block *blocks; /* array of basic blocks */ + int *predecessors; + uint32_t *map; + uint32_t flags; +} zend_cfg; + +/* Build Flags */ +#define ZEND_CFG_STACKLESS (1<<30) +#define ZEND_SSA_DEBUG_LIVENESS (1<<29) +#define ZEND_SSA_DEBUG_PHI_PLACEMENT (1<<28) +#define ZEND_SSA_RC_INFERENCE (1<<27) +#define ZEND_CFG_NO_ENTRY_PREDECESSORS (1<<25) +#define ZEND_CFG_RECV_ENTRY (1<<24) +#define ZEND_CALL_TREE (1<<23) +#define ZEND_SSA_USE_CV_RESULTS (1<<22) + +#define CRT_CONSTANT_EX(op_array, opline, node) \ + (((op_array)->fn_flags & ZEND_ACC_DONE_PASS_TWO) ? \ + RT_CONSTANT(opline, (node)) \ + : \ + CT_CONSTANT_EX(op_array, (node).constant) \ + ) + +#define CRT_CONSTANT(node) \ + CRT_CONSTANT_EX(op_array, opline, node) + +#define RETURN_VALUE_USED(opline) \ + ((opline)->result_type != IS_UNUSED) + +BEGIN_EXTERN_C() + +ZEND_API int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_cfg *cfg); +void zend_cfg_remark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg); +ZEND_API int zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg); +ZEND_API int zend_cfg_compute_dominators_tree(const zend_op_array *op_array, zend_cfg *cfg); +ZEND_API int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg); + +END_EXTERN_C() + +#endif /* ZEND_CFG_H */ |