zend_cfg.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine, CFG - Control Flow Graph |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1998-2018 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Dmitry Stogov <dmitry@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #ifndef ZEND_CFG_H
  19. #define ZEND_CFG_H
  20. /* zend_basic_bloc.flags */
  21. #define ZEND_BB_START (1<<0) /* fist block */
  22. #define ZEND_BB_FOLLOW (1<<1) /* follows the next block */
  23. #define ZEND_BB_TARGET (1<<2) /* jump taget */
  24. #define ZEND_BB_EXIT (1<<3) /* without successors */
  25. #define ZEND_BB_ENTRY (1<<4) /* stackless entry */
  26. #define ZEND_BB_TRY (1<<5) /* start of try block */
  27. #define ZEND_BB_CATCH (1<<6) /* start of catch block */
  28. #define ZEND_BB_FINALLY (1<<7) /* start of finally block */
  29. #define ZEND_BB_FINALLY_END (1<<8) /* end of finally block */
  30. #define ZEND_BB_GEN_VAR (1<<9) /* start of live range */
  31. #define ZEND_BB_KILL_VAR (1<<10) /* end of live range */
  32. #define ZEND_BB_UNREACHABLE_FREE (1<<11) /* unreachable loop free */
  33. #define ZEND_BB_RECV_ENTRY (1<<12) /* RECV entry */
  34. #define ZEND_BB_LOOP_HEADER (1<<16)
  35. #define ZEND_BB_IRREDUCIBLE_LOOP (1<<17)
  36. #define ZEND_BB_REACHABLE (1<<31)
  37. #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_GEN_VAR|ZEND_BB_KILL_VAR)
  38. typedef struct _zend_basic_block {
  39. int *successors; /* successor block indices */
  40. uint32_t flags;
  41. uint32_t start; /* first opcode number */
  42. uint32_t len; /* number of opcodes */
  43. int successors_count; /* number of successors */
  44. int predecessors_count; /* number of predecessors */
  45. int predecessor_offset; /* offset of 1-st predecessor */
  46. int idom; /* immediate dominator block */
  47. int loop_header; /* closest loop header, or -1 */
  48. int level; /* steps away from the entry in the dom. tree */
  49. int children; /* list of dominated blocks */
  50. int next_child; /* next dominated block */
  51. int successors_storage[2]; /* up to 2 successor blocks */
  52. } zend_basic_block;
  53. /*
  54. +------------+---+---+---+---+---+
  55. | |OP1|OP2|EXT| 0 | 1 |
  56. +------------+---+---+---+---+---+
  57. |JMP |ADR| | |OP1| - |
  58. |JMPZ | |ADR| |OP2|FOL|
  59. |JMPNZ | |ADR| |OP2|FOL|
  60. |JMPZNZ | |ADR|ADR|OP2|EXT|
  61. |JMPZ_EX | |ADR| |OP2|FOL|
  62. |JMPNZ_EX | |ADR| |OP2|FOL|
  63. |JMP_SET | |ADR| |OP2|FOL|
  64. |COALESCE | |ADR| |OP2|FOL|
  65. |ASSERT_CHK | |ADR| |OP2|FOL|
  66. |NEW | |ADR| |OP2|FOL|
  67. |DCL_ANON* |ADR| | |OP1|FOL|
  68. |FE_RESET_* | |ADR| |OP2|FOL|
  69. |FE_FETCH_* | | |ADR|EXT|FOL|
  70. |CATCH | | |ADR|EXT|FOL|
  71. |FAST_CALL |ADR| | |OP1|FOL|
  72. |FAST_RET | | | | - | - |
  73. |RETURN* | | | | - | - |
  74. |EXIT | | | | - | - |
  75. |THROW | | | | - | - |
  76. |* | | | |FOL| - |
  77. +------------+---+---+---+---+---+
  78. */
  79. typedef struct _zend_cfg {
  80. int blocks_count; /* number of basic blocks */
  81. int edges_count; /* number of edges */
  82. zend_basic_block *blocks; /* array of basic blocks */
  83. int *predecessors;
  84. uint32_t *map;
  85. uint32_t flags;
  86. } zend_cfg;
  87. /* Build Flags */
  88. #define ZEND_RT_CONSTANTS (1<<31)
  89. #define ZEND_CFG_STACKLESS (1<<30)
  90. #define ZEND_SSA_DEBUG_LIVENESS (1<<29)
  91. #define ZEND_SSA_DEBUG_PHI_PLACEMENT (1<<28)
  92. #define ZEND_SSA_RC_INFERENCE (1<<27)
  93. #define ZEND_CFG_SPLIT_AT_LIVE_RANGES (1<<26)
  94. #define ZEND_CFG_NO_ENTRY_PREDECESSORS (1<<25)
  95. #define ZEND_CFG_RECV_ENTRY (1<<24)
  96. #define ZEND_CALL_TREE (1<<23)
  97. #define ZEND_SSA_USE_CV_RESULTS (1<<22)
  98. #define CRT_CONSTANT_EX(op_array, opline, node, rt_constants) \
  99. ((rt_constants) ? \
  100. RT_CONSTANT(opline, (node)) \
  101. : \
  102. CT_CONSTANT_EX(op_array, (node).constant) \
  103. )
  104. #define CRT_CONSTANT(node) \
  105. CRT_CONSTANT_EX(op_array, opline, node, (build_flags & ZEND_RT_CONSTANTS))
  106. #define RETURN_VALUE_USED(opline) \
  107. ((opline)->result_type != IS_UNUSED)
  108. BEGIN_EXTERN_C()
  109. int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t build_flags, zend_cfg *cfg);
  110. void zend_cfg_remark_reachable_blocks(const zend_op_array *op_array, zend_cfg *cfg);
  111. int zend_cfg_build_predecessors(zend_arena **arena, zend_cfg *cfg);
  112. int zend_cfg_compute_dominators_tree(const zend_op_array *op_array, zend_cfg *cfg);
  113. int zend_cfg_identify_loops(const zend_op_array *op_array, zend_cfg *cfg);
  114. END_EXTERN_C()
  115. #endif /* ZEND_CFG_H */
  116. /*
  117. * Local variables:
  118. * tab-width: 4
  119. * c-basic-offset: 4
  120. * indent-tabs-mode: t
  121. * End:
  122. */