summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2020-10-20 12:19:44 +0300
committerDmitry Stogov <dmitry@zend.com>2020-10-20 12:19:44 +0300
commitea1590937b9923eb0ef370123b8dfbf46a535f37 (patch)
tree1a92d891c14572e2ce065a355afbd46012878117
parent87d2bb7424e776833480be778c42816a7911c423 (diff)
downloadphp-git-ea1590937b9923eb0ef370123b8dfbf46a535f37.tar.gz
Improve register allocator (give preference to loop variables).
-rw-r--r--ext/opcache/jit/zend_jit.c4
-rw-r--r--ext/opcache/jit/zend_jit_trace.c14
2 files changed, 16 insertions, 2 deletions
diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c
index 4794a1c0d7..6b16f83d51 100644
--- a/ext/opcache/jit/zend_jit.c
+++ b/ext/opcache/jit/zend_jit.c
@@ -964,7 +964,7 @@ static zend_lifetime_interval *zend_jit_sort_intervals(zend_lifetime_interval **
if (ival) {
if ((ival->range.start > last->range.start) ||
(ival->range.start == last->range.start &&
- ((!ival->hint && last->hint) ||
+ ((!ival->hint && last->hint && last->hint != ival) ||
ival->range.end > last->range.end))) {
last->list_next = ival;
last = ival;
@@ -979,7 +979,7 @@ static zend_lifetime_interval *zend_jit_sort_intervals(zend_lifetime_interval **
break;
} else if ((ival->range.start < (*p)->range.start) ||
(ival->range.start == (*p)->range.start &&
- ((ival->hint && !(*p)->hint) ||
+ ((ival->hint && !(*p)->hint && ival->hint != *p) ||
ival->range.end < (*p)->range.end))) {
ival->list_next = *p;
*p = ival;
diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c
index a6d27caece..2353ec0a93 100644
--- a/ext/opcache/jit/zend_jit_trace.c
+++ b/ext/opcache/jit/zend_jit_trace.c
@@ -2641,12 +2641,26 @@ static zend_lifetime_interval** zend_jit_trace_allocate_registers(zend_jit_trace
intervals[ssa->ops[line].op1_use] &&
ssa->ops[line].op1_use_chain < 0 &&
!ssa->vars[ssa->ops[line].op1_use].phi_use_chain) {
+
+ zend_ssa_phi *phi = ssa->vars[ssa->ops[line].op1_use].definition_phi;
+ if (phi &&
+ intervals[phi->sources[1]] &&
+ intervals[phi->sources[1]]->hint == intervals[ssa->ops[line].op1_use]) {
+ break;
+ }
zend_jit_add_hint(intervals, i, ssa->ops[line].op1_use);
} else if (opline->opcode != ZEND_SUB &&
ssa->ops[line].op2_use >= 0 &&
intervals[ssa->ops[line].op2_use] &&
ssa->ops[line].op2_use_chain < 0 &&
!ssa->vars[ssa->ops[line].op2_use].phi_use_chain) {
+
+ zend_ssa_phi *phi = ssa->vars[ssa->ops[line].op2_use].definition_phi;
+ if (phi &&
+ intervals[phi->sources[1]] &&
+ intervals[phi->sources[1]]->hint == intervals[ssa->ops[line].op2_use]) {
+ break;
+ }
zend_jit_add_hint(intervals, i, ssa->ops[line].op2_use);
}
}