summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--VEX/priv/host_generic_reg_alloc3.c31
2 files changed, 22 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index 097930a..b043c58 100644
--- a/NEWS
+++ b/NEWS
@@ -58,6 +58,7 @@ where XXXXXX is the bug number as listed below.
58384526 reduce number of spill instructions generated by VEX register allocator v3 58384526 reduce number of spill instructions generated by VEX register allocator v3
59384584 Callee saved registers listed first for AMD64, X86, and PPC architectures 59384584 Callee saved registers listed first for AMD64, X86, and PPC architectures
60n-i-bz Fix missing workq_ops operations (macOS) 60n-i-bz Fix missing workq_ops operations (macOS)
61384987 VEX register allocator: allocate caller-save registers for short lived vregs
61385182 PPC64 is missing support for the DSCR 62385182 PPC64 is missing support for the DSCR
62385207 PPC64, generate_store_FPRF() generates too many Iops 63385207 PPC64, generate_store_FPRF() generates too many Iops
63385208 PPC64, xxperm instruction exhausts temporary memory 64385208 PPC64, xxperm instruction exhausts temporary memory
diff --git a/VEX/priv/host_generic_reg_alloc3.c b/VEX/priv/host_generic_reg_alloc3.c
index 9ab9549..0d35c62 100644
--- a/VEX/priv/host_generic_reg_alloc3.c
+++ b/VEX/priv/host_generic_reg_alloc3.c
@@ -408,22 +408,27 @@ static inline HReg find_vreg_to_spill(
408} 408}
409 409
410/* Find a free rreg of the correct class. 410/* Find a free rreg of the correct class.
411 Tries to find an rreg whose live range (if any) is as far ahead in the 411 Tries to find an rreg whose hard live range (if any) starts after the vreg's
412 incoming instruction stream as possible. An ideal rreg candidate is 412 live range ends. If that is not possible, then at least whose live range
413 a callee-save register because it won't be used for parameter passing 413 is as far ahead in the incoming instruction stream as possible.
414 around helper function calls. */ 414 An ideal rreg candidate is a caller-save register for short-lived vregs
415 and a callee-save register for long-lived vregs because it won't need to
416 be spilled around helper calls. */
415static Bool find_free_rreg( 417static Bool find_free_rreg(
416 const VRegState* vreg_state, UInt n_vregs, 418 const VRegState* vreg_state, UInt n_vregs,
417 const RRegState* rreg_state, UInt n_rregs, 419 const RRegState* rreg_state, UInt n_rregs,
418 const RRegLRState* rreg_lr_state, 420 const RRegLRState* rreg_lr_state,
419 UInt current_ii, HRegClass target_hregclass, 421 UInt v_idx, UInt current_ii, HRegClass target_hregclass,
420 Bool reserve_phase, const RegAllocControl* con, UInt* r_idx_found) 422 Bool reserve_phase, const RegAllocControl* con, UInt* r_idx_found)
421{ 423{
422 Bool found = False; 424 Bool found = False;
423 UInt distance_so_far = 0; /* running max for |live_after - current_ii| */ 425 UInt distance_so_far = 0; /* running max for |live_after - current_ii| */
426 const VRegState* vreg = &vreg_state[v_idx];
424 427
425 for (UInt r_idx = con->univ->allocable_start[target_hregclass]; 428 /* Assume majority of vregs are short-lived. Start scannig from caller-save
426 r_idx <= con->univ->allocable_end[target_hregclass]; r_idx++) { 429 registers first. */
430 for (Int r_idx = (Int) con->univ->allocable_end[target_hregclass];
431 r_idx >= (Int) con->univ->allocable_start[target_hregclass]; r_idx--) {
427 const RRegState* rreg = &rreg_state[r_idx]; 432 const RRegState* rreg = &rreg_state[r_idx];
428 const RRegLRState* rreg_lrs = &rreg_lr_state[r_idx]; 433 const RRegLRState* rreg_lrs = &rreg_lr_state[r_idx];
429 if (rreg->disp == Free) { 434 if (rreg->disp == Free) {
@@ -434,7 +439,12 @@ static Bool find_free_rreg(
434 } else { 439 } else {
435 const RRegLR* lr = rreg_lrs->lr_current; 440 const RRegLR* lr = rreg_lrs->lr_current;
436 if (lr->live_after > (Short) current_ii) { 441 if (lr->live_after > (Short) current_ii) {
437 /* Not live, yet. */ 442 /* RReg's hard live range is not live, yet. */
443 if (vreg->effective_dead_before <= lr->live_after) {
444 found = True;
445 *r_idx_found = r_idx;
446 break; /* VReg is short-lived; it fits in. */
447 }
438 if ((lr->live_after - (Short) current_ii) > distance_so_far) { 448 if ((lr->live_after - (Short) current_ii) > distance_so_far) {
439 distance_so_far = lr->live_after - (Short) current_ii; 449 distance_so_far = lr->live_after - (Short) current_ii;
440 found = True; 450 found = True;
@@ -548,8 +558,9 @@ HInstrArray* doRegisterAllocation_v3(
548 ({ \ 558 ({ \
549 UInt _r_free_idx; \ 559 UInt _r_free_idx; \
550 Bool free_rreg_found = find_free_rreg( \ 560 Bool free_rreg_found = find_free_rreg( \
551 vreg_state, n_vregs, rreg_state, n_rregs, rreg_lr_state, \ 561 vreg_state, n_vregs, rreg_state, n_rregs, rreg_lr_state, \
552 (_ii), (_reg_class), (_reserve_phase), con, &_r_free_idx); \ 562 (_v_idx), (_ii), (_reg_class), (_reserve_phase), \
563 con, &_r_free_idx); \
553 if (!free_rreg_found) { \ 564 if (!free_rreg_found) { \
554 HReg vreg_to_spill = find_vreg_to_spill( \ 565 HReg vreg_to_spill = find_vreg_to_spill( \
555 vreg_state, n_vregs, rreg_state, n_rregs, \ 566 vreg_state, n_vregs, rreg_state, n_rregs, \