mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Support custom passes in Optimizer
This commit is contained in:
parent
e2e770c442
commit
2f710f5bb2
4 changed files with 78 additions and 0 deletions
|
@ -31,6 +31,15 @@
|
|||
#include "zend_inference.h"
|
||||
#include "zend_dump.h"
|
||||
|
||||
#ifndef ZEND_OPTIMIZER_MAX_REGISTERED_PASSES
|
||||
# define ZEND_OPTIMIZER_MAX_REGISTERED_PASSES 32
|
||||
#endif
|
||||
|
||||
struct {
|
||||
zend_optimizer_pass_t pass[ZEND_OPTIMIZER_MAX_REGISTERED_PASSES];
|
||||
int last;
|
||||
} zend_optimizer_registered_passes = {{NULL}, 0};
|
||||
|
||||
static void zend_optimizer_zval_dtor_wrapper(zval *zvalue)
|
||||
{
|
||||
zval_ptr_dtor_nogc(zvalue);
|
||||
|
@ -1402,6 +1411,16 @@ static void step_dump_after_optimizer(zend_op_array *op_array, void *context) {
|
|||
zend_dump_op_array(op_array, ZEND_DUMP_LIVE_RANGES, "after optimizer", NULL);
|
||||
}
|
||||
|
||||
static void zend_optimizer_call_registered_passes(zend_script *script, void *ctx) {
|
||||
for (int i = 0; i < zend_optimizer_registered_passes.last; i++) {
|
||||
if (!zend_optimizer_registered_passes.pass[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
zend_optimizer_registered_passes.pass[i](script, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API int zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level)
|
||||
{
|
||||
zend_class_entry *ce;
|
||||
|
@ -1541,6 +1560,8 @@ ZEND_API int zend_optimize_script(zend_script *script, zend_long optimization_le
|
|||
} ZEND_HASH_FOREACH_END();
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
zend_optimizer_call_registered_passes(script, &ctx);
|
||||
|
||||
if ((debug_level & ZEND_DUMP_AFTER_OPTIMIZER) &&
|
||||
(ZEND_OPTIMIZER_PASS_7 & optimization_level)) {
|
||||
zend_foreach_op_array(script, step_dump_after_optimizer, NULL);
|
||||
|
@ -1554,6 +1575,27 @@ ZEND_API int zend_optimize_script(zend_script *script, zend_long optimization_le
|
|||
return 1;
|
||||
}
|
||||
|
||||
ZEND_API int zend_optimizer_register_pass(zend_optimizer_pass_t pass)
|
||||
{
|
||||
if (!pass) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zend_optimizer_registered_passes.last == ZEND_OPTIMIZER_MAX_REGISTERED_PASSES) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
zend_optimizer_registered_passes.pass[
|
||||
zend_optimizer_registered_passes.last++] = pass;
|
||||
|
||||
return zend_optimizer_registered_passes.last;
|
||||
}
|
||||
|
||||
ZEND_API void zend_optimizer_unregister_pass(int idx)
|
||||
{
|
||||
zend_optimizer_registered_passes.pass[idx-1] = NULL;
|
||||
}
|
||||
|
||||
int zend_optimizer_startup(void)
|
||||
{
|
||||
return zend_func_info_startup();
|
||||
|
|
|
@ -89,8 +89,12 @@ typedef struct _zend_script {
|
|||
uint32_t first_early_binding_opline; /* the linked list of delayed declarations */
|
||||
} zend_script;
|
||||
|
||||
typedef void (*zend_optimizer_pass_t)(zend_script *, void *context);
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API int zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level);
|
||||
ZEND_API int zend_optimizer_register_pass(zend_optimizer_pass_t pass);
|
||||
ZEND_API void zend_optimizer_unregister_pass(int idx);
|
||||
int zend_optimizer_startup(void);
|
||||
int zend_optimizer_shutdown(void);
|
||||
END_EXTERN_C()
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "zend_observer.h"
|
||||
#include "zend_smart_str.h"
|
||||
#include "zend_fibers.h"
|
||||
#include "Zend/Optimizer/zend_optimizer.h"
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(zend_test)
|
||||
int observer_enabled;
|
||||
|
@ -43,6 +44,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
|
|||
int observer_nesting_depth;
|
||||
int observer_fiber_switch;
|
||||
int replace_zend_execute_ex;
|
||||
int register_passes;
|
||||
ZEND_END_MODULE_GLOBALS(zend_test)
|
||||
|
||||
ZEND_DECLARE_MODULE_GLOBALS(zend_test)
|
||||
|
@ -86,6 +88,16 @@ static ZEND_FUNCTION(zend_test_void_return)
|
|||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
}
|
||||
|
||||
static void pass1(zend_script *script, void *context)
|
||||
{
|
||||
php_printf("pass1\n");
|
||||
}
|
||||
|
||||
static void pass2(zend_script *script, void *context)
|
||||
{
|
||||
php_printf("pass2\n");
|
||||
}
|
||||
|
||||
static ZEND_FUNCTION(zend_test_deprecated)
|
||||
{
|
||||
zval *arg1;
|
||||
|
@ -365,6 +377,7 @@ PHP_INI_BEGIN()
|
|||
STD_PHP_INI_ENTRY("zend_test.observer.show_opcode_in_user_handler", "", PHP_INI_SYSTEM, OnUpdateString, observer_show_opcode_in_user_handler, zend_zend_test_globals, zend_test_globals)
|
||||
STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_switch", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_switch, zend_zend_test_globals, zend_test_globals)
|
||||
STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals)
|
||||
STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals)
|
||||
PHP_INI_END()
|
||||
|
||||
static zend_observer_fcall_handlers observer_fcall_init(zend_execute_data *execute_data);
|
||||
|
@ -503,6 +516,11 @@ PHP_MINIT_FUNCTION(zend_test)
|
|||
zend_observer_fiber_switch_register(fiber_suspend_observer);
|
||||
}
|
||||
|
||||
if (ZT_G(register_passes)) {
|
||||
zend_optimizer_register_pass(pass1);
|
||||
zend_optimizer_register_pass(pass2);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
|
14
ext/zend_test/tests/optimizer_register_pass.phpt
Normal file
14
ext/zend_test/tests/optimizer_register_pass.phpt
Normal file
|
@ -0,0 +1,14 @@
|
|||
--TEST--
|
||||
Optimizer: Pass Registration
|
||||
--EXTENSIONS--
|
||||
opcache
|
||||
--INI--
|
||||
opcache.enable_cli=1
|
||||
zend_test.register_passes=1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
pass1
|
||||
pass2
|
Loading…
Add table
Add a link
Reference in a new issue