Skip to content

Commit 131887d

Browse files
committed
Merge branch 'custom_pass'
* custom_pass: Support custom passes in Optimizer
2 parents e2e770c + 2f710f5 commit 131887d

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

Zend/Optimizer/zend_optimizer.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@
3131
#include "zend_inference.h"
3232
#include "zend_dump.h"
3333

34+
#ifndef ZEND_OPTIMIZER_MAX_REGISTERED_PASSES
35+
# define ZEND_OPTIMIZER_MAX_REGISTERED_PASSES 32
36+
#endif
37+
38+
struct {
39+
zend_optimizer_pass_t pass[ZEND_OPTIMIZER_MAX_REGISTERED_PASSES];
40+
int last;
41+
} zend_optimizer_registered_passes = {{NULL}, 0};
42+
3443
static void zend_optimizer_zval_dtor_wrapper(zval *zvalue)
3544
{
3645
zval_ptr_dtor_nogc(zvalue);
@@ -1402,6 +1411,16 @@ static void step_dump_after_optimizer(zend_op_array *op_array, void *context) {
14021411
zend_dump_op_array(op_array, ZEND_DUMP_LIVE_RANGES, "after optimizer", NULL);
14031412
}
14041413

1414+
static void zend_optimizer_call_registered_passes(zend_script *script, void *ctx) {
1415+
for (int i = 0; i < zend_optimizer_registered_passes.last; i++) {
1416+
if (!zend_optimizer_registered_passes.pass[i]) {
1417+
continue;
1418+
}
1419+
1420+
zend_optimizer_registered_passes.pass[i](script, ctx);
1421+
}
1422+
}
1423+
14051424
ZEND_API int zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level)
14061425
{
14071426
zend_class_entry *ce;
@@ -1541,6 +1560,8 @@ ZEND_API int zend_optimize_script(zend_script *script, zend_long optimization_le
15411560
} ZEND_HASH_FOREACH_END();
15421561
} ZEND_HASH_FOREACH_END();
15431562

1563+
zend_optimizer_call_registered_passes(script, &ctx);
1564+
15441565
if ((debug_level & ZEND_DUMP_AFTER_OPTIMIZER) &&
15451566
(ZEND_OPTIMIZER_PASS_7 & optimization_level)) {
15461567
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
15541575
return 1;
15551576
}
15561577

1578+
ZEND_API int zend_optimizer_register_pass(zend_optimizer_pass_t pass)
1579+
{
1580+
if (!pass) {
1581+
return -1;
1582+
}
1583+
1584+
if (zend_optimizer_registered_passes.last == ZEND_OPTIMIZER_MAX_REGISTERED_PASSES) {
1585+
return -1;
1586+
}
1587+
1588+
zend_optimizer_registered_passes.pass[
1589+
zend_optimizer_registered_passes.last++] = pass;
1590+
1591+
return zend_optimizer_registered_passes.last;
1592+
}
1593+
1594+
ZEND_API void zend_optimizer_unregister_pass(int idx)
1595+
{
1596+
zend_optimizer_registered_passes.pass[idx-1] = NULL;
1597+
}
1598+
15571599
int zend_optimizer_startup(void)
15581600
{
15591601
return zend_func_info_startup();

Zend/Optimizer/zend_optimizer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,12 @@ typedef struct _zend_script {
8989
uint32_t first_early_binding_opline; /* the linked list of delayed declarations */
9090
} zend_script;
9191

92+
typedef void (*zend_optimizer_pass_t)(zend_script *, void *context);
93+
9294
BEGIN_EXTERN_C()
9395
ZEND_API int zend_optimize_script(zend_script *script, zend_long optimization_level, zend_long debug_level);
96+
ZEND_API int zend_optimizer_register_pass(zend_optimizer_pass_t pass);
97+
ZEND_API void zend_optimizer_unregister_pass(int idx);
9498
int zend_optimizer_startup(void);
9599
int zend_optimizer_shutdown(void);
96100
END_EXTERN_C()

ext/zend_test/test.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "zend_observer.h"
2929
#include "zend_smart_str.h"
3030
#include "zend_fibers.h"
31+
#include "Zend/Optimizer/zend_optimizer.h"
3132

3233
ZEND_BEGIN_MODULE_GLOBALS(zend_test)
3334
int observer_enabled;
@@ -43,6 +44,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
4344
int observer_nesting_depth;
4445
int observer_fiber_switch;
4546
int replace_zend_execute_ex;
47+
int register_passes;
4648
ZEND_END_MODULE_GLOBALS(zend_test)
4749

4850
ZEND_DECLARE_MODULE_GLOBALS(zend_test)
@@ -86,6 +88,16 @@ static ZEND_FUNCTION(zend_test_void_return)
8688
ZEND_PARSE_PARAMETERS_NONE();
8789
}
8890

91+
static void pass1(zend_script *script, void *context)
92+
{
93+
php_printf("pass1\n");
94+
}
95+
96+
static void pass2(zend_script *script, void *context)
97+
{
98+
php_printf("pass2\n");
99+
}
100+
89101
static ZEND_FUNCTION(zend_test_deprecated)
90102
{
91103
zval *arg1;
@@ -365,6 +377,7 @@ PHP_INI_BEGIN()
365377
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)
366378
STD_PHP_INI_BOOLEAN("zend_test.observer.fiber_switch", "0", PHP_INI_SYSTEM, OnUpdateBool, observer_fiber_switch, zend_zend_test_globals, zend_test_globals)
367379
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)
380+
STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals)
368381
PHP_INI_END()
369382

370383
static zend_observer_fcall_handlers observer_fcall_init(zend_execute_data *execute_data);
@@ -503,6 +516,11 @@ PHP_MINIT_FUNCTION(zend_test)
503516
zend_observer_fiber_switch_register(fiber_suspend_observer);
504517
}
505518

519+
if (ZT_G(register_passes)) {
520+
zend_optimizer_register_pass(pass1);
521+
zend_optimizer_register_pass(pass2);
522+
}
523+
506524
return SUCCESS;
507525
}
508526

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Optimizer: Pass Registration
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable_cli=1
7+
zend_test.register_passes=1
8+
--FILE--
9+
<?php
10+
11+
?>
12+
--EXPECT--
13+
pass1
14+
pass2

0 commit comments

Comments
 (0)