]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Cherry pick 074de238d44c0cdaf394489ea69a67b76916fbce from master. jit-hacks-2
authorIvo Raisr <ivosh@ivosh.net>
Sat, 23 Sep 2017 07:46:40 +0000 (09:46 +0200)
committerIvo Raisr <ivosh@ivosh.net>
Thu, 12 Oct 2017 23:22:26 +0000 (01:22 +0200)
VEX register allocator: allocate caller-save registers for short lived vregs.

Allocate caller-saved registers for short lived vregs and callee-save registers
for vregs which span accross helper calls.
Fixes BZ#384987.

NEWS
VEX/priv/host_generic_reg_alloc3.c

diff --git a/NEWS b/NEWS
index 6b9734ef14bacfe3ed824aac958ed7915ff39445..bf6c0c7bc717f00630a1da753d4cd69720d79188 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -49,6 +49,7 @@ where XXXXXX is the bug number as listed below.
 382998  xml-socket doesn't work
 383275  massif valgrind: m_xarray.c:162 (ensureSpaceXA): Assertion '!xa->arr' failed
 384584  Callee saved registers listed first for AMD64, X86, and PPC architectures
+384987  VEX register allocator: allocate caller-save registers for short lived vregs
 
 Release 3.13.0 (15 June 2017)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index d8e5302df64a7cbd44f78a11f01b4d2b323ada57..7c753820bf696d87fd89a17a4f0c5fc1ad89aa3d 100644 (file)
@@ -632,20 +632,25 @@ static inline HReg find_vreg_to_spill(
 }
 
 /* Find a free rreg of the correct class.
-   Tries to find an rreg whose live range (if any) is as far ahead in the
-   incoming instruction stream as possible. An ideal rreg candidate is
-   a callee-save register because it won't be used for parameter passing
-   around helper function calls. */
+   Tries to find an rreg whose hard live range (if any) starts after the vreg's
+   live range ends. If that is not possible, then at least whose live range
+   is as far ahead in the incoming instruction stream as possible.
+   An ideal rreg candidate is a caller-save register for short-lived vregs
+   and a callee-save register for long-lived vregs because it won't need to
+   be spilled around helper calls. */
 static inline Bool find_free_rreg(
    const RegAllocChunk* chunk, const RegAllocState* state,
-   Short ii_chunk_current, HRegClass target_hregclass,
+   UInt v_idx, Short ii_chunk_current, HRegClass target_hregclass,
    Bool reserve_phase, const RegAllocControl* con, UInt* r_idx_found)
 {
    Bool found = False;
    Short distance_so_far = 0; /* running max for |live_after - current_ii| */
+   const VRegState* vreg = &state->vregs[v_idx];
 
-   for (UInt r_idx = con->univ->allocable_start[target_hregclass];
-        r_idx <= con->univ->allocable_end[target_hregclass]; r_idx++) {
+   /* Assume majority of vregs are short-lived. Start scannig from caller-save
+      registers first. */
+   for (Int r_idx = (Int) con->univ->allocable_end[target_hregclass];
+        r_idx >= (Int) con->univ->allocable_start[target_hregclass]; r_idx--) {
       const RRegState*   rreg     = &state->rregs[r_idx];
       const RRegLRState* rreg_lrs = &chunk->rreg_lr_state[r_idx];
       if (rreg->disp == Free) {
@@ -656,7 +661,12 @@ static inline Bool find_free_rreg(
          } else {
             const RRegLR* lr = rreg_lrs->lr_current;
             if (lr->live_after > ii_chunk_current) {
-               /* Not live, yet. */
+               /* RReg's hard live range is not live, yet. */
+               if (vreg->effective_dead_before <= lr->live_after) {
+                  found = True;
+                  *r_idx_found = r_idx;
+                  break; /* VReg is short-lived; it fits in. */
+               }
                if ((lr->live_after - ii_chunk_current) > distance_so_far) {
                   distance_so_far = lr->live_after - ii_chunk_current;
                   found = True;
@@ -1294,9 +1304,9 @@ static void stage5_chunk(RegAllocChunk* chunk, RegAllocState* state,
 #  define FIND_OR_MAKE_FREE_RREG(_v_idx, _reg_class, _reserve_phase)           \
    ({                                                                          \
       UInt _r_free_idx;                                                        \
-      Bool free_rreg_found = find_free_rreg(chunk, state,                      \
-                                     ii_chunk, (_reg_class), (_reserve_phase), \
-                                     con, &_r_free_idx);                       \
+      Bool free_rreg_found = find_free_rreg(chunk, state, (_v_idx), ii_chunk,  \
+                                            (_reg_class), (_reserve_phase),    \
+                                            con, &_r_free_idx);                \
       if (!free_rreg_found) {                                                  \
          HReg vreg_to_spill = find_vreg_to_spill(chunk, state,                 \
                                     &chunk->reg_usage[ii_chunk], (_reg_class), \